Index: COFF/SymbolTable.cpp =================================================================== --- COFF/SymbolTable.cpp +++ COFF/SymbolTable.cpp @@ -63,6 +63,7 @@ void SymbolTable::reportRemainingUndefines() { SmallPtrSet Undefs; + DenseMap LocalImports; for (auto &I : SymMap) { Symbol *Sym = I.second; @@ -98,6 +99,7 @@ auto *D = cast(Imp); replaceSymbol(Sym, Name, D); LocalImportChunks.push_back(cast(Sym)->getChunk()); + LocalImports[Sym] = D; continue; } } @@ -109,17 +111,28 @@ Undefs.insert(Sym); } - if (Undefs.empty()) + if (Undefs.empty() && LocalImports.empty()) return; - for (Symbol *B : Config->GCRoot) + for (Symbol *B : Config->GCRoot) { if (Undefs.count(B)) errorOrWarn(": undefined symbol: " + B->getName()); + if (Symbol *Imp = LocalImports.lookup(B)) + warn(": locally defined symbol imported: " + Imp->getName() + + " (defined in " + toString(Imp->getFile()) + ")"); + } - for (ObjFile *File : ObjFile::Instances) - for (Symbol *Sym : File->getSymbols()) - if (Sym && Undefs.count(Sym)) + for (ObjFile *File : ObjFile::Instances) { + for (Symbol *Sym : File->getSymbols()) { + if (!Sym) + continue; + if (Undefs.count(Sym)) errorOrWarn(toString(File) + ": undefined symbol: " + Sym->getName()); + if (Symbol *Imp = LocalImports.lookup(Sym)) + warn(toString(File) + ": locally defined symbol imported: " + + Imp->getName() + " (defined in " + toString(Imp->getFile()) + ")"); + } + } } std::pair SymbolTable::insert(StringRef Name) { Index: test/COFF/Inputs/locally-imported-def.s =================================================================== --- test/COFF/Inputs/locally-imported-def.s +++ test/COFF/Inputs/locally-imported-def.s @@ -0,0 +1,4 @@ +.text +.globl f +f: + ret Index: test/COFF/Inputs/locally-imported-imp.s =================================================================== --- test/COFF/Inputs/locally-imported-imp.s +++ test/COFF/Inputs/locally-imported-imp.s @@ -0,0 +1,2 @@ +.text + call __imp_f Index: test/COFF/locally-imported-warn-multiple.s =================================================================== --- test/COFF/locally-imported-warn-multiple.s +++ test/COFF/locally-imported-warn-multiple.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %T/locally-imported-def.obj %S/Inputs/locally-imported-def.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %T/locally-imported-imp1.obj %S/Inputs/locally-imported-imp.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %T/locally-imported-imp2.obj %S/Inputs/locally-imported-imp.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc -o %t.obj %s +# RUN: lld-link /entry:main %T/locally-imported-def.obj %T/locally-imported-imp1.obj %T/locally-imported-imp2.obj %t.obj 2>&1 | FileCheck %s + +# CHECK: warning: [[TESTDIR:[^:]+]]locally-imported-imp1.obj: locally defined symbol imported: f (defined in [[TESTDIR]]locally-imported-def.obj) +# CHECK-NEXT: warning: [[TESTDIR:[^:]+]]locally-imported-imp2.obj: locally defined symbol imported: f (defined in [[TESTDIR]]locally-imported-def.obj) + +.globl main +main: + ret Index: test/COFF/locally-imported.test =================================================================== --- test/COFF/locally-imported.test +++ test/COFF/locally-imported.test @@ -1,8 +1,10 @@ # RUN: yaml2obj < %s > %t.obj -# RUN: lld-link /out:%t.exe /entry:main %t.obj +# RUN: lld-link /out:%t.exe /entry:main %t.obj 2>&1 | FileCheck -check-prefix=WARN %s # RUN: llvm-objdump -s %t.exe | FileCheck %s # RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s +# WARN: warning: [[INPUT:[^:]+]]: locally defined symbol imported: main (defined in [[INPUT]]) + # CHECK: Contents of section .text: # CHECK-NEXT: 1000 00200000 # CHECK: Contents of section .rdata: