Bug 23154 – Linker error through templated __traits(compiles) in separate compilation unit

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2022-06-02T00:08:19Z
Last change time
2024-12-13T19:23:15Z
Assigned to
No Owner
Creator
Jan Jurzitza
Moved to GitHub: dmd#20116 →

Comments

Comment #0 by d.bugs — 2022-06-02T00:08:19Z
minimized reproduction test case: --- protocol.d enum hasCallableFoobar(T) = __traits(compiles, { T.init.foobar(); }); size_t barfoo(T)(T ) if (is(T == S[], S) && hasCallableFoobar!S) { return 0; } size_t barfoo(T)(T val) { static if (hasCallableFoobar!T) return val.foobar; } template ResolveThis(T) { static if (is(T : SelfRef!U, U)) alias ResolveThis = T; else alias ResolveThis = SelfRef!T[]; } struct SelfRef(T) { ResolveThis!T payload; size_t foobar() { static if (__traits(compiles, barfoo(payload))) barfoo(payload); return 0; } } alias SelfRefArray = SelfRef!bool; --- foo.d import protocol; unittest { SelfRef!(SelfRefArray) x; } --- to test: #!/bin/bash dmd -lib -ofprotocol.a protocol.d dmd -main -c -oflib.o -unittest -I. foo.d dmd -oftestlib lib.o protocol.a observe that there is no compiler error for potential issues, but also we are failing with a linker error: ld: error: undefined symbol: _D8protocol__T7SelfRefTbZQl6foobarMFNaNbNiNfZm >>> referenced by __main.d >>> lib.o:(_D8protocol__T6barfooTSQv__T7SelfRefTbZQlZQBcFNaNbNiNfQBgZm) collect2: error: ld returned 1 exit status Error: linker exited with status 1 Note: in my actual code this is much much more complex, basically calling Variant!MyVariant j; j.match!(v => v); with MyVariant being defined as Variant!JsonAlgebraic in another compilation unit.
Comment #1 by d.bugs — 2022-06-13T14:35:03Z
note: linker looks for _D8protocol__T7SelfRefTbZQl6foobarMFNaNbNiNfZm demangled: `pure nothrow @nogc @safe ulong protocol.SelfRef!(bool).SelfRef.foobar()` the protocol.a file contains the following foobar symbol: _D8protocol__T7SelfRefTbZQl6foobarMFNbZm demangled: `nothrow ulong protocol.SelfRef!(bool).SelfRef.foobar()` so it looks like the foo.d module doesn't resolve the attributes consistently with the other compilation unit.
Comment #2 by kinke — 2022-06-13T16:32:21Z
(In reply to Jan Jurzitza from comment #1) > so it looks like the foo.d module doesn't resolve the attributes > consistently with the other compilation unit. Yep, probably the same issue as https://issues.dlang.org/show_bug.cgi?id=23127.
Comment #3 by d.bugs — 2022-06-13T20:29:22Z
seems to be a bug in the DMD backend, does not reproduce with LDC
Comment #4 by d.bugs — 2022-06-13T20:45:05Z
nvm, actually reproduces with ldc as well, so more likely a frontend bug: ldc2 -main -c -unittest -I. foo.d -of foo.o ldc2 -lib -ofprotocol.a protocol.d dmd -oftestlib foo.o protocol.a For some reason ldc generated extra objects which I accidentally used instead, which were the wrong symbols and didn't cause this linker error.
Comment #5 by robert.schadek — 2024-12-13T19:23:15Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20116 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB