Handle recursive variable definitions directly. This gives us better error
authorRafael Espindola <rafael.espindola@gmail.com>
Sat, 28 Jan 2012 05:57:00 +0000 (05:57 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Sat, 28 Jan 2012 05:57:00 +0000 (05:57 +0000)
messages and allows us to fix PR11865.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149174 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/MCParser/AsmParser.cpp
test/MC/AsmParser/pr11865.s [new file with mode: 0644]
test/MC/AsmParser/variables-invalid.s

index 1af7cd9ee0d9694972ffd29bb8f494e503bf184b..8acdf38400410b6ceea0234eafa8e2e194f5aa0e 100644 (file)
@@ -1553,22 +1553,22 @@ void AsmParser::HandleMacroExit() {
   ActiveMacros.pop_back();
 }
 
-static void MarkUsed(const MCExpr *Value) {
+static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) {
   switch (Value->getKind()) {
-  case MCExpr::Binary:
-    MarkUsed(static_cast<const MCBinaryExpr*>(Value)->getLHS());
-    MarkUsed(static_cast<const MCBinaryExpr*>(Value)->getRHS());
+  case MCExpr::Binary: {
+    const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value);
+    return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS());
     break;
+  }
   case MCExpr::Target:
   case MCExpr::Constant:
-    break;
+    return false;
   case MCExpr::SymbolRef: {
-    static_cast<const MCSymbolRefExpr*>(Value)->getSymbol().setUsed(true);
-    break;
+    const MCSymbol &S = static_cast<const MCSymbolRefExpr*>(Value)->getSymbol();
+    return &S.AliasedSymbol() == Sym;
   }
   case MCExpr::Unary:
-    MarkUsed(static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
-    break;
+    return IsUsedIn(Sym, static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
   }
 }
 
@@ -1580,7 +1580,9 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
   if (ParseExpression(Value))
     return true;
 
-  MarkUsed(Value);
+  // Note: we don't count b as used in "a = b". This is to allow
+  // a = b
+  // b = c
 
   if (Lexer.isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in assignment");
@@ -1602,7 +1604,9 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
     //
     // FIXME: Diagnostics. Note the location of the definition as a label.
     // FIXME: Diagnose assignment to protected identifier (e.g., register name).
-    if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
+    if (IsUsedIn(Sym, Value))
+      return Error(EqualLoc, "Recursive use of '" + Name + "'");
+    else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
       ; // Allow redefinitions of undefined symbols only used in directives.
     else if (!Sym->isUndefined() && (!Sym->isVariable() || !allow_redef))
       return Error(EqualLoc, "redefinition of '" + Name + "'");
diff --git a/test/MC/AsmParser/pr11865.s b/test/MC/AsmParser/pr11865.s
new file mode 100644 (file)
index 0000000..1c03e11
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: llvm-mc -triple i386-unknown-unknown %s
+
+i:
+        .long    g
+g = h
+h = i
index 9656889c5b1a5ec02855cc40e4703f7c6d5dfbc4..c0f6c3987676c18e0d0c93048738f52c32e83b29 100644 (file)
@@ -2,7 +2,7 @@
 // RUN: FileCheck --input-file %t %s
 
         .data
-// CHECK: invalid assignment to 't0_v0'
+// CHECK: Recursive use of 't0_v0'
         t0_v0 = t0_v0 + 1
 
         t1_v1 = 1
@@ -15,3 +15,9 @@ t2_s0:
         t3_s0 = t2_s0 + 1
 // CHECK: invalid reassignment of non-absolute variable 't3_s0'
         t3_s0 = 1
+
+
+// CHECK: Recursive use of 't4_s2'
+        t4_s0 = t4_s1
+        t4_s1 = t4_s2
+        t4_s2 = t4_s0