Skip to content

Commit cbfd526

Browse files
[release/10.0-rc1] Add trim analysis for implicit constructors (#118854)
* Add trim analysis for implicit constructors * Fix RequiresExcludeStatics test * Fix test for native AOT * Fix test, move to base analyzer * Clean up whitespace * Fix RegexLWCGCompiler annotations This was warning on the implicit ctor. --------- Co-authored-by: Sven Boemer <sbomer@gmail.com>
1 parent 13f9524 commit cbfd526

File tree

4 files changed

+71
-2
lines changed

4 files changed

+71
-2
lines changed

src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexLWCGCompiler.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
namespace System.Text.RegularExpressions
1010
{
11+
[RequiresDynamicCode("Compiling a RegEx requires dynamic code.")]
1112
internal sealed class RegexLWCGCompiler : RegexCompiler
1213
{
1314
/// <summary>
@@ -31,7 +32,6 @@ internal sealed class RegexLWCGCompiler : RegexCompiler
3132
private static int s_regexCount;
3233

3334
/// <summary>The top-level driver. Initializes everything then calls the Generate* methods.</summary>
34-
[RequiresDynamicCode("Compiling a RegEx requires dynamic code.")]
3535
public RegexRunnerFactory? FactoryInstanceFromCode(string pattern, RegexTree regexTree, RegexOptions options, bool hasTimeout)
3636
{
3737
if (!regexTree.Root.SupportsCompilation(out _))
@@ -67,7 +67,6 @@ internal sealed class RegexLWCGCompiler : RegexCompiler
6767
}
6868

6969
/// <summary>Begins the definition of a new method (no args) with a specified return value.</summary>
70-
[RequiresDynamicCode("Compiling a RegEx requires dynamic code.")]
7170
private DynamicMethod DefineDynamicMethod(string methname, Type? returntype, Type hostType, Type[] paramTypes)
7271
{
7372
// We're claiming that these are static methods, but really they are instance methods.

src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ public override void Initialize(AnalysisContext context)
128128
foreach (var extraSyntaxNodeAction in ExtraSyntaxNodeActions)
129129
context.RegisterSyntaxNodeAction(extraSyntaxNodeAction.Action, extraSyntaxNodeAction.SyntaxKind);
130130

131+
// Register the implicit base constructor analysis for all analyzers
132+
context.RegisterSymbolAction(AnalyzeImplicitBaseCtor, SymbolKind.NamedType);
133+
131134
foreach (var extraSymbolAction in ExtraSymbolActions)
132135
context.RegisterSymbolAction(extraSymbolAction.Action, extraSymbolAction.SymbolKind);
133136

@@ -197,6 +200,33 @@ internal void CheckAndCreateRequiresDiagnostic(
197200
CreateRequiresDiagnostic(member, requiresAttribute, diagnosticContext);
198201
}
199202

203+
private void AnalyzeImplicitBaseCtor(SymbolAnalysisContext context)
204+
{
205+
var typeSymbol = (INamedTypeSymbol)context.Symbol;
206+
207+
if (typeSymbol.TypeKind != TypeKind.Class || typeSymbol.BaseType == null)
208+
return;
209+
210+
if (typeSymbol.InstanceConstructors.Length != 1 || !typeSymbol.InstanceConstructors[0].IsImplicitlyDeclared)
211+
return;
212+
213+
var implicitCtor = typeSymbol.InstanceConstructors[0];
214+
215+
var baseCtor = typeSymbol.BaseType.InstanceConstructors.FirstOrDefault(ctor => ctor.Parameters.IsEmpty);
216+
if (baseCtor == null)
217+
return;
218+
219+
var diagnosticContext = new DiagnosticContext(
220+
typeSymbol.Locations[0],
221+
context.ReportDiagnostic);
222+
223+
CheckAndCreateRequiresDiagnostic(
224+
baseCtor,
225+
implicitCtor,
226+
ImmutableArray<ISymbol>.Empty,
227+
diagnosticContext);
228+
}
229+
200230
[Flags]
201231
protected enum DiagnosticTargets
202232
{

src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresExcludeStatics.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ public static void Test()
145145
}
146146
}
147147

148+
[ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Analyzer, "")]
149+
[ExpectedWarning("IL2026", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)]
150+
[ExpectedWarning("IL3050", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.Analyzer, "NativeAOT Specific warning")]
151+
[ExpectedWarning("IL3050", "BaseWithRequires.BaseWithRequires()", "--BaseWithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)]
148152
class DerivedWithoutRequires : BaseWithRequires
149153
{
150154
[ExpectedWarning("IL2026", "--Requires--")]
@@ -157,6 +161,9 @@ public static void Test()
157161
{
158162
StaticMethod();
159163
DerivedStaticMethod();
164+
165+
// Instantiate for linker test consistency
166+
new DerivedWithoutRequires();
160167
}
161168
}
162169

src/tools/illink/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ public static void Main()
3636
AttributeParametersAndProperties.Test();
3737
MembersOnClassWithRequires<int>.Test();
3838
ConstFieldsOnClassWithRequires.Test();
39+
40+
// Instantiate classes so linker warnings match analyzer warnings
41+
new TestUnconditionalSuppressMessage();
42+
new DerivedWithoutRequiresOnType();
3943
}
4044

4145
[RequiresUnreferencedCode("Message for --ClassWithRequires--")]
@@ -128,6 +132,10 @@ public DerivedFromNestedInRequiresClass() { }
128132
public static void StaticMethod() { }
129133
}
130134

135+
[ExpectedWarning("IL2026", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Analyzer, "")]
136+
[ExpectedWarning("IL2026", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)]
137+
[ExpectedWarning("IL3050", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.Analyzer, "NativeAOT Specific warning")]
138+
[ExpectedWarning("IL3050", "ClassWithRequires.ClassWithRequires()", "--ClassWithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)]
131139
class TestUnconditionalSuppressMessage : ClassWithRequires
132140
{
133141
public static void StaticMethodInTestSuppressionClass() { }
@@ -339,6 +347,10 @@ class BaseWithRequiresOnType
339347
public virtual void Method() { }
340348
}
341349

350+
[ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Analyzer, "")]
351+
[ExpectedWarning("IL2026", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RUC", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)]
352+
[ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RDC", Tool.Analyzer, "NativeAOT Specific warning")]
353+
[ExpectedWarning("IL3050", "BaseWithRequiresOnType.BaseWithRequiresOnType()", "RDC", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)]
342354
class DerivedWithoutRequiresOnType : BaseWithRequiresOnType
343355
{
344356
public override void Method() { }
@@ -694,6 +706,10 @@ class WithRequiresOnlyInstanceFields
694706
public int InstanceField;
695707
}
696708

709+
[ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")]
710+
[ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)]
711+
[ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "NativeAOT Specific warning")]
712+
[ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)]
697713
class DerivedWithoutRequires : WithRequires
698714
{
699715
public static int DerivedStaticField;
@@ -831,6 +847,9 @@ public static void Test()
831847
TestDAMOnTypeAccessInRUCScope(new DAMAnnotatedClassAccessedFromRUCScope());
832848
TestDAMAccessOnOpenGeneric();
833849
TestDAMAccessOnInstantiatedGeneric();
850+
851+
// Instantiate for linker test consistency
852+
new DerivedWithoutRequires();
834853
}
835854
}
836855

@@ -854,6 +873,10 @@ class DerivedRequires : WithRequires
854873
private event EventHandler DerivedPrivateInstanceEvent;
855874
}
856875

876+
[ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")]
877+
[ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)]
878+
[ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "NativeAOT Specific warning")]
879+
[ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)]
857880
class DerivedWithoutRequires : WithRequires
858881
{
859882
public static event EventHandler DerivedStaticEvent;
@@ -1029,6 +1052,9 @@ public static void Test()
10291052
DerivedRequiresPublicEvents();
10301053
DerivedRequiresNonPublicEvents();
10311054
DerivedRequiresAllEvents();
1055+
1056+
// Instantiate for linker test consistency
1057+
new DerivedWithoutRequires();
10321058
}
10331059
}
10341060

@@ -1050,6 +1076,10 @@ class WithRequiresOnlyInstanceProperties
10501076
public int InstanceProperty { get; set; }
10511077
}
10521078

1079+
[ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "")]
1080+
[ExpectedWarning("IL2026", "WithRequires.WithRequires()", "--WithRequires--", Tool.Trimmer | Tool.NativeAot, "", CompilerGeneratedCode = true)]
1081+
[ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.Analyzer, "NativeAOT Specific warning")]
1082+
[ExpectedWarning("IL3050", "WithRequires.WithRequires()", "--WithRequires--", Tool.NativeAot, "NativeAOT Specific warning", CompilerGeneratedCode = true)]
10531083
class DerivedWithoutRequires : WithRequires
10541084
{
10551085
public static int DerivedStaticProperty { get; set; }
@@ -1217,6 +1247,9 @@ public static void Test()
12171247
TestDirectReflectionAccess();
12181248
TestDynamicDependencyAccess();
12191249
TestDAMOnTypeAccess(new DAMAnnotatedClass());
1250+
1251+
// Instantiate for linker test consistency
1252+
new DerivedWithoutRequires();
12201253
}
12211254
}
12221255

0 commit comments

Comments
 (0)