From 70deea8dde89617cc4752ddaf0435b66946eb5ff Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Mon, 20 Feb 2017 17:12:52 +0100 Subject: [PATCH] [mcs] Inflate constraints of compiler generated proxy base call methods. Fixes #52294 --- mcs/mcs/class.cs | 14 ++++++++++++-- mcs/mcs/ecore.cs | 2 ++ mcs/mcs/generic.cs | 8 ++++++-- mcs/mcs/method.cs | 8 ++++++++ mcs/tests/test-anon-178.cs | 31 +++++++++++++++++++++++++++++++ mcs/tests/ver-il-net_4_x.xml | 39 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 mcs/tests/test-anon-178.cs diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs index e5d0b1f1735..fe79b444e36 100644 --- a/mcs/mcs/class.cs +++ b/mcs/mcs/class.cs @@ -1443,7 +1443,11 @@ namespace Mono.CSharp targs.Arguments = new TypeSpec[hoisted_tparams.Length]; for (int i = 0; i < hoisted_tparams.Length; ++i) { var tp = hoisted_tparams[i]; - var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null); + var tp_name = tp.Name; +#if DEBUG + tp_name += "_Proxy"; +#endif + var local_tp = new TypeParameter (tp, null, new MemberName (tp_name, Location), null); tparams.Add (local_tp); targs.Add (new SimpleName (tp.Name, Location)); @@ -1459,6 +1463,12 @@ namespace Mono.CSharp var mutator = new TypeParameterMutator (hoisted_tparams, tparams); return_type = mutator.Mutate (return_type); local_param_types = mutator.Mutate (local_param_types); + + var inflator = new TypeParameterInflator (this, null, hoisted_tparams, targs.Arguments); + for (int i = 0; i < hoisted_tparams.Length; ++i) { + var tp_spec = (TypeParameterSpec) targs.Arguments [i]; + tp_spec.InflateConstraints (inflator, tp_spec); + } } else { member_name = new MemberName (name); } @@ -1471,7 +1481,7 @@ namespace Mono.CSharp base_parameters[i].Resolve (this, i); } - var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types); + var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, local_param_types); if (method.Parameters.HasArglist) { cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location); cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve (); diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 8475a9e4894..5dff5e73d79 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -3352,6 +3352,8 @@ namespace Mono.CSharp { // introduce redundant storey but with `this' only but it's tricky to avoid // at this stage as we don't know what expressions follow base // + // TODO: It's needed only when the method with base call is moved to a storey + // if (rc.CurrentAnonymousMethod != null) { if (targs == null && method.IsGeneric) { targs = method.TypeArguments; diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs index fdf5b81f92c..8ddef4f3694 100644 --- a/mcs/mcs/generic.cs +++ b/mcs/mcs/generic.cs @@ -428,13 +428,13 @@ namespace Mono.CSharp { public TypeParameter (TypeParameterSpec spec, TypeSpec parentSpec, MemberName name, Attributes attrs) : base (null, name, attrs) { - this.spec = new TypeParameterSpec (parentSpec, spec.DeclaredPosition, spec.MemberDefinition, spec.SpecialConstraint, spec.Variance, null) { + this.spec = new TypeParameterSpec (parentSpec, spec.DeclaredPosition, this, spec.SpecialConstraint, spec.Variance, null) { BaseType = spec.BaseType, InterfacesDefined = spec.InterfacesDefined, TypeArguments = spec.TypeArguments }; } - + #region Properties public override AttributeTargets AttributeTargets { @@ -2162,6 +2162,10 @@ namespace Mono.CSharp { return this; var mutated = (InflatedTypeSpec) MemberwiseClone (); +#if DEBUG + mutated.ID += 1000000; +#endif + if (decl != DeclaringType) { // Gets back MethodInfo in case of metaInfo was inflated //mutated.info = MemberCache.GetMember (DeclaringType.GetDefinition (), this).info; diff --git a/mcs/mcs/method.cs b/mcs/mcs/method.cs index 5cce6a10361..2f42ebbaa0b 100644 --- a/mcs/mcs/method.cs +++ b/mcs/mcs/method.cs @@ -444,6 +444,10 @@ namespace Mono.CSharp { return ms; } +#if DEBUG + int counter = 100000; +#endif + public MethodSpec MakeGenericMethod (IMemberContext context, params TypeSpec[] targs) { if (targs == null) @@ -465,6 +469,10 @@ namespace Mono.CSharp { inflated.constraints = TypeParameterSpec.InflateConstraints (inflator, constraints ?? GenericDefinition.TypeParameters); inflated.state |= StateFlags.PendingMakeMethod; +#if DEBUG + inflated.ID += counter; + counter += 100000; +#endif // if (inflated.parent == null) // inflated.parent = parent; diff --git a/mcs/tests/test-anon-178.cs b/mcs/tests/test-anon-178.cs new file mode 100644 index 00000000000..278bdbe58b6 --- /dev/null +++ b/mcs/tests/test-anon-178.cs @@ -0,0 +1,31 @@ +using System; + +public abstract class BaseClass +{ +} + +public class DerivedClass : BaseClass +{ +} + +public abstract class CA +{ + [Obsolete] + public virtual void Foo (U args) where T : BaseClass, new() + { + } +} + +public class CB : CA +{ + public CB () + { + int x = 4; + Action pp = r => base.Foo (x); + } + + public static void Main () + { + new CB (); + } +} \ No newline at end of file diff --git a/mcs/tests/ver-il-net_4_x.xml b/mcs/tests/ver-il-net_4_x.xml index 058f365c1bd..f6db8ad2194 100644 --- a/mcs/tests/ver-il-net_4_x.xml +++ b/mcs/tests/ver-il-net_4_x.xml @@ -56725,6 +56725,45 @@ + + + + 7 + + + + + 7 + + + + + 2 + + + 7 + + + + + 8 + + + 8 + + + 41 + + + + + 18 + + + 7 + + + -- 2.11.4.GIT