[Issue 17398] New: Partial template struct instantiation with __FILE__ leading to link error

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Sun May 14 09:22:26 PDT 2017


https://issues.dlang.org/show_bug.cgi?id=17398

          Issue ID: 17398
           Summary: Partial template struct instantiation with __FILE__
                    leading to link error
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: jbc.engelen at gmail.com

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)

--


More information about the Digitalmars-d-bugs mailing list