[mcs] More tweaks to undefined tie-breaking rules. Fixes #40945
authorMarek Safar <marek.safar@gmail.com>
Tue, 10 May 2016 15:37:10 +0000 (17:37 +0200)
committerMarek Safar <marek.safar@gmail.com>
Tue, 10 May 2016 15:38:04 +0000 (17:38 +0200)
mcs/errors/cs0121-24.cs [deleted file]
mcs/mcs/ecore.cs
mcs/tests/gtest-optional-38.cs [new file with mode: 0644]
mcs/tests/gtest-optional-39.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml

diff --git a/mcs/errors/cs0121-24.cs b/mcs/errors/cs0121-24.cs
deleted file mode 100644 (file)
index 6617508..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// CS0121: The call is ambiguous between the following methods or properties: `A.GetValues(string[], string)' and `A.GetValues(string, params string[])'
-// Line: 23
-// CSC BUG: Correct according the spec, no identity conversion to do tie-breaking
-
-class A
-{
-       public int GetValues (string[] s, string value = null)
-       {
-               return 1;
-       }
-
-       public int GetValues (string s, params string [] args)
-       {
-               return 2;
-       }
-}
-
-
-class B
-{
-       public static void Main ()
-       {
-               var a = new A ();
-               a.GetValues (null);
-       }
-}
\ No newline at end of file
index fc99defc44e19359646b879d59bb7feb63bba902..63d6367309d7150bc430e8da642c61072b66a955 100644 (file)
@@ -4658,7 +4658,9 @@ namespace Mono.CSharp {
                        AParametersCollection candidate_pd = ((IParametersMember) candidate).Parameters;
                        AParametersCollection best_pd = ((IParametersMember) best).Parameters;
 
-                       bool better_at_least_one = false;
+                       int candidate_better_count = 0;
+                       int best_better_count = 0;
+
                        bool are_equivalent = true;
                        int args_count = args == null ? 0 : args.Count;
                        int j = 0;
@@ -4713,30 +4715,31 @@ namespace Mono.CSharp {
                                        //
                                        // No optional parameters tie breaking rules for delegates overload resolution
                                        //
-                                       if ((this.restrictions & Restrictions.CovariantDelegate) != 0)
+                                       if ((restrictions & Restrictions.CovariantDelegate) != 0)
                                                return false;
 
-                                       better_at_least_one = false;
-
-                                       ++j;
-                                       while (j < args_count && !args [j++].IsDefaultArgument) ;
-
-                                       break;
+                                       ++best_better_count;
+                                       continue;
                                }
 
                                // for at least one argument, the conversion to 'ct' should be better than 
                                // the conversion to 'bt'.
                                if (result != 0)
-                                       better_at_least_one = true;
+                                       ++candidate_better_count;
                        }
 
-                       if (better_at_least_one)
+                       if (candidate_better_count != 0 && best_better_count == 0)
                                return true;
 
+                       if (best_better_count > 0 && candidate_better_count == 0)
+                               return false;
+
                        //
                        // LAMESPEC: Tie-breaking rules for not equivalent parameter types
                        //
                        if (!are_equivalent) {
+                               while (j < args_count && !args [j++].IsDefaultArgument) ;
+
                                //
                                // A candidate with no default parameters is still better when there
                                // is no better expression conversion
diff --git a/mcs/tests/gtest-optional-38.cs b/mcs/tests/gtest-optional-38.cs
new file mode 100644 (file)
index 0000000..1f44b03
--- /dev/null
@@ -0,0 +1,36 @@
+class C
+{
+}
+
+class Foo 
+{
+               public int SetValue (string name, string value, string defaultValue = null, bool preserveExistingCase = false)
+               {
+                       return 1;
+               }
+
+               public int SetValue (string name, C value, C defaultValue = default(C), bool relativeToProject = true, C relativeToPath = default(C), bool mergeToMainGroup = false, string condition = null)
+               {
+                       return 2;
+               }
+
+               public int SetValue (string name, object value, C defaultValue = null)
+               {
+                       return 3;
+               }
+}
+
+class Test 
+{
+       static int Main() 
+       {
+               var f = new Foo ();
+               C b = null;
+               C c = null;
+
+               if (f.SetValue ("a", b, c) != 2)
+                       return 1;
+
+               return 0;
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/gtest-optional-39.cs b/mcs/tests/gtest-optional-39.cs
new file mode 100644 (file)
index 0000000..26aee13
--- /dev/null
@@ -0,0 +1,25 @@
+class A
+{
+       public int GetValues (string[] s, string value = null)
+       {
+               return 1;
+       }
+
+       public int GetValues (string s, params string [] args)
+       {
+               return 2;
+       }
+}
+
+
+class B
+{
+       public static int Main ()
+       {
+               var a = new A ();
+               if (a.GetValues (null) != 1)
+                       return 1;
+
+               return 0;
+       }
+}
\ No newline at end of file
index 027fd9871ef422bf008dc6f7e66ff4196ed13027..7ba3329b35d0b6ec07745f7a19c895346b2b589b 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-optional-38.cs">
+    <type name="C">
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Foo">
+      <method name="Int32 SetValue(System.String, System.String, System.String, Boolean)" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Int32 SetValue(System.String, C, C, Boolean, C, Boolean, System.String)" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Int32 SetValue(System.String, System.Object, C)" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Int32 Main()" attrs="145">
+        <size>50</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-optional-39.cs">
+    <type name="A">
+      <method name="Int32 GetValues(System.String[], System.String)" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Int32 GetValues(System.String, System.String[])" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="B">
+      <method name="Int32 Main()" attrs="150">
+        <size>37</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">