digitalmars.D.bugs - [Issue 15318] New: Templates not emitted for two "partial cycles"
- via Digitalmars-d-bugs (77/77) Nov 11 2015 https://issues.dlang.org/show_bug.cgi?id=15318
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 puremagic.com Reporter: code 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. --
Nov 11 2015