Fix pr13145 - Naming a function like a register name confuses the asm parser.
authorChad Rosier <mcrosier@apple.com>
Tue, 19 Mar 2013 23:44:03 +0000 (23:44 +0000)
committerChad Rosier <mcrosier@apple.com>
Tue, 19 Mar 2013 23:44:03 +0000 (23:44 +0000)
Patch by Stepan Dyatkovskiy <stpworld@narod.ru>
rdar://13457826

llvm-svn: 177463

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/test/MC/ARM/2013-03-18-Br-to-label-named-like-reg.s [new file with mode: 0644]

index c897efd..ed7b7ec 100644 (file)
@@ -4593,20 +4593,26 @@ bool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
     Error(Parser.getTok().getLoc(), "unexpected token in operand");
     return true;
   case AsmToken::Identifier: {
-    if (!tryParseRegisterWithWriteBack(Operands))
-      return false;
-    int Res = tryParseShiftRegister(Operands);
-    if (Res == 0) // success
-      return false;
-    else if (Res == -1) // irrecoverable error
-      return true;
-    // If this is VMRS, check for the apsr_nzcv operand.
-    if (Mnemonic == "vmrs" &&
-        Parser.getTok().getString().equals_lower("apsr_nzcv")) {
-      S = Parser.getTok().getLoc();
-      Parser.Lex();
-      Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S));
-      return false;
+    // If we've seen a branch mnemonic, the next operand must be a label.  This
+    // is true even if the label is a register name.  So "br r1" means branch to
+    // label "r1".
+    bool ExpectLabel = Mnemonic == "b" || Mnemonic == "bl";
+    if (!ExpectLabel) {
+      if (!tryParseRegisterWithWriteBack(Operands))
+        return false;
+      int Res = tryParseShiftRegister(Operands);
+      if (Res == 0) // success
+        return false;
+      else if (Res == -1) // irrecoverable error
+        return true;
+      // If this is VMRS, check for the apsr_nzcv operand.
+      if (Mnemonic == "vmrs" &&
+          Parser.getTok().getString().equals_lower("apsr_nzcv")) {
+        S = Parser.getTok().getLoc();
+        Parser.Lex();
+        Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S));
+        return false;
+      }
     }
 
     // Fall though for the Identifier case that is not a register or a
diff --git a/llvm/test/MC/ARM/2013-03-18-Br-to-label-named-like-reg.s b/llvm/test/MC/ARM/2013-03-18-Br-to-label-named-like-reg.s
new file mode 100644 (file)
index 0000000..172abcf
--- /dev/null
@@ -0,0 +1,5 @@
+@ RUN: llvm-mc -arch arm %s
+@ CHECK: test:
+@ CHECK: br r1
+test:
+  bl r1