diff options
| -rw-r--r-- | lld/test/wasm/lto/signature-mismatch.ll | 19 | ||||
| -rw-r--r-- | lld/wasm/LTO.cpp | 7 | ||||
| -rw-r--r-- | lld/wasm/SymbolTable.cpp | 19 |
3 files changed, 38 insertions, 7 deletions
diff --git a/lld/test/wasm/lto/signature-mismatch.ll b/lld/test/wasm/lto/signature-mismatch.ll new file mode 100644 index 00000000000..4b6b3b8f426 --- /dev/null +++ b/lld/test/wasm/lto/signature-mismatch.ll @@ -0,0 +1,19 @@ +; RUN: llc -filetype=obj -o %t.o %s +; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o +; RUN: not wasm-ld --fatal-warnings %t.o %t1.o -o %t.wasm 2>&1 | FileCheck %s + +; Test that functions defined in bitcode correctly report signature +; mistmaches with existing undefined sybmols in normal objects. + +target triple = "wasm32-unknown-unknown" + +; f is defined to take no argument in archive.ll which is compiled to bitcode +declare void @f(i32); + +define void @_start() { + call void @f(i32 0) + ret void +} + +; CHECK: >>> defined as (I32) -> void in {{.*}}signature-mismatch.ll.tmp1.o +; CHECK: >>> defined as () -> void in lto.tmp diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp index f15551da8b8..933607a0938 100644 --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -72,10 +72,11 @@ BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {} BitcodeCompiler::~BitcodeCompiler() = default; static void undefine(Symbol *S) { - if (isa<DefinedFunction>(S)) - replaceSymbol<UndefinedFunction>(S, S->getName(), 0); + if (auto F = dyn_cast<DefinedFunction>(S)) + replaceSymbol<UndefinedFunction>(F, F->getName(), 0, F->getFile(), + F->FunctionType); else if (isa<DefinedData>(S)) - replaceSymbol<UndefinedData>(S, S->getName(), 0); + replaceSymbol<UndefinedData>(S, S->getName(), 0, S->getFile()); else llvm_unreachable("unexpected symbol kind"); } diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp index 2a4249e3307..d1e9c054265 100644 --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -201,7 +201,9 @@ static bool shouldReplace(const Symbol *Existing, InputFile *NewFile, Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, InputFunction *Function) { - LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << "\n"); + LLVM_DEBUG(dbgs() << "addDefinedFunction: " << Name << " [" + << (Function ? toString(Function->Signature) : "none") + << "]\n"); Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name, File); @@ -214,8 +216,16 @@ Symbol *SymbolTable::addDefinedFunction(StringRef Name, uint32_t Flags, if (Function) checkFunctionType(S, File, &Function->Signature); - if (shouldReplace(S, File, Flags)) - replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); + if (shouldReplace(S, File, Flags)) { + // If the new defined function doesn't have signture (i.e. bitcode + // functions) but the old symbols does then preserve the old signature + const WasmSignature *OldSig = nullptr; + if (auto* F = dyn_cast<FunctionSymbol>(S)) + OldSig = F->FunctionType; + auto NewSym = replaceSymbol<DefinedFunction>(S, Name, Flags, File, Function); + if (!NewSym->FunctionType) + NewSym->FunctionType = OldSig; + } return S; } @@ -263,7 +273,8 @@ Symbol *SymbolTable::addDefinedGlobal(StringRef Name, uint32_t Flags, Symbol *SymbolTable::addUndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, const WasmSignature *Sig) { - LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n"); + LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << + " [" << (Sig ? toString(*Sig) : "none") << "]\n"); Symbol *S; bool WasInserted; |

