From 3c186f04bf23a78f2c591d5a2594a9a691e00f10 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Thu, 14 Aug 2025 15:49:31 -0700 Subject: [PATCH 1/6] Add trim analysis for implicit constructors --- .../RequiresUnreferencedCodeAnalyzer.cs | 32 +++++++++++++++++++ .../RequiresExcludeStatics.cs | 1 + .../RequiresCapability/RequiresOnClass.cs | 23 +++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs index 09d2625d56b0aa..4848762cf10e94 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs @@ -36,6 +36,38 @@ public sealed class RequiresUnreferencedCodeAnalyzer : RequiresAnalyzerBase private protected override DiagnosticTargets AnalyzerDiagnosticTargets => DiagnosticTargets.MethodOrConstructor | DiagnosticTargets.Class; + private protected override ImmutableArray<(Action Action, SymbolKind[] SymbolKind)> ExtraSymbolActions => + ImmutableArray.Create<(Action Action, SymbolKind[] SymbolKind)>( + (AnalyzeImplicitBaseCtor, new[] { SymbolKind.NamedType }) + ); + + private void AnalyzeImplicitBaseCtor(SymbolAnalysisContext context) + { + var typeSymbol = (INamedTypeSymbol)context.Symbol; + + if (typeSymbol.TypeKind != TypeKind.Class || typeSymbol.BaseType == null) + return; + + if (typeSymbol.InstanceConstructors.Length != 1 || !typeSymbol.InstanceConstructors[0].IsImplicitlyDeclared) + return; + + var implicitCtor = typeSymbol.InstanceConstructors[0]; + + var baseCtor = typeSymbol.BaseType.InstanceConstructors.FirstOrDefault(ctor => ctor.Parameters.IsEmpty); + if (baseCtor == null) + return; + + var diagnosticContext = new DiagnosticContext( + typeSymbol.Locations[0], + context.ReportDiagnostic); + + CheckAndCreateRequiresDiagnostic( + baseCtor, + implicitCtor, + ImmutableArray.Empty, + diagnosticContext); + } + private protected override DiagnosticDescriptor RequiresDiagnosticRule => s_requiresUnreferencedCodeRule; private protected override DiagnosticId RequiresDiagnosticId => DiagnosticId.RequiresUnreferencedCode; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs index 524a0c0f3a2866..2ec73813dcba42 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs @@ -145,6 +145,7 @@ public static void Test() } } + [ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--")] class DerivedWithoutRequires : BaseWithRequires { [ExpectedWarning("IL2026", "--Requires--")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index 886743417bb549..88b87302559c44 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -36,6 +36,10 @@ public static void Main() AttributeParametersAndProperties.Test(); MembersOnClassWithRequires.Test(); ConstFieldsOnClassWithRequires.Test(); + + // Instantiate classes so linker warnings match analyzer warnings + new TestUnconditionalSuppressMessage(); + new DerivedWithoutRequiresOnType(); } [RequiresUnreferencedCode("Message for --ClassWithRequires--")] @@ -128,6 +132,8 @@ public DerivedFromNestedInRequiresClass() { } public static void StaticMethod() { } } + [ExpectedWarning("IL2026", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] class TestUnconditionalSuppressMessage : ClassWithRequires { public static void StaticMethodInTestSuppressionClass() { } @@ -339,6 +345,8 @@ class BaseWithRequiresOnType public virtual void Method() { } } + [ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] class DerivedWithoutRequiresOnType : BaseWithRequiresOnType { public override void Method() { } @@ -694,6 +702,8 @@ class WithRequiresOnlyInstanceFields public int InstanceField; } + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] class DerivedWithoutRequires : WithRequires { public static int DerivedStaticField; @@ -831,6 +841,9 @@ public static void Test() TestDAMOnTypeAccessInRUCScope(new DAMAnnotatedClassAccessedFromRUCScope()); TestDAMAccessOnOpenGeneric(); TestDAMAccessOnInstantiatedGeneric(); + + // Instantiate for linker test consistency + new DerivedWithoutRequires(); } } @@ -854,6 +867,8 @@ class DerivedRequires : WithRequires private event EventHandler DerivedPrivateInstanceEvent; } + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] class DerivedWithoutRequires : WithRequires { public static event EventHandler DerivedStaticEvent; @@ -1029,6 +1044,9 @@ public static void Test() DerivedRequiresPublicEvents(); DerivedRequiresNonPublicEvents(); DerivedRequiresAllEvents(); + + // Instantiate for linker test consistency + new DerivedWithoutRequires(); } } @@ -1050,6 +1068,8 @@ class WithRequiresOnlyInstanceProperties public int InstanceProperty { get; set; } } + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] class DerivedWithoutRequires : WithRequires { public static int DerivedStaticProperty { get; set; } @@ -1217,6 +1237,9 @@ public static void Test() TestDirectReflectionAccess(); TestDynamicDependencyAccess(); TestDAMOnTypeAccess(new DAMAnnotatedClass()); + + // Instantiate for linker test consistency + new DerivedWithoutRequires(); } } From 1d30cd73a3377a065c8edde0d8e06e688b4a9296 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 15 Aug 2025 10:41:12 -0700 Subject: [PATCH 2/6] Fix RequiresExcludeStatics test --- .../RequiresCapability/RequiresExcludeStatics.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs index 2ec73813dcba42..94c333a5d03511 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs @@ -145,7 +145,8 @@ public static void Test() } } - [ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--")] + [ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Analyzer, "")] + [ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] class DerivedWithoutRequires : BaseWithRequires { [ExpectedWarning("IL2026", "--Requires--")] @@ -158,6 +159,9 @@ public static void Test() { StaticMethod(); DerivedStaticMethod(); + + // Instantiate for linker test consistency + new DerivedWithoutRequires(); } } From eaca747a0e65fe9f2a1168b3c974c577e785caa3 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 15 Aug 2025 11:57:41 -0700 Subject: [PATCH 3/6] Fix test for native AOT --- .../RequiresCapability/RequiresExcludeStatics.cs | 2 ++ .../RequiresCapability/RequiresOnClass.cs | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs index 94c333a5d03511..57b01bb7611fd9 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs @@ -147,6 +147,8 @@ public static void Test() [ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Analyzer, "")] [ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequires : BaseWithRequires { [ExpectedWarning("IL2026", "--Requires--")] diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index 88b87302559c44..078c19307fc6e7 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -134,6 +134,8 @@ public static void StaticMethod() { } [ExpectedWarning("IL2026", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Analyzer, "")] [ExpectedWarning("IL2026", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class TestUnconditionalSuppressMessage : ClassWithRequires { public static void StaticMethodInTestSuppressionClass() { } @@ -347,6 +349,8 @@ public virtual void Method() { } [ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Analyzer, "")] [ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequiresOnType : BaseWithRequiresOnType { public override void Method() { } From f41dd137cb198715b413a19660012b49ccccee35 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 15 Aug 2025 13:10:22 -0700 Subject: [PATCH 4/6] Fix test, move to base analyzer --- .../RequiresAnalyzerBase.cs | 30 ++++++++++++++++++ .../RequiresUnreferencedCodeAnalyzer.cs | 31 ------------------- .../RequiresCapability/RequiresOnClass.cs | 10 ++++-- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs index a8b010bdc292d7..b501fe4e6480a5 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs @@ -128,6 +128,9 @@ public override void Initialize(AnalysisContext context) foreach (var extraSyntaxNodeAction in ExtraSyntaxNodeActions) context.RegisterSyntaxNodeAction(extraSyntaxNodeAction.Action, extraSyntaxNodeAction.SyntaxKind); + // Register the implicit base constructor analysis for all analyzers + context.RegisterSymbolAction(AnalyzeImplicitBaseCtor, SymbolKind.NamedType); + foreach (var extraSymbolAction in ExtraSymbolActions) context.RegisterSymbolAction(extraSymbolAction.Action, extraSymbolAction.SymbolKind); @@ -197,6 +200,33 @@ internal void CheckAndCreateRequiresDiagnostic( CreateRequiresDiagnostic(member, requiresAttribute, diagnosticContext); } + private void AnalyzeImplicitBaseCtor(SymbolAnalysisContext context) + { + var typeSymbol = (INamedTypeSymbol)context.Symbol; + + if (typeSymbol.TypeKind != TypeKind.Class || typeSymbol.BaseType == null) + return; + + if (typeSymbol.InstanceConstructors.Length != 1 || !typeSymbol.InstanceConstructors[0].IsImplicitlyDeclared) + return; + + var implicitCtor = typeSymbol.InstanceConstructors[0]; + + var baseCtor = typeSymbol.BaseType.InstanceConstructors.FirstOrDefault(ctor => ctor.Parameters.IsEmpty); + if (baseCtor == null) + return; + + var diagnosticContext = new DiagnosticContext( + typeSymbol.Locations[0], + context.ReportDiagnostic); + + CheckAndCreateRequiresDiagnostic( + baseCtor, + implicitCtor, + ImmutableArray.Empty, + diagnosticContext); + } + [Flags] protected enum DiagnosticTargets { diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs index 4848762cf10e94..1c05c6f73d8a6d 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs @@ -36,37 +36,6 @@ public sealed class RequiresUnreferencedCodeAnalyzer : RequiresAnalyzerBase private protected override DiagnosticTargets AnalyzerDiagnosticTargets => DiagnosticTargets.MethodOrConstructor | DiagnosticTargets.Class; - private protected override ImmutableArray<(Action Action, SymbolKind[] SymbolKind)> ExtraSymbolActions => - ImmutableArray.Create<(Action Action, SymbolKind[] SymbolKind)>( - (AnalyzeImplicitBaseCtor, new[] { SymbolKind.NamedType }) - ); - - private void AnalyzeImplicitBaseCtor(SymbolAnalysisContext context) - { - var typeSymbol = (INamedTypeSymbol)context.Symbol; - - if (typeSymbol.TypeKind != TypeKind.Class || typeSymbol.BaseType == null) - return; - - if (typeSymbol.InstanceConstructors.Length != 1 || !typeSymbol.InstanceConstructors[0].IsImplicitlyDeclared) - return; - - var implicitCtor = typeSymbol.InstanceConstructors[0]; - - var baseCtor = typeSymbol.BaseType.InstanceConstructors.FirstOrDefault(ctor => ctor.Parameters.IsEmpty); - if (baseCtor == null) - return; - - var diagnosticContext = new DiagnosticContext( - typeSymbol.Locations[0], - context.ReportDiagnostic); - - CheckAndCreateRequiresDiagnostic( - baseCtor, - implicitCtor, - ImmutableArray.Empty, - diagnosticContext); - } private protected override DiagnosticDescriptor RequiresDiagnosticRule => s_requiresUnreferencedCodeRule; diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index 078c19307fc6e7..714bf9a2598fc2 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -349,8 +349,8 @@ public virtual void Method() { } [ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Analyzer, "")] [ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] - [ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Analyzer, "NativeAOT Specific warning")] - [ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RDC", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RDC", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequiresOnType : BaseWithRequiresOnType { public override void Method() { } @@ -708,6 +708,8 @@ class WithRequiresOnlyInstanceFields [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")] [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequires : WithRequires { public static int DerivedStaticField; @@ -873,6 +875,8 @@ class DerivedRequires : WithRequires [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")] [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequires : WithRequires { public static event EventHandler DerivedStaticEvent; @@ -1074,6 +1078,8 @@ class WithRequiresOnlyInstanceProperties [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")] [ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "NativeAOT Specific warning")] + [ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)] class DerivedWithoutRequires : WithRequires { public static int DerivedStaticProperty { get; set; } From 9c8242585edde065fadbd34ef17f8aa9c43ce02d Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 15 Aug 2025 13:15:53 -0700 Subject: [PATCH 5/6] Clean up whitespace --- .../ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs index 1c05c6f73d8a6d..09d2625d56b0aa 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs @@ -36,7 +36,6 @@ public sealed class RequiresUnreferencedCodeAnalyzer : RequiresAnalyzerBase private protected override DiagnosticTargets AnalyzerDiagnosticTargets => DiagnosticTargets.MethodOrConstructor | DiagnosticTargets.Class; - private protected override DiagnosticDescriptor RequiresDiagnosticRule => s_requiresUnreferencedCodeRule; private protected override DiagnosticId RequiresDiagnosticId => DiagnosticId.RequiresUnreferencedCode; From 0e6592a5360bc581d4cb0089792779aa01a8b3d0 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Fri, 15 Aug 2025 13:36:15 -0700 Subject: [PATCH 6/6] Fix RegexLWCGCompiler annotations This was warning on the implicit ctor. --- .../src/System/Text/RegularExpressions/RegexLWCGCompiler.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs index f8fef4984b9663..20dac81c48d75c 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs @@ -8,6 +8,7 @@ namespace System.Text.RegularExpressions { + [RequiresDynamicCode("Compiling a RegEx requires dynamic code.")] internal sealed class RegexLWCGCompiler : RegexCompiler { /// @@ -31,7 +32,6 @@ internal sealed class RegexLWCGCompiler : RegexCompiler private static int s_regexCount; /// The top-level driver. Initializes everything then calls the Generate* methods. - [RequiresDynamicCode("Compiling a RegEx requires dynamic code.")] public RegexRunnerFactory? FactoryInstanceFromCode(string pattern, RegexTree regexTree, RegexOptions options, bool hasTimeout) { if (!regexTree.Root.SupportsCompilation(out _)) @@ -67,7 +67,6 @@ internal sealed class RegexLWCGCompiler : RegexCompiler } /// Begins the definition of a new method (no args) with a specified return value. - [RequiresDynamicCode("Compiling a RegEx requires dynamic code.")] private DynamicMethod DefineDynamicMethod(string methname, Type? returntype, Type hostType, Type[] paramTypes) { // We're claiming that these are static methods, but really they are instance methods.