Since 2.080 the following code, compiled in debug mode, doesn't link anymore:
import std.stdio, std.bitmanip;
void main() {
int i;
final switch (i) { case 0: {} }
writef("");
}
The output from the linker (bfd or gold) is:
function _Dmain: error: undefined reference to '_D6object__T14__switch_errorZQrFNaNbNiNfAyamZv'
Compiling the same program with -allinst, -release or -O works.
Comment #1 by iamthewilsonator — 2019-01-06T03:44:37Z
Reduced a bit further
import std.stdio, std.bitmanip;
void main() {
final switch (0) { }
writef("");
}
Comment #2 by greeenify — 2019-01-06T14:19:27Z
The linker error is different for me if I add -debug to the mix when compiling :D
---
foo.o:foo.d:_D76TypeInfo_S3std3uni__T13InversionListTSQBcQBb8GcPolicyZQBh__T9IntervalsTAkZQo6__initZ: error: undefined reference to '_D6object__T10RTInfoImplVAmA2i32i8Z4datayG2m'
foo.o:foo.d:_D48TypeInfo_S3std3uni__T8CowArrayTSQwQu8GcPolicyZQz6__initZ: error: undefined reference to '_D6object__T10RTInfoImplVAmA2i16i2Z4datayG2m'
---
Also as the behavior is different for `-checkaction=C`, I presume it runs into this:
https://github.com/dlang/dmd/blob/92408ea7b43f9636a5e5b0426d7c6ffd73576ca2/src/dmd/statementsem.d#L2596
Specifically CallExp needs to be a DotTemplateInstanceExp.
So this should be a good start:
---
diff --git a/src/dmd/statementsem.d b/src/dmd/statementsem.d
index cd7ac9aca..3cb3f01c4 100644
--- a/src/dmd/statementsem.d
+++ b/src/dmd/statementsem.d
@@ -2602,16 +2602,16 @@ else
}
else
{
- Expression sl = new IdentifierExp(ss.loc, Id.empty);
- sl = new DotIdExp(ss.loc, sl, Id.object);
- sl = new DotIdExp(ss.loc, sl, Id.__switch_error);
+ Expression objectId = new IdentifierExp(ss.loc, Id.object);
Expressions* args = new Expressions();
args.push(new StringExp(ss.loc, cast(char*) ss.loc.filename));
args.push(new IntegerExp(ss.loc.linnum));
- sl = new CallExp(ss.loc, sl, args);
- sl.expressionSemantic(sc);
+ auto tiargs = new Objects();
+ auto dt = new DotTemplateInstanceExp(ss.loc, objectId, Id.__switch_error, tiargs);
+ Expression sl = new CallExp(ss.loc, dt, args);
+ sl = sl.expressionSemantic(sc);
s = new SwitchErrorStatement(ss.loc, sl);
}
---
However, it still doesn't trigger the instantiation.
(In reply to Seb from comment #3)
> PR: https://github.com/dlang/dmd/pull/9211
Please ignore this PR. While I think it's on a good track, it still doesn't fix the instantiation problem and the test wasn't testing the linking.
Comment #5 by ali.akhtarzada — 2019-07-16T09:15:13Z
Shouldn't this be marked as critical or something? You hit this issue quite randomly depending on which part of std you use. Can you mark something as a regression AND critical?
Comment #6 by schlote — 2019-11-12T10:41:36Z
I triggered this bug today some code. Works in -release mode for DMD and LDC2 only. GDC is fine.
The created object files for DMD and LDC2 do NOT directly link against the symbol '_D6object__T14__switch_errorZQrFNaNbNiNfAyamZv'.
So the missing symbol must be referenced by some of the libraries linked against the object.
Comment #7 by schlote — 2019-11-12T10:54:09Z
I triggered this bug today some code. Works in -release mode for DMD and LDC2 only. GDC is fine.
The created object files for DMD and LDC2 do NOT directly link against the symbol '_D6object__T14__switch_errorZQrFNaNbNiNfAyamZv'.
So the missing symbol must be referenced by some of the libraries linked against the object.
Comment #8 by razvan.nitu1305 — 2021-02-25T08:47:29Z
I cannot reproduce this. The filed code snippet compiles successfully for both -release and -debug. Closing as WORKSFORME. Please reopen if the issue is not fixed.