[llvm-commits] [llvm] r119144 - in /llvm/trunk: include/llvm/MC/MCSymbol.h lib/MC/MCParser/AsmParser.cpp lib/MC/MCSymbol.cpp test/MC/ELF/set.s
Rafael Espindola
rafael.espindola at gmail.com
Mon Nov 15 06:40:36 PST 2010
Author: rafael
Date: Mon Nov 15 08:40:36 2010
New Revision: 119144
URL: http://llvm.org/viewvc/llvm-project?rev=119144&view=rev
Log:
Fix PR8565.
This moves most of the isUsed logic to the MCSymbol itself. With this we
get a bit more relaxed about allowing definitions after uses: uses that
don't evaluate their argument immediately (jmp foo) are accepted.
ddunbar, this was the smallest compromise I could think of that lets us
accept gcc (and clang!) assembly.
Added:
llvm/trunk/test/MC/ELF/set.s
Modified:
llvm/trunk/include/llvm/MC/MCSymbol.h
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
llvm/trunk/lib/MC/MCSymbol.cpp
Modified: llvm/trunk/include/llvm/MC/MCSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSymbol.h?rev=119144&r1=119143&r2=119144&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSymbol.h (original)
+++ llvm/trunk/include/llvm/MC/MCSymbol.h Mon Nov 15 08:40:36 2010
@@ -52,15 +52,14 @@
/// "Lfoo" or ".foo".
unsigned IsTemporary : 1;
- /// IsUsedInExpr - True if this symbol has been used in an expression and
- /// cannot be redefined.
- unsigned IsUsedInExpr : 1;
+ /// IsUsed - True if this symbol has been used.
+ mutable unsigned IsUsed : 1;
private: // MCContext creates and uniques these.
friend class MCContext;
MCSymbol(StringRef name, bool isTemporary)
: Name(name), Section(0), Value(0),
- IsTemporary(isTemporary), IsUsedInExpr(false) {}
+ IsTemporary(isTemporary), IsUsed(false) {}
MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT
void operator=(const MCSymbol&); // DO NOT IMPLEMENT
@@ -74,9 +73,9 @@
/// isTemporary - Check if this is an assembler temporary symbol.
bool isTemporary() const { return IsTemporary; }
- /// isUsedInExpr - Check if this is an assembler temporary symbol.
- bool isUsedInExpr() const { return IsUsedInExpr; }
- void setUsedInExpr(bool Value) { IsUsedInExpr = Value; }
+ /// isUsed - Check if this is used.
+ bool isUsed() const { return IsUsed; }
+ void setUsed(bool Value) const { IsUsed = Value; }
/// @}
/// @name Associated Sections
@@ -135,6 +134,7 @@
/// getValue() - Get the value for variable symbols.
const MCExpr *getVariableValue() const {
assert(isVariable() && "Invalid accessor!");
+ IsUsed = true;
return Value;
}
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=119144&r1=119143&r2=119144&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Mon Nov 15 08:40:36 2010
@@ -485,9 +485,6 @@
std::pair<StringRef, StringRef> Split = Identifier.split('@');
MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first);
- // Mark the symbol as used in an expression.
- Sym->setUsedInExpr(true);
-
// Lookup the symbol variant if used.
MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
if (Split.first.size() != Identifier.size()) {
@@ -1191,6 +1188,25 @@
ActiveMacros.pop_back();
}
+static void MarkUsed(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);
+ break;
+ }
+ case MCExpr::Unary:
+ MarkUsed(static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
+ break;
+ }
+}
+
bool AsmParser::ParseAssignment(StringRef Name) {
// FIXME: Use better location, we should use proper tokens.
SMLoc EqualLoc = Lexer.getLoc();
@@ -1199,6 +1215,8 @@
if (ParseExpression(Value))
return true;
+ MarkUsed(Value);
+
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in assignment");
@@ -1213,7 +1231,7 @@
//
// 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->isUsedInExpr())
+ if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
; // Allow redefinitions of undefined symbols only used in directives.
else if (!Sym->isUndefined() && !Sym->isAbsolute())
return Error(EqualLoc, "redefinition of '" + Name + "'");
@@ -1222,13 +1240,14 @@
else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
Name + "'");
+
+ // Don't count these checks as uses.
+ Sym->setUsed(false);
} else
Sym = getContext().GetOrCreateSymbol(Name);
// FIXME: Handle '.'.
- Sym->setUsedInExpr(true);
-
// Do the assignment.
Out.EmitAssignment(Sym, Value);
Modified: llvm/trunk/lib/MC/MCSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSymbol.cpp?rev=119144&r1=119143&r2=119144&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCSymbol.cpp (original)
+++ llvm/trunk/lib/MC/MCSymbol.cpp Mon Nov 15 08:40:36 2010
@@ -40,6 +40,7 @@
}
void MCSymbol::setVariableValue(const MCExpr *Value) {
+ assert(!IsUsed && "Cannot set a variable that has already been used.");
assert(Value && "Invalid variable value!");
assert((isUndefined() || (isAbsolute() && isa<MCConstantExpr>(Value))) &&
"Invalid redefinition!");
Added: llvm/trunk/test/MC/ELF/set.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/set.s?rev=119144&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/set.s (added)
+++ llvm/trunk/test/MC/ELF/set.s Mon Nov 15 08:40:36 2010
@@ -0,0 +1,21 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s
+
+// Test that we accept .set of a symbol after it has been used in a statement.
+
+ jmp foo
+ .set foo, bar
+
+// or a .quad
+
+ .quad foo2
+ .set foo2,bar2
+
+// Test that there is an undefined reference to bar
+// CHECK: (('st_name', 0x00000001) # 'bar'
+// CHECK-NEXT: ('st_bind', 0x00000001)
+// CHECK-NEXT: ('st_type', 0x00000000)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000000)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
More information about the llvm-commits
mailing list