diff --git a/lld/test/wasm/Inputs/sig_mismatch.s b/lld/test/wasm/Inputs/sig_mismatch.s new file mode 100644 --- /dev/null +++ b/lld/test/wasm/Inputs/sig_mismatch.s @@ -0,0 +1,12 @@ +.globl foo +foo: + .functype foo (f32) -> (i32) + i32.const 0 + end_function + + +.globl call_foo +call_foo: + .functype call_foo () -> (i32) + call foo + end_function diff --git a/lld/test/wasm/signature-mismatch-relocatable.s b/lld/test/wasm/signature-mismatch-relocatable.s new file mode 100644 --- /dev/null +++ b/lld/test/wasm/signature-mismatch-relocatable.s @@ -0,0 +1,57 @@ +# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s +# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t2.o %S/Inputs/sig_mismatch.s +# RUN: wasm-ld --relocatable %t.o %t2.o -o %t.wasm +# RUN: obj2yaml %t.wasm | FileCheck %s + +# Regression test for handling of signature mismatches (variant function +# symbols) and relocatable output. This issue only occurred when the undefined +# function was seen first and the defined function was referenced within the +# the defining file (see %S/Inputs/sig_mismatch.s). + +.globl _start +_start: + .functype _start () -> () + i32.const 1 + i64.const 2 + i32.const 3 + call foo + end_function + +.functype foo (i32, i64, i32) -> (i32) + +# CHECK: - Type: CUSTOM +# CHECK-NEXT: Name: linking +# CHECK-NEXT: Version: 2 +# CHECK-NEXT: SymbolTable: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Name: _start +# CHECK-NEXT: Flags: [ ] +# CHECK-NEXT: Function: 1 +# CHECK-NEXT: - Index: 1 +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Name: foo +# CHECK-NEXT: Flags: [ ] +# CHECK-NEXT: Function: 2 +# CHECK-NEXT: - Index: 2 +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Name: call_foo +# CHECK-NEXT: Flags: [ ] +# CHECK-NEXT: Function: 3 +# CHECK-NEXT: - Index: 3 +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Name: 'signature_mismatch:foo' +# CHECK-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-NEXT: Function: 0 +# CHECK-NEXT: - Type: CUSTOM +# CHECK-NEXT: Name: name +# CHECK-NEXT: FunctionNames: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Name: 'signature_mismatch:foo' +# CHECK-NEXT: - Index: 1 +# CHECK-NEXT: Name: _start +# CHECK-NEXT: - Index: 2 +# CHECK-NEXT: Name: foo +# CHECK-NEXT: - Index: 3 +# CHECK-NEXT: Name: call_foo +# CHECK-NEXT:... diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -113,6 +113,7 @@ sym->isUsedInRegularObj = false; sym->canInline = true; sym->traced = trace; + sym->forceExport = false; symVector.emplace_back(sym); return {sym, true}; } @@ -598,6 +599,11 @@ // Create a new variant; LLVM_DEBUG(dbgs() << "added new variant\n"); variant = reinterpret_cast(make()); + variant->isUsedInRegularObj = + !file || file->kind() == InputFile::ObjectKind; + variant->canInline = true; + variant->traced = false; + variant->forceExport = false; variants.push_back(variant); } else { LLVM_DEBUG(dbgs() << "variant already exists: " << toString(*variant) << "\n");