[mcs] Tie-breaking rules are applied also for non-equivalent parameter types. Fixess...
authorMarek Safar <marek.safar@gmail.com>
Mon, 11 Apr 2016 14:11:34 +0000 (16:11 +0200)
committerMarek Safar <marek.safar@gmail.com>
Mon, 11 Apr 2016 16:00:06 +0000 (18:00 +0200)
mcs/mcs/ecore.cs
mcs/tests/gtest-optional-36.cs [new file with mode: 0644]
mcs/tests/test-933.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml

index 56c1b2edb88c8c0fa439c9999971ebab5952daba..145f222bdcd39d2f100c230845024b4881b99258 100644 (file)
@@ -4704,8 +4704,14 @@ namespace Mono.CSharp {
 
                                // for each argument, the conversion to 'ct' should be no worse than 
                                // the conversion to 'bt'.
-                               if (result == 2)
-                                       return false;
+                               if (result == 2) {
+                                       better_at_least_one = false;
+
+                                       ++j;
+                                       while (j < args_count && !args [j++].IsDefaultArgument) ;
+
+                                       break;
+                               }
 
                                // for at least one argument, the conversion to 'ct' should be better than 
                                // the conversion to 'bt'.
@@ -4717,15 +4723,26 @@ namespace Mono.CSharp {
                                return true;
 
                        //
-                       // Tie-breaking rules are applied only for equivalent parameter types
+                       // LAMESPEC: Tie-breaking rules for not equivalent parameter types
                        //
                        if (!are_equivalent) {
                                //
-                               // LAMESPEC: A candidate with less default parameters is still better when there
+                               // A candidate with no default parameters is still better when there
                                // is no better expression conversion
                                //
-                               if (candidate_pd.Count < best_pd.Count && !candidate_params && best_pd.FixedParameters [j].HasDefaultValue) {
-                                       return true;
+                               if (candidate_pd.Count < best_pd.Count) {
+                                       if (!candidate_params && !candidate_pd.FixedParameters [j - j].HasDefaultValue) {
+                                               return true;
+                                       }
+                               } else if (candidate_pd.Count == best_pd.Count) {
+                                       if (candidate_params)
+                                               return false;
+
+                                       if (!candidate_pd.FixedParameters [j - 1].HasDefaultValue && best_pd.FixedParameters [j - 1].HasDefaultValue)
+                                               return true;
+
+                                       if (candidate_pd.FixedParameters [j - 1].HasDefaultValue && best_pd.HasParams)
+                                               return true;
                                }
 
                                return false;
diff --git a/mcs/tests/gtest-optional-36.cs b/mcs/tests/gtest-optional-36.cs
new file mode 100644 (file)
index 0000000..bf9f7d1
--- /dev/null
@@ -0,0 +1,66 @@
+using System;
+
+public class Program
+{
+       static int Arg (uint a, long b)
+       {
+               return 2;
+       }
+
+       static int Arg (int a, ulong b, int c = 9)
+       {
+               return 3;
+       }
+
+       static int Arg_2 (uint a, long b, params int[] arg)
+       {
+               return 2;
+       }
+
+       static int Arg_2 (int a, ulong b, int c = 0)
+       {
+               return 3;
+       }
+
+       static int Arg_3 (int a, long b, params int[] arg)
+       {
+               return 2;
+       }
+
+       static int Arg_3 (uint a, ulong b, int c = 0, int d = 1, params int[] oo)
+       {
+               return 3;
+       }       
+
+       public static int Main ()
+       {
+               if (Arg (0, 0) != 2)
+                       return 1;
+
+               if (Arg (0, 0, 0) != 3)
+                       return 2;
+
+               if (Arg_2 (0, 0) != 3)
+                       return 3;
+
+               if (Arg_2 (0, 0, 0, 0) != 2)
+                       return 4;
+
+               if (Arg_3 (0, 0) != 2)
+                       return 5;
+
+               if (Arg_3 (0, 0, 0) != 2)
+                       return 6;
+
+               if (Arg_3 (0, 0, 0, 0) != 2)
+                       return 7;
+
+               if (Arg_3 (0, 0, 0, 0, 0) != 2)
+                       return 8;
+
+               if (Arg_3 (0, 0, 0, 0, 0) != 2)
+                       return 9;
+
+               return 0;
+       }
+}
diff --git a/mcs/tests/test-933.cs b/mcs/tests/test-933.cs
new file mode 100644 (file)
index 0000000..2f076eb
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+
+class X
+{
+       static int Foo (params X[] p)
+       {
+               return 1;
+       }
+
+       static int Foo (object p)
+       {
+               return 0;
+       }
+
+       static int Main ()
+       {
+               if (Foo ((X[]) null) != 1)
+                       return 1;
+
+               return 0;
+       }
+}
\ No newline at end of file
index b7054e4b28943dcc026469b86d3f13d8af453e54..21da636a0c5b8ff2b973173842b818a1cdcc6a9f 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-optional-36.cs">
+    <type name="Program">
+      <method name="Int32 Arg(UInt32, Int64)" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Int32 Arg(Int32, UInt64, Int32)" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Int32 Arg_2(UInt32, Int64, Int32[])" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Int32 Arg_2(Int32, UInt64, Int32)" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Int32 Arg_3(Int32, Int64, Int32[])" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Int32 Arg_3(UInt32, UInt64, Int32, Int32, Int32[])" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Int32 Main()" attrs="150">
+        <size>238</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-partial-01.cs">
     <type name="B`1[U]">
       <method name="Void .ctor()" attrs="6278">
       </method>
     </type>
   </test>
+  <test name="test-933.cs">
+    <type name="X">
+      <method name="Int32 Foo(X[])" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Int32 Foo(System.Object)" attrs="145">
+        <size>10</size>
+      </method>
+      <method name="Int32 Main()" attrs="145">
+        <size>29</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-94.cs">
     <type name="Base">
       <method name="Int32 IVehicle.Start()" attrs="481">