diff dmd/TypeFunction.d @ 96:acd69f84627e

further work
author Trass3r
date Tue, 31 Aug 2010 02:12:15 +0200
parents ae5b11064a9a
children 3482c73a991b
line wrap: on
line diff
--- a/dmd/TypeFunction.d	Mon Aug 30 23:08:44 2010 +0200
+++ b/dmd/TypeFunction.d	Tue Aug 31 02:12:15 2010 +0200
@@ -142,10 +142,13 @@
 		if (tf.next)
 		{
 			tf.next = tf.next.semantic(loc,sc);
+version(SARRAYVALUE) {} else
+{
 			if (tf.next.toBasetype().ty == TY.Tsarray)
 			{   error(loc, "functions cannot return static array %s", tf.next.toChars());
 				tf.next = Type.terror;
 			}
+}
 			if (tf.next.toBasetype().ty == TY.Tfunction)
 			{   error(loc, "functions cannot return a function");
 				tf.next = Type.terror;
@@ -187,10 +190,10 @@
 
 				if (arg.storageClass & (STC.STCout | STC.STCref | STC.STClazy))
 				{
-					if (t.ty == TY.Tsarray)
-						error(loc, "cannot have out or ref parameter of type %s", t.toChars());
-					if (arg.storageClass & STC.STCout && arg.type.mod)
-						error(loc, "cannot have const/invariant out parameter of type %s", t.toChars());
+					//if (t.ty == TY.Tsarray)
+						//error(loc, "cannot have out or ref parameter of type %s", t.toChars());
+					if (arg.storageClass & STC.STCout && arg.type.mod & (STCconst | STCimmutable))
+						error(loc, "cannot have const or immutabl out parameter of type %s", t.toChars());
 				}
 				if (!(arg.storageClass & STC.STClazy) && t.ty == TY.Tvoid)
 					error(loc, "cannot have parameter of type %s", arg.type.toChars());
@@ -511,10 +514,30 @@
 
 			arg = cast(Expression)args.data[u];
 			assert(arg);
+			// writef("arg: %s, type: %s\n", arg.toChars(), arg.type.toChars());
+
 
 			// Non-lvalues do not match ref or out parameters
-			if (p.storageClass & (STC.STCref | STC.STCout) && !arg.isLvalue())
-				goto Nomatch;
+			if (p.storageClass & (STC.STCref | STC.STCout))
+			{
+				if (!arg.isLvalue())
+					goto Nomatch;
+			}
+			
+			if (p.storageClass & STCref)
+			{
+				/* Don't allow static arrays to be passed to mutable refereces
+				 * to static arrays if the argument cannot be modified.
+				 */
+				Type targb = arg.type.toBasetype();
+				Type tparb = p.type.toBasetype();
+				//writef("%s\n", targb.toChars());
+				//writef("%s\n", tparb.toChars());
+				if (targb.nextOf() && tparb.ty == Tsarray &&
+				    targb.nextOf().mod != tparb.nextOf().mod &&
+				    !tparb.nextOf().isConst())
+					goto Nomatch;
+			}
 
 			if (p.storageClass & STC.STClazy && p.type.ty == TY.Tvoid && arg.type.ty != TY.Tvoid)
 				m = MATCH.MATCHconvert;
@@ -605,7 +628,7 @@
 		return MATCH.MATCHnomatch;
 	}
 	
-    override type* toCtype()
+	override type* toCtype()
 	{
 		if (ctype) {
 			return ctype;
@@ -650,7 +673,7 @@
 	 * Determine return style of function - whether in registers or
 	 * through a hidden pointer to the caller's stack.
 	 */
-    RET retStyle()
+	RET retStyle()
 	{
 		//printf("TypeFunction.retStyle() %s\n", toChars());
 version (DMDV2)
@@ -682,13 +705,13 @@
 						case 2:
 						case 4:
 						case 8:
-						return RETregs;	// return small structs in regs
-									// (not 3 byte structs!)
+						return RET.RETregs;	// return small structs in regs
+											// (not 3 byte structs!)
 						default:
 						break;
 					}
 				}
-				return RETstack;
+				return RET.RETstack;
 			}
 		}
 }