Bug 8466 – DMD segfault (2.060 git)

Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-07-29T15:17:00Z
Last change time
2013-02-01T17:30:20Z
Assigned to
nobody
Creator
chadjoan

Comments

Comment #0 by chadjoan — 2012-07-29T15:17:15Z
template BuiltinRules() { class Option(Expr) { enum dstring = Expr.ruleName~")"d;} } mixin BuiltinRules!(); class PatternExpression : Option!PatternExpression{} After being reduced this far the code doesn't look valid anymore, but I figure it should at least print a useful error message. The git hash for this dmd version should be 5a9f538ca4b5cbebb726111f5290f6116e602d41.
Comment #1 by chadjoan — 2012-08-05T11:52:49Z
I've been trying to fix this one. I'm probably going to give up. In class.c I added this code: Dsymbol *ClassDeclaration::searchBase(Loc loc, Identifier *ident) { // Search bases classes in depth-first, left to right order for (size_t i = 0; i < baseclasses->dim; i++) { BaseClass *b = (*baseclasses)[i]; Dsymbol *cdb = b->type->isClassHandle(); + if (cdb == NULL) + return NULL; if (cdb->ident->equals(ident)) return cdb; cdb = ((ClassDeclaration *)cdb)->searchBase(loc, ident); if (cdb) return cdb; } return NULL; } This eliminates the segfault and allows dmd to throw error messages closer to the source of the problem. With that in hand I returned to dustmite with the code that I reduced into the first test case I posted, and then instead reduced it into this: I created a new test case: class SpaceSeq(Expr) { } class ZeroOrMore(Expr) { dstring ruleName = Expr.ruleName; } class PatternExpressions : ZeroOrMore!PatternExpression{ } class PatternExpression : BinaryExpression { dstring ruleName = "PatternExpression"; } class BlockExpression : SpaceSeq!(PatternExpression) { } Invalid code for a couple reasons: BinaryExpression is undefined and Expr.ruleName is not compile-time evaluatable. It instead gives me this odd error message: pml.d(17): Error: SpaceSeq!(_error_) is used as a type I found out that it should be erroring around line 340 of class.c in the "void ClassDeclaration::semantic(Scope *sc)" method because of the non-existant "BinaryExpression" base class in the test. This is the code that should do it: b = (*baseclasses)[0]; //b->type = b->type->semantic(loc, sc); tb = b->type->toBasetype(); if (tb->ty != Tclass) { if (b->type != Type::terror) error("base type must be class or interface, not %s", b->type->toChars()); baseclasses->remove(0); } else However, the call to error(...) was completely silent. Even the earlier call that should have said "undefined identifier BinaryExpression" gets silenced. I dig around a lot. I'm told on IRC that there is a global.gag variable that can cause this. Who would have guessed? More digging leads me to around line 1500 in declaration.c where I find this code: /* Because we may need the results of a const declaration in a * subsequent type, such as an array dimension, before semantic2() * gets ordinarily run, try to run semantic2() now. * Ignore failure. */ if (!global.errors && !inferred) { unsigned errors = global.startGagging(); Expression *e; Initializer *i2 = init; inuse++; So it seems that in "void VarDeclaration::semantic(Scope *sc)" it attempts to do some semantic analysis that calls ClassDeclaration::semantic(). It's the semantic analysis for PatternExpression's declaration in the test case. It /should/ error but the calling code gagged it. It's OK because the calling code has a reason. However, later on the same semantic analysis for PatternExpression is called, but it returns success that time because semantic analysis has already been run! This all means that it is possible to run semantic analysis on stuff without actually having done so! I'm sure that somewhere in this contradiction a NULL value was introduced that caused the later segfault. I'm not inclined to try and change the code in VarDeclaration because I'm not sure what it is trying to do. I'm even less inclined to try and engineer it a way to attempt semantic analysis without causing unintended side-effects. There's no way I have time for it.
Comment #2 by clugdbug — 2012-08-13T03:21:24Z
This is related to bug 4269. The difficult cases of that bug (those involving templates) are now fixed, but there are still a few cases (var and enum declarations, mainly) where speculative results aren't discarded. Just haven't got around to fixing those ones.
Comment #3 by andrej.mitrovich — 2013-02-01T17:30:20Z
These are not segfaulting anymore in 2.061. Reopen or file a new report if you find another test-case.