Skip to content

Commit bbabbc9

Browse files
authored
Don't warn for reflection access to compiler-generated code (#104757)
* Don't warn for reflection access to compiler-generated code * Remove unnecessary suppressions
1 parent 97b13df commit bbabbc9

File tree

13 files changed

+5
-152
lines changed

13 files changed

+5
-152
lines changed

eng/testing/tests.wasm.targets

-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@
3838
<PropertyGroup Condition="'$(EnableAggressiveTrimming)' == 'true'">
3939
<!-- suppress warnings as these are tests, and not expected to be trim-safe -->
4040
<SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
41-
<!-- This warning code isn't yet included in SuppressTrimAnalysisWarnings -->
42-
<NoWarn>$(NoWarn);IL2118</NoWarn>
4341
<!-- IL2121: Unnecessary UnconditionalSuppressMessage attribute -->
4442
<NoWarn>$(NoWarn);IL2121</NoWarn>
4543
</PropertyGroup>

src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs

-3
Original file line numberDiff line numberDiff line change
@@ -648,9 +648,6 @@ public FilterAndTransform(string filterAndPayloadSpec, int startIdx, int endIdx,
648648

649649
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
650650
Justification = "DiagnosticSource.Write is marked with RequiresUnreferencedCode.")]
651-
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2119",
652-
Justification = "DAM on EventSource references this compiler-generated local function which calls a " +
653-
"method that requires unreferenced code. EventSource will not access this local function.")]
654651
void OnEventWritten(KeyValuePair<string, object?> evnt)
655652
{
656653
// The filter given to the DiagnosticSource may not work if users don't is 'IsEnabled' as expected.

src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourceManifestTest.cs

-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ void EventSourceTest_Method_4(){}
3535
int EventSourceTest_Method_7() => 5;
3636
}
3737

38-
[UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2118",
39-
Justification = "DAM on EventSource.GenerateManifest references compiler-generated local function GetTrimSafeTraceLoggingEventTypes " +
40-
"which calls a constructor that requires unreferenced code. EventSource will not access this local function.")]
4138
public static int Main()
4239
{
4340
string manifest = EventSource.GenerateManifest(typeof(EventSourceTest), null);

src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs

-3
Original file line numberDiff line numberDiff line change
@@ -2160,9 +2160,6 @@ private unsafe void WriteEventString(string msgString)
21602160

21612161
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
21622162
Justification = "The call to TraceLoggingEventTypes with the below parameter values are trim safe")]
2163-
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2119",
2164-
Justification = "DAM on EventSource references this compiler-generated local function which calls a " +
2165-
"constructor that requires unreferenced code. EventSource will not access this local function.")]
21662163
static TraceLoggingEventTypes GetTrimSafeTraceLoggingEventTypes() =>
21672164
new TraceLoggingEventTypes(EventName, EventTags.None, new Type[] { typeof(string) });
21682165

src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Type/TypeTests.cs

-3
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,6 @@ public static IEnumerable<object[]> FindMembers_TestData()
149149

