mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-08 19:25:47 +00:00
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
This commit is contained in:
@@ -53,6 +53,9 @@ namespace llvm {
|
|||||||
/// "Lfoo" or ".foo".
|
/// "Lfoo" or ".foo".
|
||||||
unsigned IsTemporary : 1;
|
unsigned IsTemporary : 1;
|
||||||
|
|
||||||
|
/// \brief True if this symbol can be redefined.
|
||||||
|
unsigned IsRedefinable : 1;
|
||||||
|
|
||||||
/// IsUsed - True if this symbol has been used.
|
/// IsUsed - True if this symbol has been used.
|
||||||
mutable unsigned IsUsed : 1;
|
mutable unsigned IsUsed : 1;
|
||||||
|
|
||||||
@@ -61,7 +64,7 @@ namespace llvm {
|
|||||||
friend class MCContext;
|
friend class MCContext;
|
||||||
MCSymbol(StringRef name, bool isTemporary)
|
MCSymbol(StringRef name, bool isTemporary)
|
||||||
: Name(name), Section(nullptr), Value(nullptr),
|
: Name(name), Section(nullptr), Value(nullptr),
|
||||||
IsTemporary(isTemporary), IsUsed(false) {}
|
IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false) {}
|
||||||
|
|
||||||
MCSymbol(const MCSymbol&) LLVM_DELETED_FUNCTION;
|
MCSymbol(const MCSymbol&) LLVM_DELETED_FUNCTION;
|
||||||
void operator=(const MCSymbol&) LLVM_DELETED_FUNCTION;
|
void operator=(const MCSymbol&) LLVM_DELETED_FUNCTION;
|
||||||
@@ -79,6 +82,19 @@ namespace llvm {
|
|||||||
bool isUsed() const { return IsUsed; }
|
bool isUsed() const { return IsUsed; }
|
||||||
void setUsed(bool Value) const { IsUsed = Value; }
|
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
|
/// @name Associated Sections
|
||||||
/// @{
|
/// @{
|
||||||
|
@@ -541,6 +541,8 @@ void AsmPrinter::EmitFunctionHeader() {
|
|||||||
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
|
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
|
||||||
/// function. This can be overridden by targets as required to do custom stuff.
|
/// function. This can be overridden by targets as required to do custom stuff.
|
||||||
void AsmPrinter::EmitFunctionEntryLabel() {
|
void AsmPrinter::EmitFunctionEntryLabel() {
|
||||||
|
CurrentFnSym->redefineIfPossible();
|
||||||
|
|
||||||
// The function label could have already been emitted if two symbols end up
|
// The function label could have already been emitted if two symbols end up
|
||||||
// conflicting due to asm renaming. Detect this and emit an error.
|
// conflicting due to asm renaming. Detect this and emit an error.
|
||||||
if (CurrentFnSym->isUndefined())
|
if (CurrentFnSym->isUndefined())
|
||||||
|
@@ -1298,6 +1298,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
|||||||
Sym = getContext().GetOrCreateSymbol(IDVal);
|
Sym = getContext().GetOrCreateSymbol(IDVal);
|
||||||
} else
|
} else
|
||||||
Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
|
Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
|
||||||
|
|
||||||
|
Sym->redefineIfPossible();
|
||||||
|
|
||||||
if (!Sym->isUndefined() || Sym->isVariable())
|
if (!Sym->isUndefined() || Sym->isVariable())
|
||||||
return Error(IDLoc, "invalid symbol redefinition");
|
return Error(IDLoc, "invalid symbol redefinition");
|
||||||
|
|
||||||
@@ -2217,6 +2220,8 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef,
|
|||||||
} else
|
} else
|
||||||
Sym = getContext().GetOrCreateSymbol(Name);
|
Sym = getContext().GetOrCreateSymbol(Name);
|
||||||
|
|
||||||
|
Sym->setRedefinable(allow_redef);
|
||||||
|
|
||||||
// Do the assignment.
|
// Do the assignment.
|
||||||
Out.EmitAssignment(Sym, Value);
|
Out.EmitAssignment(Sym, Value);
|
||||||
if (NoDeadStrip)
|
if (NoDeadStrip)
|
||||||
|
12
test/CodeGen/X86/pr22019.ll
Normal file
12
test/CodeGen/X86/pr22019.ll
Normal file
@@ -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
|
||||||
|
}
|
@@ -20,6 +20,10 @@ bar5 = bar4
|
|||||||
|
|
||||||
.long foo2
|
.long foo2
|
||||||
|
|
||||||
|
// Test that bar6 is a function that doesn't have the same value as foo4.
|
||||||
|
bar6 = bar5
|
||||||
|
bar6:
|
||||||
|
|
||||||
// CHECK: Symbols [
|
// CHECK: Symbols [
|
||||||
// CHECK-NEXT: Symbol {
|
// CHECK-NEXT: Symbol {
|
||||||
// CHECK-NEXT: Name: (0)
|
// CHECK-NEXT: Name: (0)
|
||||||
@@ -58,6 +62,15 @@ bar5 = bar4
|
|||||||
// CHECK-NEXT: Section: .text
|
// CHECK-NEXT: Section: .text
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
// CHECK-NEXT: Symbol {
|
// 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: Name: foo
|
||||||
// CHECK-NEXT: Value: 0x0
|
// CHECK-NEXT: Value: 0x0
|
||||||
// CHECK-NEXT: Size: 0
|
// CHECK-NEXT: Size: 0
|
||||||
|
Reference in New Issue
Block a user