diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-01-28 05:57:00 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-01-28 05:57:00 +0000 |
commit | 72f5f170c6bd1503dfebf7200e815e0952584064 (patch) | |
tree | f3f621317051fe1dfd88ff0ea5f1226f39ca626d | |
parent | 059cac4db41c0213c71ecb9dbe949ef8e4887340 (diff) | |
download | bcm5719-llvm-72f5f170c6bd1503dfebf7200e815e0952584064.tar.gz bcm5719-llvm-72f5f170c6bd1503dfebf7200e815e0952584064.zip |
Handle recursive variable definitions directly. This gives us better error
messages and allows us to fix PR11865.
llvm-svn: 149174
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 26 | ||||
-rw-r--r-- | llvm/test/MC/AsmParser/pr11865.s | 6 | ||||
-rw-r--r-- | llvm/test/MC/AsmParser/variables-invalid.s | 8 |
3 files changed, 28 insertions, 12 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 1af7cd9ee0d..8acdf384004 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -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/llvm/test/MC/AsmParser/pr11865.s b/llvm/test/MC/AsmParser/pr11865.s new file mode 100644 index 00000000000..1c03e117d98 --- /dev/null +++ b/llvm/test/MC/AsmParser/pr11865.s @@ -0,0 +1,6 @@ +// RUN: llvm-mc -triple i386-unknown-unknown %s + +i: + .long g +g = h +h = i diff --git a/llvm/test/MC/AsmParser/variables-invalid.s b/llvm/test/MC/AsmParser/variables-invalid.s index 9656889c5b1..c0f6c398767 100644 --- a/llvm/test/MC/AsmParser/variables-invalid.s +++ b/llvm/test/MC/AsmParser/variables-invalid.s @@ -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 |