diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 29791efb92fa..e26bdaed993f 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -41,7 +41,7 @@ class MCELFStreamer : public MCObjectStreamer { void InitSections(bool NoExecStack) override; void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; - void EmitLabel(MCSymbol *Symbol) override; + void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitThumbFunc(MCSymbol *Func) override; void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index f9111b7f47ea..94e8f177fff7 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -89,7 +89,7 @@ class MCObjectStreamer : public MCStreamer { /// \name MCStreamer Interface /// @{ - void EmitLabel(MCSymbol *Symbol) override; + void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc()) override; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index cf3b52a7b687..62bd2fd2a9d9 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -398,7 +398,7 @@ class MCStreamer { /// used in an assignment. // FIXME: These emission are non-const because we mutate the symbol to // add the section we're emitting it to later. - virtual void EmitLabel(MCSymbol *Symbol); + virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()); virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); diff --git a/include/llvm/MC/MCWinCOFFStreamer.h b/include/llvm/MC/MCWinCOFFStreamer.h index cf92d65f23df..d7e6271de5fc 100644 --- a/include/llvm/MC/MCWinCOFFStreamer.h +++ b/include/llvm/MC/MCWinCOFFStreamer.h @@ -40,7 +40,7 @@ class MCWinCOFFStreamer : public MCObjectStreamer { /// \{ void InitSections(bool NoExecStack) override; - void EmitLabel(MCSymbol *Symbol) override; + void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitThumbFunc(MCSymbol *Func) override; bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 2eae26bdc0c0..92dcf535ec99 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -130,7 +130,7 @@ class MCAsmStreamer final : public MCStreamer { void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override; - void EmitLabel(MCSymbol *Symbol) override; + void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitLinkerOptions(ArrayRef Options) override; @@ -397,9 +397,8 @@ void MCAsmStreamer::ChangeSection(MCSection *Section, Subsection); } -void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { - assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); - MCStreamer::EmitLabel(Symbol); +void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { + MCStreamer::EmitLabel(Symbol, Loc); Symbol->print(OS, MAI); OS << MAI->getLabelSuffix(); diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 9f2120ccfc94..789cf3ff3873 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -93,11 +93,9 @@ void MCELFStreamer::InitSections(bool NoExecStack) { SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx)); } -void MCELFStreamer::EmitLabel(MCSymbol *S) { +void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc) { auto *Symbol = cast(S); - assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); - - MCObjectStreamer::EmitLabel(Symbol); + MCObjectStreamer::EmitLabel(Symbol, Loc); const MCSectionELF &Section = static_cast(*getCurrentSectionOnly()); diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 548c2fd62d2e..5820d97dd792 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -78,7 +78,7 @@ class MCMachOStreamer : public MCObjectStreamer { /// @{ void ChangeSection(MCSection *Sect, const MCExpr *Subsect) override; - void EmitLabel(MCSymbol *Symbol) override; + void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override; @@ -194,15 +194,13 @@ void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern); } -void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { - assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); - +void MCMachOStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { // We have to create a new fragment if this is an atom defining symbol, // fragments cannot span atoms. if (getAssembler().isSymbolLinkerVisible(*Symbol)) insert(new MCDataFragment()); - MCObjectStreamer::EmitLabel(Symbol); + MCObjectStreamer::EmitLabel(Symbol, Loc); // This causes the reference type flag to be cleared. Darwin 'as' was "trying" // to clear the weak reference and weak definition bits too, but the diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index cae5c1f8d156..19269f880a41 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -153,8 +153,8 @@ void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { EmitLabel(Frame.End); } -void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { - MCStreamer::EmitLabel(Symbol); +void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { + MCStreamer::EmitLabel(Symbol, Loc); getAssembler().registerSymbol(*Symbol); diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index a8497092448c..33843d7cbed7 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -1630,12 +1630,6 @@ 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"); - // End of Labels should be treated as end of line for lexing // purposes but that information is not available to the Lexer who // does not understand Labels. This may cause us to see a Hash @@ -1654,7 +1648,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, // Emit the label. if (!ParsingInlineAsm) - Out.EmitLabel(Sym); + Out.EmitLabel(Sym, IDLoc); // If we are generating dwarf for assembly source files then gather the // info to make a dwarf label entry for this label if needed. diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index d0abd5d1dd30..cdecd48693a5 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -298,10 +298,17 @@ void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) { SymbolOrdering[Symbol] = 1 + SymbolOrdering.size(); } -void MCStreamer::EmitLabel(MCSymbol *Symbol) { +void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { + Symbol->redefineIfPossible(); + + if (!Symbol->isUndefined() || Symbol->isVariable()) + return getContext().reportError(Loc, "invalid symbol redefinition"); + assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); assert(getCurrentSectionOnly() && "Cannot emit before setting section!"); assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!"); + assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); + Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment()); MCTargetStreamer *TS = getTargetStreamer(); diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index b3abd98a9f49..2e75b5f131d5 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -79,10 +79,9 @@ void MCWinCOFFStreamer::InitSections(bool NoExecStack) { SwitchSection(getContext().getObjectFileInfo()->getTextSection()); } -void MCWinCOFFStreamer::EmitLabel(MCSymbol *S) { +void MCWinCOFFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc) { auto *Symbol = cast(S); - assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); - MCObjectStreamer::EmitLabel(Symbol); + MCObjectStreamer::EmitLabel(Symbol, Loc); } void MCWinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { diff --git a/lib/Object/RecordStreamer.cpp b/lib/Object/RecordStreamer.cpp index 572b960bc85f..da99b3fea008 100644 --- a/lib/Object/RecordStreamer.cpp +++ b/lib/Object/RecordStreamer.cpp @@ -82,7 +82,7 @@ void RecordStreamer::EmitInstruction(const MCInst &Inst, MCStreamer::EmitInstruction(Inst, STI); } -void RecordStreamer::EmitLabel(MCSymbol *Symbol) { +void RecordStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { MCStreamer::EmitLabel(Symbol); markDefined(*Symbol); } diff --git a/lib/Object/RecordStreamer.h b/lib/Object/RecordStreamer.h index 617d8a43fbd2..c795dbb2e432 100644 --- a/lib/Object/RecordStreamer.h +++ b/lib/Object/RecordStreamer.h @@ -31,7 +31,7 @@ class RecordStreamer : public MCStreamer { const_iterator end(); RecordStreamer(MCContext &Context); void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; - void EmitLabel(MCSymbol *Symbol) override; + void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp index 76cfc7f8fb43..4eeccc3995fd 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp @@ -55,7 +55,7 @@ void MipsELFStreamer::createPendingLabelRelocs() { Labels.clear(); } -void MipsELFStreamer::EmitLabel(MCSymbol *Symbol) { +void MipsELFStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { MCELFStreamer::EmitLabel(Symbol); Labels.push_back(Symbol); } diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h index 9b748ce92c3c..72cde1c90845 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h +++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h @@ -50,7 +50,7 @@ class MipsELFStreamer : public MCELFStreamer { /// Overriding this function allows us to record all labels that should be /// marked as microMIPS. Based on this data marking is done in /// EmitInstruction. - void EmitLabel(MCSymbol *Symbol) override; + void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; /// Overriding this function allows us to dismiss all labels that are /// candidates for marking as microMIPS when .section directive is processed. diff --git a/test/CodeGen/XCore/section-name.ll b/test/CodeGen/XCore/section-name.ll new file mode 100644 index 000000000000..ee9eeb606bb2 --- /dev/null +++ b/test/CodeGen/XCore/section-name.ll @@ -0,0 +1,8 @@ +; RUN: llc < %s -march=xcore + +; we used to crash in this. +@bar = internal global i32 zeroinitializer + +define void @".dp.bss"() { + ret void +}