Index: test/wasm/lto/undef.ll =================================================================== --- /dev/null +++ test/wasm/lto/undef.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as %s -o %t.o +; RUN: wasm-ld %t.o -o %t.wasm --allow-undefined +; RUN: obj2yaml %t.wasm | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +declare void @bar() + +define void @_start() { + call void @bar() + ret void +} + +; CHECK-NEXT: - Type: IMPORT +; CHECK-NEXT: Imports: +; CHECK-NEXT: - Module: env +; CHECK-NEXT: Field: bar +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SigIndex: 0 Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -257,8 +257,8 @@ // It is possible for undefined functions not to have a signature (eg. if // added via "--undefined"), but weak undefined ones do have a signature. - assert(FuncSym->getFunctionType()); - const WasmSignature &Sig = *FuncSym->getFunctionType(); + assert(FuncSym->FunctionType); + const WasmSignature &Sig = *FuncSym->FunctionType; // Add a synthetic dummy for weak undefined functions. These dummies will // be GC'd if not used as the target of any "call" instructions. Index: wasm/SymbolTable.cpp =================================================================== --- wasm/SymbolTable.cpp +++ wasm/SymbolTable.cpp @@ -106,7 +106,7 @@ " in " + toString(File)); } -static void checkFunctionType(const Symbol *Existing, const InputFile *File, +static void checkFunctionType(Symbol *Existing, const InputFile *File, const WasmSignature *NewSig) { auto ExistingFunction = dyn_cast(Existing); if (!ExistingFunction) { @@ -114,13 +114,20 @@ return; } - const WasmSignature *OldSig = ExistingFunction->getFunctionType(); - if (OldSig && NewSig && *NewSig != *OldSig) { + if (!NewSig) + return; + + const WasmSignature *OldSig = ExistingFunction->FunctionType; + if (!OldSig) { + ExistingFunction->FunctionType = NewSig; + return; + } + + if (*NewSig != *OldSig) warn("function signature mismatch: " + Existing->getName() + "\n>>> defined as " + toString(*OldSig) + " in " + toString(Existing->getFile()) + "\n>>> defined as " + toString(*NewSig) + " in " + toString(File)); - } } // Check the type of new symbol matches that of the symbol is replacing. @@ -286,8 +293,9 @@ replaceSymbol(S, Name, Flags, File, Sig); else if (auto *Lazy = dyn_cast(S)) Lazy->fetch(); - else if (S->isDefined()) + else checkFunctionType(S, File, Sig); + return S; } Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -115,8 +115,6 @@ S->kind() == UndefinedFunctionKind; } - const WasmSignature *getFunctionType() const { return FunctionType; } - // Get/set the table index void setTableIndex(uint32_t Index); uint32_t getTableIndex() const; @@ -127,6 +125,7 @@ void setFunctionIndex(uint32_t Index); bool hasFunctionIndex() const; + const WasmSignature *FunctionType; protected: FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F, const WasmSignature *Type) @@ -134,8 +133,6 @@ uint32_t TableIndex = INVALID_INDEX; uint32_t FunctionIndex = INVALID_INDEX; - - const WasmSignature *FunctionType; }; class DefinedFunction : public FunctionSymbol { Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -175,7 +175,7 @@ Import.Field = Sym->getName(); if (auto *FunctionSym = dyn_cast(Sym)) { Import.Kind = WASM_EXTERNAL_FUNCTION; - Import.SigIndex = lookupType(*FunctionSym->getFunctionType()); + Import.SigIndex = lookupType(*FunctionSym->FunctionType); } else { auto *GlobalSym = cast(Sym); Import.Kind = WASM_EXTERNAL_GLOBAL; @@ -846,7 +846,7 @@ for (const Symbol *Sym : ImportedSymbols) if (auto *F = dyn_cast(Sym)) - registerType(*F->getFunctionType()); + registerType(*F->FunctionType); for (const InputFunction *F : InputFunctions) registerType(F->Signature); @@ -989,7 +989,7 @@ const WasmLinkingData &L = File->getWasmObj()->linkingData(); for (const WasmInitFunc &F : L.InitFunctions) { FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol); - if (*Sym->getFunctionType() != WasmSignature{{}, WASM_TYPE_NORESULT}) + if (*Sym->FunctionType != WasmSignature{{}, WASM_TYPE_NORESULT}) error("invalid signature for init func: " + toString(*Sym)); InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority}); }