Bug 2323 – ICE(cgcs.c): taking address of a method of a temporary struct
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2008-08-30T11:48:00Z
Last change time
2014-03-01T00:37:01Z
Keywords
ice-on-valid-code, patch, wrong-code
Assigned to
bugzilla
Creator
snake.scaly
Comments
Comment #0 by snake.scaly — 2008-08-30T11:48:43Z
Compiler reports an internal error if an address of a temporary struct's method is taken:
---- begin test.d
void main()
{
struct A {
void foo() {}
static A opCall() {A a; return a;}
}
void delegate() x = &A().foo;
}
---- end test.d
>dmd test.d
Internal error: ..\ztc\cgcs.c 358
Workaround is to use an explicit stack variable for A():
auto y = A();
void delegate() x = &y.foo;
compiles and works correctly.
Comment #1 by clugdbug — 2009-05-27T05:43:58Z
This bug also applies to D1. And it silently generates bad code if compiled with -O. Reduced test case:
----
struct A {
void foo() {}
}
A bar() {A a; return a;}
void main() {
void delegate() x = &bar().foo;
}
---
Root cause: should not be able to make a delegate from something which isn't an lvalue (just as you can't take address of a function return).
PATCH: add one line in expression.c, DelegateExp::semantic(Scope *sc)
if (func->needThis())
e1 = getRightThis(loc, sc, ad, e1, func);
+ e1->toLvalue(sc, e1); // add this line
}
Comment #2 by bugzilla — 2009-06-22T22:27:23Z
Sergey is right, and the fix is to create a temp on the stack, copy the struct in, and take the address of that. One line fix in e2ir.c.