[COFF] Warn for locally imported symbols

Locally imported symbols are a very surprising linker feature. link.exe
warns for them, and we should warn too.

Differential Revision: https://reviews.llvm.org/D41269

llvm-svn: 320792
This commit is contained in:
Shoaib Meenai 2017-12-15 07:49:21 +00:00
parent 6995e5dae7
commit d0bd40294d
5 changed files with 41 additions and 6 deletions

View File

@ -63,6 +63,7 @@ static void errorOrWarn(const Twine &S) {
void SymbolTable::reportRemainingUndefines() {
SmallPtrSet<Symbol *, 8> Undefs;
DenseMap<Symbol *, Symbol *> LocalImports;
for (auto &I : SymMap) {
Symbol *Sym = I.second;
@ -98,6 +99,7 @@ void SymbolTable::reportRemainingUndefines() {
auto *D = cast<Defined>(Imp);
replaceSymbol<DefinedLocalImport>(Sym, Name, D);
LocalImportChunks.push_back(cast<DefinedLocalImport>(Sym)->getChunk());
LocalImports[Sym] = D;
continue;
}
}
@ -109,17 +111,28 @@ void SymbolTable::reportRemainingUndefines() {
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("<root>: undefined symbol: " + B->getName());
if (Symbol *Imp = LocalImports.lookup(B))
warn("<root>: 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<Symbol *, bool> SymbolTable::insert(StringRef Name) {

View File

@ -0,0 +1,4 @@
.text
.globl f
f:
ret

View File

@ -0,0 +1,2 @@
.text
call __imp_f

View File

@ -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

View File

@ -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: