changeset 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 6820110de311
children c61782a76dff
files dmd/expression.c dmd/expression.h dmd/template.c
diffstat 3 files changed, 95 insertions(+), 18 deletions(-) [+]
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, &parameters, &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()
 {
--- 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();
--- 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