Mercurial > projects > ldc
diff dmd/expression.c @ 1618:a87f1d6ff48e
Merge DMD r303: harmonize
---
dmd/expression.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++-----
dmd/expression.h | 8 +++++
dmd/template.c | 27 ++++++++++++-------
3 files changed, 95 insertions(+), 18 deletions(-)
author | Leandro Lucarella <llucax@gmail.com> |
---|---|
date | Wed, 06 Jan 2010 15:18:21 -0300 |
parents | c94049033c20 |
children | c61782a76dff |
line wrap: on
line diff
--- a/dmd/expression.c Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/expression.c Wed Jan 06 15:18:21 2010 -0300 @@ -1187,6 +1187,10 @@ { } +void Expression::checkEscapeRef() +{ +} + void Expression::checkScalar() { if (!type->isscalar()) @@ -1203,7 +1207,7 @@ { if (!type->isintegral()) { error("'%s' is not of integral type, it is a %s", toChars(), type->toChars()); - return new IntegerExp(0); + return new ErrorExp(); } return this; } @@ -1212,7 +1216,7 @@ { if (!type->isintegral() && !type->isfloating()) { error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars()); - return new IntegerExp(0); + return new ErrorExp(); } return this; } @@ -3998,8 +4002,15 @@ VarDeclaration *v = var->isVarDeclaration(); if (v) { - if (!v->isDataseg()) - error("escaping reference to local variable %s", v->toChars()); + if (!v->isDataseg() && !(v->storage_class & (STCref | STCout))) + { /* BUG: This should be allowed: + * void foo() + * { int a; + * int* bar() { return &a; } + * } + */ + error("escaping reference to local %s", v->toChars()); + } } } @@ -4049,6 +4060,7 @@ } #endif } + /* Fix for 1161 doesn't work because it causes protection * problems when instantiating imported templates passing private * variables as alias template parameters. @@ -4084,6 +4096,7 @@ return e; } #endif + return this; } @@ -4113,6 +4126,16 @@ } } +void VarExp::checkEscapeRef() +{ + VarDeclaration *v = var->isVarDeclaration(); + if (v) + { + if (!v->isDataseg() && !(v->storage_class & (STCref | STCout))) + error("escaping reference to local variable %s", v->toChars()); + } +} + #if DMDV2 int VarExp::isLvalue() { @@ -4744,6 +4767,12 @@ goto Lno; tded = targ; break; + + case TOKshared: + if (!targ->isShared()) + goto Lno; + tded = targ; + break; #endif case TOKsuper: @@ -4834,7 +4863,9 @@ m = targ->deduceType(NULL, tspec, ¶meters, &dedtypes); if (m == MATCHnomatch || (m != MATCHexact && tok == TOKequal)) + { goto Lno; + } else { assert(dedtypes.dim == 1); @@ -4854,6 +4885,8 @@ else if (tspec) { /* Evaluate to TRUE if targ matches tspec + * is(targ == tspec) + * is(targ : tspec) */ tspec = tspec->semantic(loc, sc); //printf("targ = %s\n", targ->toChars()); @@ -5665,11 +5698,13 @@ */ unsigned errors = global.errors; global.gag++; + Type *t1 = e1->type; e = e1->type->dotExp(sc, e1, ident); global.gag--; if (errors != global.errors) // if failed to find the property { global.errors = errors; + e1->type = t1; // kludge to restore type e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident); e = new CallExp(loc, e, e1); } @@ -5863,7 +5898,7 @@ !var->type->isAssignable() || var->storage_class & STCmanifest ) - error("cannot modify const/invariant %s", toChars()); + error("cannot modify const/immutable expression %s", toChars()); } #endif return this; @@ -6940,6 +6975,11 @@ return this; } +void AddrExp::checkEscape() +{ + e1->checkEscapeRef(); +} + /************************************************************/ PtrExp::PtrExp(Loc loc, Expression *e) @@ -6995,6 +7035,11 @@ } #endif +void PtrExp::checkEscapeRef() +{ + e1->checkEscape(); +} + Expression *PtrExp::toLvalue(Scope *sc, Expression *e) { #if 0 @@ -7572,7 +7617,9 @@ } if (t->ty == Tarray) + { type = e1->type; + } else type = t->nextOf()->arrayOf(); return e; @@ -7584,7 +7631,7 @@ else s = t->toChars(); error("%s cannot be sliced with []", s); - e = new IntegerExp(0); + e = new ErrorExp(); return e; } @@ -7593,6 +7640,11 @@ e1->checkEscape(); } +void SliceExp::checkEscapeRef() +{ + e1->checkEscapeRef(); +} + #if DMDV2 int SliceExp::isLvalue() { @@ -7638,8 +7690,7 @@ } Expression *ArrayLengthExp::semantic(Scope *sc) -{ Expression *e; - +{ #if LOGSEMANTIC printf("ArrayLengthExp::semantic('%s')\n", toChars()); #endif @@ -7792,6 +7843,11 @@ e2->checkEscape(); } +void CommaExp::checkEscapeRef() +{ + e2->checkEscapeRef(); +} + #if DMDV2 int CommaExp::isLvalue() { @@ -9971,6 +10027,12 @@ e2->checkEscape(); } +void CondExp::checkEscapeRef() +{ + e1->checkEscapeRef(); + e2->checkEscapeRef(); +} + Expression *CondExp::checkToBoolean() {