Bug 24085 – Separate Compilation Bugs

Status
NEW
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2023-08-14T18:00:38Z
Last change time
2024-12-13T19:30:23Z
Assigned to
No Owner
Creator
Puneet Goel
Moved to GitHub: dmd#20319 →

Attachments

IDFilenameSummaryContent-TypeSize
1885test.tar.gzReduced code to replicate the issueapplication/gzip699

Comments

Comment #0 by puneet — 2023-08-14T18:00:38Z
Created attachment 1885 Reduced code to replicate the issue When source files are compiled separately, DMD is not creating symbols for certain templatized methods (opCast). To replicate the issue, please untar the attachment and run compile.sh // foo.d module foo; version (SIGNED) alias INT = int; version (UNSIGNED) alias INT = uint; template Foo(N...) { alias Foo = FooImpl!(N); } struct FooImpl(INT N) { void opAssign(V)(V) { } void opAssign(bool) { } ubyte getValue() { return cast(ubyte) this; } alias getValue this; V opCast(V)() { assert (false); } } auto toFoo(INT N, T)(T ) { return Foo!N(); } // bar.d import foo; import frop; struct Bar { Foo!0 bar; } // frop.d import foo; import bar; Foo!0 frop() { return toFoo!0(0); } // dmd -version=UNSIGNED -c frop.d // dmd -version=UNSIGNED -c bar.d // nm bar.o frop.o | ddemangle | grep opCast
Comment #1 by razvan.nitu1305 — 2023-08-16T13:15:08Z
Note that if you delete the useless imports of bar in frop and frop in bar, you get the same result in both signed and unsigned versions. This looks like the unsigned case somehow manages to instantiate all of the methods of FooImpl. I don't see how this happens: maybe the compiler generates some code or tries semantic on some construction.
Comment #2 by ilya.yanok — 2024-10-18T16:38:06Z
I think I'm also affected by the same bug (also reproducible with LDC), but I think my minimal example uses even less features. There is also a cyclic dependency and an overloaded operator though. That's what dustmite produced (doesn't make sense, because of infinite recursion, but still symbols should be there, I think): // option.d import util; struct Option(T) { int opCmp()(const(Option) rhs) const { return this.opCmp(rhs); } } Option!string f; // util.d import option; Option!string x; // dmd -c option.d // dmd -c util.d // nm option.o util.o | ddemangle | grep 'opCmp!' // Neither of .o files have an implementation for this symbol It is possible to make the actual implementation more reasonable, while still having this issue.
Comment #3 by ilya.yanok — 2024-10-23T12:24:34Z
UPD: even though my issue looked similar, it turned out to be unrelated: I managed to fix my issue, but the issue described in the bug is still there.
Comment #4 by robert.schadek — 2024-12-13T19:30:23Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20319 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB