diff --git a/lld/test/wasm/lto/undef.ll b/lld/test/wasm/lto/undef.ll --- a/lld/test/wasm/lto/undef.ll +++ b/lld/test/wasm/lto/undef.ll @@ -5,10 +5,22 @@ target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" -declare void @bar() +declare i32 @bar() + +; Symbols such as foo which are only called indirectly are handled slightly +; differently with resepect to signature checking. +declare i32 @foo() + +@ptr = global i8* bitcast (i32 ()* @foo to i8*), align 8 +; Ensure access to ptr is not inlined below, even under LTO +@llvm.used = appending global [1 x i8**] [i8** @ptr], section "llvm.metadata" define void @_start() { - call void @bar() + call i32 @bar() + + %addr = load i32 ()*, i32 ()** bitcast (i8** @ptr to i32 ()**), align 8 + call i32 %addr() + ret void } @@ -18,3 +30,7 @@ ; CHECK-NEXT: Field: bar ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: SigIndex: 0 +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: foo +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SigIndex: 0 diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -136,14 +136,13 @@ // mismatch. static bool signatureMatches(FunctionSymbol *Existing, const WasmSignature *NewSig) { - if (!NewSig) - return true; - const WasmSignature *OldSig = Existing->Signature; - if (!OldSig) { - Existing->Signature = NewSig; + + // If either function is missing a signature (this happend for bitcode + // symbols) then assume they match. Any mismatch will be reported later + // when the LTO objects are added. + if (!NewSig || !OldSig) return true; - } return *NewSig == *OldSig; } @@ -390,8 +389,9 @@ uint32_t Flags, InputFile *File, const WasmSignature *Sig, bool IsCalledDirectly) { - LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << - " [" << (Sig ? toString(*Sig) : "none") << "]\n"); + LLVM_DEBUG(dbgs() << "addUndefinedFunction: " << Name << " [" + << (Sig ? toString(*Sig) : "none") + << "] IsCalledDirectly:" << IsCalledDirectly << "\n"); Symbol *S; bool WasInserted; @@ -414,6 +414,8 @@ reportTypeError(S, File, WASM_SYMBOL_TYPE_FUNCTION); return S; } + if (!ExistingFunction->Signature && Sig) + ExistingFunction->Signature = Sig; if (IsCalledDirectly && !signatureMatches(ExistingFunction, Sig)) if (getFunctionVariant(S, Sig, File, &S)) Replace();