-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Delegate.CreateDelegate is not trimming safe #46857
Comments
Tagging subscribers to 'linkable-framework': @eerhardt, @vitek-karas, @LakshanF Issue Details#45984 flipped using System;
Delegate.CreateDelegate(typeof(Action), typeof(Derived), "Method").DynamicInvoke();
class Base
{
private static void Method() => Console.WriteLine("Hello");
}
class Derived : Base { } Linker can remove I've noticed this in NativeAOT since NativeAOT implements reflection stack in C# and annotations were not matching up.
|
Is this fix here to change runtime/src/libraries/System.Private.CoreLib/src/System/Delegate.cs Lines 52 to 53 in 5078dd6
to public static Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true)!;
public static Delegate CreateDelegate(Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true)!; This will preserve everything in the Type hierarchy, even |
I'll let Vitek speak to how All operates. In my head All should be a union of all the flags because that's how it's easy to reason about but I know linker does All differently - that behavior is accidental and undocumented as far as I'm concerned. AFAIK it keeps more than necessary because we don't rely on that definition of All in the class libraries. This would be the first spot that relies on that behavior. I would just keep them as RequiresUnreferencedCode. People can still use the overload that takes
|
The special The other argument was basically along the lines of this issue - that the other enum values do not cover everything (which was also intentional - we modeled them by At least that's how I remember it - I can't find it in the API review issue though... |
Given the axiom stated in https://github.com/dotnet/designs/blob/main/accepted/2020/linking-libraries.md
My preference is to annotate the Type as
Here's where we discussed |
The underlying code will find non-public methods on base types, but the current annotation won't preserve these methods. Use All annotation on the Type to ensure they are preserved. Fix dotnet#46857
* Make Delegate.CreateDelegate trimming safe The underlying code will find non-public methods on base types, but the current annotation won't preserve these methods. Use All annotation on the Type to ensure they are preserved. Fix #46857 * Add a trimming test
#45984 flipped
public static Delegate? CreateDelegate(Type, Type, string, bool, bool)
to being trimming safe, but from how I understand things, it isn't:Linker can remove
Base.Method
since private methods declared on base types don't count intoNonPublicMethods
of the declaring type:https://github.com/mono/linker/blob/7a095faf3925689f2a3450da1a76fdd79a070de9/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs#L125-L128
I've noticed this in NativeAOT since NativeAOT implements reflection stack in C# and annotations were not matching up.
Cc @vitek-karas @eerhardt
The text was updated successfully, but these errors were encountered: