Author: martin
Date: 2005-03-22 05:07:30 -0500 (Tue, 22 Mar 2005)
New Revision: 42080

Modified:
   trunk/mcs/gmcs/ChangeLog
   trunk/mcs/gmcs/expression.cs
Log:
**** Merged r40625 from MCS ****


Modified: trunk/mcs/gmcs/ChangeLog
===================================================================
--- trunk/mcs/gmcs/ChangeLog    2005-03-22 10:05:55 UTC (rev 42079)
+++ trunk/mcs/gmcs/ChangeLog    2005-03-22 10:07:30 UTC (rev 42080)
@@ -1,3 +1,14 @@
+2005-02-14  Raja R Harinath  <[EMAIL PROTECTED]>
+
+       Fix #59209.
+       * expression.cs (Invocation.BetterFunction): Remove support for
+       comparing virtual functions and their overrides.
+       (Invocation.IsOverride): New.
+       (Invocation.OverloadResolve): Don't consider 'override' functions
+       during candidate selection.  Store them in a lookaside list.
+       If the selected method is a 'virtual' function, use the list to
+       find any overrides that are closer to the LHS type.
+
 2005-02-14  Marek Safar  <[EMAIL PROTECTED]>
 
        * expression.cs (New.DoResolve): Add complex core type reduction.

Modified: trunk/mcs/gmcs/expression.cs
===================================================================
--- trunk/mcs/gmcs/expression.cs        2005-03-22 10:05:55 UTC (rev 42079)
+++ trunk/mcs/gmcs/expression.cs        2005-03-22 10:07:30 UTC (rev 42080)
@@ -4522,7 +4522,7 @@
                                return false;
 
                        //
-                       // Note that this is not just an optimization.  This 
handles the case
+                       // This handles the case
                        //
                        //   Add (float f1, float f2, float f3);
                        //   Add (params decimal [] foo);
@@ -4530,16 +4530,6 @@
                        // The call Add (3, 4, 5) should be ambiguous.  Without 
this check, the
                        // first candidate would've chosen as better.
                        //
-                       if (candidate_params == best_params) {
-                               //
-                               // We need to handle the case of a virtual 
function and its override.
-                               // The override is ignored during 
'applicable_type' calculation.  However,
-                               // it should be chosen over the base virtual 
function, especially when handling
-                               // value types.
-                               //
-                               return IsAncestralType (best.DeclaringType, 
candidate.DeclaringType);
-                       }
-
                        //
                        // This handles the following cases:
                        //
@@ -4550,6 +4540,30 @@
                         return !candidate_params && best_params;
                }
 
+               static bool IsOverride (MethodBase cand_method, MethodBase 
base_method)
+               {
+                       if (!IsAncestralType (base_method.DeclaringType, 
cand_method.DeclaringType))
+                               return false;
+
+                       ParameterData cand_pd = TypeManager.GetParameterData 
(cand_method);
+                       ParameterData base_pd = TypeManager.GetParameterData 
(base_method);
+               
+                       if (cand_pd.Count != base_pd.Count)
+                               return false;
+
+                       for (int j = 0; j < cand_pd.Count; ++j) {
+                               Parameter.Modifier cm = 
cand_pd.ParameterModifier (j);
+                               Parameter.Modifier bm = 
base_pd.ParameterModifier (j);
+                               Type ct = TypeManager.TypeToCoreType 
(cand_pd.ParameterType (j));
+                               Type bt = TypeManager.TypeToCoreType 
(base_pd.ParameterType (j));
+
+                               if (cm != bm || ct != bt)
+                                       return false;
+                       }
+
+                       return true;
+               }
+
                public static string FullMethodDesc (MethodBase mb)
                {
                        string ret_type = "";
@@ -4831,6 +4845,7 @@
                        Type applicable_type = null;
                        int arg_count = 0;
                        ArrayList candidates = new ArrayList ();
+                       ArrayList candidate_overrides = new ArrayList ();
 
                         //
                         // Used to keep a map between the candidate
@@ -4868,6 +4883,20 @@
                                        continue;
 
                                //
+                               // Methods marked 'override' don't take part in 
'applicable_type'
+                               // computation, nor in the actual overload 
resolution.
+                               // However, they still need to be emitted 
instead of a base virtual method.
+                               // We avoid doing the 'applicable' test here, 
since it'll anyway be applied
+                               // to the base virtual function, and IsOverride 
is much faster than IsApplicable.
+                               //
+                               if (!me.IsBase &&
+                                   methods [i].IsVirtual &&
+                                   (methods [i].Attributes & 
MethodAttributes.NewSlot) == 0) {
+                                       candidate_overrides.Add (methods [i]);
+                                       continue;
+                               }
+
+                               //
                                // Check if candidate is applicable (section 
14.4.2.1)
                                //   Is candidate applicable in normal form?
                                //
@@ -4890,15 +4919,6 @@
 
                                candidates.Add (methods [i]);
 
-                               //
-                               // Methods marked 'override' don't take part in 
'applicable_type'
-                               // computation.
-                               //
-                               if (!me.IsBase &&
-                                   methods [i].IsVirtual &&
-                                   (methods [i].Attributes & 
MethodAttributes.NewSlot) == 0)
-                                       continue;
-
                                if (applicable_type == null)
                                        applicable_type = decl_type;
                                else if (applicable_type != decl_type) {
@@ -5073,6 +5093,20 @@
                        }
 
                        //
+                       // If the method is a virtual function, pick an 
override closer to the LHS type.
+                       //
+                       if (!me.IsBase && method.IsVirtual) {
+                               if ((method.Attributes & 
MethodAttributes.NewSlot) != MethodAttributes.NewSlot)
+                                       throw new InternalErrorException (
+                                               "Should not happen.  An 
'override' method took part in overload resolution: " + method);
+                                                                   
+                               foreach (MethodBase candidate in 
candidate_overrides) {
+                                       if (IsOverride (candidate, method))
+                                               method = candidate;
+                               }
+                       }
+
+                       //
                        // And now check if the arguments are all
                        // compatible, perform conversions if
                        // necessary etc. and return if everything is

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to