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, &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()
 {