Bug 22427 – betterC: casting an array causes linker error in string comparison.
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-10-19T03:49:12Z
Last change time
2023-07-14T16:02:23Z
Keywords
betterC, link-failure, pull
Assigned to
No Owner
Creator
dave287091
Comments
Comment #0 by dave287091 — 2021-10-19T03:49:12Z
This reduced code fails to link.
// foo.d
extern(C)
int main(){
if("a" == "a")
return 1;
char[] p;
auto a = cast(int[])p;
return 0;
}
A linker error results:
Undefined symbols for architecture x86_64:
"__D4core8internal5array8equality__T8__equalsTaTaZQoFNaNbNiNeMxAaMxQeZb", referenced from:
_main in foo.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: /usr/bin/cc failed with status: 1
The undefined symbol demangles to:
pure nothrow @nogc @trusted bool core.internal.array.equality.__equals!(char, char).__equals(scope const(char[]), scope const(char[]))
I have verified this problem happens both with dmd and ldc2. ldc2 1.24 - 1.28 has the error. Older ldc do not. Current dmd has the error, I don’t know how far back.
Comment #1 by dave287091 — 2021-10-19T03:52:33Z
(In reply to dave287091 from comment #0)
> This reduced code fails to link.
I forgot to mention, compile with -betterC. Without -betterC it links fine.
Comment #2 by dave287091 — 2021-10-19T03:53:12Z
(In reply to dave287091 from comment #1)
> (In reply to dave287091 from comment #0)
> > This reduced code fails to link.
>
> I forgot to mention, compile with -betterC. Without -betterC it links fine.
Also, without the array cast there it also links fine.
Comment #3 by dave287091 — 2022-05-13T04:46:03Z
This worked with dmd 2.093 and stopped working with dmd 2.094.
Comment #4 by dave287091 — 2022-05-25T01:26:39Z
The -allinst/--allinst flag will resolve the link error, but that is a counter-intuitive requirement as there is no explicit template in the program - just one injected by the compiler. The fact that array equality is implemented as a template is an implementation detail and shouldn’t require the user to work around it.
It’s also weird that the cast somehow changes whether the template is emitted.
Comment #5 by razvan.nitu1305 — 2023-07-11T14:29:28Z
It seems that the cast is lowered to __ArrayCast which in turn ends up instantiating __equals with the same template parameters, but in a speculative context (static if). Somehow, the template emission strategy decides that the instance does not require codegen (from what I can tell, the compiler decides that it's better to put the instance in the imported module - core.memory in this case), hence the linker errors.
I think that this strategy should be disabled in the case of betterC as it currently is with -allinst.
Comment #6 by dlang-bot — 2023-07-11T14:52:21Z
@RazvanN7 created dlang/dmd pull request #15404 "Fix Issue 22427 - betterC: casting an array causes linker error in string comparison" fixing this issue:
- Fix Issue 22427 - betterC: casting an array causes linker error in string comparison
https://github.com/dlang/dmd/pull/15404
Comment #7 by dlang-bot — 2023-07-14T16:02:23Z
dlang/dmd pull request #15404 "Fix Issue 22427 - betterC: casting an array causes linker error in string comparison" was merged into master:
- bab58df92fa67c4702bf001c8258ff2eeb4643bc by RazvanN7:
Fix Issue 22427 - betterC: casting an array causes linker error in string comparison
- 9e1ba7b233a73941ec094d60b226af92618301d8 by RazvanN7:
Fix Issue 22427 - betterC: casting an array causes linker error in string comparison
https://github.com/dlang/dmd/pull/15404