Bug 3488 – Segfault(expression.c): enum declared with struct static initializer
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2009-11-08T08:30:00Z
Last change time
2015-06-09T01:27:03Z
Keywords
ice-on-valid-code, patch
Assigned to
nobody
Creator
clugdbug
Comments
Comment #0 by clugdbug — 2009-11-08T08:30:45Z
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!();
Comment #1 by sockpuppet3 — 2009-11-08T10:51:30Z
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);
}
--
Comment #2 by clugdbug — 2009-11-08T11:32:12Z
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;
---
Comment #3 by clugdbug — 2009-11-09T03:24:21Z
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.
Comment #4 by clugdbug — 2009-11-23T00:23:22Z
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;
}