emscripten icon indicating copy to clipboard operation
emscripten copied to clipboard

wasm-ld: warning: function signature mismatch when compiling with -flto=thin

Open amir-l opened this issue 5 years ago • 27 comments

Hi, I'm trying to compile with IPO/LTO and I'm getting: wasm-ld: warning: function signature mismatch: _ZN12wre_frontend12ModelFactory11createModelERKNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE

defined as () -> void in ModelFactory.cpp.o defined as (i32, i32, i32) -> void in lto.tmp

Without IPO/LTO there isn't any wasm-ld warning.

This maybe happen because the function implementation is defined in a different compilation unit from the EMSCRIPTEN_BINDINGS usage. This function isn't used except in the bindings: emscripten::class_<wre_frontend::ModelFactory>(“ModelFactory”) .constructor<>() .function(“createModel”, &wre_frontend::ModelFactory::createModel);

Adding attribute((used)) to the function doesn't solve the issue. I tried both with SDK 1.39.7 and 1.39.11.

The workaround: replace the function binding with a wrapper that exists in same compilation unit of the binding (implemented in the header file of the class). The wrapper calls the original function.

Related issue: I would like to have linker warnings treated as errors. Neither -Werror nor -Xlinker --fatal-warnings error out the function signature mismatch. According to https://lld.llvm.org/WebAssembly.html - The --fatal-warnings flag can be used to disable generating stub functions and error out if mismatched are found.

amir-l avatar Apr 02 '20 15:04 amir-l

Regarding the linker flags, does -Wl,--fatal-warnings work for you? I don't think we support -Xlinker but I think we should.

sbc100 avatar Apr 02 '20 19:04 sbc100

Thanks, -Wl,--fatal-warnings solves the linker flags issue. Note that target_link_options(${target_name} PRIVATE "LINKER:--fatal-warnings") produces -Xlinker

amir-l avatar Apr 02 '20 19:04 amir-l

Still happens with 1.39.17

amir-l avatar Jun 17 '20 13:06 amir-l

Does this happen with regular / full LTO too? Or is it specific to thin LTO? Don't do any testing of thin LTO emscripten (and almost none in wasm-ld) so it wouldn't surprise me there where were issues with thin LTO specifically.

sbc100 avatar Jun 18 '20 15:06 sbc100

It is specific to thin LTO, regular/full works. Since INTERPROCEDURAL_OPTIMIZATION produces -flto=thin, I think the toolchain (Emscripten.cmake) should change CMAKE_CXX_COMPILE_OPTIONS_IPO to full.

amir-l avatar Jun 21 '20 08:06 amir-l

Sounds reasonable, at least until we have more thin LTO coverage. Would you be willing to create a PR?

sbc100 avatar Jun 22 '20 17:06 sbc100

https://github.com/emscripten-core/emscripten/pull/11517

amir-l avatar Jun 29 '20 12:06 amir-l

This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 30 days. Feel free to re-open at any time if this issue is still relevant.

stale[bot] avatar Jul 01 '21 03:07 stale[bot]

I am facing this issue when I apply -flto at compile & link time. Otherwise no warnings come. I am using emscripten version 2.0.20. @sbc100 Is it planned to get fixed ?

ravisumit33 avatar Sep 02 '21 17:09 ravisumit33

@ravisumit33 can you describe the issue you are seeing? Is it just a warning? Does the resulting program fail? Can you share the full error message?

sbc100 avatar Sep 02 '21 17:09 sbc100

@ravisumit33 can you describe the issue you are seeing? Is it just a warning? Does the resulting program fail? Can you share the full error message?

At link time I m getting warnings (not errors) from wasm-ld like below. Build succeeds without any error. Screenshot 2021-09-02 at 11 59 45 PM

ravisumit33 avatar Sep 02 '21 18:09 ravisumit33

And does the application work despite the warning? (i.e. can you ignore it?)

Would you might copy and pasting the text of the message so that I can feed it into c++filt and find the demanded symbol name? (including an imagine makes this a lot harder).

sbc100 avatar Sep 02 '21 18:09 sbc100

Hi there, this problem stably happens with emscripten 2.0.32 also for -flto=thin. Ignoring leads to crashes. Seems an LLVM problem.

andrewevstyukhin avatar Oct 28 '21 15:10 andrewevstyukhin

IIUC this issue is only about -flto=thin and does not occur with -flto. Is that your experience too @andrewevstyukhin.

If anyone has a repro case that that are able to share it would be useful in tracking this down.

sbc100 avatar Oct 28 '21 15:10 sbc100

Yes, I test -flto=thin then signatures break. Usual -flto works fine. Places are common bettween emscripten 2.0.14 and 2.0.32.

I hope you could give me some hints to better diagnose on my own, because private repo compiles to 60MB... I'll try to make a minimal reproduction for sure.

P.S. I can build wasm-ld with any desired patch. And I can debug wasm-ld on faulted data.

andrewevstyukhin avatar Oct 28 '21 15:10 andrewevstyukhin

I think to investigate the problem I need to be able reproduce the failure on my end. I will try enabling thin-lto in our test suite to see if I see this failure. If you have an example of program (the simpler the better) the fails until thin-lto in this way that would be useful.

