[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