Fix compound event assigments with dynamic side effect
authorMarek Safar <marek.safar@gmail.com>
Thu, 7 Oct 2010 18:14:48 +0000 (19:14 +0100)
committerMarek Safar <marek.safar@gmail.com>
Thu, 7 Oct 2010 18:15:52 +0000 (19:15 +0100)
mcs/errors/gcs0019-4.cs [deleted file]
mcs/errors/gcs0029-11.cs [new file with mode: 0644]
mcs/mcs/ecore.cs
mcs/mcs/import.cs
mcs/tests/dtest-036.cs [new file with mode: 0644]
mcs/tests/ver-il-dmcs.xml
mcs/tests/ver-il-gmcs.xml

diff --git a/mcs/errors/gcs0019-4.cs b/mcs/errors/gcs0019-4.cs
deleted file mode 100644 (file)
index bec37f9..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// CS0019: Operator `+=' cannot be applied to operands of type `EventHandler' and `T'
-// Line: 10
-
-using System;
-
-public delegate void EventHandler (int i, int j);
-
-public class Button {
-
-       public event EventHandler Click;
-
-       public void Connect<T> () where T : class
-       {
-               Click += default (T);
-       }
-}
diff --git a/mcs/errors/gcs0029-11.cs b/mcs/errors/gcs0029-11.cs
new file mode 100644 (file)
index 0000000..b6d3c34
--- /dev/null
@@ -0,0 +1,16 @@
+// CS0029: Cannot implicitly convert type `T' to `EventHandler'
+// Line: 14
+
+using System;
+
+public delegate void EventHandler (int i, int j);
+
+public class Button {
+
+       public event EventHandler Click;
+
+       public void Connect<T> () where T : class
+       {
+               Click += default (T);
+       }
+}
index 557dbf753c7e77444ee265431a5051635e56284b..abc7fc252b9f0cfb31606b244665c21ce3d2445d 100644 (file)
@@ -4763,7 +4763,7 @@ namespace Mono.CSharp {
 
                public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
                {
-                       prepared = prepare_for_load;
+                       prepared = prepare_for_load && !(source is DynamicExpressionStatement);
                        if (IsInstance)
                                EmitInstance (ec, prepared);
 
@@ -5265,13 +5265,12 @@ namespace Mono.CSharp {
                public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
                {
                        //
-                       // If the event is local to this class, we transform ourselves into a FieldExpr
+                       // If the event is local to this class and we are not lhs of +=/-= we transform ourselves into a FieldExpr
                        //
+                       if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope)) {
+                               if (spec.BackingField != null &&
+                                       (spec.DeclaringType == ec.CurrentType || TypeManager.IsNestedChildOf (ec.CurrentType, spec.DeclaringType))) {
 
-                       if (spec.DeclaringType == ec.CurrentType ||
-                           TypeManager.IsNestedChildOf(ec.CurrentType, spec.DeclaringType)) {
-                                       
-                               if (spec.BackingField != null) {
                                        spec.MemberDefinition.SetIsUsed ();
 
                                        if (!ec.IsObsolete) {
@@ -5280,19 +5279,18 @@ namespace Mono.CSharp {
                                                        AttributeTester.Report_ObsoleteMessage (oa, spec.GetSignatureForError (), loc, ec.Report);
                                        }
 
-                                       if ((spec.Modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0 && !ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))
+                                       if ((spec.Modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
                                                Error_AssignmentEventOnly (ec);
-                                       
+
                                        FieldExpr ml = new FieldExpr (spec.BackingField, loc);
 
                                        InstanceExpression = null;
-                               
+
                                        return ml.ResolveMemberAccess (ec, left, original);
                                }
-                       }
 
-                       if (!ec.HasSet (ResolveContext.Options.CompoundAssignmentScope))                        
                                Error_AssignmentEventOnly (ec);
+                       }
 
                        return base.ResolveMemberAccess (ec, left, original);
                }
index 5a06e8ff3c9a8c37cd3dc274378c13021e86d852..ecb69db6fdb1ac33fbf844332a25b83d27125c2f 100644 (file)
@@ -655,7 +655,7 @@ namespace Mono.CSharp
                        //
                        // Two stage setup as the base type can be inflated declaring type
                        //
-                       if (declaringType == null)
+                       if (declaringType == null || !IgnorePrivateMembers)
                                ImportTypeBase (spec, type);
 
                        return spec;
diff --git a/mcs/tests/dtest-036.cs b/mcs/tests/dtest-036.cs
new file mode 100644 (file)
index 0000000..9b5bbc0
--- /dev/null
@@ -0,0 +1,29 @@
+using System;
+
+public class C
+{
+       event Func<int, int> E;
+       Func<int, int> D;
+
+       public static int Main ()
+       {
+               var c = new C ();
+               Func<int, int> v = Foo;
+               dynamic[] arr = new dynamic [] { v };
+               
+               c.E += arr [0];
+               if (c.E.GetInvocationList ().Length != 1)
+                       return 1;
+
+               c.D += arr [0];
+               if (c.D.GetInvocationList ().Length != 1)
+                       return 2;
+               
+               return 0;
+       }
+       
+       static int Foo (int ii)
+       {
+               return 9;
+       }
+}
index 5264c61d77e574c36e7f519135055097961c2f3d..3f0f05520280b9f4c0c3c6500db2ce8f026ce523 100644 (file)
       </method>
     </type>
   </test>
+  <test name="dtest-036.cs">
+    <type name="C">
+      <method name="Void add_E(System.Func`2[System.Int32,System.Int32])">
+        <size>24</size>
+      </method>
+      <method name="Void remove_E(System.Func`2[System.Int32,System.Int32])">
+        <size>24</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>314</size>
+      </method>
+      <method name="Int32 Foo(Int32)">
+        <size>3</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="dtest-collectioninit-01.cs">
     <type name="Test">
       <method name="Int32 Main()">
         <size>24</size>
       </method>
       <method name="Void Register(A`1+Changed[T])">
-        <size>36</size>
+        <size>20</size>
       </method>
     </type>
     <type name="Test">
         <size>11</size>
       </method>
       <method name="Void .ctor(Object[], Object)">
-        <size>217</size>
+        <size>201</size>
       </method>
       <method name="Void add_DoSomething(System.EventHandler)">
         <size>24</size>
         <size>7</size>
       </method>
       <method name="Void &lt;&gt;m__0()">
-        <size>54</size>
+        <size>39</size>
       </method>
     </type>
     <type name="B+&lt;C&gt;c__AnonStorey1+&lt;C&gt;c__AnonStorey0">
       </method>
     </type>
   </test>
+  <test name="gtest-451.cs">
+    <type name="Test">
+      <method name="Int32 Main()">
+        <size>18</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-453.cs">
     <type name="Test.CompilerTest">
       <method name="Void .ctor()">
         <size>24</size>
       </method>
       <method name="Void add_Handler(Handler`1[T])">
-        <size>64</size>
+        <size>48</size>
       </method>
       <method name="Void remove_Handler(Handler`1[T])">
-        <size>24</size>
+        <size>8</size>
       </method>
       <method name="Void &lt;add_Handler&gt;m__0(System.Object)">
         <size>18</size>
         <size>24</size>
       </method>
       <method name="Int32 Main()">
-        <size>72</size>
+        <size>56</size>
       </method>
       <method name="Void &lt;Main&gt;m__0()">
         <size>1</size>
         <size>24</size>
       </method>
       <method name="Int32 Test()">
-        <size>166</size>
+        <size>134</size>
       </method>
       <method name="Void callback1(System.Object, System.EventArgs)">
         <size>7</size>
         <size>1</size>
       </method>
       <method name="Int32 Main()">
-        <size>93</size>
+        <size>61</size>
       </method>
     </type>
     <type name="Foo">
         <size>13</size>
       </method>
       <method name="Void Foo()">
-        <size>66</size>
+        <size>50</size>
       </method>
     </type>
     <type name="Y">
     </type>
     <type name="Test">
       <method name="Void &lt;Main&gt;m__0()">
-        <size>33</size>
+        <size>18</size>
       </method>
     </type>
   </test>
     </type>
     <type name="B">
       <method name="Void .ctor()">
-        <size>65</size>
+        <size>49</size>
       </method>
       <method name="Void add_Finished(System.EventHandler)">
         <size>24</size>
         <size>1</size>
       </method>
       <method name="Void Main()">
-        <size>46</size>
+        <size>31</size>
       </method>
     </type>
     <type name="X+T">
         <size>2</size>
       </method>
       <method name="Void AddSource(Source, Int32, System.Object)">
-        <size>132</size>
+        <size>100</size>
       </method>
       <method name="Void Main()">
         <size>1</size>
         <size>11</size>
       </method>
       <method name="Void Main()">
-        <size>55</size>
+        <size>39</size>
       </method>
     </type>
     <type name="X+&lt;Pipeline&gt;c__Iterator0">
index 91479a739f5633003a6ef712730ee2c09b329545..280d61b90538e9ac5d85b423a06d089a1eef90bc 100644 (file)
         <size>24</size>
       </method>
       <method name="Void Register(A`1+Changed[T])">
-        <size>36</size>
+        <size>20</size>
       </method>
     </type>
     <type name="Test">
         <size>11</size>
       </method>
       <method name="Void .ctor(Object[], Object)">
-        <size>217</size>
+        <size>201</size>
       </method>
       <method name="Void add_DoSomething(System.EventHandler)">
         <size>24</size>
       </method>
     </type>
   </test>
+  <test name="gtest-232.cs">
+    <type name="M">
+      <method name="Int32 Main()">
+        <size>68</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-233.cs">
     <type name="Program">
       <method name="Void .ctor()">
         <size>7</size>
       </method>
       <method name="Void &lt;&gt;m__0()">
-        <size>54</size>
+        <size>39</size>
       </method>
     </type>
     <type name="B+&lt;C&gt;c__AnonStorey1+&lt;C&gt;c__AnonStorey0">
       </method>
     </type>
   </test>
+  <test name="gtest-448.cs">
+    <type name="Impl`1[T]">
+      <method name="IEnumerator System.Collections.IEnumerable.GetEnumerator()">
+        <size>2</size>
+      </method>
+      <method name="Void Foo[U](IEnumerable`1)">
+        <size>1</size>
+      </method>
+      <method name="IEnumerator`1 GetEnumerator()">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="A`1[K]">
+      <method name="Void .ctor()">
+        <size>18</size>
+      </method>
+    </type>
+    <type name="Test`1[TT]">
+      <method name="Void Foo()">
+        <size>24</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="M">
+      <method name="Void Main()">
+        <size>11</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-449.cs">
     <type name="Program">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
+  <test name="gtest-451.cs">
+    <type name="Test">
+      <method name="Int32 Main()">
+        <size>18</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-453.cs">
     <type name="Test.CompilerTest">
       <method name="Void .ctor()">
         <size>24</size>
       </method>
       <method name="Void add_Handler(Handler`1[T])">
-        <size>64</size>
+        <size>48</size>
       </method>
       <method name="Void remove_Handler(Handler`1[T])">
-        <size>24</size>
+        <size>8</size>
       </method>
       <method name="Void &lt;add_Handler&gt;m__0(System.Object)">
         <size>18</size>
         <size>24</size>
       </method>
       <method name="Int32 Main()">
-        <size>72</size>
+        <size>56</size>
       </method>
       <method name="Void &lt;Main&gt;m__0()">
         <size>1</size>
         <size>24</size>
       </method>
       <method name="Int32 Test()">
-        <size>166</size>
+        <size>134</size>
       </method>
       <method name="Void callback1(System.Object, System.EventArgs)">
         <size>7</size>
         <size>1</size>
       </method>
       <method name="Int32 Main()">
-        <size>93</size>
+        <size>61</size>
       </method>
     </type>
     <type name="Foo">
         <size>13</size>
       </method>
       <method name="Void Foo()">
-        <size>66</size>
+        <size>50</size>
       </method>
     </type>
     <type name="Y">
     </type>
     <type name="Test">
       <method name="Void &lt;Main&gt;m__0()">
-        <size>33</size>
+        <size>18</size>
       </method>
     </type>
   </test>
     </type>
     <type name="B">
       <method name="Void .ctor()">
-        <size>65</size>
+        <size>49</size>
       </method>
       <method name="Void add_Finished(System.EventHandler)">
         <size>24</size>
         <size>1</size>
       </method>
       <method name="Void Main()">
-        <size>46</size>
+        <size>31</size>
       </method>
     </type>
     <type name="X+T">
         <size>2</size>
       </method>
       <method name="Void AddSource(Source, Int32, System.Object)">
-        <size>132</size>
+        <size>100</size>
       </method>
       <method name="Void Main()">
         <size>1</size>
         <size>11</size>
       </method>
       <method name="Void Main()">
-        <size>55</size>
+        <size>39</size>
       </method>
     </type>
     <type name="X+&lt;Pipeline&gt;c__Iterator0">