Skip to content
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

Trimmer implementation of type hierarchy marking shows order dependent behavior #86580

Closed
Tracked by #101149
vitek-karas opened this issue May 22, 2023 · 1 comment · Fixed by #104701
Closed
Tracked by #101149
Assignees
Labels
area-Tools-ILLink .NET linker development as well as trimming analyzers in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@vitek-karas
Copy link
Member

vitek-karas commented May 22, 2023

This bug is only observable after a fix from: #86635
But the bug exists in the code base today, it's just that without the PR above it actually shows even wrong marking behavior.

class UseByDerived
{
    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
    class AnnotatedBase
    {
        [RequiresUnreferencedCode("--AnnotatedBase.VirtualMethodWithRequires--")]
        public virtual void VirtualMethodWithRequires() { }
    }

    // BUG
    // IL2113 - AnnotatedBase.VirtualMethodWithRequires
    class Derived : AnnotatedBase
    {
        [RequiresUnreferencedCode("--Derived.VirtualMethodWithRequires--")]
        public override void VirtualMethodWithRequires() { }
    }

    static void TestMethodOnDerived(Derived instance)
    {
        instance.GetType().GetMethod("MethodWithRequires");
    }

    public static void Test()
    {
        TestMethodOnDerived(new Derived());
    }
}

In the above example, the type hierarchy marking is triggered by:

Derived instance;
instance.GetType()...

In this case the trimmer produces IL2113 because the marking is first triggered on Derived and that triggers marking of methods which show up as accessible through Derived but declared on Base (IL2113 is for methods from base, IL2112 is for method on the type itself).

But if the same is triggered by:

AnnotatedBase instance;
instance.GetType()...

Then there will be no IL2113 instead there will be IL2112 on the Base.VirtualMethodWithRequires directly.

So if the program has both access patterns in it, then the diagnostics behavior is dependent on which order trimmer will process it in. The behavior should be consistent.

@vitek-karas vitek-karas added the area-Tools-ILLink .NET linker development as well as trimming analyzers label May 22, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label May 22, 2023
@ghost
Copy link

ghost commented May 22, 2023

Tagging subscribers to this area: @agocke, @sbomer, @vitek-karas
See info in area-owners.md if you want to be subscribed.

Issue Details

This bug is only observable after a fix from: <PR TBD - chicken and egg problem>
But the bug exists in the code base today, it's just that without the PR above it actually shows even wrong marking behavior.

class UseByDerived
{
    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
    class AnnotatedBase
    {
        [RequiresUnreferencedCode("--AnnotatedBase.VirtualMethodWithRequires--")]
        public virtual void VirtualMethodWithRequires() { }
    }

    // BUG
    // IL2113 - AnnotatedBase.VirtualMethodWithRequires
    class Derived : AnnotatedBase
    {
        [RequiresUnreferencedCode("--Derived.VirtualMethodWithRequires--")]
        public override void VirtualMethodWithRequires() { }
    }

    static void TestMethodOnDerived(Derived instance)
    {
        instance.GetType().GetMethod("MethodWithRequires");
    }

    public static void Test()
    {
        TestMethodOnDerived(new Derived());
    }
}

In the above example, the type hierarchy marking is triggered by:

Derived instance;
instance.GetType()...

In this case the trimmer produces IL2113 because the marking is first triggered on Derived and that triggers marking of methods which show up as accessible through Derived but declared on Base (IL2113 is for methods from base, IL2112 is for method on the type itself).

But if the same is triggered by:

AnnotatedBase instance;
instance.GetType()...

Then there will be no IL2113 instead there will be IL2112 on the Base.VirtualMethodWithRequires directly.

So if the program has both access patterns in it, then the diagnostics behavior is dependent on which order trimmer will process it in. The behavior should be consistent.

Author: vitek-karas
Assignees: -
Labels:

area-Tools-ILLink

Milestone: -

@agocke agocke added this to the 9.0.0 milestone Jan 29, 2024
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Jan 29, 2024
@dotnet-policy-service dotnet-policy-service bot added the in-pr There is an active PR which will close this issue when it is merged label Jul 10, 2024
@sbomer sbomer self-assigned this Jul 10, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Aug 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Tools-ILLink .NET linker development as well as trimming analyzers in-pr There is an active PR which will close this issue when it is merged
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants