Index: lld/trunk/ELF/Config.h =================================================================== --- lld/trunk/ELF/Config.h +++ lld/trunk/ELF/Config.h @@ -78,6 +78,7 @@ bool SysvHash = true; bool Threads; bool Verbose; + bool WarnCommon; bool ZExecStack; bool ZNodelete; bool ZNow; Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -244,6 +244,7 @@ Config->StripAll = Args.hasArg(OPT_strip_all); Config->Threads = Args.hasArg(OPT_threads); Config->Verbose = Args.hasArg(OPT_verbose); + Config->WarnCommon = Args.hasArg(OPT_warn_common); Config->DynamicLinker = getString(Args, OPT_dynamic_linker); Config->Entry = getString(Args, OPT_entry); Index: lld/trunk/ELF/Options.td =================================================================== --- lld/trunk/ELF/Options.td +++ lld/trunk/ELF/Options.td @@ -131,6 +131,9 @@ def version : Flag<["--", "-"], "version">, HelpText<"Display the version number">; +def warn_common : Flag<["--", "-"], "warn-common">, + HelpText<"Warn about duplicate common symbols">; + def whole_archive : Flag<["--", "-"], "whole-archive">, HelpText<"Force load of all members in a static library">; @@ -178,9 +181,9 @@ def fatal_warnings : Flag<["--"], "fatal-warnings">; def no_add_needed : Flag<["--"], "no-add-needed">; def no_fatal_warnings : Flag<["--"], "no-fatal-warnings">; +def no_warn_common : Flag<["--", "-"], "no-warn-common">; def no_warn_mismatch : Flag<["--"], "no-warn-mismatch">; def version_script : Separate<["--"], "version-script">; -def warn_common : Flag<["--"], "warn-common">; def warn_shared_textrel : Flag<["--"], "warn-shared-textrel">; def G : Separate<["-"], "G">; Index: lld/trunk/ELF/Symbols.cpp =================================================================== --- lld/trunk/ELF/Symbols.cpp +++ lld/trunk/ELF/Symbols.cpp @@ -159,6 +159,8 @@ } static int compareCommons(DefinedCommon *A, DefinedCommon *B) { + if (Config->WarnCommon) + warning("multiple common of " + A->getName()); A->Alignment = B->Alignment = std::max(A->Alignment, B->Alignment); if (A->Size < B->Size) return -1; @@ -199,6 +201,8 @@ if (isCommon() && Other->isCommon()) return compareCommons(cast(this), cast(Other)); + if (Config->WarnCommon) + warning("common " + this->getName() + " is overridden"); return isCommon() ? -1 : 1; } Index: lld/trunk/test/ELF/Inputs/warn-common.s =================================================================== --- lld/trunk/test/ELF/Inputs/warn-common.s +++ lld/trunk/test/ELF/Inputs/warn-common.s @@ -0,0 +1,2 @@ +.type arr,@object +.comm arr,8,4 Index: lld/trunk/test/ELF/Inputs/warn-common2.s =================================================================== --- lld/trunk/test/ELF/Inputs/warn-common2.s +++ lld/trunk/test/ELF/Inputs/warn-common2.s @@ -0,0 +1,8 @@ +.type arr,@object +.data +.globl arr +.p2align 2 +arr: + .long 1 + .long 0 + .size arr, 8 Index: lld/trunk/test/ELF/warn-common.s =================================================================== --- lld/trunk/test/ELF/warn-common.s +++ lld/trunk/test/ELF/warn-common.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common.s -o %t2.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common2.s -o %t3.o + +## Report multiple commons if warn-common is specified +# RUN: ld.lld --warn-common %t1.o %t2.o -o %t.out 2>&1 | FileCheck %s --check-prefix=WARN +# WARN: multiple common of arr + +## no-warn-common is ignored +# RUN: ld.lld --no-warn-common %t1.o %t2.o -o %t.out +# RUN: llvm-readobj %t.out > /dev/null + +## Report if common is overridden +# RUN: ld.lld --warn-common %t1.o %t3.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER +# OVER: common arr is overridden + +## Report if common is overridden, but in different order +# RUN: ld.lld --warn-common %t3.o %t1.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER + +.globl _start +_start: + +.type arr,@object +.comm arr,4,4