From: Kevin Enderby Date: Tue, 22 Apr 2014 17:27:29 +0000 (+0000) Subject: Fix the assembler to print a better relocatable expression error X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=29c96f133e9e10a8a2f1a8da4441a53f6d461b7c;p=oota-llvm.git Fix the assembler to print a better relocatable expression error diagnostic that includes location information. Currently if one has this assembly: .quad (0x1234 + (4 * SOME_VALUE)) where SOME_VALUE is undefined ones gets the less than useful error message with no location information: % clang -c x.s clang -cc1as: fatal error: error in backend: expected relocatable expression With this fix one now gets a more useful error message with location information: % clang -c x.s x.s:5:8: error: expected relocatable expression .quad (0x1234 + (4 * SOME_VALUE)) ^ To do this I plumbed the SMLoc through the MCObjectStreamer EmitValue() and EmitValueImpl() interfaces so it could be used when creating the MCFixup. rdar://12391022 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206906 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index a2f56f1c208..da37d0d0128 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -72,7 +72,8 @@ public: uint64_t Size = 0, unsigned ByteAlignment = 0) override; void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0) override; - void EmitValueImpl(const MCExpr *Value, unsigned Size) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc = SMLoc()) override; void EmitFileDirective(StringRef Filename) override; diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index a42b7a05844..e57dc364bd0 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -81,7 +81,8 @@ public: void EmitLabel(MCSymbol *Symbol) override; void EmitDebugLabel(MCSymbol *Symbol) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; - void EmitValueImpl(const MCExpr *Value, unsigned Size) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc = SMLoc()) override; void EmitULEB128Value(const MCExpr *Value) override; void EmitSLEB128Value(const MCExpr *Value) override; void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 510d582e8ad..88f2b71f187 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -529,9 +529,12 @@ public: /// @param Value - The value to emit. /// @param Size - The size of the integer (in bytes) to emit. This must /// match a native machine width. - virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) = 0; + /// @param Loc - The location of the expression for error reporting. + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc = SMLoc()) = 0; - void EmitValue(const MCExpr *Value, unsigned Size); + void EmitValue(const MCExpr *Value, unsigned Size, + const SMLoc &Loc = SMLoc()); /// EmitIntValue - Special case of EmitValue that avoids the client having /// to pass in a MCExpr for constant integers. diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index 4b471cd0d78..c02f05c94a8 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -698,7 +698,8 @@ namespace { void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override {} void EmitBytes(StringRef Data) override {} - void EmitValueImpl(const MCExpr *Value, unsigned Size) override {} + void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) override {} void EmitULEB128Value(const MCExpr *Value) override {} void EmitSLEB128Value(const MCExpr *Value) override {} void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 9c447f171bb..265d73dde3a 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -175,7 +175,8 @@ public: void EmitBytes(StringRef Data) override; - void EmitValueImpl(const MCExpr *Value, unsigned Size) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc = SMLoc()) override; void EmitIntValue(uint64_t Value, unsigned Size) override; void EmitULEB128Value(const MCExpr *Value) override; @@ -702,7 +703,8 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) { EmitValue(MCConstantExpr::Create(Value, getContext()), Size); } -void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { +void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { assert(Size <= 8 && "Invalid size"); assert(getCurrentSection().first && "Cannot emit contents before setting section!"); diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 4242b626b3c..d42636e1803 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -275,11 +275,12 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, EmitCommonSymbol(Symbol, Size, ByteAlignment); } -void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { +void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { if (getCurrentSectionData()->isBundleLocked()) report_fatal_error("Emitting values inside a locked bundle is forbidden"); fixSymbolsInTLSFixups(Value); - MCObjectStreamer::EmitValueImpl(Value, Size); + MCObjectStreamer::EmitValueImpl(Value, Size, Loc); } void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 2747090bd60..53f9548f68e 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -70,7 +70,8 @@ namespace { uint64_t Size, unsigned ByteAlignment) override {} void EmitBytes(StringRef Data) override {} - void EmitValueImpl(const MCExpr *Value, unsigned Size) override {} + void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc = SMLoc()) override {} void EmitULEB128Value(const MCExpr *Value) override {} void EmitSLEB128Value(const MCExpr *Value) override {} void EmitGPRel32Value(const MCExpr *Value) override {} diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 50f67c1c113..ea3f42574da 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -97,7 +97,8 @@ const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { return Value; } -void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { +void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { MCDataFragment *DF = getOrCreateDataFragment(); MCLineEntry::Make(this, getCurrentSection().first); @@ -110,7 +111,7 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { } DF->getFixups().push_back( MCFixup::Create(DF->getContents().size(), Value, - MCFixup::getKindForSize(Size, false))); + MCFixup::getKindForSize(Size, false), Loc)); DF->getContents().resize(DF->getContents().size() + Size, 0); } diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 910a424ce84..345b59c6cea 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -2364,7 +2364,7 @@ bool AsmParser::parseDirectiveValue(unsigned Size) { return Error(ExprLoc, "literal value out of range for directive"); getStreamer().EmitIntValue(IntValue, Size); } else - getStreamer().EmitValue(Value, Size); + getStreamer().EmitValue(Value, Size, ExprLoc); if (getLexer().is(AsmToken::EndOfStatement)) break; diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index f85f7d3210c..50b6576766c 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -147,8 +147,9 @@ void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size) { } -void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size) { - EmitValueImpl(Value, Size); +void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { + EmitValueImpl(Value, Size, Loc); } void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size) { diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp index 473b7dda004..16485217a2f 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp +++ b/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp @@ -92,9 +92,10 @@ public: /// This is one of the functions used to emit data into an ELF section, so the /// AArch64 streamer overrides it to add the appropriate mapping symbol ($d) /// if necessary. - virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) { + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { EmitDataMappingSymbol(); - MCELFStreamer::EmitValueImpl(Value, Size); + MCELFStreamer::EmitValueImpl(Value, Size, Loc); } private: diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 5a01d261d47..5f706dfe894 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -531,7 +531,8 @@ public: /// This is one of the functions used to emit data into an ELF section, so the /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if /// necessary. - void EmitValueImpl(const MCExpr *Value, unsigned Size) override { + void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) override { EmitDataMappingSymbol(); MCELFStreamer::EmitValueImpl(Value, Size); } diff --git a/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.cpp b/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.cpp index 97a34938af1..9af21d8cee8 100644 --- a/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.cpp +++ b/lib/Target/ARM64/MCTargetDesc/ARM64ELFStreamer.cpp @@ -92,7 +92,8 @@ public: /// This is one of the functions used to emit data into an ELF section, so the /// ARM64 streamer overrides it to add the appropriate mapping symbol ($d) /// if necessary. - virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) { + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { EmitDataMappingSymbol(); MCELFStreamer::EmitValueImpl(Value, Size); } diff --git a/test/MC/MachO/bad-darwin-x86_64-reloc-expr.s b/test/MC/MachO/bad-darwin-x86_64-reloc-expr.s new file mode 100644 index 00000000000..2b4271f349d --- /dev/null +++ b/test/MC/MachO/bad-darwin-x86_64-reloc-expr.s @@ -0,0 +1,6 @@ +// RUN: not llvm-mc -triple x86_64-apple-darwin10 %s -filetype=obj -o - 2> %t.err > %t +// RUN: FileCheck --check-prefix=CHECK-ERROR < %t.err %s + +.quad (0x1234 + (4 * SOME_VALUE)) +// CHECK-ERROR: error: expected relocatable expression +// CHECK-ERROR: ^