[Mono-dev] Bugzilla Bug 475860, or, "the wrong patch for the right job"

Marek Safar marek.safar at seznam.cz
Mon Feb 16 08:39:36 EST 2009


Hi,
> I'm investigating http://bugzilla.novell.com/show_bug.cgi?id=475860; I've
> come up with a patch that addresses the issue, but I'm certain that it's the
> wrong way to solve the problem. Here's the patch:
>
> ---
> Index: ecore.cs
> ===================================================================
> --- ecore.cs	(revision 126868)
> +++ ecore.cs	(working copy)
> @@ -4027,6 +4027,12 @@
>  						Methods [j++] = m;
>  				}
>  				nmethods = j;
> +
> +				if (nmethods == 0 && candidate_overrides != null) {
> +					foreach (MethodBase m in candidate_overrides)
> +						Methods [j++] = m;
> +					nmethods = j;
> +				}
>  			}
>  
>  			//
> @@ -4291,11 +4297,11 @@
>  			// If the method is a virtual function, pick an override closer to the
> LHS type.
>  			//
>  			if (!IsBase && best_candidate.IsVirtual) {
> -				if (TypeManager.IsOverride (best_candidate))
> +/*				if (TypeManager.IsOverride (best_candidate))
>  					throw new InternalErrorException (
> -						"Should not happen.  An 'override' method took part in overload
> resolution: " + best_candidate);
> +						"Should not happen.  An 'override' method took part in overload
> resolution: " + best_candidate);*/
>  
> -				if (candidate_overrides != null) {
> +				if (!TypeManager.IsOverride (best_candidate) && candidate_overrides !=
> null) {
>  					Type[] gen_args = null;
>  					bool gen_override = false;
>  					if (TypeManager.IsGenericMethod (best_candidate))
> ---
>
> The reason that the code listed in the Bugzilla bug fails to compile is that
> at the time of overload resolution, the method table for the family of
> Reference classes has not been completely initialized. Because of this, when
> TypeManager.TryGetBaseDefinition is called, it fails, and no candidates are
> added to the list of method overloads.
>
> The patch included above addresses this problem by allowing overrides to be
> added to the list of candidates if no other candidates have been found.
> While this allows the example code to compile and even produces correct
> results at runtime, I'm pretty sure that the most appropriate way to solve
> this problem would be to instead make sure that the method table is
> appropriately populated before we even get to this code (also, a comparison
> of the IL produced by gmcs and the IL produced by csc reveals that csc
> produces virtual calls to Reference::CompareTo(), while gmcs produces
> virtual calls to ReferencePoint::CompareTo() and
> ReferenceRange::CompareTo()).
>
> I'm afraid that fixing this bug will require a deeper knowledge of the
> compiler than I currently possess. Can anyone suggest a more appropriate way
> of solving this problem?
>   
The right fix is to change how MemberCache is populated in such 
scenarios, we have several similar bugs reported and they are all 
related to missing members/types in type's MemberCache.

Marek


More information about the Mono-devel-list mailing list