User operators are resolved in a batch, pick up the foremost
authorMarek Safar <marek.safar@gmail.com>
Fri, 17 Sep 2010 14:45:12 +0000 (15:45 +0100)
committerMarek Safar <marek.safar@gmail.com>
Fri, 17 Sep 2010 14:45:12 +0000 (15:45 +0100)
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/tests/test-298.cs [new file with mode: 0644]
mcs/tests/ver-il-dmcs.xml
mcs/tests/ver-il-gmcs.xml

index 9197c8ad70c1102a3fbccb36f049281fe6b47f45..3ab3ec5b107cee5ad673c2841d1128525ebed3c2 100644 (file)
@@ -679,7 +679,7 @@ namespace Mono.CSharp {
                        Arguments arguments = new Arguments (1);
                        arguments.Add (new Argument (e));
 
-                       var res = new OverloadResolver (methods, OverloadResolver.Restrictions.NoBaseMembers, loc);
+                       var res = new OverloadResolver (methods, OverloadResolver.Restrictions.BaseMembersIncluded | OverloadResolver.Restrictions.NoBaseMembers, loc);
                        var oper = res.ResolveOperator (ec, ref arguments);
 
                        if (oper == null)
@@ -3139,7 +3139,8 @@ namespace Mono.CSharp {
                        DelegateInvoke = 1,
                        ProbingOnly     = 1 << 1,
                        CovariantDelegate = 1 << 2,
-                       NoBaseMembers = 1 << 3
+                       NoBaseMembers = 1 << 3,
+                       BaseMembersIncluded = 1 << 4
                }
 
                public interface IBaseMembersProvider
@@ -3907,6 +3908,16 @@ namespace Mono.CSharp {
                                                                best_candidate_args = candidate_args;
                                                                best_candidate_params = params_expanded_form;
                                                        } else if (candidate_rate == 0) {
+                                                               //
+                                                               // The member look is done per type for most operations but sometimes
+                                                               // it's not possible like for binary operators overload because they
+                                                               // are unioned between 2 sides
+                                                               //
+                                                               if ((restrictions & Restrictions.BaseMembersIncluded) != 0) {
+                                                                       if (TypeSpec.IsBaseClass (best_candidate.DeclaringType, member.DeclaringType, true))
+                                                                               continue;
+                                                               }
+
                                                                // Is new candidate better
                                                                if (BetterFunction (rc, candidate_args, member, params_expanded_form, best_candidate, best_candidate_params)) {
                                                                        best_candidate = member;
index 0fd91dfae68b8073bc2a83273c3c16aa1b0398b9..0f867e0952a0a22b22ac4981c254fa389a15b664 100644 (file)
@@ -688,7 +688,7 @@ namespace Mono.CSharp {
                        Arguments args = new Arguments (1);
                        args.Add (new Argument (expr));
 
-                       var res = new OverloadResolver (methods, OverloadResolver.Restrictions.NoBaseMembers, loc);
+                       var res = new OverloadResolver (methods, OverloadResolver.Restrictions.BaseMembersIncluded | OverloadResolver.Restrictions.NoBaseMembers, loc);
                        var oper = res.ResolveOperator (ec, ref args);
 
                        if (oper == null)
@@ -1125,7 +1125,7 @@ namespace Mono.CSharp {
                        }
 
                        //
-                       // Step 2: Perform Operator Overload location
+                       // Step 2: Perform Operator overload resolution
                        //
                        var user_op = IsDecrement ? Operator.OpType.Decrement : Operator.OpType.Increment;
                        var methods = MemberCache.GetUserOperator (type, user_op, false);
@@ -1134,7 +1134,7 @@ namespace Mono.CSharp {
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (expr));
 
-                               var res = new OverloadResolver (methods, OverloadResolver.Restrictions.NoBaseMembers, loc);
+                               var res = new OverloadResolver (methods, OverloadResolver.Restrictions.BaseMembersIncluded | OverloadResolver.Restrictions.NoBaseMembers, loc);
                                var op = res.ResolveOperator (ec, ref args);
                                if (op == null)
                                        return null;
@@ -3329,7 +3329,8 @@ namespace Mono.CSharp {
                                left_operators = right_operators;
                        }
 
-                       var res = new OverloadResolver (left_operators, OverloadResolver.Restrictions.ProbingOnly, loc);
+                       var res = new OverloadResolver (left_operators, OverloadResolver.Restrictions.ProbingOnly | 
+                               OverloadResolver.Restrictions.NoBaseMembers | OverloadResolver.Restrictions.BaseMembersIncluded, loc);
 
                        var oper_method = res.ResolveOperator (ec, ref args);
                        if (oper_method == null)
diff --git a/mcs/tests/test-298.cs b/mcs/tests/test-298.cs
new file mode 100644 (file)
index 0000000..10ea181
--- /dev/null
@@ -0,0 +1,50 @@
+using System;
+
+class A
+{
+       public static int operator + (short x, A b)
+       {
+               return -1;
+       }
+       
+       public static int operator - (A a)
+       {
+               return -1;
+       }
+}
+
+class B : A
+{
+       public static int operator + (int x, B d)
+       {
+               return 1;
+       }
+       
+       public static int operator - (B b)
+       {
+               return 1;
+       }
+}
+
+class C : B
+{
+}
+
+public class Test
+{
+       public static int Main ()
+       {
+               var b = new B ();
+               short s = 3;
+               var res = s + b;
+
+               if (res != 1)
+                       return 1;
+               
+               var c = new C ();
+               if (-c != 1)
+                       return 2;
+
+               return 0;
+       }
+}
\ No newline at end of file
index 9baf68bc25ed31069bb4102e0f08683b50734428..bdb33286ff1d378ec18533dea18ff7c53fe19cb1 100644 (file)
         <size>7</size>
       </method>
     </type>
-    <type name="Tester+&lt;InvokeMember_3&gt;c__DynamicSite0+Container0">
-      <method name="Void Invoke(System.Runtime.CompilerServices.CallSite, System.Object, Int32 ByRef)">
-        <size>0</size>
-      </method>
-      <method name="Void .ctor(Object, IntPtr)">
-        <size>0</size>
-      </method>
-    </type>
-    <type name="Tester+&lt;InvokeMember_4&gt;c__DynamicSite0+Container0">
-      <method name="Void Invoke(System.Runtime.CompilerServices.CallSite, System.Object, Int32 ByRef)">
-        <size>0</size>
-      </method>
-      <method name="Void .ctor(Object, IntPtr)">
-        <size>0</size>
-      </method>
-    </type>
     <type name="Tester">
       <method name="Void Invoke_6(System.Object, DynamicObjectMock)">
         <size>124</size>
         <size>119</size>
       </method>
     </type>
+    <type name="Tester+&lt;InvokeMember_3&gt;c__DynamicSite30+Container0">
+      <method name="Void Invoke(System.Runtime.CompilerServices.CallSite, System.Object, Int32 ByRef)">
+        <size>0</size>
+      </method>
+      <method name="Void .ctor(Object, IntPtr)">
+        <size>0</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;InvokeMember_4&gt;c__DynamicSite31+Container0">
+      <method name="Void Invoke(System.Runtime.CompilerServices.CallSite, System.Object, Int32 ByRef)">
+        <size>0</size>
+      </method>
+      <method name="Void .ctor(Object, IntPtr)">
+        <size>0</size>
+      </method>
+    </type>
   </test>
   <test name="dtest-004.cs">
     <type name="G`1[T]">
         <size>101</size>
       </method>
     </type>
-    <type name="Tester+&lt;InvokeMember&gt;c__DynamicSite0+Container0">
+    <type name="Tester+&lt;InvokeMember&gt;c__DynamicSite2+Container0">
       <method name="Void Invoke(System.Runtime.CompilerServices.CallSite, System.Object, Int32 ByRef, System.String ByRef)">
         <size>0</size>
       </method>
     </type>
     <type name="Test">
       <method name="Int32 Main()">
-        <size>194</size>
+        <size>360</size>
       </method>
       <method name="Void .ctor()">
         <size>7</size>
       </method>
     </type>
+    <type name="C">
+      <method name="Int32 M2(System.Object)">
+        <size>2</size>
+      </method>
+      <method name="Int32 M2(Byte)">
+        <size>2</size>
+      </method>
+    </type>
   </test>
   <test name="dtest-028.cs">
     <type name="C">
       </method>
     </type>
   </test>
+  <test name="gtest-539.cs">
+    <type name="S">
+      <method name="Int32 get_ID()">
+        <size>7</size>
+      </method>
+      <method name="Void set_ID(Int32)">
+        <size>8</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="C op_Explicit(S)">
+        <size>11</size>
+      </method>
+      <method name="C op_Explicit(Nullable`1)">
+        <size>39</size>
+      </method>
+      <method name="Void .ctor(Int32)">
+        <size>14</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Int32 Main()">
+        <size>79</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-anon-1.cs">
     <type name="X">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
+  <test name="gtest-lambda-26.cs">
+    <type name="C">
+      <method name="Void Main()">
+        <size>35</size>
+      </method>
+      <method name="Void Execute(System.Action)">
+        <size>1</size>
+      </method>
+      <method name="Void &lt;Main&gt;m__0()">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-linq-01.cs">
     <type name="from.C">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
+  <test name="test-298.cs">
+    <type name="A">
+      <method name="Int32 op_Addition(Int16, A)">
+        <size>2</size>
+      </method>
+      <method name="Int32 op_UnaryNegation(A)">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="B">
+      <method name="Int32 op_Addition(Int32, B)">
+        <size>2</size>
+      </method>
+      <method name="Int32 op_UnaryNegation(B)">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Int32 Main()">
+        <size>47</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-299.cs">
     <type name="SampleClass">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
+  <test name="test-801.cs">
+    <type name="C">
+      <method name="Int32 Main()">
+        <size>154</size>
+      </method>
+      <method name="E op_Implicit(C)">
+        <size>3</size>
+      </method>
+      <method name="Int32 op_Implicit(C)">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-81.cs">
     <type name="N1.A">
       <method name="Void .ctor()">
index d24f2f478e8caa79b465f7663805abcaeb7320b4..67f7d123221134d8c2a9b75831ef553fe69c01a5 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-298.cs">
+    <type name="A">
+      <method name="Int32 op_Addition(Int16, A)">
+        <size>2</size>
+      </method>
+      <method name="Int32 op_UnaryNegation(A)">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="B">
+      <method name="Int32 op_Addition(Int32, B)">
+        <size>2</size>
+      </method>
+      <method name="Int32 op_UnaryNegation(B)">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Int32 Main()">
+        <size>47</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-299.cs">
     <type name="SampleClass">
       <method name="Void .ctor()">