Be less pedantic when issuing CS0219 warning (some people write crappy code)
authorMarek Safar <marek.safar@gmail.com>
Thu, 5 Apr 2012 15:46:39 +0000 (16:46 +0100)
committerMarek Safar <marek.safar@gmail.com>
Thu, 5 Apr 2012 15:46:39 +0000 (16:46 +0100)
mcs/mcs/expression.cs
mcs/tests/test-844.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml

index db9babed55c3a22ca2cecd8a07879acf5869e195..22e76bfb153060761e53f06be8c3475b2f8bd070 100644 (file)
@@ -4984,22 +4984,25 @@ namespace Mono.CSharp
                        return this;
                }
 
-               public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+               public override Expression DoResolveLValue (ResolveContext ec, Expression rhs)
                {
-                       // is out param
-                       if (right_side == EmptyExpression.OutAccess)
+                       //
+                       // Don't be too pedantic when variable is used as out param or for some broken code
+                       // which uses property/indexer access to run some initialization
+                       //
+                       if (rhs == EmptyExpression.OutAccess || rhs.eclass == ExprClass.PropertyAccess || rhs.eclass == ExprClass.IndexerAccess)
                                local_info.SetIsUsed ();
 
                        if (local_info.IsReadonly && !ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.UsingInitializerScope)) {
                                int code;
                                string msg;
-                               if (right_side == EmptyExpression.OutAccess) {
+                               if (rhs == EmptyExpression.OutAccess) {
                                        code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'";
-                               } else if (right_side == EmptyExpression.LValueMemberAccess) {
+                               } else if (rhs == EmptyExpression.LValueMemberAccess) {
                                        code = 1654; msg = "Cannot assign to members of `{0}' because it is a `{1}'";
-                               } else if (right_side == EmptyExpression.LValueMemberOutAccess) {
+                               } 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 (right_side == EmptyExpression.UnaryAddress) {
+                               } 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}'";
@@ -5012,7 +5015,7 @@ namespace Mono.CSharp
                        if (eclass == ExprClass.Unresolved)
                                DoResolveBase (ec);
 
-                       return base.DoResolveLValue (ec, right_side);
+                       return base.DoResolveLValue (ec, rhs);
                }
 
                public override int GetHashCode ()
diff --git a/mcs/tests/test-844.cs b/mcs/tests/test-844.cs
new file mode 100644 (file)
index 0000000..1f7e5fa
--- /dev/null
@@ -0,0 +1,27 @@
+// Compiler options: -warn:4 -warnaserror
+
+// Checks no CS0219 warning is issued
+
+class C
+{
+       int Prop { get { return 4; } }
+
+       int this[char arg] { get { return 2; } }
+
+       static void Foo (ref int arg)
+       {
+       }
+
+       public void Method (int i)
+       {
+               long p1 = Prop;
+               long p2 = new C ()['h'];
+
+               int arg = 1;
+               Foo (ref arg);
+       }
+
+       public static void Main ()
+       {
+       }
+}
index 2f6fe76ff6005ed97b3d725ce21d02ef1c4a3e88..2eace8b309e59b969aff6a7f04c8fd35bfa13f1d 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-844.cs">
+    <type name="C">
+      <method name="Int32 get_Prop()" attrs="2177">
+        <size>10</size>
+      </method>
+      <method name="Int32 get_Item(Char)" attrs="2177">
+        <size>10</size>
+      </method>
+      <method name="Void Foo(Int32 ByRef)" attrs="145">
+        <size>2</size>
+      </method>
+      <method name="Void Method(Int32)" attrs="134">
+        <size>33</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-85.cs">
     <type name="X">
       <method name="Int32 Main()" attrs="145">