Bug 14272 – DMD segfault on invalid circular enum initialization
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-03-10T21:13:00Z
Last change time
2015-06-17T21:02:01Z
Keywords
ice, pull
Assigned to
nobody
Creator
dransic
Comments
Comment #0 by dransic — 2015-03-10T21:13:01Z
---
struct A(int tag)
{
enum int tag = tag;
}
alias A1 = A!1;
---
Comment #1 by ketmar — 2015-03-11T10:23:41Z
heh. this is stack overflow when trying to do semantic analysis on `tag`. compiler sees `tag` declaration inside struct with initialiser and starts semantic analysis of initializer, which comes to `tag` declaration inside struct with initialiser, and compiler starts semantic analysis of initializer, which comes to... also, this is not template-related bug, the following code gives the same result:
struct A {
enum int tag = tag;
}
void main () {
auto a = A();
}
compiler needs to check for recursive symbol usage in initializer.
Comment #2 by dransic — 2015-03-11T11:01:20Z
Right.
Both codes are invalid, aren't they? If you remove int after enum in both of them, there's a forward reference error, which seems logical.
Comment #3 by ketmar — 2015-03-11T11:24:16Z
yes, such code should trigger forward reference error. the following patch seems to fix it:
diff --git a/src/expression.c b/src/expression.c
index a69c9b8..270a37b 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -3295,6 +3295,11 @@ Lagain:
{
if (v->scope)
{
+ if (v->inuse)
+ {
+ error("forward reference of %s %s", s->kind(), s->toChars());
+ return new ErrorExp();
+ }
v->inuse++;
v->init = v->init->semantic(v->scope, v->type, INITinterpret);
v->scope = NULL;
Comment #4 by k.hara.pg — 2015-03-11T11:53:40Z
(In reply to Ketmar Dark from comment #3)
> yes, such code should trigger forward reference error. the following patch
> seems to fix it:
>
[snip]
At the head of VarDeclaration::semantic(), v->scope is set to NULL, so the v->inuse check needs to be placed before the if (v->scope) { ... } statement.
https://github.com/D-Programming-Language/dmd/pull/4482
Comment #5 by ketmar — 2015-03-11T12:28:22Z
thank you. may i ask you a question? why it checks for `global.gag`? judjing from comments i suspect that this is a hackfix for something, as no other `error()` calls does such check in this function.
Comment #6 by k.hara.pg — 2015-03-11T12:44:35Z
(In reply to Ketmar Dark from comment #5)
> thank you. may i ask you a question? why it checks for `global.gag`? judjing
> from comments i suspect that this is a hackfix for something, as no other
> `error()` calls does such check in this function.
Yes, it's a hack to avoid Phobos code breaking, that was added by Don. When I create a pull for this issue, I tested whether we can be remove it, but unfortunately it's still needed.
Comment #7 by github-bugzilla — 2015-03-11T14:45:19Z