The following code crashes both DMD1 and DMD2:
File crash.d:
struct Number
{
public int value;
static Number opCall(int value)
{
Number n = void;
n.value = value;
return n;
}
}
class Crash
{
Number number = Number(0);
}
// end of file
replacing Number n = void; with Number n; resolves issue.
Comment #1 by 2korden — 2008-07-18T04:22:43Z
Is this code a correct D in the first place?
struct Number
{
static Number opCall()
{
Number n = void;
return n;
}
}
class Crash
{
Number number = Number();
}
crash.d(6): Error: variable n is used before initialization
crash.d(12): Error: cannot evaluate opCall() at compile time
If it isn't and variable can't use void initializer for expression to work in compile time, then the fix is trivial.
But I think that it should work. IIRC, if you initialize a variable with void it means "initialize with anything, I don't care" so that compiler could simply increase stack pointer instead of putting some meaningful values to stack for a variable to initialize, or do some other optimization. If it is, then a void initializer can be ignored for CTFE and a variable can be initialized with a zero- or default initializer, since both belongs to/are subset of "any initializer". Moreover CTFE should have determinative behavior.
Adding something like this:
if ((v->value == NULL) && (v->init->isVoidInitializer()) {
v->value = v->type->defaultInit();
}
solved the problem and compiled both samples for me.
Comment #2 by clugdbug — 2009-04-24T05:25:03Z
Created attachment 337
Patch against DMD2.029
Koroskin's patch