From de3a32250da651eeacf6fcb5c715e591ef0f9438 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Thu, 10 Dec 2020 18:13:47 -0600 Subject: [PATCH 1/7] Add RequiresUnreferencedCode to Delegate constructors Contributes to #45623 --- .../src/System/Delegate.CoreCLR.cs | 2 ++ .../src/System/MulticastDelegate.cs | 2 ++ .../src/ILLink/ILLink.Suppressions.Shared.xml | 12 ------------ src/libraries/System.Runtime/ref/System.Runtime.cs | 4 ++++ .../src/System/Delegate.Mono.cs | 2 ++ .../src/System/MulticastDelegate.cs | 2 ++ 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs index ab338cd0bc9cd..110ebf5305cbd 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs @@ -33,6 +33,7 @@ public abstract partial class Delegate : ICloneable, ISerializable // This constructor is called from the class generated by the // compiler generated code + [RequiresUnreferencedCode("The target method might be removed")] protected Delegate(object target, string method) { if (target == null) @@ -56,6 +57,7 @@ protected Delegate(object target, string method) // This constructor is called from a class to generate a // delegate based upon a static method name and the Type object // for the class defining the method. + [RequiresUnreferencedCode("The target method might be removed")] protected Delegate(Type target, string method) { if (target == null) diff --git a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs index 34d08a8b056be..b63e3009dedad 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -25,6 +25,7 @@ public abstract class MulticastDelegate : Delegate // This constructor is called from the class generated by the // compiler generated code (This must match the constructor // in Delegate + [RequiresUnreferencedCode("The target method might be removed")] protected MulticastDelegate(object target, string method) : base(target, method) { } @@ -32,6 +33,7 @@ protected MulticastDelegate(object target, string method) : base(target, method) // This constructor is called from a class to generate a // delegate based upon a static method name and the Type object // for the class defining the method. + [RequiresUnreferencedCode("The target method might be removed")] protected MulticastDelegate(Type target, string method) : base(target, method) { } diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml index 9afad56f2df8c..03e36e7ca092d 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml @@ -19,18 +19,6 @@ member M:Internal.Runtime.InteropServices.IsolatedComponentLoadContext.Load(System.Reflection.AssemblyName) - - ILLink - IL2026 - member - M:System.Delegate.#ctor(System.Object,System.String) - - - ILLink - IL2026 - member - M:System.Delegate.#ctor(System.Type,System.String) - ILLink IL2026 diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index cf87c368b37d0..59bcbb084929f 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -1691,7 +1691,9 @@ void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Ser } public abstract partial class Delegate : System.ICloneable, System.Runtime.Serialization.ISerializable { + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] protected Delegate(object target, string method) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] protected Delegate(System.Type target, string method) { } public System.Reflection.MethodInfo Method { get { throw null; } } public object? Target { get { throw null; } } @@ -2933,7 +2935,9 @@ public MTAThreadAttribute() { } } public abstract partial class MulticastDelegate : System.Delegate { + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] protected MulticastDelegate(object target, string method) : base (default(object), default(string)) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] protected MulticastDelegate(System.Type target, string method) : base (default(object), default(string)) { } protected sealed override System.Delegate CombineImpl(System.Delegate? follow) { throw null; } public sealed override bool Equals(object? obj) { throw null; } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs index b9589b49f9bd9..53ebdedb4b848 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs @@ -71,6 +71,7 @@ public partial class Delegate private bool method_is_virtual; #endregion + [RequiresUnreferencedCode("The target method might be removed")] protected Delegate(object target, string method) { if (target is null) @@ -86,6 +87,7 @@ protected Delegate(object target, string method) }; } + [RequiresUnreferencedCode("The target method might be removed")] protected Delegate(Type target, string method) { if (target is null) diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs index 5582c760b6c2a..9cf377d923220 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -12,11 +12,13 @@ public abstract class MulticastDelegate : Delegate { private Delegate[]? delegates; + [RequiresUnreferencedCode("The target method might be removed")] protected MulticastDelegate(object target, string method) : base(target, method) { } + [RequiresUnreferencedCode("The target method might be removed")] protected MulticastDelegate(Type target, string method) : base(target, method) { From cfbee636c9d53264a6b57a89a7622553706f7cb1 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 11 Dec 2020 10:59:27 -0600 Subject: [PATCH 2/7] Add RequiresUnreferencedCode to some internal Reflection methods to address ILLink warnings. --- .../src/System/Reflection/RuntimeAssembly.cs | 1 + .../src/System/Reflection/RuntimeModule.cs | 2 ++ .../src/ILLink/ILLink.Suppressions.Shared.xml | 24 ------------------- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index 20a72464b3ac7..76ba75e0c2627 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -691,6 +691,7 @@ public sealed override Type[] GetForwardedTypes() return types.ToArray(); } + [RequiresUnreferencedCode("Types might be removed")] private static void AddPublicNestedTypes(Type type, List types, List exceptions) { Type[] nestedTypes; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs index 2aff858f173be..6bf7b6ad3bce7 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs @@ -144,6 +144,7 @@ public override byte[] ResolveSignature(int metadataToken) } } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] private FieldInfo? ResolveLiteralField(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { MetadataToken tk = new MetadataToken(metadataToken); @@ -360,6 +361,7 @@ public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFile return GetMethodInternal(name, bindingAttr, binder, callConvention, types, modifiers); } + [RequiresUnreferencedCode("Methods might be removed")] internal MethodInfo? GetMethodInternal(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml index 03e36e7ca092d..21ef3e35ab1f0 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml @@ -37,12 +37,6 @@ member M:System.Reflection.Emit.ModuleBuilder.GetTypeToken(System.String) - - ILLink - IL2026 - member - M:System.Reflection.RuntimeModule.ResolveLiteralField(System.Int32,System.Type[],System.Type[]) - ILLink IL2026 @@ -157,12 +151,6 @@ member M:System.Diagnostics.Tracing.TypeAnalysis.#ctor(System.Type,System.Diagnostics.Tracing.EventDataAttribute,System.Collections.Generic.List{System.Type}) - - ILLink - IL2070 - member - M:System.Reflection.RuntimeAssembly.AddPublicNestedTypes(System.Type,System.Collections.Generic.List{System.Type},System.Collections.Generic.List{System.Exception}) - ILLink IL2072 @@ -211,18 +199,6 @@ member M:System.Reflection.Emit.TypeBuilder.DefineDefaultConstructorNoLock(System.Reflection.MethodAttributes) - - ILLink - IL2075 - member - M:System.Reflection.RuntimeModule.GetMethodInternal(System.String,System.Reflection.BindingFlags,System.Reflection.Binder,System.Reflection.CallingConventions,System.Type[],System.Reflection.ParameterModifier[]) - - - ILLink - IL2075 - member - M:System.Reflection.RuntimeModule.ResolveLiteralField(System.Int32,System.Type[],System.Type[]) - ILLink IL2075 From 42069f630a26ec309f7128e972e35c90aea648ac Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 11 Dec 2020 17:28:23 -0600 Subject: [PATCH 3/7] Address remaining ILLink warnings in Reflection.Emit. --- .../Reflection/Emit/ConstructorBuilder.cs | 2 +- .../src/System/Reflection/Emit/EnumBuilder.cs | 2 + .../System/Reflection/Emit/ModuleBuilder.cs | 6 ++ .../src/System/Reflection/Emit/TypeBuilder.cs | 20 +++++ .../src/ILLink/ILLink.Suppressions.Shared.xml | 78 ------------------- 5 files changed, 29 insertions(+), 79 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs index 2454864138683..0e608f73bdf9b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs @@ -27,7 +27,7 @@ internal ConstructorBuilder(string name, MethodAttributes attributes, CallingCon } internal ConstructorBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention, - Type[]? parameterTypes, ModuleBuilder mod, TypeBuilder type) : + Type[]? parameterTypes, ModuleBuilder mod, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TypeBuilder type) : this(name, attributes, callingConvention, parameterTypes, null, null, mod, type) { } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs index 873979ecb7acf..fd0807c4eb0c2 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs @@ -332,6 +332,8 @@ public override Type MakeArrayType(int rank) // Constructs a EnumBuilder. // EnumBuilder can only be a top-level (not nested) enum type. + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2064:UnrecognizedReflectionPattern", + Justification = "Reflection.Emit is not subject to trimming")] internal EnumBuilder( string name, // name of type Type underlyingType, // underlying type for an Enum diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs index d741713ecee2a..1481ba0f6f499 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs @@ -428,6 +428,11 @@ internal SignatureHelper GetMemberRefSignature(CallingConventions call, Type? re return sig; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "Module.ResolveMethod is marked as RequiresUnreferencedCode because it relies on tokens " + + "which are not guaranteed to be stable across trimming. So if somebody hardcodes a token it could break. " + + "The usage here is not like that as all these tokens come from existing metadata loaded from some IL " + + "and so trimming has no effect (the tokens are read AFTER trimming occured).")] private static MethodBase GetGenericMethodBaseDefinition(MethodBase methodBase) { // methodInfo = G.M ==> methDef = G.M @@ -601,6 +606,7 @@ internal Type[] GetTypesNoLock() } } + [RequiresUnreferencedCode("Types might be removed")] private Type? GetTypeNoLock(string className, bool throwOnError, bool ignoreCase) { // public API to to a type. The reason that we need this function override from module diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs index d87985db96d3c..7c1f93c8a379d 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs @@ -62,6 +62,8 @@ public void Bake(ModuleBuilder module, int token) #endregion #region Public Static Methods + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", + Justification = "MakeGenericType is only called on a TypeBuilder which is not subject to trimming")] public static MethodInfo GetMethod(Type type, MethodInfo method) { if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation)) @@ -94,6 +96,9 @@ public static MethodInfo GetMethod(Type type, MethodInfo method) return MethodOnTypeBuilderInstantiation.GetMethod(method, (type as TypeBuilderInstantiation)!); } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", + Justification = "MakeGenericType is only called on a TypeBuilder which is not subject to trimming")] public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor) { if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation)) @@ -114,6 +119,9 @@ public static ConstructorInfo GetConstructor(Type type, ConstructorInfo construc return ConstructorOnTypeBuilderInstantiation.GetConstructor(constructor, (type as TypeBuilderInstantiation)!); } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", + Justification = "MakeGenericType is only called on a TypeBuilder which is not subject to trimming")] public static FieldInfo GetField(Type type, FieldInfo field) { if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation)) @@ -1265,6 +1273,8 @@ public MethodBuilder DefineMethod(string name, MethodAttributes attributes, Call } } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2082:UnrecognizedReflectionPattern", + Justification = "Reflection.Emit is not subject to trimming")] private MethodBuilder DefineMethodNoLock(string name, MethodAttributes attributes, CallingConventions callingConvention, Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers) @@ -1344,6 +1354,8 @@ public MethodBuilder DefinePInvokeMethod(string name, string dllName, string ent return method; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2082:UnrecognizedReflectionPattern", + Justification = "Reflection.Emit is not subject to trimming")] private MethodBuilder DefinePInvokeMethodHelper( string name, string dllName, string importName, MethodAttributes attributes, CallingConventions callingConvention, Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, @@ -1459,6 +1471,8 @@ public ConstructorBuilder DefineTypeInitializer() } } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2082:UnrecognizedReflectionPattern", + Justification = "Reflection.Emit is not subject to trimming")] private ConstructorBuilder DefineTypeInitializerNoLock() { ThrowIfCreated(); @@ -1485,6 +1499,10 @@ public ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes) } } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", + Justification = "MakeGenericType is only called on a TypeBuilderInstantiation which is not subject to trimming")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", + Justification = "GetConstructor is only called on a TypeBuilderInstantiation which is not subject to trimming")] private ConstructorBuilder DefineDefaultConstructorNoLock(MethodAttributes attributes) { ConstructorBuilder constBuilder; @@ -1558,6 +1576,8 @@ public ConstructorBuilder DefineConstructor(MethodAttributes attributes, Calling } } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2082:UnrecognizedReflectionPattern", + Justification = "Reflection.Emit is not subject to trimming")] private ConstructorBuilder DefineConstructorNoLock(MethodAttributes attributes, CallingConventions callingConvention, Type[]? parameterTypes, Type[][]? requiredCustomModifiers, Type[][]? optionalCustomModifiers) { diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml index 21ef3e35ab1f0..16fa0cc8238d7 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml @@ -19,24 +19,6 @@ member M:Internal.Runtime.InteropServices.IsolatedComponentLoadContext.Load(System.Reflection.AssemblyName) - - ILLink - IL2026 - member - M:System.Reflection.Emit.ModuleBuilder.GetGenericMethodBaseDefinition(System.Reflection.MethodBase) - - - ILLink - IL2026 - member - M:System.Reflection.Emit.ModuleBuilder.GetTypeNoLock(System.String,System.Boolean,System.Boolean) - - - ILLink - IL2026 - member - M:System.Reflection.Emit.ModuleBuilder.GetTypeToken(System.String) - ILLink IL2026 @@ -61,30 +43,6 @@ member M:System.Runtime.InteropServices.Marshal.MkParseDisplayName(System.Runtime.InteropServices.ComTypes.IBindCtx,System.String,System.UInt32@,System.Runtime.InteropServices.ComTypes.IMoniker@) - - ILLink - IL2055 - member - M:System.Reflection.Emit.TypeBuilder.DefineDefaultConstructorNoLock(System.Reflection.MethodAttributes) - - - ILLink - IL2055 - member - M:System.Reflection.Emit.TypeBuilder.GetConstructor(System.Type,System.Reflection.ConstructorInfo) - - - ILLink - IL2055 - member - M:System.Reflection.Emit.TypeBuilder.GetField(System.Type,System.Reflection.FieldInfo) - - - ILLink - IL2055 - member - M:System.Reflection.Emit.TypeBuilder.GetMethod(System.Type,System.Reflection.MethodInfo) - ILLink IL2057 @@ -115,24 +73,12 @@ member T:System.Resources.ResourceReader - - ILLink - IL2064 - member - M:System.Reflection.Emit.EnumBuilder.#ctor(System.String,System.Type,System.Reflection.TypeAttributes,System.Reflection.Emit.ModuleBuilder) - ILLink IL2067 member M:System.__ComObject.CreateEventProvider(System.RuntimeType) - - ILLink - IL2067 - member - M:System.Reflection.Emit.ConstructorBuilder.#ctor(System.String,System.Reflection.MethodAttributes,System.Reflection.CallingConventions,System.Type[],System.Reflection.Emit.ModuleBuilder,System.Reflection.Emit.TypeBuilder) - ILLink IL2070 @@ -193,12 +139,6 @@ member M:System.Diagnostics.Tracing.ManifestBuilder.CreateManifestString - - ILLink - IL2075 - member - M:System.Reflection.Emit.TypeBuilder.DefineDefaultConstructorNoLock(System.Reflection.MethodAttributes) - ILLink IL2075 @@ -223,23 +163,5 @@ member T:System.Resources.ResourceReader - - ILLink - IL2082 - member - M:System.Reflection.Emit.TypeBuilder.DefineConstructorNoLock(System.Reflection.MethodAttributes,System.Reflection.CallingConventions,System.Type[],System.Type[][],System.Type[][]) - - - ILLink - IL2082 - member - M:System.Reflection.Emit.TypeBuilder.DefineMethodNoLock(System.String,System.Reflection.MethodAttributes,System.Reflection.CallingConventions,System.Type,System.Type[],System.Type[],System.Type[],System.Type[][],System.Type[][]) - - - ILLink - IL2082 - member - M:System.Reflection.Emit.TypeBuilder.DefinePInvokeMethodHelper(System.String,System.String,System.String,System.Reflection.MethodAttributes,System.Reflection.CallingConventions,System.Type,System.Type[],System.Type[],System.Type[],System.Type[][],System.Type[][],System.Runtime.InteropServices.CallingConvention,System.Runtime.InteropServices.CharSet) - From 34979517373a5b1a392aaabe67650fc8c9f23ec5 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 11 Dec 2020 18:37:56 -0600 Subject: [PATCH 4/7] add using --- .../System.Private.CoreLib/src/System/MulticastDelegate.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs index 9cf377d923220..15b49858be606 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.Serialization; using System.Runtime.InteropServices; From df9e8475d8829b1553e56f7c7cbab98b72e1b4c5 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 14 Dec 2020 14:45:30 -0600 Subject: [PATCH 5/7] Respond to PR feedback Annotate Delegate.BindToMethod with DynamicallyAccessedMembers Fix up requires unreferenced code comments --- .../src/System/Delegate.CoreCLR.cs | 10 +++------- .../src/System/MulticastDelegate.cs | 3 +-- .../src/System/Reflection/RuntimeAssembly.cs | 2 +- .../src/System/Reflection/RuntimeModule.cs | 4 ++-- .../src/ILLink/ILLink.Suppressions.Shared.xml | 2 +- .../System.Private.CoreLib/src/System/Delegate.cs | 8 ++++---- .../System.Runtime/ref/System.Runtime.cs | 15 +++++---------- .../src/System/Delegate.Mono.cs | 6 ++---- .../src/System/MulticastDelegate.cs | 3 +-- 9 files changed, 20 insertions(+), 33 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs index 110ebf5305cbd..07988b1e8b710 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs @@ -57,8 +57,7 @@ protected Delegate(object target, string method) // This constructor is called from a class to generate a // delegate based upon a static method name and the Type object // for the class defining the method. - [RequiresUnreferencedCode("The target method might be removed")] - protected Delegate(Type target, string method) + protected Delegate([DynamicallyAccessedMembers(AllMethods)] Type target, string method) { if (target == null) throw new ArgumentNullException(nameof(target)); @@ -259,8 +258,7 @@ protected virtual MethodInfo GetMethodImpl() } // V1 API. - [RequiresUnreferencedCode("The target method might be removed")] - public static Delegate? CreateDelegate(Type type, Type target, string method, bool ignoreCase, bool throwOnBindFailure) + public static Delegate? CreateDelegate(Type type, [DynamicallyAccessedMembers(AllMethods)] Type target, string method, bool ignoreCase, bool throwOnBindFailure) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -419,10 +417,8 @@ internal static Delegate CreateDelegateNoSecurityCheck(Type type, object? target // // internal implementation details (FCALLS and utilities) // - - [RequiresUnreferencedCode("The target method might be removed")] [MethodImpl(MethodImplOptions.InternalCall)] - private extern bool BindToMethodName(object? target, RuntimeType methodType, string method, DelegateBindingFlags flags); + private extern bool BindToMethodName(object? target, [DynamicallyAccessedMembers(AllMethods)] RuntimeType methodType, string method, DelegateBindingFlags flags); [MethodImpl(MethodImplOptions.InternalCall)] private extern bool BindToMethodInfo(object? target, IRuntimeMethodInfo method, RuntimeType methodType, DelegateBindingFlags flags); diff --git a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs index b63e3009dedad..eb061b88205fe 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -33,8 +33,7 @@ protected MulticastDelegate(object target, string method) : base(target, method) // This constructor is called from a class to generate a // delegate based upon a static method name and the Type object // for the class defining the method. - [RequiresUnreferencedCode("The target method might be removed")] - protected MulticastDelegate(Type target, string method) : base(target, method) + protected MulticastDelegate([DynamicallyAccessedMembers(AllMethods)] Type target, string method) : base(target, method) { } diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index 76ba75e0c2627..2f78002822166 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -691,7 +691,7 @@ public sealed override Type[] GetForwardedTypes() return types.ToArray(); } - [RequiresUnreferencedCode("Types might be removed")] + [RequiresUnreferencedCode("Types might be removed because recursive nested types can't currently be annotated for dynamic access.")] private static void AddPublicNestedTypes(Type type, List types, List exceptions) { Type[] nestedTypes; diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs index 6bf7b6ad3bce7..0b31bf27759e2 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs @@ -354,14 +354,14 @@ public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFile #endregion #region Protected Virtuals - [RequiresUnreferencedCode("Methods might be removed")] + [RequiresUnreferencedCode("Methods might be removed because Module methods can't currently be annotated for dynamic access.")] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { return GetMethodInternal(name, bindingAttr, binder, callConvention, types, modifiers); } - [RequiresUnreferencedCode("Methods might be removed")] + [RequiresUnreferencedCode("Methods might be removed because Module methods can't currently be annotated for dynamic access.")] internal MethodInfo? GetMethodInternal(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { diff --git a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml index 16fa0cc8238d7..67723c1e1589c 100644 --- a/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml +++ b/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.Shared.xml @@ -9,7 +9,7 @@ ILLink - IL2026 + IL2072 member M:Internal.Runtime.InteropServices.ComponentActivator.InternalGetFunctionPointer(System.Runtime.Loader.AssemblyLoadContext,System.String,System.String,System.IntPtr) diff --git a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs index d4e15c0f541ff..f013de2547532 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Delegate.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Delegate.cs @@ -10,6 +10,8 @@ namespace System { public abstract partial class Delegate : ICloneable, ISerializable { + private protected const DynamicallyAccessedMemberTypes AllMethods = DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods; + public virtual object Clone() => MemberwiseClone(); [return: NotNullIfNotNull("a")] @@ -47,10 +49,8 @@ public abstract partial class Delegate : ICloneable, ISerializable public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true)!; // V1 api: Creates open delegates to static methods only, relaxed signature checking disallowed. - [RequiresUnreferencedCode("The target method might be removed")] - public static Delegate CreateDelegate(Type type, Type target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true)!; - [RequiresUnreferencedCode("The target method might be removed")] - public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true)!; + public static Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(AllMethods)] Type target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true)!; + public static Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(AllMethods)] Type target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true)!; #if !CORERT protected virtual Delegate CombineImpl(Delegate? d) => throw new MulticastNotSupportedException(SR.Multicast_Combine); diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 59bcbb084929f..c84c3499cc8b7 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -1693,8 +1693,7 @@ public abstract partial class Delegate : System.ICloneable, System.Runtime.Seria { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] protected Delegate(object target, string method) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] - protected Delegate(System.Type target, string method) { } + protected Delegate([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods)] System.Type target, string method) { } public System.Reflection.MethodInfo Method { get { throw null; } } public object? Target { get { throw null; } } public virtual object Clone() { throw null; } @@ -1713,12 +1712,9 @@ protected Delegate(System.Type target, string method) { } public static System.Delegate? CreateDelegate(System.Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure) { throw null; } public static System.Delegate CreateDelegate(System.Type type, System.Reflection.MethodInfo method) { throw null; } public static System.Delegate? CreateDelegate(System.Type type, System.Reflection.MethodInfo method, bool throwOnBindFailure) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] - public static System.Delegate CreateDelegate(System.Type type, System.Type target, string method) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] - public static System.Delegate CreateDelegate(System.Type type, System.Type target, string method, bool ignoreCase) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] - public static System.Delegate? CreateDelegate(System.Type type, System.Type target, string method, bool ignoreCase, bool throwOnBindFailure) { throw null; } + public static System.Delegate CreateDelegate(System.Type type, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods)] System.Type target, string method) { throw null; } + public static System.Delegate CreateDelegate(System.Type type, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods)] System.Type target, string method, bool ignoreCase) { throw null; } + public static System.Delegate? CreateDelegate(System.Type type, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods)] System.Type target, string method, bool ignoreCase, bool throwOnBindFailure) { throw null; } public object? DynamicInvoke(params object?[]? args) { throw null; } protected virtual object? DynamicInvokeImpl(object?[]? args) { throw null; } public override bool Equals(object? obj) { throw null; } @@ -2937,8 +2933,7 @@ public abstract partial class MulticastDelegate : System.Delegate { [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] protected MulticastDelegate(object target, string method) : base (default(object), default(string)) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The target method might be removed")] - protected MulticastDelegate(System.Type target, string method) : base (default(object), default(string)) { } + protected MulticastDelegate([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods)] System.Type target, string method) : base (default(object), default(string)) { } protected sealed override System.Delegate CombineImpl(System.Delegate? follow) { throw null; } public sealed override bool Equals(object? obj) { throw null; } public sealed override int GetHashCode() { throw null; } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs index 53ebdedb4b848..a2da6563dba56 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs @@ -87,8 +87,7 @@ protected Delegate(object target, string method) }; } - [RequiresUnreferencedCode("The target method might be removed")] - protected Delegate(Type target, string method) + protected Delegate([DynamicallyAccessedMembers(AllMethods)] Type target, string method) { if (target is null) throw new ArgumentNullException(nameof(target)); @@ -183,8 +182,7 @@ public static Delegate CreateDelegate(Type type, object? firstArgument, MethodIn return CreateDelegate_internal(type, target, info, throwOnBindFailure); } - [RequiresUnreferencedCode("The target method might be removed")] - public static Delegate? CreateDelegate(Type type, Type target, string method, bool ignoreCase, bool throwOnBindFailure) + public static Delegate? CreateDelegate(Type type, [DynamicallyAccessedMembers(AllMethods)] Type target, string method, bool ignoreCase, bool throwOnBindFailure) { if (type is null) throw new ArgumentNullException(nameof(type)); diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs index 15b49858be606..244e638253324 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -19,8 +19,7 @@ protected MulticastDelegate(object target, string method) { } - [RequiresUnreferencedCode("The target method might be removed")] - protected MulticastDelegate(Type target, string method) + protected MulticastDelegate([DynamicallyAccessedMembers(AllMethods)] Type target, string method) : base(target, method) { } From 529996ae7c0e0e9d556bbef5d0574cff2148947b Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 14 Dec 2020 20:19:45 -0600 Subject: [PATCH 6/7] Update API Compat txt for Delegate.CreateDelegate attribute removal --- .../shims/ApiCompatBaseline.PreviousNetCoreApp.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt index 00f5742042d12..33a7dfae8973e 100644 --- a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt +++ b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt @@ -1,4 +1,11 @@ +Compat issues with assembly mscorlib: +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute' exists on 'System.Delegate.CreateDelegate(System.Type, System.Type, System.String)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute' exists on 'System.Delegate.CreateDelegate(System.Type, System.Type, System.String, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute' exists on 'System.Delegate.CreateDelegate(System.Type, System.Type, System.String, System.Boolean, System.Boolean)' in the contract but not the implementation. Compat issues with assembly netstandard: +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute' exists on 'System.Delegate.CreateDelegate(System.Type, System.Type, System.String)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute' exists on 'System.Delegate.CreateDelegate(System.Type, System.Type, System.String, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute' exists on 'System.Delegate.CreateDelegate(System.Type, System.Type, System.String, System.Boolean, System.Boolean)' in the contract but not the implementation. CannotChangeAttribute : Attribute 'System.ComponentModel.DesignerAttribute' on 'System.ComponentModel.IComponent' changed from '[DesignerAttribute("System.ComponentModel.Design.ComponentDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]' in the contract to '[DesignerAttribute("System.ComponentModel.Design.ComponentDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]' in the implementation. CannotRemoveAttribute : Attribute 'System.ComponentModel.DesignerAttribute' exists on 'System.ComponentModel.MarshalByValueComponent' in the contract but not the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("windows")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. @@ -23,4 +30,8 @@ MembersMustExist : Member 'public void System.Net.Http.SocketsHttpHandler.Plaint Compat issues with assembly System.Net.Primitives: TypesMustExist : Type 'System.Net.NetworkError' does not exist in the implementation but it does exist in the contract. TypesMustExist : Type 'System.Net.NetworkException' does not exist in the implementation but it does exist in the contract. -Total Issues: 18 +Compat issues with assembly System.Runtime: +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute' exists on 'System.Delegate.CreateDelegate(System.Type, System.Type, System.String)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute' exists on 'System.Delegate.CreateDelegate(System.Type, System.Type, System.String, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute' exists on 'System.Delegate.CreateDelegate(System.Type, System.Type, System.String, System.Boolean, System.Boolean)' in the contract but not the implementation. +Total Issues: 27 From 10ce71cb82e37e177c1c5c6c69569a48a404df25 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 15 Dec 2020 11:25:19 -0600 Subject: [PATCH 7/7] Fix Mono ILLink warnings --- .../src/System/Delegate.Mono.cs | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs index a2da6563dba56..a541fd398d731 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Delegate.Mono.cs @@ -32,6 +32,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; @@ -137,7 +138,7 @@ public static Delegate CreateDelegate(Type type, object? firstArgument, MethodIn if (!rtType.IsDelegate()) throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type)); - if (!IsMatchingCandidate(type, firstArgument, method, allowClosed, out DelegateData? delegate_data)) + if (!IsMatchingCandidate(rtType, firstArgument, method, allowClosed, out DelegateData? delegate_data)) { if (throwOnBindFailure) throw new ArgumentException(SR.Arg_DlgtTargMeth); @@ -170,7 +171,7 @@ public static Delegate CreateDelegate(Type type, object? firstArgument, MethodIn if (!rtType.IsDelegate()) throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type)); - MethodInfo? info = GetCandidateMethod(type, target.GetType(), method, BindingFlags.Instance, ignoreCase); + MethodInfo? info = GetCandidateMethod(rtType, target.GetType(), method, BindingFlags.Instance, ignoreCase); if (info is null) { if (throwOnBindFailure) @@ -201,7 +202,7 @@ public static Delegate CreateDelegate(Type type, object? firstArgument, MethodIn if (!rtType.IsDelegate()) throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type)); - MethodInfo? info = GetCandidateMethod(type, target, method, BindingFlags.Static, ignoreCase); + MethodInfo? info = GetCandidateMethod(rtType, target, method, BindingFlags.Static, ignoreCase); if (info is null) { if (throwOnBindFailure) @@ -213,10 +214,9 @@ public static Delegate CreateDelegate(Type type, object? firstArgument, MethodIn return CreateDelegate_internal(type, null, info, throwOnBindFailure); } - [RequiresUnreferencedCode("The target method might be removed")] - private static MethodInfo? GetCandidateMethod(Type type, Type target, string method, BindingFlags bflags, bool ignoreCase) + private static MethodInfo? GetCandidateMethod(RuntimeType type, [DynamicallyAccessedMembers(AllMethods)] Type target, string method, BindingFlags bflags, bool ignoreCase) { - MethodInfo? invoke = type.GetMethod("Invoke"); + MethodInfo? invoke = GetDelegateInvokeMethod(type); if (invoke is null) return null; @@ -251,12 +251,9 @@ public static Delegate CreateDelegate(Type type, object? firstArgument, MethodIn return null; } - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern", - Justification = "Invoke method is never removed from delegates")] - private static bool IsMatchingCandidate(Type type, object? target, MethodInfo method, bool allowClosed, out DelegateData? delegateData) + private static bool IsMatchingCandidate(RuntimeType type, object? target, MethodInfo method, bool allowClosed, out DelegateData? delegateData) { - MethodInfo? invoke = type.GetMethod("Invoke"); - + MethodInfo? invoke = GetDelegateInvokeMethod(type); if (invoke == null || !IsReturnTypeMatch(invoke.ReturnType!, method.ReturnType!)) { delegateData = null; @@ -370,6 +367,15 @@ private static bool IsMatchingCandidate(Type type, object? target, MethodInfo me return argsMatch; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern", + Justification = "ILLinker will never remove the Invoke method from delegates.")] + private static MethodInfo? GetDelegateInvokeMethod(RuntimeType type) + { + Debug.Assert(type.IsDelegate()); + + return type.GetMethod("Invoke"); + } + private static bool IsReturnTypeMatch(Type delReturnType, Type returnType) { bool returnMatch = returnType == delReturnType;