struct Foo {
float a, b;
Foo opUnary(string op)() const { return this; }
Foo opBinary(string op)(float) { return this; }
}
auto f1(T)(T a) { return 1; }
auto f2(T)(T a) { return a * f1(a); }
void main() {}
unittest {
auto a = Foo(0, 1);
assert(f2(-a) == a);
}
I've reduce the code as much I thought possible, removal of anything else stops the ICE occuring.
When compiling the above code, with the following command line arguments:
`dmd -unittest -inline test.d`
Displays
`Internal error: backend/symbol.c 1036`
Confirmed with Arch Linux and OSX.
Comment #1 by daniel350 — 2013-10-08T22:39:04Z
Confirmed on Git HEAD (511b24a457)
Comment #2 by daniel350 — 2013-10-08T22:43:06Z
Further reduced:
struct Foo {
float a, b;
Foo opUnary(string op)() const { return this; }
}
auto f1(T)(T a) { return a; }
auto f2(T)(T a) { return f1(a); }
void main() {}
unittest {
auto a = Foo(0, 1);
assert(f2(-a) == a);
}
Comment #3 by yebblies — 2013-11-13T23:56:21Z
Does not require -unittest
struct Foo {
int a;
float b;
Foo func()() const { return this; }
}
auto f1()(Foo a) { return a; }
void main() {
auto a = Foo(0, 1);
cast(void)(f1(a.func!()()) == a);
}
Produces this ast for main:
Foo a = Foo(0, 1.00000F);
cast(void)((Foo __inlineretval2 = Foo a = Foo __inlineretval1 = ref Foo this = a
;
, (assert(&this, "null this") , this);
, __inlineretval1;
, a;
, __inlineretval2).a == a.a && (Foo __inlineretval3 = Foo a = Foo __inlineretva
l1 = ref Foo this = a;
, (assert(&this, "null this") , this);
, __inlineretval1;
, a;
, __inlineretval3).b == a.b);
return 0;
The most suspect thing is that __inlineretval1 is declared twice - the crash in symbol.c happens on this symbol with assert(s->Ssymnum == -1); - ie the symbol is already numbered.