Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -339,10 +339,8 @@ // A forms group 0. B form group 1. C and D (including their member object // files) form group 2. E forms group 3. I think that you can see how this // group assignment rule simulates the traditional linker's semantics. -static void checkBackrefs(StringRef Name, InputFile *Old, InputFile *New) { - if (Config->WarnBackrefs && New && Old->GroupId < New->GroupId) - warn("backward reference detected: " + Name + " in " + toString(New) + - " refers to " + toString(Old)); +static bool checkBackrefs(StringRef Name, InputFile *Old, InputFile *New) { + return Config->WarnBackrefs && New && Old->GroupId < New->GroupId; } template @@ -377,8 +375,13 @@ return S; } - checkBackrefs(Name, S->File, File); + bool Backref = checkBackrefs(Name, S->File, File); fetchLazy(S); + // We don't report backward references to weak symbols as they can be + // overriden later. + if (Backref && S->Binding != STB_WEAK) + warn("backward reference detected: " + Name + " in " + toString(File) + + " refers to " + toString(S->File)); } return S; } Index: test/ELF/warn-backrefs.s =================================================================== --- test/ELF/warn-backrefs.s +++ test/ELF/warn-backrefs.s @@ -39,6 +39,10 @@ # RUN: echo ".globl foo; foo: call bar" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t4.o # RUN: ld.lld --fatal-warnings --warn-backrefs %t1.o --start-lib %t3.o %t4.o --end-lib -o %t.exe +# We don't report backward references to weak symbols as they can be overriden later. +# RUN: echo ".weak foo; foo:" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t5.o +# RUN: ld.lld --fatal-warnings --warn-backrefs --start-lib %t5.o --end-lib %t1.o %t2.o + .globl _start, foo _start: call foo