sbc100 avatar Oct 28 '21 18:10 sbc100

I'm minimizing a fragile Example where -O0 has the same problem as -Os/-O3. The Example does #include of the class in many .cpp. I hope to finish in a day or two...

We have a working hack: move method body to the header.

enum class Result { NoData }; using Callback = std::function<void(Result)>; class C { virtual void OnE(Callback callback); ... void C::OnE(Callback callback) { callback(Result::NoData); }

=> virtual void OnE(Callback callback) { callback(Result::NoData); }

defined as () -> void in engine/libengine.a defined as (i32, i32) -> void in lto.tmp

andrewevstyukhin avatar Oct 28 '21 20:10 andrewevstyukhin

Hi @sbc100, minimal repro is at link

bash ./test.sh

[100%] Linking CXX executable app.js wasm-ld: warning: function signature mismatch: _ZN9Namespace8Delegate3OnEENSt3__28functionIFvNS0_6ResultEEEE defined as () -> void in engine/libengine.a(Dispatcher.cpp.o) defined as (i32, i32) -> void in lto.tmp

andrewevstyukhin avatar Nov 01 '21 09:11 andrewevstyukhin

Breaking news about reproduction:

  1. Problem exists if I use target_link_libraries(app PUBLIC engine) but disappears for target_link_options(app PUBLIC ${LINK_FLAGS} engine/libengine.a)

  2. Order of objects matters: broken: em++.py CMakeFiles/app.dir/Main.cpp.o engine/libengine.a -o app.js working: em++.py engine/libengine.a CMakeFiles/app.dir/Main.cpp.o -o app.js

Broken order comes from cmake version 3.22.1 and emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.0.0 (3fd52e107187b8a169bb04a02b9f982c8a075205)

andrewevstyukhin avatar Dec 17 '21 09:12 andrewevstyukhin

Is this still an issue with the latest version of emscripten?

sbc100 avatar Oct 10 '22 19:10 sbc100

For the latest emsdk installation (3.1.23) the issue is still relevant.

_thinLtoProblem>bash test.sh [100%] Linking CXX executable app.js wasm-ld: warning: function signature mismatch: _ZN8Delegate3OnEENSt3__28functionIFvvEEE defined as () -> void in engine/libengine.a(Dispatcher.cpp.o) defined as (i32, i32) -> void in lto.tmp [100%] Built target app

I can say these problems occur even for the -flto when libraries form diamond dependencies.

andrewevstyukhin avatar Oct 11 '22 05:10 andrewevstyukhin

It looks like the same issue is happening when linking with the proj library: asm-ld: warning: function signature mismatch: _ZTv0_n32_NK5osgeo4proj9operation15SingleOperation11gridsNeededERKNSt3__210shared_ptrINS0_2io15DatabaseContextEEEb

defined as () -> void in myLib/libproj.a(singleoperation.cpp.o) defined as (i32, i32, i32, i32) -> void in lto.tmp

asmundnordstoga avatar Mar 30 '23 07:03 asmundnordstoga

also happens when trying to build Qt with lto: https://bugreports.qt.io/browse/QTBUG-129522?filter=-2

adam-ce avatar Oct 25 '24 11:10 adam-ce

What is the status of this issue? For large programs full LTO isn't really an option.

xermicus avatar Jan 10 '25 18:01 xermicus

https://github.com/llvm/llvm-project/pull/136197 is now merged, can anyone confirm if that fixes the issue?

michaelharmonart avatar Apr 21 '25 17:04 michaelharmonart

I repeated steps for the latest emsdk version 4.0.7 and expectedly got broken signatures:

[100%] Linking CXX executable app.js wasm-ld: warning: function signature mismatch: _ZN8Delegate3OnEENSt3__28functionIFvvEEE defined as () -> void in engine/libengine.a(Dispatcher.cpp.o) defined as (i32, i32) -> void in lto.tmp [100%] Built target app

Then I compiled llvm-project with parameters cmake -DLLVM_ENABLE_PROJECTS=lld -DLLVM_TARGETS_TO_BUILD=WebAssembly, replaced wasm-ld and successfully passed the test:

[100%] Linking CXX executable app.js [100%] Built target app

andrewevstyukhin avatar Apr 22 '25 11:04 andrewevstyukhin

That sounds like this can be closed then, but llvm has not yet rolled into emsdk, so I'll wait until then before closing.

sbc100 avatar Apr 22 '25 21:04 sbc100

Hi, emsdk release 4.0.8 still failed the test:

[100%] Linking CXX executable app.js wasm-ld: warning: function signature mismatch: _ZN8Delegate3OnEENSt3__28functionIFvvEEE defined as () -> void in engine/libengine.a(Dispatcher.cpp.o) defined as (i32, i32) -> void in lto.tmp [100%] Built target app

andrewevstyukhin avatar May 07 '25 12:05 andrewevstyukhin

I'm glad to write these words: emsdk 4.0.9 passed the test.

[100%] Linking CXX executable app.js [100%] Built target app

andrewevstyukhin avatar May 29 '25 06:05 andrewevstyukhin

Interesting. I'm not really sure what might have fixed the issue.

I guess we can close this out?

sbc100 avatar May 29 '25 13:05 sbc100