Bug 3273 – Regression(2.031): struct invariant + dtor fails to compile (no line number)
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2009-08-30T06:26:00Z
Last change time
2015-06-09T01:28:06Z
Keywords
diagnostic, patch, rejects-valid
Assigned to
nobody
Creator
2korden
Comments
Comment #0 by 2korden — 2009-08-30T06:26:18Z
The following is a minimal test-case to reproduce the bug:
module A;
struct A {
~this() {
}
invariant() {
}
}
> dmd A
Error: __result = this is not an lvalue
Note that this is a regression since DMD2.030 successfully compiled the code above.
Comment #1 by clugdbug — 2010-06-11T04:43:07Z
The error message is generated while running the semantic pass on the synthesised opAssign().
Here's an extraordinary variation:
struct A {
~this() { }
invariant() { }
A opAssign(A a) { return this; }
}
--
Error: cannot goto forward into different try block level
This has to be the most bizarre and unhelpful error message I've ever seen in D.
Comment #2 by clugdbug — 2010-06-15T13:23:27Z
There's a few different issues involved in this.
(1) The result variable isn't mutable.
Generated opAssign will return a const(A), because the result variable is
in func.c 1114:
if (!isVirtual())
v->storage_class |= STCconst;
because opAssign is not virtual. This line of code was added in svn 259 as part of the fix for bug 3390 (out(result) contract should not be able to rebind result). I think this line of code is wrong.
(2) The result variable isn't an lvalue.
This is the bug which was introduced in 2.031.
(3) invariant + dtor + a non-void function with this struct as parameter, has never worked.
For example this code fails on 2.022 with "cannot goto forward into different try block level". It's never worked.
struct A {
invariant() { }
~this() { }
int blah(A a) { return 0; }
void opAssign(A a) {}
}
Comment #3 by clugdbug — 2010-06-17T13:44:50Z
(In reply to comment #2)
> (3) invariant + dtor + a non-void function with this struct as parameter, has
> never worked.
> For example this code fails on 2.022 with "cannot goto forward into different
> try block level". It's never worked.
I've moved that case into a new bug, bug 4339, since it's not a regression, unlike the test case in this bug.
Comment #4 by clugdbug — 2010-07-20T00:21:01Z
(In reply to comment #3)
> (In reply to comment #2)
> > (3) invariant + dtor + a non-void function with this struct as parameter, has
> > never worked.
> > For example this code fails on 2.022 with "cannot goto forward into different
> > try block level". It's never worked.
>
> I've moved that case into a new bug, bug 4339, since it's not a regression,
> unlike the test case in this bug.
Now that bug 4339 is fixed, there's a reasonable workaround for this bug: create an opAssign.
Comment #5 by clugdbug — 2010-09-14T11:42:15Z
PATCH: A normal opAssign, such as in the case below, does not have 'isref' set.
struct A {
A opAssign(A a){ return this; }
}
Compiler-generated opAssign shouldn't either.
clone.c line 143, StructDeclaration::buildOpAssign()
------------
Parameter *param = new Parameter(STCnodtor, type, Id::p, NULL);
Parameters *fparams = new Parameters;
fparams->push(param);
Type *ftype = new TypeFunction(fparams, handle, FALSE, LINKd);
-#if STRUCTTHISREF
- ((TypeFunction *)ftype)->isref = 1;
-#endif
fop = new FuncDeclaration(0, 0, Id::assign, STCundefined, ftype);
Comment #6 by clugdbug — 2010-09-20T08:34:31Z
Have just discovered bug 4714, which still fails with this patch. I think this patch is wrong.
Comment #7 by clugdbug — 2011-01-01T22:26:12Z
*** Issue 5397 has been marked as a duplicate of this issue. ***
Comment #8 by k.hara.pg — 2011-06-18T06:46:17Z
*** Issue 4714 has been marked as a duplicate of this issue. ***
Comment #9 by k.hara.pg — 2011-06-18T07:28:11Z
*** Issue 3973 has been marked as a duplicate of this issue. ***