From 7e2b51ddb0c31251240930f408c8f60aac2448ed Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Mon, 26 Oct 2015 02:45:50 +0000 Subject: [PATCH] [MC] Don't crash when .word is given bogus values We didn't validate that the .word directive was given a sane value, leading to crashes when we attempt to write out the object file. Instead, perform some validation and issue a diagnostic pointing at the start of the diagnostic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251270 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp | 11 ++++++++++- lib/Target/X86/AsmParser/X86AsmParser.cpp | 11 ++++++++++- test/MC/AsmParser/exprs-invalid.s | 3 +++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index 1ad3d07831a..85d3fa39181 100644 --- a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -1730,10 +1730,19 @@ bool PPCAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { if (getLexer().isNot(AsmToken::EndOfStatement)) { for (;;) { const MCExpr *Value; + SMLoc ExprLoc = getLexer().getLoc(); if (getParser().parseExpression(Value)) return false; - getParser().getStreamer().EmitValue(Value, Size); + if (const auto *MCE = dyn_cast(Value)) { + assert(Size <= 8 && "Invalid size"); + uint64_t IntValue = MCE->getValue(); + if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) + return Error(ExprLoc, "literal value out of range for directive"); + getStreamer().EmitIntValue(IntValue, Size); + } else { + getStreamer().EmitValue(Value, Size, ExprLoc); + } if (getLexer().is(AsmToken::EndOfStatement)) break; diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 159fcc1dafb..1760bce4a35 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2831,10 +2831,19 @@ bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { if (getLexer().isNot(AsmToken::EndOfStatement)) { for (;;) { const MCExpr *Value; + SMLoc ExprLoc = getLexer().getLoc(); if (getParser().parseExpression(Value)) return false; - getParser().getStreamer().EmitValue(Value, Size); + if (const auto *MCE = dyn_cast(Value)) { + assert(Size <= 8 && "Invalid size"); + uint64_t IntValue = MCE->getValue(); + if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue)) + return Error(ExprLoc, "literal value out of range for directive"); + getStreamer().EmitIntValue(IntValue, Size); + } else { + getStreamer().EmitValue(Value, Size, ExprLoc); + } if (getLexer().is(AsmToken::EndOfStatement)) break; diff --git a/test/MC/AsmParser/exprs-invalid.s b/test/MC/AsmParser/exprs-invalid.s index 88b2a0a486b..d2f29248967 100644 --- a/test/MC/AsmParser/exprs-invalid.s +++ b/test/MC/AsmParser/exprs-invalid.s @@ -12,3 +12,6 @@ // CHECK-ERRORS: error: literal value out of range for directive .long 4e71cf69 // double floating point constant due to missing "0x" + +// CHECK-ERRORS: error: literal value out of range for directive +.word 0xfffffffff -- 2.34.1