Reported by g in d.learn. Segfaults in expression.c. D2 only. -- struct Move{ int Dx; } template genMove(){ enum Move genMove = { Dx:4 }; } enum Move b = genMove!();
also to note that this also don't works: -- struct A{ int n; } template genA(){ enum A genA = { n:4 }; } immutable A b = genA!(); -- but this works: -- struct A{ int n; } template genA(){ //works with immutable immutable A genA = { n:4 }; } immutable A b = genA!(); void main(){ //ok assert(b.n == 4); } --
Further reduced test case shows it doesn't need a template. It's just an enum static initializer problem. --- struct Move{ int Dx; } enum Move genMove = { Dx:4 }; immutable Move b = genMove; ---
It's happening because static struct initializers with names are not evaluated at compile time. And this is because init.c, StructInitializer::toExpression() doesn't deal with it. BTW -- now that we have struct literals, I'm not sure that we need struct initializers any more. They're a bit annoying, implementation-wise. --- TEST CASE --- struct Move{ int Dx; } immutable Move genMove = { Dx:4}; static assert(genMove.Dx == 4); // not evaluatable at compile time.
PATCH: With the demise of struct initializers, it's not worth fixing properly. But DsymbolExp::semantic() should check for a null value anyway (it checks in other places in expression.c). This would prevent the segfault. expression.c line 2306 (svn 267): if ((v->storage_class & STCmanifest) && v->init) { e = v->init->toExpression(); + if (!e) + { error("cannot make expression out of initializer for %s", v->toChars()); + e = new ErrorExp(); + } e->semantic(sc); return e; }
Changeset 349
fixed dmd 2.040