From 6663f8f2c0b930731dbbfd51d19d9d942cd34ad2 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 22 May 2014 02:18:10 +0000 Subject: [PATCH] MC: formalise some assertions into proper errors Now that clang can be used as an assembler via the IAS, invalid assembler inputs would cause the assertions to trigger. Although we cannot recover from the errors here, nor provide caret diagnostics, attempt to handle them slightly more gracefully by reporting a fatal error. llvm-svn: 209387 --- llvm/include/llvm/MC/MCWinCOFFStreamer.h | 3 +++ llvm/lib/MC/WinCOFFStreamer.cpp | 31 ++++++++++++++++++------ llvm/test/MC/COFF/invalid-def.s | 6 +++++ llvm/test/MC/COFF/invalid-endef.s | 5 ++++ llvm/test/MC/COFF/invalid-scl-range.s | 7 ++++++ llvm/test/MC/COFF/invalid-scl.s | 5 ++++ llvm/test/MC/COFF/invalid-type-range.s | 7 ++++++ llvm/test/MC/COFF/invalid-type.s | 5 ++++ 8 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 llvm/test/MC/COFF/invalid-def.s create mode 100644 llvm/test/MC/COFF/invalid-endef.s create mode 100644 llvm/test/MC/COFF/invalid-scl-range.s create mode 100644 llvm/test/MC/COFF/invalid-scl.s create mode 100644 llvm/test/MC/COFF/invalid-type-range.s create mode 100644 llvm/test/MC/COFF/invalid-type.s diff --git a/llvm/include/llvm/MC/MCWinCOFFStreamer.h b/llvm/include/llvm/MC/MCWinCOFFStreamer.h index b0a27cdbd75b..34e39bb0a636 100644 --- a/llvm/include/llvm/MC/MCWinCOFFStreamer.h +++ b/llvm/include/llvm/MC/MCWinCOFFStreamer.h @@ -65,6 +65,9 @@ public: protected: const MCSymbol *CurSymbol; void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override; + +private: + LLVM_ATTRIBUTE_NORETURN void FatalError(const Twine &Msg) const; }; } diff --git a/llvm/lib/MC/WinCOFFStreamer.cpp b/llvm/lib/MC/WinCOFFStreamer.cpp index 40b8dd944bd9..e6df4651a536 100644 --- a/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/llvm/lib/MC/WinCOFFStreamer.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringExtras.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" @@ -125,30 +126,39 @@ void MCWinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) { assert((!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!"); - assert(!CurSymbol && "starting new symbol definition in a symbol definition"); + + if (CurSymbol) + FatalError("starting a new symbol definition without completing the " + "previous one"); CurSymbol = Symbol; } void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { - assert(CurSymbol && "StorageClass specified outside of symbol definition"); - assert((StorageClass & ~0xFF) == 0 && - "StorageClass must only have data in the first byte!"); + if (!CurSymbol) + FatalError("storage class specified outside of symbol definition"); + + if (StorageClass & ~0xff) + FatalError(Twine("storage class value '") + itostr(StorageClass) + + "' out of range"); MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*CurSymbol); SD.modifyFlags(StorageClass << COFF::SF_ClassShift, COFF::SF_ClassMask); } void MCWinCOFFStreamer::EmitCOFFSymbolType(int Type) { - assert(CurSymbol && "SymbolType specified outside of a symbol definition"); - assert((Type & ~0xFFFF) == 0 && - "Type must only have data in the first 2 bytes"); + if (!CurSymbol) + FatalError("symbol type specified outside of a symbol definition"); + + if (Type & ~0xffff) + FatalError(Twine("type value '") + itostr(Type) + "' out of range"); MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*CurSymbol); SD.modifyFlags(Type << COFF::SF_TypeShift, COFF::SF_TypeMask); } void MCWinCOFFStreamer::EndCOFFSymbolDef() { - assert(CurSymbol && "ending symbol definition without beginning one"); + if (!CurSymbol) + FatalError("ending symbol definition without starting one"); CurSymbol = nullptr; } @@ -239,5 +249,10 @@ void MCWinCOFFStreamer::EmitWin64EHHandlerData() { void MCWinCOFFStreamer::FinishImpl() { MCObjectStreamer::FinishImpl(); } + +LLVM_ATTRIBUTE_NORETURN +void MCWinCOFFStreamer::FatalError(const Twine &Msg) const { + getContext().FatalError(SMLoc(), Msg); +} } diff --git a/llvm/test/MC/COFF/invalid-def.s b/llvm/test/MC/COFF/invalid-def.s new file mode 100644 index 000000000000..bfa1a54cbd75 --- /dev/null +++ b/llvm/test/MC/COFF/invalid-def.s @@ -0,0 +1,6 @@ +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# REQUIRES: asserts + + .def first + .def second + diff --git a/llvm/test/MC/COFF/invalid-endef.s b/llvm/test/MC/COFF/invalid-endef.s new file mode 100644 index 000000000000..543685a66c6b --- /dev/null +++ b/llvm/test/MC/COFF/invalid-endef.s @@ -0,0 +1,5 @@ +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# REQUIRES: asserts + + .endef + diff --git a/llvm/test/MC/COFF/invalid-scl-range.s b/llvm/test/MC/COFF/invalid-scl-range.s new file mode 100644 index 000000000000..ec0c2bb19252 --- /dev/null +++ b/llvm/test/MC/COFF/invalid-scl-range.s @@ -0,0 +1,7 @@ +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# REQUIRES: asserts + + .def storage_class_range + .scl 1337 + .endef + diff --git a/llvm/test/MC/COFF/invalid-scl.s b/llvm/test/MC/COFF/invalid-scl.s new file mode 100644 index 000000000000..0d62497e96d9 --- /dev/null +++ b/llvm/test/MC/COFF/invalid-scl.s @@ -0,0 +1,5 @@ +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# REQUIRES: asserts + + .scl 1337 + diff --git a/llvm/test/MC/COFF/invalid-type-range.s b/llvm/test/MC/COFF/invalid-type-range.s new file mode 100644 index 000000000000..9397cc50c35b --- /dev/null +++ b/llvm/test/MC/COFF/invalid-type-range.s @@ -0,0 +1,7 @@ +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# REQUIRES: asserts + + .def invalid_type_range + .type 65536 + .endef + diff --git a/llvm/test/MC/COFF/invalid-type.s b/llvm/test/MC/COFF/invalid-type.s new file mode 100644 index 000000000000..a5c61f4aba8b --- /dev/null +++ b/llvm/test/MC/COFF/invalid-type.s @@ -0,0 +1,5 @@ +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# REQUIRES: asserts + + .type 65536 +