[MC/AsmParser] Avoid setting MCSymbol.IsUsed in some cases
authorVedant Kumar <vsk@apple.com>
Mon, 31 Aug 2015 17:44:53 +0000 (17:44 +0000)
committerVedant Kumar <vsk@apple.com>
Mon, 31 Aug 2015 17:44:53 +0000 (17:44 +0000)
Avoid marking some MCSymbols as used in MC/AsmParser.cpp when no uses
exist. This fixes a bug in parseAssignmentExpression() which
inadvertently sets IsUsed, thereby triggering:

    "invalid re-assignment of non-absolute variable"

on otherwise valid code. No other functionality change intended.

The original version of this patch touched many calls to MCSymbol
accessors. On rafael's advice, I have stripped this patch down a bit.

As a follow-up, I intend to find the call sites which intentionally set
IsUsed and force them to do so explicitly.

Differential Revision: http://reviews.llvm.org/D12347

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

include/llvm/MC/MCSymbol.h
lib/MC/MCParser/AsmParser.cpp
test/MC/AsmParser/reassign.s [new file with mode: 0644]

index a48a09e6a75b871b0133afb5c2dd98cbe577b3db..563fa803b0e4b2bc1f30d41891babae3585f1727 100644 (file)
@@ -223,7 +223,7 @@ public:
 
   /// isUsed - Check if this is used.
   bool isUsed() const { return IsUsed; }
-  void setUsed(bool Value) const { IsUsed = Value; }
+  void setUsed(bool Value) const { IsUsed |= Value; }
 
   /// \brief Check if this symbol is redefinable.
   bool isRedefinable() const { return IsRedefinable; }
index 3f45b3d85a38683294cc6187f908681683e82b6e..5e174de8a9335cdf9a4ac36a15cbd5fa07233c9e 100644 (file)
@@ -693,9 +693,9 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
         // FIXME: We would really like to refer back to where the symbol was
         // first referenced for a source location. We need to add something
         // to track that. Currently, we just point to the end of the file.
-        printMessage(
-            getLexer().getLoc(), SourceMgr::DK_Error,
-            "assembler local symbol '" + Sym->getName() + "' not defined");
+        printMessage(getLexer().getLoc(), SourceMgr::DK_Error,
+                     "assembler local symbol '" + Sym->getName() +
+                         "' not defined");
     }
   }
 
@@ -867,11 +867,12 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
 
     // If this is an absolute variable reference, substitute it now to preserve
     // semantics in the face of reassignment.
-    if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) {
+    if (Sym->isVariable() &&
+        isa<MCConstantExpr>(Sym->getVariableValue(/*SetUsed*/ false))) {
       if (Variant)
         return Error(EndLoc, "unexpected modifier on variable reference");
 
-      Res = Sym->getVariableValue();
+      Res = Sym->getVariableValue(/*SetUsed*/ false);
       return false;
     }
 
@@ -4805,7 +4806,8 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
     // FIXME: Diagnose assignment to protected identifier (e.g., register name).
     if (isSymbolUsedInExpression(Sym, Value))
       return Parser.Error(EqualLoc, "Recursive use of '" + Name + "'");
-    else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
+    else if (Sym->isUndefined(/*SetUsed*/ false) && !Sym->isUsed() &&
+             !Sym->isVariable())
       ; // Allow redefinitions of undefined symbols only used in directives.
     else if (Sym->isVariable() && !Sym->isUsed() && allow_redef)
       ; // Allow redefinitions of variables that haven't yet been used.
@@ -4817,9 +4819,6 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
       return Parser.Error(EqualLoc,
                           "invalid reassignment of non-absolute variable '" +
                               Name + "'");
-
-    // Don't count these checks as uses.
-    Sym->setUsed(false);
   } else if (Name == ".") {
     if (Parser.getStreamer().EmitValueToOffset(Value, 0)) {
       Parser.Error(EqualLoc, "expected absolute expression");
diff --git a/test/MC/AsmParser/reassign.s b/test/MC/AsmParser/reassign.s
new file mode 100644 (file)
index 0000000..817836b
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+
+       .text
+bar:
+
+       .data
+.globl foo
+.set   foo, bar
+.globl foo
+.set   foo, bar
+
+// CHECK-NOT: invalid reassignment of non-absolute variable