[mono/mono] a7348279: [mcs] Assignment to value type readonly generated variables needs to check all member access expressions. Fixes #15832

"Marek Safar ([email protected])" <[email protected]> Thu, 14 Nov 2013 17:27:59 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <0000014257a7bc41-c587d78c-fb76-42d5-829a-038bae58510a-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/58d4cd39c7cb...a7348279926d

   Commit: a7348279926db8f4b17855166f1c1d9371cad5ba
   Author: Marek Safar <[email protected]> (marek-safar)
     Date: 2013-11-14 17:16:57 GMT
      URL: https://github.com/mono/mono/commit/a7348279926db8f4b17855166f1c1d9371cad5ba

[mcs] Assignment to value type readonly generated variables needs to check all member access expressions. Fixes #15832

Changed paths:
  M mcs/mcs/ecore.cs
  M mcs/mcs/expression.cs
Added paths:
  A mcs/errors/cs1654-3.cs
  A mcs/errors/cs1654-4.cs

Added: mcs/errors/cs1654-3.cs
===================================================================
@@ -0,0 +1,25 @@
+// CS1654: Cannot assign to members of `f' because it is a `using variable'
+// Line: 22
+
+using System;
+
+struct Foo : IDisposable
+{
+	public int Property {
+		set { }
+	}
+
+	public void Dispose ()
+	{
+	}
+}
+
+class Bar
+{
+	static void Main ()
+	{
+		using (var f = new Foo ()) {
+			f.Property = 0;
+		}
+	}
+}
\ No newline at end of file

Added: mcs/errors/cs1654-4.cs
===================================================================
@@ -0,0 +1,25 @@
+// CS1654: Cannot assign to members of `f' because it is a `using variable'
+// Line: 22
+
+using System;
+
+struct Foo : IDisposable
+{
+	public int this[int arg] {
+		set { }
+	}
+
+	public void Dispose ()
+	{
+	}
+}
+
+class Bar
+{
+	static void Main ()
+	{
+		using (var f = new Foo ()) {
+			f[0] = 1;
+		}
+	}
+}
\ No newline at end of file

Modified: mcs/mcs/ecore.cs
===================================================================
@@ -3183,7 +3183,11 @@ public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs)
 						rc.Report.Error (1648, loc, "Members of readonly field `{0}' cannot be modified (except in a constructor or a variable initializer)",
 							fexpr.GetSignatureForError ());
 					}
-				} else if (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation) {
+
+					return true;
+				}
+
+				if (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation) {
 					if (rc.CurrentInitializerVariable != null) {
 						rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
 							InstanceExpression.Type.GetSignatureForError (), InstanceExpression.GetSignatureForError ());
@@ -3192,6 +3196,18 @@ public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs)
 							"Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
 							InstanceExpression.GetSignatureForError ());
 					}
+
+					return true;
+				}
+
+				var lvr = InstanceExpression as LocalVariableReference;
+				if (lvr != null) {
+
+					if (!lvr.local_info.IsReadonly)
+						return true;
+
+					rc.Report.Error (1654, loc, "Cannot assign to members of `{0}' because it is a `{1}'",
+						InstanceExpression.GetSignatureForError (), lvr.local_info.GetReadOnlyContext ());
 				}
 			}
 

Modified: mcs/mcs/expression.cs
===================================================================
@@ -5705,20 +5705,22 @@ public override Expression DoResolveLValue (ResolveContext ec, Expression rhs)
 				local_info.SetIsUsed ();
 
 			if (local_info.IsReadonly && !ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.UsingInitializerScope)) {
-				int code;
-				string msg;
-				if (rhs == EmptyExpression.OutAccess) {
-					code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'";
-				} else if (rhs == EmptyExpression.LValueMemberAccess) {
-					code = 1654; msg = "Cannot assign to members of `{0}' because it is a `{1}'";
-				} else if (rhs == EmptyExpression.LValueMemberOutAccess) {
-					code = 1655; msg = "Cannot pass members of `{0}' as ref or out arguments because it is a `{1}'";
-				} else if (rhs == EmptyExpression.UnaryAddress) {
-					code = 459; msg = "Cannot take the address of {1} `{0}'";
+				if (rhs == EmptyExpression.LValueMemberAccess) {
+					// CS1654 already reported
 				} else {
-					code = 1656; msg = "Cannot assign to `{0}' because it is a `{1}'";
+					int code;
+					string msg;
+					if (rhs == EmptyExpression.OutAccess) {
+						code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'";
+					} else if (rhs == EmptyExpression.LValueMemberOutAccess) {
+						code = 1655; msg = "Cannot pass members of `{0}' as ref or out arguments because it is a `{1}'";
+					} else if (rhs == EmptyExpression.UnaryAddress) {
+						code = 459; msg = "Cannot take the address of {1} `{0}'";
+					} else {
+						code = 1656; msg = "Cannot assign to `{0}' because it is a `{1}'";
+					}
+					ec.Report.Error (code, loc, msg, Name, local_info.GetReadOnlyContext ());
 				}
-				ec.Report.Error (code, loc, msg, Name, local_info.GetReadOnlyContext ());
 			} else if (VariableInfo != null) {
 				VariableInfo.SetAssigned (ec);
 			}


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches