diff --git a/src/attrib.c b/src/attrib.c index d53b655de994..7fe8c81a4aae 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -955,6 +955,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 a737244e351f..24440c5bb10e 100644 --- a/src/cast.c +++ b/src/cast.c @@ -622,6 +622,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 d8c0fb8a18cb..aa282e53cd59 100644 --- a/src/expression.c +++ b/src/expression.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -3152,17 +3152,21 @@ Expression *StructLiteralExp::semantic(Scope *sc) else { if (v->init) - { e = v->init->toExpression(); - if (!e) - { error("cannot make expression out of initializer for %s", v->toChars()); - e = new ErrorExp(); - } - else if (v->scope) - { // Do deferred semantic anaylsis - Initializer *i2 = v->init->syntaxCopy(); - i2 = i2->semantic(v->scope, v->type); - e = i2->toExpression(); - v->scope = NULL; + { if (v->init->isVoidInitializer()) + e = NULL; + else + { e = v->init->toExpression(); + if (!e) + { error("cannot make expression out of initializer for %s", v->toChars()); + e = new ErrorExp(); + } + else if (v->scope) + { // Do deferred semantic anaylsis + Initializer *i2 = v->init->syntaxCopy(); + i2 = i2->semantic(v->scope, v->type); + e = i2->toExpression(); + v->scope = NULL; + } } } else @@ -3410,6 +3414,8 @@ Expression *ScopeExp::semantic(Scope *sc) } //printf("sds = %s, '%s'\n", sds->kind(), sds->toChars()); } + if (global.errors) + return new ErrorExp(); } else { @@ -5176,6 +5182,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()); @@ -5908,6 +5916,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) @@ -7201,6 +7211,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/init.c b/src/init.c index d876c633bc4f..0a85d68716f7 100644 --- a/src/init.c +++ b/src/init.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2009 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -166,6 +166,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t) { if (fieldi >= ad->fields.dim) { error(loc, "too many initializers for %s", ad->toChars()); + errors = 1; field.remove(i); i--; continue; @@ -182,6 +183,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t) if (!s) { error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars()); + errors = 1; continue; } @@ -191,6 +193,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t) if (fieldi >= ad->fields.dim) { s->error("is not a per-instance initializable field"); + errors = 1; break; } if (s == (Dsymbol *)ad->fields.data[fieldi]) diff --git a/src/interpret.c b/src/interpret.c index 58518e61243a..0497869b8422 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -1266,7 +1266,7 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d) } else if ((v->isCTFE() || (!v->isDataseg() && istate)) && !v->value) { - if (v->init) + if (v->init && v->type->size() != 0) { if (v->init->isVoidInitializer()) { @@ -1339,6 +1339,10 @@ Expression *DeclarationExp::interpret(InterState *istate) e = EXP_CANT_INTERPRET; } } + else if (s == v && !v->init && v->type->size()==0) + { // Zero-length arrays don't need an initializer + e = v->type->defaultInitLiteral(loc); + } #if DMDV2 else if (s == v && (v->isConst() || v->isImmutable()) && v->init) #else diff --git a/src/mtype.c b/src/mtype.c index 869aa7bcd2df..0a66f1923812 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2010 by Digital Mars +// Copyright (c) 1999-2011 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -3377,8 +3377,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: @@ -3494,6 +3497,7 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc, else error(loc, "undefined identifier %s", p); } + *pt = Type::terror; } } @@ -4682,7 +4686,11 @@ Expression *TypeStruct::defaultInitLiteral(Loc loc) VarDeclaration *vd = (VarDeclaration *)(sym->fields.data[j]); Expression *e; if (vd->init) - e = vd->init->toExpression(); + { if (vd->init->isVoidInitializer()) + e = NULL; + else + e = vd->init->toExpression(); + } else e = vd->type->defaultInitLiteral(); structelems->data[j] = e; diff --git a/src/statement.c b/src/statement.c index b0f5db0b9cec..26004df1d68a 100644 --- a/src/statement.c +++ b/src/statement.c @@ -305,6 +305,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; @@ -1887,6 +1889,9 @@ Statement *ForeachStatement::semantic(Scope *sc) } break; } + case Terror: + s = NULL; + break; default: error("foreach: %s is not an aggregate type", aggr->type->toChars()); @@ -2814,7 +2819,7 @@ Statement *CaseStatement::semantic(Scope *sc) { exp = exp->implicitCastTo(sc, sw->condition->type); exp = exp->optimize(WANTvalue | WANTinterpret); - 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); @@ -2914,11 +2919,15 @@ Statement *CaseRangeStatement::semantic(Scope *sc) first = first->semantic(sc); first = first->implicitCastTo(sc, sw->condition->type); first = first->optimize(WANTvalue | WANTinterpret); - dinteger_t fval = first->toInteger(); last = last->semantic(sc); last = last->implicitCastTo(sc, sw->condition->type); last = last->optimize(WANTvalue | WANTinterpret); + + if (first->op == TOKerror || last->op == TOKerror) + return statement ? statement->semantic(sc) : NULL; + + dinteger_t fval = first->toInteger(); dinteger_t lval = last->toInteger(); if (lval - fval > 256) @@ -3227,11 +3236,12 @@ Statement *ReturnStatement::semantic(Scope *sc) } else if (fd->inferRetType) { - if (fd->type->nextOf()) + Type *tfret = fd->type->nextOf(); + if (tfret) { - if (!exp->type->equals(fd->type->nextOf())) + if (tfret != Type::terror && !exp->type->equals(tfret)) error("mismatched function return type inference of %s and %s", - exp->type->toChars(), fd->type->nextOf()->toChars()); + exp->type->toChars(), tfret->toChars()); } else { @@ -3768,6 +3778,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; @@ -4196,6 +4208,8 @@ Statement *ThrowStatement::semantic(Scope *sc) error("Throw statements cannot be in contracts"); exp = exp->semantic(sc); exp = resolveProperties(sc, exp); + if (exp->op == TOKerror) + return this; if (!exp->type->toBasetype()->isClassHandle()) error("can only throw class objects, not type %s", exp->type->toChars()); return this;