Index: test/wasm/Inputs/comdat2.ll =================================================================== --- test/wasm/Inputs/comdat2.ll +++ test/wasm/Inputs/comdat2.ll @@ -9,5 +9,5 @@ define i32 @callInline2() { entry: - ret i32 ptrtoint (i32 ()* @inlineFn to i32) + ret i32 ptrtoint (i32 ()* @inlineFn to i32) } Index: test/wasm/entry-signature.ll =================================================================== --- /dev/null +++ test/wasm/entry-signature.ll @@ -0,0 +1,11 @@ +; Verify that the entry point signauture can be flexible. +; RUN: llc -filetype=obj %s -o %t.o +; RUN: wasm-ld -o %t1.wasm %t.o + +target triple = "wasm32-unknown-unknown-wasm" + +define hidden i32 @_start(i32, i64) local_unnamed_addr #0 { +entry: + ret i32 0 +} + Index: test/wasm/entry.ll =================================================================== --- test/wasm/entry.ll +++ test/wasm/entry.ll @@ -28,8 +28,8 @@ ; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: -; The __wasm_call_ctors is somewhat special. Make sure we can use it -; as the entry point if we choose +; The __wasm_call_ctors is somewhat special since its created by the linker. +; Make sure we can use it as the entry point if we choose ; RUN: wasm-ld --entry=__wasm_call_ctors -o %t3.wasm %t.o ; RUN: obj2yaml %t3.wasm | FileCheck %s -check-prefix=CHECK-CTOR Index: test/wasm/fatal-warnings.ll =================================================================== --- test/wasm/fatal-warnings.ll +++ test/wasm/fatal-warnings.ll @@ -1,14 +1,17 @@ ; RUN: llc -filetype=obj %s -o %t.main.o -; RUN: lld -flavor wasm -o %t.wasm %t.main.o 2>&1 | FileCheck %s -check-prefix=CHECK-WARN -; RUN: not lld -flavor wasm --fatal-warnings -o %t.wasm %t.main.o 2>&1 | FileCheck %s -check-prefix=CHECK-FATAL +; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o +; RUN: lld -flavor wasm -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-WARN +; RUN: not lld -flavor wasm --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-FATAL -; CHECK-WARN: warning: Function type mismatch: _start -; CHECK-FATAL: error: Function type mismatch: _start +; CHECK-WARN: warning: Function type mismatch: ret32 +; CHECK-FATAL: error: Function type mismatch: ret32 target triple = "wasm32-unknown-unknown-wasm" -define hidden i32 @_start(i32 %arg) local_unnamed_addr { +define hidden void @_start() local_unnamed_addr #0 { entry: - ret i32 %arg + %call = tail call i32 @ret32(i32 1, i64 2, i32 3) #2 + ret void } +declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1 Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -358,9 +358,11 @@ "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN); WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0); + // For now, since we don't actually use the start function as the + // wasm start symbol, we don't need to care about it signature. if (!Config->Entry.empty()) - EntrySym = Symtab->addUndefinedFunction(Config->Entry, 0, nullptr, - &NullSignature); + EntrySym = + Symtab->addUndefinedFunction(Config->Entry, 0, nullptr, nullptr); // Handle the `--undefined ` options. for (auto *Arg : Args.filtered(OPT_undefined)) Index: wasm/SymbolTable.cpp =================================================================== --- wasm/SymbolTable.cpp +++ wasm/SymbolTable.cpp @@ -78,14 +78,14 @@ static void checkFunctionType(const Symbol *Existing, const InputFile *File, const WasmSignature *NewSig) { - if (!isa(Existing)) { + auto ExistingFunction = dyn_cast(Existing); + if (!ExistingFunction) { reportTypeError(Existing, File, "Function"); return; } - const WasmSignature *OldSig = - cast(Existing)->getFunctionType(); - if (OldSig && *NewSig != *OldSig) { + const WasmSignature *OldSig = ExistingFunction->getFunctionType(); + if (OldSig && NewSig && *NewSig != *OldSig) { warn("Function type mismatch: " + Existing->getName() + "\n>>> defined as " + toString(*OldSig) + " in " + toString(Existing->getFile()) + "\n>>> defined as " + Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -742,12 +742,18 @@ if (!Sym->isLive()) continue; - DEBUG(dbgs() << "import: " << Sym->getName() << "\n"); - ImportedSymbols.emplace_back(Sym); - if (auto *F = dyn_cast(Sym)) + if (auto *F = dyn_cast(Sym)) { + if (F->getFunctionType() == nullptr) { + assert(Config->AllowUndefined); + continue; + } F->setFunctionIndex(NumImportedFunctions++); - else + } else { cast(Sym)->setGlobalIndex(NumImportedGlobals++); + } + + ImportedSymbols.emplace_back(Sym); + DEBUG(dbgs() << "import: " << Sym->getName() << "\n"); } }