150150
[Theory]
151151
[MemberData(nameof(FindMembers_TestData))]
152-
[UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2118",
153-
Justification = "DAM on FindMembers references compiler-generated members which use reflection. " +
154-
"These members are not accessed by the test.")]
155152
public void FindMembers_Invoke_ReturnsExpected(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria, int expectedLength)
156153
{
157154
Assert.Equal(expectedLength, typeof(TypeTests).FindMembers(memberType, bindingAttr, filter, filterCriteria).Length);

src/tools/illink/src/ILLink.Shared/DiagnosticId.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ public enum DiagnosticId
182182
DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithDynamicallyAccessedMembers = 2115,
183183
RequiresUnreferencedCodeOnStaticConstructor = 2116,
184184
MethodsAreAssociatedWithUserMethod = 2117,
185-
CompilerGeneratedMemberAccessedViaReflection = 2118,
186-
DynamicallyAccessedMembersOnTypeReferencesCompilerGeneratedMember = 2119,
187-
DynamicallyAccessedMembersOnTypeReferencesCompilerGeneratedMemberOnBase = 2120,
185+
_unused_CompilerGeneratedMemberAccessedViaReflection = 2118,
186+
_unused_DynamicallyAccessedMembersOnTypeReferencesCompilerGeneratedMember = 2119,
187+
_unused_DynamicallyAccessedMembersOnTypeReferencesCompilerGeneratedMemberOnBase = 2120,
188188
RedundantSuppression = 2121,
189189
TypeNameIsNotAssemblyQualified = 2122,
190190

src/tools/illink/src/linker/Linker.Steps/MarkStep.cs

+2-62
Original file line numberDiff line numberDiff line change
@@ -1616,20 +1616,6 @@ void ReportWarningsForReflectionAccess (in MessageOrigin origin, MethodDefinitio
16161616
break;
16171617
}
16181618
}
1619-
1620-
// Warn on reflection access to compiler-generated methods, if the method isn't already unsafe to access via reflection
1621-
// due to annotations. For the annotation-based warnings, we skip virtual overrides since those will produce warnings on
1622-
// the base, but for unannotated compiler-generated methods this is not the case, so we must produce these warnings even
1623-
// for virtual overrides. This ensures that we include the unannotated MoveNext state machine method. Lambdas and local
1624-
// functions should never be virtual overrides in the first place.
1625-
bool isCoveredByAnnotations = isReflectionAccessCoveredByRUC || isReflectionAccessCoveredByDAM;
1626-
switch (dependencyKind) {
1627-
case DependencyKind.AccessedViaReflection:
1628-
case DependencyKind.DynamicallyAccessedMember:
1629-
if (ShouldWarnForReflectionAccessToCompilerGeneratedCode (method, isCoveredByAnnotations))
1630-
Context.LogWarning (origin, DiagnosticId.CompilerGeneratedMemberAccessedViaReflection, method.GetDisplayName ());
1631-
break;
1632-
}
16331619
}
16341620

16351621
void ReportWarningsForTypeHierarchyReflectionAccess (IMemberDefinition member, MessageOrigin origin)
@@ -1672,23 +1658,6 @@ static bool IsDeclaredWithinType (IMemberDefinition member, TypeDefinition type)
16721658
var id = reportOnMember ? DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberWithDynamicallyAccessedMembers : DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithDynamicallyAccessedMembers;
16731659
Context.LogWarning (origin, id, type.GetDisplayName (), ((MemberReference) member).GetDisplayName ());
16741660
}
1675-
1676-
// Warn on reflection access to compiler-generated methods, if the method isn't already unsafe to access via reflection
1677-
// due to annotations. For the annotation-based warnings, we skip virtual overrides since those will produce warnings on
1678-
// the base, but for unannotated compiler-generated methods this is not the case, so we must produce these warnings even
1679-
// for virtual overrides. This ensures that we include the unannotated MoveNext state machine method. Lambdas and local
1680-
// functions should never be virtual overrides in the first place.
1681-
bool isCoveredByAnnotations = isReflectionAccessCoveredByRUC || isReflectionAccessCoveredByDAM;
1682-
if (member is MethodDefinition method && ShouldWarnForReflectionAccessToCompilerGeneratedCode (method, isCoveredByAnnotations)) {
1683-
var id = reportOnMember ? DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesCompilerGeneratedMember : DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesCompilerGeneratedMemberOnBase;
1684-
Context.LogWarning (origin, id, type.GetDisplayName (), method.GetDisplayName ());
1685-
}
1686-
1687-
// Warn on reflection access to compiler-generated fields.
1688-
if (member is FieldDefinition field && ShouldWarnForReflectionAccessToCompilerGeneratedCode (field, isCoveredByAnnotations)) {
1689-
var id = reportOnMember ? DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesCompilerGeneratedMember : DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesCompilerGeneratedMemberOnBase;
1690-
Context.LogWarning (origin, id, type.GetDisplayName (), field.GetDisplayName ());
1691-
}
16921661
}
16931662

16941663
void MarkField (FieldDefinition field, in DependencyInfo reason, in MessageOrigin origin)
@@ -1752,24 +1721,6 @@ void MarkField (FieldDefinition field, in DependencyInfo reason, in MessageOrigi
17521721
}
17531722
}
17541723

