Skip to content

Commit

Permalink
Allow trimming FeatureGuard and FeatureSwitchDefinition attributes (#…
Browse files Browse the repository at this point in the history
…100263)

Under AggressiveAttributeTrimming setting.

Fixes
#100256. AggressiveAttributeTrimming
was attempting to remove RequiresDynamicCode attributes, but the
type was still referenced by FeatureGuardAttribute on
IsDynamicCodeCompiled.

Adding FeatureGuardAttribute to the set of attributes that get
removed with AggressiveAttributeTrimming fixes this. Also adding
FeatureSwitchDefinitionAttribute because that one can be removed
as well.
  • Loading branch information
sbomer authored and pull[bot] committed Aug 18, 2024
1 parent a6ede7a commit 84ad56c
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@
<type fullname="System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute">
<attribute internal="RemoveAttributeInstances" />
</type>
<type fullname="System.Diagnostics.CodeAnalysis.FeatureGuardAttribute">
<attribute internal="RemoveAttributeInstances" />
</type>
<type fullname="System.Diagnostics.CodeAnalysis.FeatureSwitchDefinitionAttribute">
<attribute internal="RemoveAttributeInstances" />
</type>
<type fullname="System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute">
<attribute internal="RemoveAttributeInstances" />
</type>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable enable

using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Reflection;

/// <summary>
/// Ensures setting _AggressiveAttributeTrimming = true causes various attributes to be trimmed
/// </summary>
class Program
{
[UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2111", Justification = "Expected trim warning for reflection over annotated members.")]
[UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2026", Justification = "Expected trim warning for reflection over annotated members.")]
static int Main(string[] args)
{
// Reference to IsDynamicCodeSupported (which has FeatureGuard(typeof(RequiresDynamicCodeAttribute)))
// should not produce a warning because both RequiresDynamicCodeAttribute and FeatureGuardAttribute are removed.
if (RuntimeFeature.IsDynamicCodeSupported)
{
UseDynamicCode();
}

// Check that a few attribute instances are indeed removed
CheckRemovedAttributes(typeof(MembersWithRemovedAttributes));

return 100;
}

[RequiresDynamicCode(nameof(UseDynamicCode))]
static void UseDynamicCode() { }

class MembersWithRemovedAttributes
{
static void DynamicallyAccessedMembers([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) { }

[FeatureGuard(typeof(RequiresUnreferencedCodeAttribute))]
static bool FeatureGuard => throw null!;

[FeatureSwitchDefinition("Program.MembersWithRemovedAttributes.FeatureSwitchDefinition")]
static bool FeatureSwitchDefinition => throw null!;

[RequiresDynamicCode(nameof(RequiresDynamicCode))]
static void RequiresDynamicCode() { }

[RequiresUnreferencedCode(nameof(RequiresUnreferencedCode))]
static void RequiresUnreferencedCode() { }
}

static void CheckRemovedAttributes([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type)
{
Console.WriteLine($"Validating {type}");
foreach (var member in type.GetMembers(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
{
CheckRemovedAttributes(member);

if (member is MethodInfo method)
{
foreach (var parameter in method.GetParameters())
{
CheckRemovedAttributes(parameter);
}
}
}
}

static void CheckRemovedAttributes(ICustomAttributeProvider provider)
{
foreach (var attribute in provider.GetCustomAttributes(false))
{
if (attribute is NullableContextAttribute)
continue;

throw new Exception($"Unexpected attribute {attribute.GetType()} on {provider}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))" />

<ItemGroup>
<TestConsoleAppSourceFiles Include="AggressiveAttributeTrimmingTest.cs">
<EnabledProperties>_AggressiveAttributeTrimming</EnabledProperties>
<DisabledProperties>SuppressTrimAnalysisWarnings;TrimmerSingleWarn</DisabledProperties>
</TestConsoleAppSourceFiles>
<TestConsoleAppSourceFiles Include="AppDomainGetThreadGenericPrincipalTest.cs" />
<TestConsoleAppSourceFiles Include="AppDomainGetThreadWindowsPrincipalTest.cs">
<SkipOnTestRuntimes>osx-x64;linux-x64;browser-wasm</SkipOnTestRuntimes>
Expand Down

0 comments on commit 84ad56c

Please sign in to comment.