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 | e71cc86ad10143173195182f28bf90844f682436 (patch) | |
tree | 2fd46ef7768e4eeb74c0a98185f3e6beeea27f37 /lib/MC | |
parent | f1639abf1aaba1448f719f595156cd0f4cd560cc (diff) | |
download | external_llvm-e71cc86ad10143173195182f28bf90844f682436.zip external_llvm-e71cc86ad10143173195182f28bf90844f682436.tar.gz external_llvm-e71cc86ad10143173195182f28bf90844f682436.tar.bz2 |
Handle recursive variable definitions directly. This gives us better error
messages and allows us to fix PR11865.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149174 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 1af7cd9..8acdf38 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/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 + "'"); |