1755-
bool ShouldWarnForReflectionAccessToCompilerGeneratedCode (FieldDefinition field, bool isCoveredByAnnotations)
1756-
{
1757-
// No need to warn if it's already covered by the Requires attribute or explicit annotations on the field.
1758-
if (isCoveredByAnnotations)
1759-
return false;
1760-
1761-
if (!CompilerGeneratedState.IsNestedFunctionOrStateMachineMember (field))
1762-
return false;
1763-
1764-
// Only warn for types which are interesting for dataflow. Note that this does
1765-
// not include integer types, even though we track integers in the dataflow analysis.
1766-
// Technically we should also warn for integer types, but this leads to more warnings
1767-
// for example about the compiler-generated "state" field for state machine methods.
1768-
// This should be ok because in most cases the state machine types will also have other
1769-
// hoisted locals that produce warnings anyway when accessed via reflection.
1770-
return Annotations.FlowAnnotations.IsTypeInterestingForDataflow (field.FieldType);
1771-
}
1772-
17731724
void ProcessAnalysisAnnotationsForField (FieldDefinition field, DependencyKind dependencyKind, in MessageOrigin origin)
17741725
{
17751726
switch (dependencyKind) {
@@ -1790,32 +1741,21 @@ void ProcessAnalysisAnnotationsForField (FieldDefinition field, DependencyKind d
17901741
if (Annotations.ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode (origin.Provider, out _))
17911742
return;
17921743

1793-
bool isReflectionAccessCoveredByRUC;
1794-
if (isReflectionAccessCoveredByRUC = Annotations.ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode (field, out RequiresUnreferencedCodeAttribute? requiresUnreferencedCodeAttribute))
1744+
if (Annotations.ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode (field, out RequiresUnreferencedCodeAttribute? requiresUnreferencedCodeAttribute))
17951745
ReportRequiresUnreferencedCode (field.GetDisplayName (), requiresUnreferencedCodeAttribute!, new DiagnosticContext (origin, diagnosticsEnabled: true, Context));
17961746

1797-
bool isReflectionAccessCoveredByDAM = false;
17981747
switch (dependencyKind) {
17991748
case DependencyKind.AccessedViaReflection:
18001749
case DependencyKind.DynamicDependency:
18011750
case DependencyKind.DynamicallyAccessedMember:
18021751
case DependencyKind.InteropMethodDependency:
18031752
case DependencyKind.Ldtoken:
18041753
case DependencyKind.UnsafeAccessorTarget:
1805-
if (isReflectionAccessCoveredByDAM = Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (field))
1754+
if (Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (field))
18061755
Context.LogWarning (origin, DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection, field.GetDisplayName ());
18071756

18081757
break;
18091758
}
1810-
1811-
switch (dependencyKind) {
1812-
case DependencyKind.AccessedViaReflection:
1813-
case DependencyKind.DynamicallyAccessedMember:
1814-
bool isCoveredByAnnotations = isReflectionAccessCoveredByRUC || isReflectionAccessCoveredByDAM;
1815-
if (ShouldWarnForReflectionAccessToCompilerGeneratedCode (field, isCoveredByAnnotations))
1816-
Context.LogWarning (origin, DiagnosticId.CompilerGeneratedMemberAccessedViaReflection, field.GetDisplayName ());
1817-
break;
1818-
}
18191759
}
18201760

18211761
/// <summary>

src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs

-4
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,6 @@ static void Ldvirtftn ()
333333
[ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))]
334334
[ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))]
335335
[ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))]
336-
[UnexpectedWarning ("IL2118", nameof (LdftnOnLambdaTriggersLamdaAnalysis), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/85042")]
337-
[UnexpectedWarning ("IL2118", nameof (LdftnOnLocalMethodTriggersLocalMethodAnalysis), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/85042")]
338336
static void DynamicallyAccessedMembersAll1 ()
339337
{
340338
typeof (AnnotatedMethodParameters).RequiresAll ();
@@ -347,8 +345,6 @@ static void DynamicallyAccessedMembersAll1 ()
347345
[ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))]
348346
[ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))]
349347
[ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))]
350-
[UnexpectedWarning ("IL2118", nameof (LdftnOnLambdaTriggersLamdaAnalysis), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/85042")]
351-
[UnexpectedWarning ("IL2118", nameof (LdftnOnLocalMethodTriggersLocalMethodAnalysis), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/85042")]
352348
static void DynamicallyAccessedMembersAll2 ()
353349
{
354350
typeof (AnnotatedMethodParameters).RequiresAll ();

0 commit comments

Comments
 (0)