[MC] Don't crash when .word is given bogus values
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 26 Oct 2015 02:45:50 +0000 (02:45 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 26 Oct 2015 02:45:50 +0000 (02:45 +0000)
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
lib/Target/X86/AsmParser/X86AsmParser.cpp
test/MC/AsmParser/exprs-invalid.s

index 1ad3d07831af36c9c9c7b83b5e2b9466c4d388c0..85d3fa391811c72e074fbfe199bad6d992b777ce 100644 (file)
@@ -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<MCConstantExpr>(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;
index 159fcc1dafb1d3d14b60924ff880029aad0e731d..1760bce4a35d2f8cf4188ad48356c75023fe02c0 100644 (file)
@@ -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<MCConstantExpr>(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;
index 88b2a0a486bc0feb630c8e65d9d6f8cf0301fc71..d2f29248967cc1bbd63db62aa47bba3bb2a51994 100644 (file)
@@ -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