# HG changeset patch # User Leandro Lucarella # Date 1262801901 10800 # Node ID a87f1d6ff48ef7d77c86b4a1dab9d1026e162770 # Parent 6820110de31134375928f9b250cb3584006cba39 Merge DMD r303: harmonize --- dmd/expression.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++----- dmd/expression.h | 8 +++++ dmd/template.c | 27 ++++++++++++------- 3 files changed, 95 insertions(+), 18 deletions(-) diff -r 6820110de311 -r a87f1d6ff48e dmd/expression.c --- 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() { diff -r 6820110de311 -r a87f1d6ff48e dmd/expression.h --- a/dmd/expression.h Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/expression.h Wed Jan 06 15:18:21 2010 -0300 @@ -123,6 +123,7 @@ virtual MATCH implicitConvTo(Type *t); virtual Expression *castTo(Scope *sc, Type *t); virtual void checkEscape(); + virtual void checkEscapeRef(); void checkScalar(); void checkNoBool(); Expression *checkIntegral(); @@ -678,6 +679,8 @@ char *toChars(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); void checkEscape(); + void checkEscapeRef(); + int isLvalue(); Expression *toLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); #if IN_DMD @@ -1051,6 +1054,7 @@ AddrExp(Loc loc, Expression *e); Expression *semantic(Scope *sc); + void checkEscape(); #if IN_DMD elem *toElem(IRState *irs); #endif @@ -1069,6 +1073,7 @@ PtrExp(Loc loc, Expression *e); PtrExp(Loc loc, Expression *e, Type *t); Expression *semantic(Scope *sc); + void checkEscapeRef(); Expression *toLvalue(Scope *sc, Expression *e); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); #if IN_DMD @@ -1221,6 +1226,7 @@ Expression *syntaxCopy(); Expression *semantic(Scope *sc); void checkEscape(); + void checkEscapeRef(); Expression *toLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); @@ -1294,6 +1300,7 @@ CommaExp(Loc loc, Expression *e1, Expression *e2); Expression *semantic(Scope *sc); void checkEscape(); + void checkEscapeRef(); Expression *toLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); int isBool(int result); @@ -1828,6 +1835,7 @@ Expression *optimize(int result); Expression *interpret(InterState *istate); void checkEscape(); + void checkEscapeRef(); Expression *toLvalue(Scope *sc, Expression *e); Expression *modifiableLvalue(Scope *sc, Expression *e); Expression *checkToBoolean(); diff -r 6820110de311 -r a87f1d6ff48e dmd/template.c --- a/dmd/template.c Wed Jan 06 15:18:21 2010 -0300 +++ b/dmd/template.c Wed Jan 06 15:18:21 2010 -0300 @@ -762,7 +762,8 @@ int tuple_dim = 0; MATCH match = MATCHexact; FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration(); - TypeFunction *fdtype; // type of fd + Parameters *fparameters; // function parameter list + int fvarargs; // function varargs Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T #if 0 @@ -771,6 +772,8 @@ { Expression *e = (Expression *)fargs->data[i]; printf("\tfarg[%d] is %s, type is %s\n", i, e->toChars(), e->type->toChars()); } + printf("fd = %s\n", fd->toChars()); + printf("fd->type = %p\n", fd->type); #endif assert((size_t)scope > 0x10000); @@ -849,10 +852,8 @@ } #endif - assert(fd->type->ty == Tfunction); - fdtype = (TypeFunction *)fd->type; - - nfparams = Parameter::dim(fdtype->parameters); // number of function parameters + fparameters = fd->getParameters(&fvarargs); + nfparams = Parameter::dim(fparameters); // number of function parameters nfargs = fargs ? fargs->dim : 0; // number of function arguments /* Check for match of function arguments with variadic template @@ -882,14 +883,14 @@ */ for (fptupindex = 0; fptupindex < nfparams; fptupindex++) { - Parameter *fparam = (Parameter *)fdtype->parameters->data[fptupindex]; + Parameter *fparam = (Parameter *)fparameters->data[fptupindex]; if (fparam->type->ty != Tident) continue; TypeIdentifier *tid = (TypeIdentifier *)fparam->type; if (!tp->ident->equals(tid->ident) || tid->idents.dim) continue; - if (fdtype->varargs) // variadic function doesn't + if (fvarargs) // variadic function doesn't goto Lnomatch; // go with variadic template /* The types of the function arguments @@ -916,7 +917,7 @@ ; else if (nfargs > nfparams) { - if (fdtype->varargs == 0) + if (fvarargs == 0) goto Lnomatch; // too many args, no match match = MATCHconvert; // match ... with a conversion } @@ -956,7 +957,7 @@ continue; } - Parameter *fparam = Parameter::getNth(fdtype->parameters, i); + Parameter *fparam = Parameter::getNth(fparameters, i); if (i >= nfargs) // if not enough arguments { @@ -1020,7 +1021,7 @@ /* The following code for variadic arguments closely * matches TypeFunction::callMatch() */ - if (!(fdtype->varargs == 2 && i + 1 == nfparams)) + if (!(fvarargs == 2 && i + 1 == nfparams)) goto Lnomatch; /* Check for match with function parameter T... @@ -1132,6 +1133,7 @@ if (constraint) { /* Check to see if constraint is satisfied. */ + makeParamNamesVisibleInConstraint(paramscope); Expression *e = constraint->syntaxCopy(); paramscope->flags |= SCOPEstaticif; e = e->semantic(paramscope); @@ -3262,7 +3264,10 @@ // Nesting must match if (isnested != ti->isnested) + { + //printf("test2 isnested %s ti->isnested %s\n", isnested ? isnested->toChars() : "", ti->isnested ? ti->isnested->toChars() : ""); continue; + } #if 0 if (isnested && sc->parent != ti->parent) continue; @@ -3271,7 +3276,9 @@ { Object *o1 = (Object *)tdtypes.data[j]; Object *o2 = (Object *)ti->tdtypes.data[j]; if (!match(o1, o2, tempdecl, sc)) + { goto L1; + } } // It's a match