[Issue 20802] [REG2.088.0] Link failure with writefln
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sun Feb 11 11:04:38 UTC 2024
https://issues.dlang.org/show_bug.cgi?id=20802
Spoov <spoov0.707 at gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |spoov0.707 at gmail.com
--- Comment #3 from Spoov <spoov0.707 at gmail.com> ---
The example can be simplified a bit, same error as in previous comment:
############ test.d ##############
import std.uni;
void main()
{
CodepointSet('a', 'z');
dstring s;
decodeGrapheme(s);
}
##################################
Reducing std.uni yields the code below, same error as above:
#### phobos/std/uni/package.d ####
module std.uni;
enum TransformRes { goOn }
void writeAligned()()
{
final switch (TransformRes.goOn) { case TransformRes.goOn: break; }
}
struct GcPolicy {}
alias CodepointSet = InversionList!GcPolicy;
struct InversionList(SP=GcPolicy)
{
this()(uint[] intervals...)
{
sanitize();
}
void sanitize()
{
throw new Exception("");
writeAligned();
}
}
void decodeGrapheme(Input)(ref Input inp)
{
final switch (TransformRes.goOn) { case TransformRes.goOn: break; }
}
##################################
A final switch generates a call to core.internal.switch_.__switch_error for
handling the default case.
core.internal.switch_.__switch_error calls core.exception.__switch_errorT.
Both functions are templates.
By default a D program links with libphobos2.a.
libphobos2.a contains sanitize and writeAligned but not __switch_error and
__switch_errorT.
This is because libphobos2.a gets build in release mode which causes the call
to __switch_error to be replaced with a ud2 instruction.
The linker error shows that __switch_error is present but __switch_errorT is
missing.
In the compiler is this code
https://github.com/dlang/dmd/blob/8ab0636400d890a777889b3c84b09bcaa119fd57/compiler/src/dmd/dsymbolsem.d#L4666
which handles the case where a template that got instantiated from a non-root
module,
gets instantiated from a root module.
The code fixes the template instantiation, but misses the template
instantiations that are caused by it.
Because of this __switch_errorT is not emitted to the object file.
The following three files form a minimal example that reproduces the issue:
############# a.d ################
import b;
extern(C) void main() => bar!true;
############# b.d ################
void missing()() {}
void foo()() => missing();
void bar(bool b)() { version (Release) {} else foo(); }
enum fptr = &bar!false;
########## object.d ##############
// empty to make debugging simpler
$ dmd -c -version=Release b.d
$ dmd a.d b.o
a.o: In function `_D1b__T3fooZQfFNaNbNiNfZv':
a.d:(.text._D1b__T3fooZQfFNaNbNiNfZv[_D1b__T3fooZQfFNaNbNiNfZv]+0x5): undefined
reference to `_D1b__T7missingZQjFNaNbNiNfZv'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
--
More information about the Digitalmars-d-bugs
mailing list