Bug 13113 – cannot build druntime's gc.d with -debug=INVARIANT, bad @nogc inference?

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-07-12T18:04:00Z
Last change time
2014-08-22T08:04:45Z
Assigned to
nobody
Creator
r.sagitario

Comments

Comment #0 by r.sagitario — 2014-07-12T18:04:29Z
When trying to compile gc.d from druntime with -debug=INVARIANT, I get the following error: gc.d(1367): Error: @nogc function 'gc.gc.Gcx.~this' cannot call non-@nogc function 'gc.gc.Gcx.__invariant' I've tried reduce this, here's what I get for ////////////////////// class Gcx { ~this() {} invariant() { foreach(t; tr) {} } Treap!int tr; } struct Treap(E) { nothrow: E e; ~this() {} int opApply(scope int delegate(const ref E) nothrow dg) const { return 1; } } /////////////////////// Error: pure function 'nogcinv.Gcx.~this' cannot call impure function 'nogcinv.Gcx.__invariant' nogcinv.d(5): Error: safe function 'nogcinv.Gcx.~this' cannot call system function 'nogcinv.Gcx.__invariant' nogcinv.d(5): Error: @nogc function 'nogcinv.Gcx.~this' cannot call non-@nogc function 'nogcinv.Gcx.__invariant'
Comment #1 by r.sagitario — 2014-07-12T18:09:20Z
I'm not 100% sure this is a regression, because the code inside the invariant changed, too. Is there a reason why the destructor has to be @safe, pure and @nogc?
Comment #2 by safety0ff.bugz — 2014-07-13T09:08:12Z
Comment #3 by r.sagitario — 2014-07-13T09:39:40Z
>Does reverting the invariant portion of [1] allow it to compile? I haven't actually reverted the code, but commenting out the contents of Gcx.invariant didn't help. Commenting out the destructor of Treap DOES help. Here is a further reduction of the test case: class Gcx { invariant() {} Treap!int tr; } struct Treap(E) { ~this() {} // no error if this line is removed }
Comment #4 by bugzilla — 2014-07-13T19:14:03Z
The trouble seems to be that destructors are getting their attributes inferred, while invariants are not.
Comment #5 by bugzilla — 2014-07-14T05:16:11Z
Comment #6 by k.hara.pg — 2014-07-15T02:46:55Z
This is not a regression, it's a compiler bug around invariant and attributes. Currently dmd implements both post invariant call in constructor and pre invariant call in destructor as direct call. But in normal member functions, pre/post invariant call is done virtually. And, only direct invariant call is affected by the check of pure, @safe, and @nogc attributes. Note that, it is not affected by nothrow but it is not intentional behavior. class C { invariant() {} // impure, throwable, system, and gc-able this(int) pure nothrow @safe @nogc {} // line 5 // post invaiant is called directly and reports attribute violation error ~this() pure nothrow @safe @nogc {} // line 8 // pre invaiant is called directly and reports attribute violation error void foo() pure nothrow @safe @nogc {} // pre/post virtual invariant call does not report attribute violation error } Output: Error: pure function 'test.C.this' cannot call impure function 'test.C.__invariant' test.d(5): Error: safe function 'test.C.this' cannot call system function 'test.C.__invariant' test.d(5): Error: @nogc function 'test.C.this' cannot call non-@nogc function 'test.C.__invariant' Error: pure function 'test.C.~this' cannot call impure function 'test.C.__invariant' test.d(8): Error: safe function 'test.C.~this' cannot call system function 'test.C.__invariant' test.d(8): Error: @nogc function 'test.C.~this' cannot call non-@nogc function 'test.C.__invariant' (In reply to Rainer Schuetze from comment #1) > I'm not 100% sure this is a regression, because the code inside the > invariant changed, too. > Is there a reason why the destructor has to be @safe, pure and @nogc? So, the original issue is not a compiler regression. It was introduced by druntime change in Gcx class invariant code.
Comment #7 by k.hara.pg — 2014-07-15T03:59:29Z
*** Issue 12834 has been marked as a duplicate of this issue. ***
Comment #8 by r.sagitario — 2014-07-15T07:32:48Z
> So, the original issue is not a compiler regression. It was introduced by druntime change in Gcx class invariant code. I cannot test the current gc.d code with dmd 2.065 because of other changes, but the reduced test case works with that version. Isn't this a regression for user code, too?
Comment #9 by k.hara.pg — 2014-07-16T04:35:23Z
(In reply to Rainer Schuetze from comment #8) > > So, the original issue is not a compiler regression. It was introduced by druntime change in Gcx class invariant code. > > I cannot test the current gc.d code with dmd 2.065 because of other changes, > but the reduced test case works with that version. Isn't this a regression > for user code, too? OK... make sense. So, I'd propose that direct invariant calls in constructor and destructor should bypass attribute enforcement. https://github.com/D-Programming-Language/dmd/pull/3775 Of course it is debatable behavior, but attribute enforcement does not work _at all_ on virtual invariant calls in normal member functions, so the change itself would not make things much worse.
Comment #10 by github-bugzilla — 2014-07-20T21:52:40Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/ac4de32709c2fafd0bd73222458f6899e0e2641c fix Issue 13113 - cannot build druntime's gc.d with -debug=INVARIANT, bad @nogc inference? Bypass attribute check on direct invariant calls. https://github.com/D-Programming-Language/dmd/commit/8e56b9faffb2c9a3d9e1d6c3a0c74ffc9c486033 Merge pull request #3775 from 9rnsr/fix13113 Issue 13113 - cannot build druntime's gc.d with -debug=INVARIANT, bad @nogc inference?
Comment #11 by github-bugzilla — 2014-07-21T06:00:06Z
Commit pushed to 2.066 at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/2c4668be4ff2a538c321c3efd55b96dad9330537 Merge pull request #3775 from 9rnsr/fix13113 Issue 13113 - cannot build druntime's gc.d with -debug=INVARIANT, bad @nogc inference?
Comment #12 by github-bugzilla — 2014-08-22T08:04:45Z