From: David Majnemer Date: Wed, 24 Dec 2014 10:27:50 +0000 (+0000) Subject: MC: Label definitions are permitted after .set directives X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e54eacce75b781e344cdf1c844c2b7deb0b565d4;p=oota-llvm.git MC: Label definitions are permitted after .set directives .set directives may be overridden by other .set directives as well as label definitions. This fixes PR22019. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224811 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 0b3c3ceb210..47a8789d463 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -53,6 +53,9 @@ namespace llvm { /// "Lfoo" or ".foo". unsigned IsTemporary : 1; + /// \brief True if this symbol can be redefined. + unsigned IsRedefinable : 1; + /// IsUsed - True if this symbol has been used. mutable unsigned IsUsed : 1; @@ -61,7 +64,7 @@ namespace llvm { friend class MCContext; MCSymbol(StringRef name, bool isTemporary) : Name(name), Section(nullptr), Value(nullptr), - IsTemporary(isTemporary), IsUsed(false) {} + IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false) {} MCSymbol(const MCSymbol&) LLVM_DELETED_FUNCTION; void operator=(const MCSymbol&) LLVM_DELETED_FUNCTION; @@ -79,6 +82,19 @@ namespace llvm { bool isUsed() const { return IsUsed; } void setUsed(bool Value) const { IsUsed = Value; } + /// \brief Check if this symbol is redefinable. + bool isRedefinable() const { return IsRedefinable; } + /// \brief Mark this symbol as redefinable. + void setRedefinable(bool Value) { IsRedefinable = Value; } + /// \brief Prepare this symbol to be redefined. + void redefineIfPossible() { + if (IsRedefinable) { + Value = nullptr; + Section = nullptr; + IsRedefinable = false; + } + } + /// @} /// @name Associated Sections /// @{ diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 69e3a5df919..ec7da6b99c4 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -541,6 +541,8 @@ void AsmPrinter::EmitFunctionHeader() { /// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the /// function. This can be overridden by targets as required to do custom stuff. void AsmPrinter::EmitFunctionEntryLabel() { + CurrentFnSym->redefineIfPossible(); + // The function label could have already been emitted if two symbols end up // conflicting due to asm renaming. Detect this and emit an error. if (CurrentFnSym->isUndefined()) diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 9becb403d57..8eff90a9ef7 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -1298,6 +1298,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, Sym = getContext().GetOrCreateSymbol(IDVal); } else Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal); + + Sym->redefineIfPossible(); + if (!Sym->isUndefined() || Sym->isVariable()) return Error(IDLoc, "invalid symbol redefinition"); @@ -2217,6 +2220,8 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, } else Sym = getContext().GetOrCreateSymbol(Name); + Sym->setRedefinable(allow_redef); + // Do the assignment. Out.EmitAssignment(Sym, Value); if (NoDeadStrip) diff --git a/test/CodeGen/X86/pr22019.ll b/test/CodeGen/X86/pr22019.ll new file mode 100644 index 00000000000..f4a1707ad01 --- /dev/null +++ b/test/CodeGen/X86/pr22019.ll @@ -0,0 +1,12 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +module asm "pselect = __pselect" +; CHECK: pselect = __pselect + +; CHECK: pselect: +; CHECK: retq +define void @pselect() { + ret void +} diff --git a/test/MC/ELF/alias.s b/test/MC/ELF/alias.s index 2e65ace6ba1..8e1318230bb 100644 --- a/test/MC/ELF/alias.s +++ b/test/MC/ELF/alias.s @@ -20,6 +20,10 @@ bar5 = bar4 .long foo2 +// Test that bar6 is a function that doesn't have the same value as foo4. +bar6 = bar5 +bar6: + // CHECK: Symbols [ // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: (0) @@ -58,6 +62,15 @@ bar5 = bar4 // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: bar6 +// CHECK-NEXT: Value: 0x5 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: foo // CHECK-NEXT: Value: 0x0 // CHECK-NEXT: Size: 0