Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Boemer <sbomer@gmail.com>2022-06-15 19:28:50 +0300
committerGitHub <noreply@github.com>2022-06-15 19:28:50 +0300
commit226107b9117b9d166e38dd00e30f9ab54399e658 (patch)
tree410de8da2b0f1555d977b78938f7ced082a32c72 /test/Mono.Linker.Tests.Cases
parent2abcee1070e38d2994a25777023dfa61615ea498 (diff)
Analyze implicit indexer reference operations (#2839)
Adds support for `IImplicitIndexerReferenceOperation`, which represents an implicit access to an indexer that uses `System.Index`. Implicit means that there is no `System.Index` accessor in IL, but the compiler supports `System.Index` access via an existing indexer (for example one that takes int) for types that satisfy certain criteria. See https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/ranges#implicit-index-support for details. This operation only showed up in the CFG with a more recent version of the Roslyn APIs, so this includes an update to match the one used in dotnet/runtime. This resulted in a few changes to the generated code that required tweaking some of the test validation: - Delegate cache fields are emitted. This reuses an existing attribute originally designed for mcs, but it has been updated to check for these compiler-generated fields. - `<PrivateImplementationDetails>.ThrowSwitchExpressionException` is emitted for an implicit unhandled case in switch expressions. This change includes a new attribute to check that this is kept in a few of the tests.
Diffstat (limited to 'test/Mono.Linker.Tests.Cases')
-rw-r--r--test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnEvent.cs2
-rw-r--r--test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnEvent.cs2
-rw-r--r--test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnEvent.cs2
-rw-r--r--test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeTypeOnEventIsRemoved.cs2
-rw-r--r--test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UsedAttributeTypeOnEventIsKept.cs2
-rw-r--r--test/Mono.Linker.Tests.Cases/Basic/DelegateBeginInvokeEndInvokePair.cs3
-rw-r--r--test/Mono.Linker.Tests.Cases/Basic/UsedEventIsKept.cs3
-rw-r--r--test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsKept.cs2
-rw-r--r--test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsRemovedWhenUsedFromClass.cs2
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs1
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs82
-rw-r--r--test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/GenericInterfaceWithEvent.cs2
-rw-r--r--test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/SimpleEvent.cs2
-rw-r--r--test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs1
-rw-r--r--test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs2
15 files changed, 99 insertions, 11 deletions
diff --git a/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnEvent.cs b/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnEvent.cs
index 6b9c5ff8e..eaf9a4866 100644
--- a/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnEvent.cs
+++ b/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnEvent.cs
@@ -14,7 +14,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.Csc
[KeptTypeInAssembly ("LibraryWithType.dll", typeof (TypeDefinedInReference))]
[RemovedMemberInAssembly ("LibraryWithType.dll", typeof (TypeDefinedInReference), "Unused()")]
[KeptMemberInAssembly ("LibraryWithAttribute.dll", typeof (AttributeDefinedInReference), ".ctor(System.Type)")]
- [KeptDelegateCacheField ("0")]
+ [KeptDelegateCacheField ("0", nameof (FooOnMyEvent))]
public class OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnEvent
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnEvent.cs b/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnEvent.cs
index 9026e6048..d069585c0 100644
--- a/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnEvent.cs
+++ b/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnEvent.cs
@@ -15,7 +15,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.Csc
[RemovedMemberInAssembly ("LibraryWithType.dll", typeof (TypeDefinedInReference), "Unused()")]
[KeptMemberInAssembly ("LibraryWithAttribute.dll", typeof (AttributeDefinedInReference), ".ctor()")]
[KeptMemberInAssembly ("LibraryWithAttribute.dll", typeof (AttributeDefinedInReference), "FieldType")]
- [KeptDelegateCacheField ("0")]
+ [KeptDelegateCacheField ("0", nameof (FooOnMyEvent))]
public class OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnEvent
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnEvent.cs b/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnEvent.cs
index 5f1791948..83466e847 100644
--- a/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnEvent.cs
+++ b/test/Mono.Linker.Tests.Cases/Attributes/Csc/OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnEvent.cs
@@ -15,7 +15,7 @@ namespace Mono.Linker.Tests.Cases.Attributes.Csc
[RemovedMemberInAssembly ("LibraryWithType.dll", typeof (TypeDefinedInReference), "Unused()")]
[KeptMemberInAssembly ("LibraryWithAttribute.dll", typeof (AttributeDefinedInReference), ".ctor()")]
[KeptMemberInAssembly ("LibraryWithAttribute.dll", typeof (AttributeDefinedInReference), "set_PropertyType(System.Type)")]
- [KeptDelegateCacheField ("0")]
+ [KeptDelegateCacheField ("0", nameof (FooOnMyEvent))]
public class OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnEvent
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeTypeOnEventIsRemoved.cs b/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeTypeOnEventIsRemoved.cs
index ff8775974..c05e9ad30 100644
--- a/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeTypeOnEventIsRemoved.cs
+++ b/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UnusedAttributeTypeOnEventIsRemoved.cs
@@ -5,7 +5,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata;
namespace Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed
{
[SetupLinkerArgument ("--used-attrs-only", "true")]
- [KeptDelegateCacheField ("0")]
+ [KeptDelegateCacheField ("0", nameof (Tmp_Something))]
class UnusedAttributeTypeOnEventIsRemoved
{
static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UsedAttributeTypeOnEventIsKept.cs b/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UsedAttributeTypeOnEventIsKept.cs
index 27d50d3cd..0a5e3cfe3 100644
--- a/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UsedAttributeTypeOnEventIsKept.cs
+++ b/test/Mono.Linker.Tests.Cases/Attributes/OnlyKeepUsed/UsedAttributeTypeOnEventIsKept.cs
@@ -5,7 +5,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata;
namespace Mono.Linker.Tests.Cases.Attributes.OnlyKeepUsed
{
[SetupLinkerArgument ("--used-attrs-only", "true")]
- [KeptDelegateCacheField ("0")]
+ [KeptDelegateCacheField ("0", nameof (Tmp_Something))]
class UsedAttributeTypeOnEventIsKept
{
static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Basic/DelegateBeginInvokeEndInvokePair.cs b/test/Mono.Linker.Tests.Cases/Basic/DelegateBeginInvokeEndInvokePair.cs
index d39ab89d9..99e8e90ae 100644
--- a/test/Mono.Linker.Tests.Cases/Basic/DelegateBeginInvokeEndInvokePair.cs
+++ b/test/Mono.Linker.Tests.Cases/Basic/DelegateBeginInvokeEndInvokePair.cs
@@ -5,6 +5,9 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions;
namespace Mono.Linker.Tests.Cases.Basic
{
+ [KeptDelegateCacheField ("0", nameof (Method))]
+ [KeptDelegateCacheField ("1", nameof (Method))]
+ [KeptDelegateCacheField ("2", nameof (Method))]
class DelegateBeginInvokeEndInvokePair
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Basic/UsedEventIsKept.cs b/test/Mono.Linker.Tests.Cases/Basic/UsedEventIsKept.cs
index 8453f1624..490ffa348 100644
--- a/test/Mono.Linker.Tests.Cases/Basic/UsedEventIsKept.cs
+++ b/test/Mono.Linker.Tests.Cases/Basic/UsedEventIsKept.cs
@@ -3,8 +3,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions;
namespace Mono.Linker.Tests.Cases.Basic
{
- [KeptDelegateCacheField ("0")]
- [KeptDelegateCacheField ("1")]
+ [KeptDelegateCacheField ("0", nameof (Tmp_Bar))]
class UsedEventIsKept
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsKept.cs b/test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsKept.cs
index 099b92ab2..47e45e75e 100644
--- a/test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsKept.cs
+++ b/test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsKept.cs
@@ -3,7 +3,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions;
namespace Mono.Linker.Tests.Cases.Basic
{
- [KeptDelegateCacheField ("0")]
+ [KeptDelegateCacheField ("0", nameof (Bar_Ping))]
class UsedEventOnInterfaceIsKept
{
static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsRemovedWhenUsedFromClass.cs b/test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsRemovedWhenUsedFromClass.cs
index 464db7008..10555f041 100644
--- a/test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsRemovedWhenUsedFromClass.cs
+++ b/test/Mono.Linker.Tests.Cases/Basic/UsedEventOnInterfaceIsRemovedWhenUsedFromClass.cs
@@ -3,7 +3,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions;
namespace Mono.Linker.Tests.Cases.Basic
{
- [KeptDelegateCacheField ("0")]
+ [KeptDelegateCacheField ("0", nameof (Bar_Ping))]
class UsedEventOnInterfaceIsRemovedWhenUsedFromClass
{
static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs b/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs
index d19a1fb82..90c24fd9f 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/NullableAnnotations.cs
@@ -11,6 +11,7 @@ using DAMT = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes;
namespace Mono.Linker.Tests.Cases.DataFlow
{
[ExpectedNoWarnings]
+ [KeptPrivateImplementationDetails ("ThrowSwitchExpressionException")]
class NullableAnnotations
{
[Kept]
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs
index 2128b8e41..15508baca 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs
@@ -45,6 +45,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
BasePropertyAccess.Test ();
AccessReturnedInstanceProperty.Test ();
+
+ ExplicitIndexerAccess.Test ();
+ ImplicitIndexerAccess.Test ();
}
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)]
@@ -653,6 +656,85 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
}
+ class ExplicitIndexerAccess
+ {
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ Type this[Index idx] {
+ get => throw new NotImplementedException ();
+ set => throw new NotImplementedException ();
+ }
+
+ [ExpectedWarning ("IL2072", "this[Index].get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = ProducedBy.Analyzer)]
+ [ExpectedWarning ("IL2072", "Item.get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = ProducedBy.Trimmer)]
+ static void TestRead (ExplicitIndexerAccess instance = null)
+ {
+ instance[new Index (1)].RequiresAll ();
+ }
+
+ [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "this[Index].set", ProducedBy = ProducedBy.Analyzer)]
+ [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "Item.set", ProducedBy = ProducedBy.Trimmer)]
+ static void TestWrite (ExplicitIndexerAccess instance = null)
+ {
+ instance[^1] = GetTypeWithPublicConstructors ();
+ }
+
+ public static void Test ()
+ {
+ TestRead ();
+ TestWrite ();
+ }
+ }
+
+ class ImplicitIndexerAccess
+ {
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
+ Type this[int idx] {
+ get => throw new NotImplementedException ();
+ set => throw new NotImplementedException ();
+ }
+
+ int Length => throw new NotImplementedException ();
+
+ [ExpectedWarning ("IL2072", "this[Int32].get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = ProducedBy.Analyzer)]
+ [ExpectedWarning ("IL2072", "Item.get", nameof (DataFlowTypeExtensions.RequiresAll), ProducedBy = ProducedBy.Trimmer)]
+ static void TestRead (ImplicitIndexerAccess instance = null)
+ {
+ instance[new Index (1)].RequiresAll ();
+ }
+
+ [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "this[Int32].set", ProducedBy = ProducedBy.Analyzer)]
+ [ExpectedWarning ("IL2072", nameof (GetTypeWithPublicConstructors), "Item.set", ProducedBy = ProducedBy.Trimmer)]
+ static void TestWrite (ImplicitIndexerAccess instance = null)
+ {
+ instance[^1] = GetTypeWithPublicConstructors ();
+ }
+
+ [ExpectedWarning ("IL2072", nameof (GetUnknownType), "this[Int32].set", ProducedBy = ProducedBy.Analyzer)]
+ [ExpectedWarning ("IL2072", nameof (GetUnknownType), "Item.set", ProducedBy = ProducedBy.Trimmer)]
+ static void TestNullCoalescingAssignment (ImplicitIndexerAccess instance = null)
+ {
+ instance[new Index (1)] ??= GetUnknownType ();
+ }
+
+ [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll))]
+ static void TestSpanIndexerAccess (int start = 0, int end = 3)
+ {
+ Span<byte> bytes = stackalloc byte[4] { 1, 2, 3, 4 };
+ bytes[^4] = 0; // This calls the get indexer which has a ref return.
+ int index = bytes[0];
+ Type[] types = new Type[] { GetUnknownType () };
+ types[index].RequiresAll ();
+ }
+
+ public static void Test ()
+ {
+ TestRead ();
+ TestWrite ();
+ TestNullCoalescingAssignment ();
+ TestSpanIndexerAccess ();
+ }
+ }
+
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
private static Type GetTypeWithPublicParameterlessConstructor ()
{
diff --git a/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/GenericInterfaceWithEvent.cs b/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/GenericInterfaceWithEvent.cs
index e8856be3b..ec4a75670 100644
--- a/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/GenericInterfaceWithEvent.cs
+++ b/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/GenericInterfaceWithEvent.cs
@@ -2,7 +2,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions;
namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMember
{
- [KeptDelegateCacheField ("0")]
+ [KeptDelegateCacheField ("0", nameof (EventMethod))]
public class GenericInterfaceWithEvent
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/SimpleEvent.cs b/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/SimpleEvent.cs
index 11e5860a6..98597a4b2 100644
--- a/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/SimpleEvent.cs
+++ b/test/Mono.Linker.Tests.Cases/Inheritance.Interfaces/OnReferenceType/BaseProvidesInterfaceMember/SimpleEvent.cs
@@ -2,7 +2,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions;
namespace Mono.Linker.Tests.Cases.Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMember
{
- [KeptDelegateCacheField ("0")]
+ [KeptDelegateCacheField ("0", nameof (EventMethod))]
public class SimpleEvent
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs
index 10ac90435..5489497a8 100644
--- a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs
+++ b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs
@@ -10,6 +10,7 @@ namespace Mono.Linker.Tests.Cases.Reflection
[SetupCSharpCompilerToUse ("csc")]
[Reference ("System.Core.dll")]
[ExpectedNoWarnings]
+ [KeptPrivateImplementationDetails ("ThrowSwitchExpressionException")]
public class ExpressionCallString
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs
index 906f56ab4..5bec60d50 100644
--- a/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs
+++ b/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs
@@ -9,6 +9,8 @@ namespace Mono.Linker.Tests.Cases.Reflection
{
[KeptMember (".cctor()")]
[ExpectedNoWarnings ()]
+ [KeptDelegateCacheField ("0", nameof (AssemblyResolver))]
+ [KeptDelegateCacheField ("1", nameof (GetTypeFromAssembly))]
public class TypeUsedViaReflection
{
public static void Main ()