From 2ca8f0f5d6b258c53bcf781124e01d264cd8ff1a Mon Sep 17 00:00:00 2001 From: Colin LeMahieu Date: Sat, 6 Jun 2015 20:12:40 +0000 Subject: [PATCH] [MC] Common symbols weren't being checked for redeclaration which allowed an assembly file to generate an assertion in setCommon(): !isCommon(). This change allows redeclaration as long as the size and alignment match exactly, otherwise report a fatal error. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239227 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCSymbol.h | 15 +++++++++++++++ lib/MC/MCELFStreamer.cpp | 4 +++- test/MC/ELF/common-error3.s | 5 +++++ test/MC/ELF/common-redeclare.s | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/MC/ELF/common-error3.s create mode 100644 test/MC/ELF/common-redeclare.s diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 137251b6356..7f74f378d46 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -258,6 +258,21 @@ public: return CommonAlign; } + /// Declare this symbol as being 'common'. + /// + /// \param Size - The size of the symbol. + /// \param Align - The alignment of the symbol. + /// \return True if symbol was already declared as a different type + bool declareCommon(uint64_t Size, unsigned Align) { + assert(isCommon() || getOffset() == 0); + if(isCommon()) { + if(CommonSize != Size || CommonAlign != Align) + return true; + } else + setCommon(Size, Align); + return false; + } + /// Is this a 'common' symbol. bool isCommon() const { return CommonAlign != -1U; } diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index da664f57803..e0f4a2ae16a 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -320,7 +320,9 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size, struct LocalCommon L = {Symbol, Size, ByteAlignment}; LocalCommons.push_back(L); } else { - Symbol->setCommon(Size, ByteAlignment); + if(Symbol->declareCommon(Size, ByteAlignment)) + report_fatal_error("Symbol: " + Symbol->getName() + + " redeclared as different type"); } cast(Symbol) diff --git a/test/MC/ELF/common-error3.s b/test/MC/ELF/common-error3.s new file mode 100644 index 00000000000..a84779e653e --- /dev/null +++ b/test/MC/ELF/common-error3.s @@ -0,0 +1,5 @@ +# RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux %s 2>&1 | FileCheck %s + +# CHECK: Symbol: C redeclared as different type + .comm C,4,4 + .comm C,8,4 \ No newline at end of file diff --git a/test/MC/ELF/common-redeclare.s b/test/MC/ELF/common-redeclare.s new file mode 100644 index 00000000000..f8ee17d84e2 --- /dev/null +++ b/test/MC/ELF/common-redeclare.s @@ -0,0 +1,5 @@ +# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux %s | llvm-objdump -t - | FileCheck %s + +# CHECK: 0000000000000004 g *COM* 00000004 C + .comm C,4,4 + .comm C,4,4 \ No newline at end of file