[Issue 18868] New: Separate compilation generates two static this functions, runs it twice

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed May 16 21:34:27 UTC 2018


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

          Issue ID: 18868
           Summary: Separate compilation generates two static this
                    functions, runs it twice
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: critical
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: johanengelen at weka.io

Testcase that shows that the static this is called twice.

```
// File: fls.d

template FLS(T) {
    int offset = -1;

    static this() {
        assert (offset == -1);
        offset += 2;
    }
}
```
```
// File: a.d

shared static this() { }
import fls;
alias floop = FLS!(int);
```

```
// File: b.d

import fls;
alias floop = FLS!(int);
void main() {}
```

Build+run script:
```
~/weka/ldc/installcurrent/bin/ldc2 -c a.d -of=a.o
~/weka/ldc/installcurrent/bin/ldc2 -c b.d -of=b.o
~/weka/ldc/installcurrent/bin/ldc2 fls.d a.o b.o
./fls
```

Fails with DMD (tested with 2.080) and LDC.


What is happening:
1. Because of separate compilation and template instantiation, the static ctor
is codegenned in two compilation units and added to both moduleinfos such that
it will be called on startup of each module (`a` and `b`)
2. After linking, two modules will call that same static ctor.
3. The static ctor contains code to catch multiple call case! Upon second or
more calls it simply returns. The checking is using a __gate variable. For
example: `....._sharedStaticCtor67().__gate` However, as you can see there is
this number "67" there. It is a number that is deterministic but may vary
across separate compilations depending, among others, on how many other static
ctors there are.
4. In one compilation case, the number is "x", in the other compilation case
the number is "not x". Thus we now have two _different_ staticctor functions
and gate variables, that access and write to the _same_ `offset` variable. So
the appearance is that the static ctor is run twice.

This is a similar problem as what we had with unittest function naming that was
semi-non-deterministic.
https://issues.dlang.org/show_bug.cgi?id=16995
https://issues.dlang.org/show_bug.cgi?id=18097
https://github.com/dlang/dmd/pull/7761

I think the fix is easy: instead of using a counter number, use the line+column
number like what we do now for the unittest functions.

--


More information about the Digitalmars-d-bugs mailing list