[llvm-commits] [llvm] r135055 - in /llvm/trunk: lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/diagnostics.s

Jim Grosbach grosbach at apple.com
Wed Jul 13 11:49:30 PDT 2011


Author: grosbach
Date: Wed Jul 13 13:49:30 2011
New Revision: 135055

URL: http://llvm.org/viewvc/llvm-project?rev=135055&view=rev
Log:
Improve ARM assembly parsing diagnostics a bit.

Catch potential cascading errors on a malformed so_reg operand and bail after
the first error.

Add some tests for the diagnostics we do want.


Added:
    llvm/trunk/test/MC/ARM/diagnostics.s
Modified:
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=135055&r1=135054&r2=135055&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Wed Jul 13 13:49:30 2011
@@ -53,7 +53,7 @@
   int TryParseRegister();
   virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
   bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
-  bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
+  int TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
                    ARMII::AddrMode AddrMode);
@@ -1017,11 +1017,12 @@
   return RegNum;
 }
 
-/// Try to parse a register name.  The token must be an Identifier when called,
-/// and if it is a register name the token is eaten and the register number is
-/// returned.  Otherwise return -1.
-///
-bool ARMAsmParser::TryParseShiftRegister(
+// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
+// If a recoverable error occurs, return 1. If an irrecoverable error
+// occurs, return -1. An irrecoverable error is one where tokens have been
+// consumed in the process of trying to parse the shifter (i.e., when it is
+// indeed a shifter operand, but malformed).
+int ARMAsmParser::TryParseShiftRegister(
                                SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   SMLoc S = Parser.getTok().getLoc();
   const AsmToken &Tok = Parser.getTok();
@@ -1038,7 +1039,7 @@
       .Default(ARM_AM::no_shift);
 
   if (ShiftTy == ARM_AM::no_shift)
-    return true;
+    return 1;
 
   Parser.Lex(); // Eat the operator.
 
@@ -1062,12 +1063,16 @@
       Parser.Lex(); // Eat hash.
       SMLoc ImmLoc = Parser.getTok().getLoc();
       const MCExpr *ShiftExpr = 0;
-      if (getParser().ParseExpression(ShiftExpr))
-        return Error(ImmLoc, "invalid immediate shift value");
+      if (getParser().ParseExpression(ShiftExpr)) {
+        Error(ImmLoc, "invalid immediate shift value");
+        return -1;
+      }
       // The expression must be evaluatable as an immediate.
       const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
-      if (!CE)
-        return Error(ImmLoc, "invalid immediate shift value");
+      if (!CE) {
+        Error(ImmLoc, "invalid immediate shift value");
+        return -1;
+      }
       // Range check the immediate.
       // lsl, ror: 0 <= imm <= 31
       // lsr, asr: 0 <= imm <= 32
@@ -1075,24 +1080,28 @@
       if (Imm < 0 ||
           ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
           ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
-        return Error(ImmLoc, "immediate shift value out of range");
+        Error(ImmLoc, "immediate shift value out of range");
+        return -1;
       }
     } else if (Parser.getTok().is(AsmToken::Identifier)) {
       ShiftReg = TryParseRegister();
       SMLoc L = Parser.getTok().getLoc();
-      if (ShiftReg == -1)
-        return Error (L, "expected immediate or register in shift operand");
-    } else
-      return Error (Parser.getTok().getLoc(),
+      if (ShiftReg == -1) {
+        Error (L, "expected immediate or register in shift operand");
+        return -1;
+      }
+    } else {
+      Error (Parser.getTok().getLoc(),
                     "expected immediate or register in shift operand");
+      return -1;
+    }
   }
 
-
   Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
                                                        ShiftReg, Imm,
                                                S, Parser.getTok().getLoc()));
 
-  return false;
+  return 0;
 }
 
 
@@ -1737,15 +1746,18 @@
   default:
     Error(Parser.getTok().getLoc(), "unexpected token in operand");
     return true;
-  case AsmToken::Identifier:
+  case AsmToken::Identifier: {
     if (!TryParseRegisterWithWriteBack(Operands))
       return false;
-    if (!TryParseShiftRegister(Operands))
+    int Res = TryParseShiftRegister(Operands);
+    if (Res == 0) // success
       return false;
-
+    else if (Res == -1) // irrecoverable error
+      return true;
 
     // Fall though for the Identifier case that is not a register or a
     // special name.
+  }
   case AsmToken::Integer: // things like 1f and 2b as a branch targets
   case AsmToken::Dot: {   // . as a branch target
     // This was not a register so parse other operands that start with an

Added: llvm/trunk/test/MC/ARM/diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/diagnostics.s?rev=135055&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/diagnostics.s (added)
+++ llvm/trunk/test/MC/ARM/diagnostics.s Wed Jul 13 13:49:30 2011
@@ -0,0 +1,43 @@
+@ RUN: not llvm-mc -triple=armv7-apple-darwin < %s 2> %t
+@ RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
+
+@ Check for various assembly diagnostic messages on invalid input.
+
+        @ Out of range shift immediate values.
+        adc r1, r2, r3, lsl #invalid
+        adc r4, r5, r6, lsl #-1
+        adc r4, r5, r6, lsl #32
+        adc r4, r5, r6, lsr #-1
+        adc r4, r5, r6, lsr #33
+        adc r4, r5, r6, asr #-1
+        adc r4, r5, r6, asr #33
+        adc r4, r5, r6, ror #-1
+        adc r4, r5, r6, ror #32
+
+@ CHECK-ERRORS: error: invalid immediate shift value
+@ CHECK-ERRORS:         adc r1, r2, r3, lsl #invalid
+@ CHECK-ERRORS:                              ^
+@ CHECK-ERRORS: error: immediate shift value out of range
+@ CHECK-ERRORS:         adc r4, r5, r6, lsl #-1
+@ CHECK-ERRORS:                              ^
+@ CHECK-ERRORS: error: immediate shift value out of range
+@ CHECK-ERRORS:         adc r4, r5, r6, lsl #32
+@ CHECK-ERRORS:                              ^
+@ CHECK-ERRORS: error: immediate shift value out of range
+@ CHECK-ERRORS:         adc r4, r5, r6, lsr #-1
+@ CHECK-ERRORS:                              ^
+@ CHECK-ERRORS: error: immediate shift value out of range
+@ CHECK-ERRORS:         adc r4, r5, r6, lsr #33
+@ CHECK-ERRORS:                              ^
+@ CHECK-ERRORS: error: immediate shift value out of range
+@ CHECK-ERRORS:         adc r4, r5, r6, asr #-1
+@ CHECK-ERRORS:                              ^
+@ CHECK-ERRORS: error: immediate shift value out of range
+@ CHECK-ERRORS:         adc r4, r5, r6, asr #33
+@ CHECK-ERRORS:                              ^
+@ CHECK-ERRORS: error: immediate shift value out of range
+@ CHECK-ERRORS:         adc r4, r5, r6, ror #-1
+@ CHECK-ERRORS:                              ^
+@ CHECK-ERRORS: error: immediate shift value out of range
+@ CHECK-ERRORS:         adc r4, r5, r6, ror #32
+@ CHECK-ERRORS:                              ^





More information about the llvm-commits mailing list