diff --git a/src/attrib.c b/src/attrib.c index 71619867d71d..3966cea2e2d8 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -949,6 +949,8 @@ void PragmaDeclaration::semantic(Scope *sc) e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); args->data[0] = (void *)e; + if (e->op == TOKerror) + goto Lnodecl; if (e->op != TOKstring) error("string expected for library name, not '%s'", e->toChars()); else if (global.params.verbose) diff --git a/src/cast.c b/src/cast.c index dcd61dd97028..4052681d8792 100644 --- a/src/cast.c +++ b/src/cast.c @@ -775,6 +775,8 @@ Expression *Expression::castTo(Scope *sc, Type *t) #endif if (type == t) return this; + if (op == TOKerror) + return this; Expression *e = this; Type *tb = t->toBasetype(); Type *typeb = type->toBasetype(); diff --git a/src/expression.c b/src/expression.c index dbdcf0b9622b..96ea8c9fa7fa 100644 --- a/src/expression.c +++ b/src/expression.c @@ -3627,6 +3627,8 @@ Expression *ScopeExp::semantic(Scope *sc) } //printf("sds = %s, '%s'\n", sds->kind(), sds->toChars()); } + if (global.errors) + return new ErrorExp(); } else { @@ -5622,6 +5624,8 @@ Expression *CompileExp::semantic(Scope *sc) #endif UnaExp::semantic(sc); e1 = resolveProperties(sc, e1); + if (e1->op == TOKerror) + return e1; if (!e1->type->isString()) { error("argument to mixin must be a string type, not %s\n", e1->type->toChars()); @@ -6364,6 +6368,8 @@ Expression *DotTemplateInstanceExp::semantic(Scope *sc) Expression *e = new DotIdExp(loc, e1, ti->name); L1: e = e->semantic(sc); + if (e->op == TOKerror) + return e; if (e->op == TOKdottd) { if (global.errors) @@ -7685,6 +7691,8 @@ Expression *DeleteExp::semantic(Scope *sc) UnaExp::semantic(sc); e1 = resolveProperties(sc, e1); e1 = e1->toLvalue(sc, NULL); + if (e1->op == TOKerror) + return e1; type = Type::tvoid; tb = e1->type->toBasetype(); diff --git a/src/mtype.c b/src/mtype.c index 3d2bfa007528..16e3e06a9cf5 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -5615,8 +5615,11 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc, *pe = e; } else + { Lerror: error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars()); + *pe = new ErrorExp(); + } return; } L2: @@ -5715,6 +5718,7 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc, else error(loc, "undefined identifier %s", p); } + *pt = Type::terror; } } diff --git a/src/statement.c b/src/statement.c index fe598ce97017..8ca14b4d3137 100644 --- a/src/statement.c +++ b/src/statement.c @@ -321,6 +321,8 @@ Statements *CompileStatement::flatten(Scope *sc) exp = exp->semantic(sc); exp = resolveProperties(sc, exp); exp = exp->optimize(WANTvalue | WANTinterpret); + if (exp->op == TOKerror) + return NULL; if (exp->op != TOKstring) { error("argument to mixin must be a string, not (%s)", exp->toChars()); return NULL; @@ -1966,6 +1968,9 @@ Statement *ForeachStatement::semantic(Scope *sc) } break; } + case Terror: + s = NULL; + break; default: error("foreach: %s is not an aggregate type", aggr->type->toChars()); @@ -2957,7 +2962,7 @@ Statement *CaseStatement::semantic(Scope *sc) } } - if (exp->op != TOKstring && exp->op != TOKint64) + if (exp->op != TOKstring && exp->op != TOKint64 && exp->op != TOKerror) { error("case must be a string or an integral constant, not %s", exp->toChars()); exp = new IntegerExp(0); @@ -3068,6 +3073,9 @@ Statement *CaseRangeStatement::semantic(Scope *sc) last = last->optimize(WANTvalue | WANTinterpret); uinteger_t lval = last->toInteger(); + if (first->op == TOKerror || last->op == TOKerror) + return statement ? statement->semantic(sc) : NULL; + if ( (first->type->isunsigned() && fval > lval) || (!first->type->isunsigned() && (sinteger_t)fval > (sinteger_t)lval)) { @@ -3982,6 +3990,8 @@ Statement *WithStatement::semantic(Scope *sc) //printf("WithStatement::semantic()\n"); exp = exp->semantic(sc); exp = resolveProperties(sc, exp); + if (exp->op == TOKerror) + return NULL; if (exp->op == TOKimport) { ScopeExp *es = (ScopeExp *)exp; @@ -4440,6 +4450,8 @@ Statement *ThrowStatement::semantic(Scope *sc) #endif exp = exp->semantic(sc); exp = resolveProperties(sc, exp); + if (exp->op == TOKerror) + return this; ClassDeclaration *cd = exp->type->toBasetype()->isClassHandle(); if (!cd || ((cd != ClassDeclaration::throwable) && !ClassDeclaration::throwable->isBaseOf(cd, NULL))) error("can only throw class objects derived from Throwable, not type %s", exp->type->toChars());