Bug 15989 – Initializing manifest constants with CTFE allocated data
Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2016-05-03T22:11:20Z
Last change time
2018-01-03T22:32:00Z
Keywords
accepts-invalid, pull
Assigned to
No Owner
Creator
Dmitry Olshansky
Comments
Comment #0 by dmitry.olsh — 2016-05-03T22:11:20Z
The test case below segfaults with -O but passes without it. Only Windows x86, tested on DMD from the latest master.
struct Input{}
interface Kickstart{
bool opCall(ref Input );
}
struct Regex
{
Kickstart kickstart;
}
auto regex()
{
return Regex(new ShiftOr());
}
class ShiftOr : Kickstart
{
bool opCall(ref Input )
{
return false;
}
}
enum ctRegex = regex();
void main()
{
auto r = ctRegex;
auto s = Input();
r.kickstart(s);
}
This most likely happens as a consequence of not copying in optimize.d line 237-238.
Comment #4 by bugzilla — 2016-09-30T20:40:56Z
The trouble appears to be the line:
new ShiftOr();
which is evaluated at compile time (because of the enum) yet is expected to exist at runtime. Creating items on the GC heap with operator new does not transfer from compile time to runtime. I don't see how this can possibly work, and the compiler should issue an error message for it.
It has nothing to do with optimizer flags, as it doesn't work regardless, it just happens to fail in a way that doesn't seg fault when -O is not specified.
Comment #5 by bugzilla — 2016-09-30T20:45:20Z
For example:
void main()
{
enum pi = new int(3);
*pi = 4;
}
emits:
foo4.d(4): Error: cannot use non-constant CTFE pointer in an initializer '&[3][0]'
This error message should be printed for the bug case.
Comment #6 by uplink.coder — 2016-09-30T21:23:53Z
Yes this code is invalid.
finding this condition will involve scanning the members of a struct for classReferances and disallowing the creation of a manifest consntant if there are those in there.
Comment #7 by dlang-bugzilla — 2016-09-30T22:12:31Z
Workaround: use "static const" instead of "enum"?
Comment #8 by uplink.coder — 2016-09-30T22:14:35Z
No. It has to be static immutable.
Otherwise it will not be there at CT.