Bug 17398 – Partial template struct instantiation with __FILE__ leading to link error
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-05-14T16:22:26Z
Last change time
2021-08-17T15:17:15Z
Keywords
industry
Assigned to
No Owner
Creator
Johan Engelen
Comments
Comment #0 by jbc.engelen — 2017-05-14T16:22:26Z
File a.d:
```
module a;
import c;
S!int a;
void main() {}
```
File c.d:
```
module c;
import a;
enum BUG = true; // `false` "removes" the bug by reordering,
// but this does not work in the original failing code.
struct S(F)
{
void templateTaking__FILE__(string file = __FILE__)() {
}
static if (BUG) {
auto addrFoo() {
return &foo;
}
}
private void foo() {
templateTaking__FILE__();
}
static if (!BUG) {
auto addrFoo() {
return &foo;
}
}
}
S!int cInst;
```
When these two files are compiled separately, the following link error occurs:
```
> dmd -c /Users/johan/weka/ldc/build39release/tests/c.d -of=c.o
> dmd /Users/johan/weka/ldc/build39release/tests/a.d c_dmd.o
Undefined symbols for architecture x86_64:
"_D1c8__T1STiZ1S128__T22templateTaking__FILE__VAyaa46_2f55736572732f6a6f68616e2f77656b612f6c64632f6275696c64333972656c656173652f74657374732f632e64Z22templateTaking__FILE__MFNaNbNiNfZv", referenced from:
_D1c8__T1STiZ1S3fooMFNaNbNiNfZv in c.o
"_D1c8__T1STiZ1S41__T22templateTaking__FILE__VAyaa3_632e64Z22templateTaking__FILE__MFNaNbNiNfZv", referenced from:
_D1c8__T1STiZ1S3fooMFNaNbNiNfZv in a.o
```
The reason for the link error is that parts of `S!int` are instantiated in c.o and other parts in a.o. When compiling c.o, __FILE__ in templateTaking__FILE__ is c.d's absolute path. When compiling a.o however, c.d is an import and __FILE__ in templateTaking__FILE__ is c.d's relative path.
The circular import results in some S!int things being instantiated in a.o but partly (it refers to the templateTaking__FILE__!<relative path> symbol). Interestingly, reordering of the functions in struct S "fixes" this issue.
This issue is another example of troubles with __FILE__ as a template parameter. __FILE_FULL_PATH__ would resolve this.
But, this issue also highlights a template instantiation problem: part of the template instantiated in a.o, but it should either be fully instantiated or not at all. The "partly instantiated" is causing the troubles. If the template struct was fully instantiated, there would be template bloat, yes, but there would not be linker errors.
Tested with dmd 2.074.0 and dmd 2.072.2. (LDC has the same problem)
Also related: https://issues.dlang.org/show_bug.cgi?id=15318
(for the given testcase, the fix proposed by David in issue 15318 does not make a difference, but it does make a difference (for worse) for non-circular import testcase)
Comment #3 by dlang-bugzilla — 2017-05-16T05:57:18Z