Bug 23255 – [REG 2.099] undefined reference to 'core.internal.switch.__switch_error()(string, size_t)'

Status
RESOLVED
Resolution
DUPLICATE
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2022-07-16T15:28:36Z
Last change time
2024-02-20T13:23:37Z
Assigned to
No Owner
Creator
Puneet Goel

Comments

Comment #0 by puneet — 2022-07-16T15:28:36Z
With latest DMD: $ dmd -release -shared -fPIC foo.d -oflibesdl-ldc-shared.so $ dmd test.d libesdl-ldc-shared.so /usr/bin/ld: test.o: in function `_D3std3uni__T21genericDecodeGraphemeVbi0Z__TQBfTAxwZQBnFNaNbNiNfKQrZv': test.d:(.text._D3std3uni__T21genericDecodeGraphemeVbi0Z__TQBfTAxwZQBnFNaNbNiNfKQrZv[_D3std3uni__T21genericDecodeGraphemeVbi0Z__TQBfTAxwZQBnFNaNbNiNfKQrZv]+0x3a5): undefined reference to `_D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv' collect2: error: ld returned 1 exit status Error: linker exited with status 1 // $ cat foo.d class Bar { Foo!false FOO; } struct Foo(bool S) { import std.format; const string toString(FormatSpec!char f) { return format("%0b", 42); } bool opEquals(V)(V other) { format("%s" , this); return false; } } // $ cat test.d import foo; enum Mode: int {SINGLE} void main() { import std.stdio; import std.format; Mode mode; writeln(format("%08b", 42), mode); }
Comment #1 by ibuclaw — 2022-07-18T11:42:56Z
Somewhat self-contained: ---format.d void formatValueImpl(T)(const(T)) { enum GraphemeState { Start, } auto state = GraphemeState.Start; final switch (state) with(GraphemeState) { case Start: } } template hasToString(T) { static if ((T val) {val.toString;}) enum hasToString; } void formatValueImpl(T)(T) if (is(T == struct) && hasToString!T) { } --- ---foo.d class Bar { Foo!false FOO; } struct Foo(bool S) { import format; const toString() { formatValueImpl(42); } bool opEquals(V)(V ) { formatValueImpl(this); } } --- ---test.d import foo; enum Mode{SINGLE} extern(C) void main() { import format; Mode mode; formatValueImpl(42); formatValueImpl(mode); } ---
Comment #2 by ibuclaw — 2022-07-18T11:48:20Z
Looks like mixing of release and non-release causes this. foo-release -> does not generate __switch_error. test-non-release -> generates __switch_error, but assumes that `foo` will too, so elides the emission. This results in the undefined reference. Confirmed that in 2.098, test-non-release always emits __switch_error.
Comment #3 by puneet — 2022-07-23T16:57:57Z
Using git bisect I hit the dmd version 2acf5570964ef1eaa403b602b86d41cac5567655. This is the commit that introduced the error >>>> commit 2acf5570964ef1eaa403b602b86d41cac5567655 (HEAD) Author: Martin Kinkelin <[email protected]> Date: Mon Jan 24 11:00:34 2022 +0100 Remove -unittest special cases wrt. template emission (#13224) * WIP: Remove -unittest special cases wrt. template emission * WIP * WIP2 * WIP3 * WIP4 * WIP5 * Print full compiler command-line in case building the unit_test_runner executable fails * WIP6 * WIP7 * Ignore unittest blocks in non-root modules * Temporary: Test with enforced -allinst * Revert "Temporary: Test with enforced -allinst" This reverts commit 6f1a5302d7cb981654e55722860fae0ddadbbc07. * Add comment as to why unittests in non-root modules are ignored And ignore them for doDocComments/doHdrGeneration too, for consistency. * Add changelog entry
Comment #4 by kinke — 2022-07-23T21:19:37Z
(In reply to Iain Buclaw from comment #2) > Looks like mixing of release and non-release causes this. > > foo-release -> does not generate __switch_error. > > test-non-release -> generates __switch_error, but assumes that `foo` will > too, so elides the emission. This results in the undefined reference. > > Confirmed that in 2.098, test-non-release always emits __switch_error. Makes perfect sense, and is accordingly no regression, just a missed case of culling which is now properly culled. Linking code compiled with different flags affecting template codegen is a well-known issue, and `-allinst` is supposed to handle that, but isn't enough in all cases (which are real bugs, either regarding template emission or inconsistent attributes inference).
Comment #5 by ibuclaw — 2022-07-23T21:29:45Z
(In reply to kinke from comment #4) > (In reply to Iain Buclaw from comment #2) > > Looks like mixing of release and non-release causes this. > > > > foo-release -> does not generate __switch_error. > > > > test-non-release -> generates __switch_error, but assumes that `foo` will > > too, so elides the emission. This results in the undefined reference. > > > > Confirmed that in 2.098, test-non-release always emits __switch_error. > > Makes perfect sense, and is accordingly no regression, just a missed case of > culling which is now properly culled. Linking code compiled with different > flags affecting template codegen is a well-known issue, and `-allinst` is > supposed to handle that, but isn't enough in all cases (which are real bugs, > either regarding template emission or inconsistent attributes inference). Or perhaps when importing modules across (multiple) DSO boundaries, only expose .di interface files between them.
Comment #6 by ibuclaw — 2024-02-20T13:23:37Z
Marking this as duplicate. *** This issue has been marked as a duplicate of issue 20802 ***