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
This commit is contained in:
Rafael Espindola 2012-01-28 05:57:00 +00:00
parent f1639abf1a
commit e71cc86ad1
3 changed files with 31 additions and 15 deletions

View 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());
break;
case MCExpr::Target:
case MCExpr::Constant:
break;
case MCExpr::SymbolRef: {
static_cast<const MCSymbolRefExpr*>(Value)->getSymbol().setUsed(true);
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:
return false;
case MCExpr::SymbolRef: {
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 + "'");

View File

@ -0,0 +1,6 @@
// RUN: llvm-mc -triple i386-unknown-unknown %s
i:
.long g
g = h
h = i

View 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