http://d.puremagic.com/issues/show_bug.cgi?id=8466
--- Comment #1 from Chad Joan <chadj...@gmail.com> 2012-08-05 11:52:49 PDT --- 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. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------