Skip to content

Commit ee3ca1b

Browse files
authored
Trimming: Add tests for handling of annotated string type names representing generic instantiations (#95143)
This change: * Adds new tests which validate behavior of generic parameter data flow when the type is specified as a string in either an annotated parameter or Type.GetType * This found new issues in both the analyzer and NativeAOT * #95140 * #95118 * Adds a test for invalid type name in the same situation - this is basically another test for #94830 (And the related fix in #95109) * Fixes test names in the NativeAOT test infra for the shared tests * Enable the generic parameter data flow warnings test full validation in the analyzer * This surfaced a lot of issues in the analyzer around generic parameter data flow - #95121
1 parent f0bd9db commit ee3ca1b

File tree

8 files changed

+223
-105
lines changed

8 files changed

+223
-105
lines changed

src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestCase.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public TestCase (NPath sourceFile, NPath rootCasesDirectory, NPath originalTestC
2323
DisplayName = sourceFile.FileNameWithoutExtension == "Program" && sourceFile.Parent.FileName == originalTestCaseAssemblyPath.FileNameWithoutExtension
2424
? displayNameBase
2525
: $"{displayNameBase}.{sourceFile.FileNameWithoutExtension}";
26+
if (DisplayName.StartsWith("."))
27+
DisplayName = DisplayName.Substring(1);
2628

2729
// A little hacky, but good enough for name. No reason why namespace & type names
2830
// should not follow the directory structure

src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestSuites.cs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,28 @@ public void InlineArrays(string t)
3737
Run(t);
3838
}
3939

40-
[Theory]
41-
[MemberData(nameof(TestDatabase.Inheritance_Interaces), MemberType = typeof(TestDatabase))]
42-
public void Inheritance_Interfaces(string t)
43-
{
44-
switch (t) {
45-
case ".InterfaceWithoutNewSlot":
46-
Run (t);
47-
break;
48-
default:
49-
// Skip the rest for now
50-
break;
51-
}
52-
}
53-
54-
[Theory]
55-
[MemberData(nameof(TestDatabase.Libraries), MemberType = typeof(TestDatabase))]
56-
public void Libraries(string t)
57-
{
58-
Run(t);
59-
}
60-
61-
[Theory]
40+
[Theory]
41+
[MemberData(nameof(TestDatabase.Inheritance_Interaces), MemberType = typeof(TestDatabase))]
42+
public void Inheritance_Interfaces(string t)
43+
{
44+
switch (t) {
45+
case ".InterfaceWithoutNewSlot":
46+
Run (t);
47+
break;
48+
default:
49+
// Skip the rest for now
50+
break;
51+
}
52+
}
53+
54+
[Theory]
55+
[MemberData(nameof(TestDatabase.Libraries), MemberType = typeof(TestDatabase))]
56+
public void Libraries(string t)
57+
{
58+
Run(t);
59+
}
60+
61+
[Theory]
6262
[MemberData (nameof (TestDatabase.LinkXml), MemberType = typeof (TestDatabase))]
6363
public void LinkXml (string t)
6464
{
@@ -73,6 +73,7 @@ public void Reflection (string t)
7373
case "TypeHierarchyReflectionWarnings":
7474
case "ParametersUsedViaReflection":
7575
case "UnsafeAccessor":
76+
case "TypeUsedViaReflection":
7677
Run (t);
7778
break;
7879
default:

src/tools/illink/src/ILLink.RoslynAnalyzer/TrimAnalysis/RequireDynamicallyAccessedMembersAction.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public RequireDynamicallyAccessedMembersAction (
2424
public partial bool TryResolveTypeNameAndMark (string typeName, bool needsAssemblyName, out TypeProxy type)
2525
{
2626
// TODO: Implement type name resolution to type symbol
27+
// https://github.com/dotnet/runtime/issues/95118
2728

2829
// Important corner cases:
2930
// IL2105 (see it's occurences in the tests) - non-assembly qualified type name which doesn't resolve warns

src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,13 @@ public Task FileScopedClasses ()
164164
[Fact]
165165
public Task GenericParameterDataFlow ()
166166
{
167-
return RunTest (nameof (GenericParameterDataFlow));
167+
return RunTest ();
168+
}
169+
170+
[Fact]
171+
public Task GenericParameterWarningLocation ()
172+
{
173+
return RunTest ();
168174
}
169175

170176
[Fact]

src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ public Task GenericParameterDataFlowMarking ()
1919
return RunTest (allowMissingWarnings: true);
2020
}
2121

22-
[Fact]
23-
public Task GenericParameterWarningLocation ()
24-
{
25-
return RunTest (allowMissingWarnings: true);
26-
}
27-
2822
[Fact]
2923
public Task MethodByRefParameterDataFlow ()
3024
{

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ public static void TestKeepsPublicMethods ()
5555

5656
[Kept]
5757
[KeptAttributeAttribute (typeof (KeepsPublicMethodsAttribute))]
58-
// Trimmer/NativeAot only for now - https://github.com/dotnet/linker/issues/2273
59-
[ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethodsKeptByName--", ProducedBy = Tool.Trimmer | Tool.NativeAot)]
58+
// Trimmer/NativeAot only for now - https://github.com/dotnet/runtime/issues/95118
59+
[ExpectedWarning ("IL2026", "--ClassWithKeptPublicMethodsKeptByName--", ProducedBy = Tool.Trimmer | Tool.NativeAot)]
6060
[KeepsPublicMethods (TypeName = "Mono.Linker.Tests.Cases.DataFlow.AttributePropertyDataflow+AttributesOnMethod+ClassWithKeptPublicMethodsKeptByName")]
6161
public static void TestKeepsPublicMethodsByName ()
6262
{

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

Lines changed: 163 additions & 65 deletions
Large diffs are not rendered by default.

src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ public static void Main ()
4141
TestTypeOverloadWith5ParametersWithIgnoreCase ();
4242
TestTypeOverloadWith5ParametersWithoutIgnoreCase ();
4343
TestInvalidTypeName ();
44-
TestUnkownIgnoreCase3Params (1);
45-
TestUnkownIgnoreCase5Params (1);
44+
TestUnknownIgnoreCase3Params (1);
45+
TestUnknownIgnoreCase5Params (1);
4646
TestGenericTypeWithAnnotations ();
4747

4848
BaseTypeInterfaces.Test ();
49+
50+
51+
TestInvalidTypeCombination ();
4952
}
5053

5154
[Kept]
@@ -327,8 +330,9 @@ static void TestTypeOverloadWith4Parameters ()
327330
public class OverloadWith5ParametersWithIgnoreCase { }
328331

329332
[Kept]
330-
// Small difference in formatting between analyzer/linker
333+
// Small difference in formatting between analyzer/NativeAOT/linker
331334
[ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean)'", ProducedBy = Tool.Trimmer)]
335+
[ExpectedWarning ("IL2096", "'System.Type.GetType(String,Func`2<AssemblyName,Assembly>,Func`4<Assembly,String,Boolean,Type>,Boolean,Boolean)'", ProducedBy = Tool.NativeAot)]
332336
[ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func<AssemblyName, Assembly>, Func<Assembly, String, Boolean, Type>, Boolean, Boolean)'", ProducedBy = Tool.Analyzer)]
333337
static void TestTypeOverloadWith5ParametersWithIgnoreCase ()
334338
{
@@ -371,18 +375,19 @@ static Type GetTypeFromAssembly (Assembly assembly, string name, bool caseSensit
371375

372376
[Kept]
373377
[ExpectedWarning ("IL2096", "'System.Type.GetType(String, Boolean, Boolean)'")]
374-
static void TestUnkownIgnoreCase3Params (int num)
378+
static void TestUnknownIgnoreCase3Params (int num)
375379
{
376380
const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
377381
bool unknownValue = num + 1 == 1;
378382
var typeKept = Type.GetType (reflectionTypeKeptString, false, unknownValue);
379383
}
380384

381385
[Kept]
382-
// Small difference in formatting between analyzer/linker
386+
// Small difference in formatting between analyzer/NativeAOT/linker
383387
[ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean)'", ProducedBy = Tool.Trimmer)]
388+
[ExpectedWarning ("IL2096", "'System.Type.GetType(String,Func`2<AssemblyName,Assembly>,Func`4<Assembly,String,Boolean,Type>,Boolean,Boolean)'", ProducedBy = Tool.NativeAot)]
384389
[ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func<AssemblyName, Assembly>, Func<Assembly, String, Boolean, Type>, Boolean, Boolean)'", ProducedBy = Tool.Analyzer)]
385-
static void TestUnkownIgnoreCase5Params (int num)
390+
static void TestUnknownIgnoreCase5Params (int num)
386391
{
387392
const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
388393
bool unknownValue = num + 1 == 1;
@@ -399,9 +404,10 @@ public class GenericTypeWithAnnotations_OuterType<
399404
[Kept]
400405
public class GenericTypeWithAnnotations_InnerType
401406
{
402-
[Kept]
407+
// NativeAOT: https://github.com/dotnet/runtime/issues/95140
408+
[Kept (By = Tool.Trimmer)]
403409
[KeptBackingField]
404-
private static bool PrivateProperty { [Kept] get; [Kept] set; }
410+
private static bool PrivateProperty { [Kept (By = Tool.Trimmer)] get; [Kept (By = Tool.Trimmer)] set; }
405411

406412
private static void PrivateMethod () { }
407413
}
@@ -421,7 +427,7 @@ class BaseTypeInterfaces
421427
[Kept]
422428
interface ITest
423429
{
424-
[Kept]
430+
[Kept (By = Tool.Trimmer)]
425431
void Method ();
426432
}
427433

@@ -450,5 +456,15 @@ public static void Test ()
450456
typeof (DerivedType).GetInterfaces ();
451457
}
452458
}
459+
460+
[Kept]
461+
static void TestInvalidTypeCombination ()
462+
{
463+
try {
464+
// It's invalid to create an array of Span
465+
// This should throw at runtime, but should not warn nor fail the compilation
466+
Console.WriteLine (Type.GetType ("System.Span`1[[System.Byte, System.Runtime]][], System.Runtime"));
467+
} catch (Exception e) { }
468+
}
453469
}
454470
}

0 commit comments

Comments
 (0)