[Issue 15318] New: Templates not emitted for two "partial cycles"
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Wed Nov 11 04:14:21 PST 2015
https://issues.dlang.org/show_bug.cgi?id=15318
Issue ID: 15318
Summary: Templates not emitted for two "partial cycles"
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: regression
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: code at klickverbot.at
Consider the following program:
---
module A;
import C;
---
module B;
import E;
alias value = bar!5;
void foo() {
import core.stdc.stdio;
printf("%p\n", &value);
}
---
module C;
import E;
alias value = bar!5;
void foo() {
import core.stdc.stdio;
printf("%p\n", &value);
}
---
module D;
import B;
---
module E;
immutable bar(int v) = v;
---
If you compile it like this using DMD 2.068.2 or 2.069.1
---
dmd -c -offirst.o A.d B.d
dmd -c -ofsecond.o C.d D.d
dmd -main E.d first.o second.o
---
you'll get an undefined symbol for the bar!5 instance. The same occurs when
using -lib instead of "-c -of…", and E.d is of course unnecessary to compile in
this case, but just added for completeness.
The issue is that when compiling the first "package" (this test case is derived
from problems using by-package compilation in a big code base), i.e. A and B,
the symbol is determined to be instantiated by a non-root module (A -> C), so
even though it is instantiated in B, it doesn't get emitted into the object
file. But when compiling the second package, the D -> B import causes that
instance in C not to be emitted either.
One fix/workaround is to remove the following piece of logic from
TemplateInstance.needsCodegen():
--- dtemplate.d
if (tnext && !tnext.needsCodegen() && tnext.minst)
{
minst = tnext.minst; // cache result
assert(!minst.isRoot());
return false;
}
---
Now, of course, this fix is not ideal in the sense that it also causes more
work to be done in cases that are currently handled correctly. But
fundamentally I can't see how eliding instances that are being done directly in
root modules (B and C in this case) would ever be possible. There can always be
parts of the global module dependency graph for a whole executable that are not
visible from the local point of view when compiling a subset of the modules.
For instance, in the above example there is no way the compiler can know about
the existence of D when compiling A and B.
Marked as a regression, as the issue didn't occur using 2.067.1 in said large
real-world code base, but my suspicion is that the template instantiation logic
was broken before too.
--
More information about the Digitalmars-d-bugs
mailing list