diff options
Diffstat (limited to 'test')
7 files changed, 898 insertions, 29 deletions
diff --git a/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs b/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs index b92038a6a..5e7ccb3dd 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs @@ -71,6 +71,12 @@ namespace ILLink.RoslynAnalyzer.Tests } [Fact] + public Task CompilerGeneratedCodeAccessedViaReflection () + { + return RunTest (); + } + + [Fact] public Task DynamicDependencyDataflow () { return RunTest (nameof (DynamicDependencyDataflow)); diff --git a/test/ILLink.RoslynAnalyzer.Tests/RequiresCapabilityTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresCapabilityTests.cs index 52873a9d0..ad36b4884 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/RequiresCapabilityTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresCapabilityTests.cs @@ -6,7 +6,7 @@ using Xunit; namespace ILLink.RoslynAnalyzer.Tests { - public sealed class RequiresCapabilityTests : LinkerTestBase + public sealed partial class RequiresCapabilityTests : LinkerTestBase { protected override string TestSuiteName => "RequiresCapability"; @@ -17,6 +17,12 @@ namespace ILLink.RoslynAnalyzer.Tests } [Fact] + public Task ReflectionAccessFromCompilerGeneratedCode () + { + return RunTest (); + } + + [Fact] public Task RequiresAccessedThrough () { return RunTest (nameof (RequiresAccessedThrough)); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs b/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs new file mode 100644 index 000000000..1b5f65c7e --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeAccessedViaReflection.cs @@ -0,0 +1,523 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Linq.Expressions; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.DataFlow; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class CompilerGeneratedCodeAccessedViaReflection + { + public static void Main () + { + IteratorStateMachines.Test (); + AsyncStateMachines.Test (); + AsyncIteratorStateMachines.Test (); + Lambdas.Test (); + LocalFunctions.Test (); + } + + class BaseTypeWithIteratorStateMachines + { + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions.RequiresAll), CompilerGeneratedCode = true)] + public static IEnumerable<int> BaseIteratorWithCorrectDataflow () + { + var t = GetAll (); + yield return 0; + t.RequiresAll (); + } + } + + [ExpectedWarning ("IL2120", "<" + nameof (BaseIteratorWithCorrectDataflow) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + class IteratorStateMachines : BaseTypeWithIteratorStateMachines + { + public static IEnumerable<int> IteratorWithoutDataflow () + { + yield return 0; + } + + [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2119", "<" + nameof (IteratorCallsMethodWithRequires) + ">", "MoveNext", CompilerGeneratedCode = true)] + public static IEnumerable<int> IteratorCallsMethodWithRequires () + { + yield return 0; + MethodWithRequires (); + } + + [ExpectedWarning ("IL2119", "<" + nameof (IteratorWithCorrectDataflow) + ">", "MoveNext", CompilerGeneratedCode = true)] + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions.RequiresAll), CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + public static IEnumerable<int> IteratorWithCorrectDataflow () + { + var t = GetAll (); + yield return 0; + t.RequiresAll (); + } + + [ExpectedWarning ("IL2119", "<" + nameof (IteratorWithProblematicDataflow) + ">", "MoveNext", CompilerGeneratedCode = true)] + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions.RequiresAll), CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + public static IEnumerable<int> IteratorWithProblematicDataflow () + { + var t = GetWithPublicMethods (); + yield return 0; + t.RequiresAll (); + } + + [ExpectedWarning ("IL2112", nameof (RUCTypeWithIterators) + "()", "--RUCTypeWithIterators--", CompilerGeneratedCode = true)] + [RequiresUnreferencedCode ("--RUCTypeWithIterators--")] + class RUCTypeWithIterators + { + [ExpectedWarning ("IL2112", nameof (StaticIteratorCallsMethodWithRequires), "--RUCTypeWithIterators--", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2112", "<" + nameof (StaticIteratorCallsMethodWithRequires) + ">", "--RUCTypeWithIterators--", CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] // state machine ctor + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + public static IEnumerable<int> StaticIteratorCallsMethodWithRequires () + { + yield return 0; + MethodWithRequires (); + } + + // BUG: this should also give IL2112 for the InstanceIteratorCallsMethodWithRequires state machine constructor. + // https://github.com/dotnet/linker/issues/2806 + // [ExpectedWarning ("IL2026", "<" + nameof (RUCTypeWithIterators.InstanceIteratorCallsMethodWithRequires) + ">")] + // With that, the IL2119 warning should also go away. + [ExpectedWarning ("IL2119", "<" + nameof (InstanceIteratorCallsMethodWithRequires) + ">", "MoveNext", CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + public IEnumerable<int> InstanceIteratorCallsMethodWithRequires () + { + yield return 0; + MethodWithRequires (); + } + } + + [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithProblematicDataflow) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (IteratorCallsMethodWithRequires) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (IteratorWithCorrectDataflow) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (BaseIteratorWithCorrectDataflow) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", nameof (RUCTypeWithIterators) + "()", "--RUCTypeWithIterators--")] + // Expect to see warnings about RUC on type, for all static state machine members. + [ExpectedWarning ("IL2026", nameof (RUCTypeWithIterators.StaticIteratorCallsMethodWithRequires) + "()", "--RUCTypeWithIterators--")] + [ExpectedWarning ("IL2026", "<" + nameof (RUCTypeWithIterators.StaticIteratorCallsMethodWithRequires) + ">", + ProducedBy = ProducedBy.Trimmer)] + // BUG: this should also give IL2026 for the InstanceIteratorCallsMethodWithRequires state machine constructor. + // https://github.com/dotnet/linker/issues/2806 + // [ExpectedWarning ("IL2026", "<" + nameof (RUCTypeWithIterators.InstanceIteratorCallsMethodWithRequires) + ">")] + // With that, the IL2118 warning should also go away. + [ExpectedWarning ("IL2118", "<" + nameof (RUCTypeWithIterators.InstanceIteratorCallsMethodWithRequires) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + public static void Test (IteratorStateMachines test = null) + { + typeof (IteratorStateMachines).RequiresAll (); + + test.GetType ().RequiresAll (); + } + } + + class AsyncStateMachines + { + public static async Task AsyncWithoutDataflow () + { + } + + [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + public static async Task AsyncCallsMethodWithRequires () + { + MethodWithRequires (); + } + + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions.RequiresAll), CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + public static async Task AsyncWithCorrectDataflow () + { + var t = GetAll (); + t.RequiresAll (); + } + + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions.RequiresAll), CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + public static async Task AsyncWithProblematicDataflow () + { + var t = GetWithPublicMethods (); + t.RequiresAll (); + } + + [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithProblematicDataflow) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncCallsMethodWithRequires) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncWithCorrectDataflow) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + public static void Test () + { + typeof (AsyncStateMachines).RequiresAll (); + } + } + + class AsyncIteratorStateMachines + { + public static async IAsyncEnumerable<int> AsyncIteratorWithoutDataflow () + { + yield return await MethodAsync (); + } + + [ExpectedWarning ("IL2026", "--MethodWithRequires--", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + public static async IAsyncEnumerable<int> AsyncIteratorCallsMethodWithRequires () + { + yield return await MethodAsync (); + MethodWithRequires (); + } + + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions.RequiresAll), CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + public static async IAsyncEnumerable<int> AsyncIteratorWithCorrectDataflow () + { + var t = GetAll (); + yield return await MethodAsync (); + t.RequiresAll (); + } + + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions.RequiresAll), + nameof (AsyncIteratorWithProblematicDataflow), CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + public static async IAsyncEnumerable<int> AsyncIteratorWithProblematicDataflow () + { + var t = GetWithPublicMethods (); + yield return await MethodAsync (); + t.RequiresAll (); + } + + [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithProblematicDataflow) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorCallsMethodWithRequires) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (AsyncIteratorWithCorrectDataflow) + ">", "MoveNext", + ProducedBy = ProducedBy.Trimmer)] + public static void Test () + { + typeof (AsyncIteratorStateMachines).RequiresAll (); + } + } + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + class Lambdas + { + static void LambdaWithoutDataflow () + { + var lambda = () => 0; + lambda (); + } + + static void LambdaCallsMethodWithRequires () + { + var lambda = + [ExpectedWarning ("IL2026", "--MethodWithRequires--")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2119", "<" + nameof (LambdaCallsMethodWithRequires) + ">", + ProducedBy = ProducedBy.Trimmer)] + () => MethodWithRequires (); + lambda (); + } + + static void LambdaWithCorrectDataflow () + { + var lambda = + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2119", "<" + nameof (LambdaWithCorrectDataflow) + ">", + ProducedBy = ProducedBy.Trimmer)] + () => { + var t = GetAll (); + t.RequiresAll (); + }; + lambda (); + } + + [ExpectedWarning ("IL2111", "<" + nameof (LambdaWithCorrectParameter) + ">", + ProducedBy = ProducedBy.Trimmer)] + static void LambdaWithCorrectParameter () + { + var lambda = + [ExpectedWarning ("IL2114", "<" + nameof (LambdaWithCorrectParameter) + ">", + ProducedBy = ProducedBy.Trimmer)] + ([DynamicallyAccessedMembersAttribute (DynamicallyAccessedMemberTypes.All)] Type t) => { + t.RequiresAll (); + }; + lambda (null); + } + + static void LambdaWithProblematicDataflow () + { + var lambda = + [ExpectedWarning ("IL2119", "<" + nameof (LambdaWithProblematicDataflow) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), + ProducedBy = ProducedBy.Trimmer)] + () => { + var t = GetWithPublicMethods (); + t.RequiresAll (); + }; + lambda (); + } + + static void LambdaWithCapturedTypeToDAM () + { + var t = GetWithPublicMethods (); + var lambda = + [ExpectedWarning ("IL2119", "<" + nameof (LambdaWithCapturedTypeToDAM) + ">", + ProducedBy = ProducedBy.Trimmer)] + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions.RequiresAll), + ProducedBy = ProducedBy.Trimmer)] + () => { + t.RequiresAll (); + }; + lambda (); + } + + static void LambdaWithCapturedInt () + { + int i = 0; + var lambda = + () => i; + i++; + lambda (); + } + + [ExpectedWarning ("IL2112", nameof (RUCTypeWithLambdas) + "()", "--RUCTypeWithLambdas--", CompilerGeneratedCode = true)] + [RequiresUnreferencedCode ("--RUCTypeWithLambdas--")] + class RUCTypeWithLambdas + { + public void MethodWithLambdas () + { + var lambda = + [ExpectedWarning ("IL2119", "<" + nameof (MethodWithLambdas) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + () => MethodWithRequires (); + + int i = 0; + var lambdaWithCapturedState = + [ExpectedWarning ("IL2119", "<" + nameof (MethodWithLambdas) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + () => { + i++; + MethodWithRequires (); + }; + + lambda (); + lambdaWithCapturedState (); + } + } + + [ExpectedWarning ("IL2118", "<" + nameof (LambdaCallsMethodWithRequires) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (LambdaWithCorrectDataflow) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", "<" + nameof (LambdaWithCorrectParameter) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (LambdaWithProblematicDataflow) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (LambdaWithCapturedTypeToDAM) + ">", + ProducedBy = ProducedBy.Trimmer)] + // Expect RUC warnings for static, compiler-generated code warnings for instance. + [ExpectedWarning ("IL2026", nameof (RUCTypeWithLambdas) + "()", "--RUCTypeWithLambdas--")] + [ExpectedWarning ("IL2118", "<" + nameof (RUCTypeWithLambdas.MethodWithLambdas) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", "<" + nameof (RUCTypeWithLambdas.MethodWithLambdas) + ">", + ProducedBy = ProducedBy.Trimmer)] + public static void Test (Lambdas test = null) + { + typeof (Lambdas).RequiresAll (); + + test.GetType ().RequiresAll (); + } + } + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + class LocalFunctions + { + static void LocalFunctionWithoutDataflow () + { + int LocalFunction () => 0; + LocalFunction (); + } + + static void LocalFunctionCallsMethodWithRequires () + { + [ExpectedWarning ("IL2026", "--MethodWithRequires--")] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionCallsMethodWithRequires) + ">", + ProducedBy = ProducedBy.Trimmer)] + void LocalFunction () => MethodWithRequires (); + LocalFunction (); + } + + static void LocalFunctionWithCorrectDataflow () + { + [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionWithCorrectDataflow) + ">", + ProducedBy = ProducedBy.Trimmer)] + void LocalFunction () + { + var t = GetAll (); + t.RequiresAll (); + }; + LocalFunction (); + } + + static void LocalFunctionWithProblematicDataflow () + { + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionWithProblematicDataflow) + ">", + ProducedBy = ProducedBy.Trimmer)] + void LocalFunction () + { + var t = GetWithPublicMethods (); + t.RequiresAll (); + }; + LocalFunction (); + } + + static void LocalFunctionWithCapturedTypeToDAM () + { + var t = GetAll (); + [ExpectedWarning ("IL2119", "<" + nameof (LocalFunctionWithCapturedTypeToDAM) + ">", + ProducedBy = ProducedBy.Trimmer)] + // Annotations aren't propagated to hoisted locals: https://github.com/dotnet/linker/issues/2001 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions.RequiresAll), + ProducedBy = ProducedBy.Trimmer)] + void LocalFunction () + { + t.RequiresAll (); + }; + LocalFunction (); + } + + static void LocalFunctionWithCapturedInt () + { + int i = 0; + int LocalFunction () => i; + i++; + LocalFunction (); + } + + [ExpectedWarning ("IL2112", nameof (RUCTypeWithLocalFunctions) + "()", CompilerGeneratedCode = true)] + [RequiresUnreferencedCode ("--RUCTypeWithLocalFunctions--")] + class RUCTypeWithLocalFunctions + { + public void MethodWithLocalFunctions () + { + [ExpectedWarning ("IL2112", "<" + nameof (MethodWithLocalFunctions) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + void LocalFunction () => MethodWithRequires (); + + [ExpectedWarning ("IL2112", "<" + nameof (MethodWithLocalFunctions) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + static void StaticLocalFunction () => MethodWithRequires (); + + int i = 0; + [ExpectedWarning ("IL2112", "<" + nameof (MethodWithLocalFunctions) + ">", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", ProducedBy = ProducedBy.Analyzer)] + void LocalFunctionWithCapturedState () + { + i++; + MethodWithRequires (); + } + + LocalFunction (); + StaticLocalFunction (); + LocalFunctionWithCapturedState (); + } + } + + [ExpectedWarning ("IL2118", nameof (LocalFunctionCallsMethodWithRequires), + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", nameof (LocalFunctionWithCorrectDataflow), + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", nameof (LocalFunctionWithProblematicDataflow), + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", nameof (LocalFunctionWithCapturedTypeToDAM), + ProducedBy = ProducedBy.Trimmer)] + // Expect RUC warnings for static, compiler-generated code warnings for instance. + [ExpectedWarning ("IL2026", nameof (RUCTypeWithLocalFunctions) + "()", "--RUCTypeWithLocalFunctions--")] + [ExpectedWarning ("IL2026", "<" + nameof (RUCTypeWithLocalFunctions.MethodWithLocalFunctions) + ">", "LocalFunctionWithCapturedState", + ProducedBy = ProducedBy.Trimmer)] // displayclass ctor + [ExpectedWarning ("IL2026", "<" + nameof (RUCTypeWithLocalFunctions.MethodWithLocalFunctions) + ">", "StaticLocalFunction", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "<" + nameof (RUCTypeWithLocalFunctions.MethodWithLocalFunctions) + ">", "LocalFunction", + ProducedBy = ProducedBy.Trimmer)] + public static void Test (LocalFunctions test = null) + { + typeof (LocalFunctions).RequiresAll (); + + test.GetType ().RequiresAll (); + } + } + + [RequiresUnreferencedCode ("--MethodWithRequires--")] + [RequiresAssemblyFiles ("--MethodWithRequires--")] + [RequiresDynamicCode ("--MethodWithRequires--")] + static void MethodWithRequires () + { + } + + static async Task<int> MethodAsync () + { + return await Task.FromResult (0); + } + + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + static Type GetWithPublicMethods () => null; + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + static Type GetAll () => null; + } +} diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs new file mode 100644 index 000000000..14fd917fb --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/ReflectionAccessFromCompilerGeneratedCode.cs @@ -0,0 +1,213 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.RequiresCapability +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class ReflectionAccessFromCompilerGeneratedCode + { + public static void Main () + { + ReflectionAccessFromStateMachine.Test (); + ReflectionAccessFromLocalFunction.Test (); + ReflectionAccessFromLambda.Test (); + } + + class ReflectionAccessFromStateMachine + { + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + static IEnumerable<int> TestIterator () + { + typeof (TypeWithMethodWithRequires).RequiresAll (); + yield return 0; + } + + [RequiresUnreferencedCode ("--TestIteratorWithRUC--")] + static IEnumerable<int> TestIteratorWithRUC () + { + typeof (TypeWithMethodWithRequires).RequiresAll (); + yield return 0; + } + + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), CompilerGeneratedCode = true, + ProducedBy = ProducedBy.Trimmer)] + static async void TestAsync () + { + typeof (TypeWithMethodWithRequires).RequiresAll (); + await MethodAsync (); + } + + [RequiresUnreferencedCode ("--TestAsyncWithRUC--")] + static async void TestAsyncWithRUC () + { + typeof (TypeWithMethodWithRequires).RequiresAll (); + await MethodAsync (); + } + + [ExpectedWarning ("IL2026", "--TestIteratorWithRUC--")] + [ExpectedWarning ("IL2026", "--TestAsyncWithRUC--")] + public static void Test () + { + TestIterator (); + TestIteratorWithRUC (); + TestAsync (); + TestAsyncWithRUC (); + } + } + + class ReflectionAccessFromLocalFunction + { + static void TestLocalFunction () + { + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), + ProducedBy = ProducedBy.Trimmer)] + void LocalFunction () + { + typeof (TypeWithMethodWithRequires).RequiresAll (); + } + LocalFunction (); + } + + [ExpectedWarning ("IL2026", "--LocalFunction--")] + static void TestLocalFunctionWithRUC () + { + [RequiresUnreferencedCode ("--LocalFunction--")] + void LocalFunction () + { + typeof (TypeWithMethodWithRequires).RequiresAll (); + } + LocalFunction (); + } + + [RequiresUnreferencedCode ("--TestLocalFunctionInMethodWithRUC--")] + static void TestLocalFunctionInMethodWithRUC () + { + void LocalFunction () + { + typeof (TypeWithMethodWithRequires).RequiresAll (); + } + LocalFunction (); + } + + [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRUC--")] + public static void Test () + { + TestLocalFunction (); + TestLocalFunctionWithRUC (); + TestLocalFunctionInMethodWithRUC (); + } + } + + class ReflectionAccessFromLambda + { + static void TestLambda () + { + var lambda = + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", nameof (TypeWithMethodWithRequires.MethodWithLocalFunctionCallsRUC), "LocalFunction", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (TypeWithMethodWithRequires.MethodWithAnnotations), + ProducedBy = ProducedBy.Trimmer)] + () => { + typeof (TypeWithMethodWithRequires).RequiresAll (); + }; + lambda (); + } + + [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRUC--")] + static void TestLambdaWithRUC () + { + var lambda = + [RequiresUnreferencedCode ("--TestLambdaInMethodWithRUC--")] + () => { + typeof (TypeWithMethodWithRequires).RequiresAll (); + }; + lambda (); + } + + [RequiresUnreferencedCode ("--TestLambdaInMethodWithRUC--")] + static void TestLambdaInMethodWithRUC () + { + var lambda = + () => { + typeof (TypeWithMethodWithRequires).RequiresAll (); + }; + lambda (); + } + + [ExpectedWarning ("IL2026", "--TestLambdaInMethodWithRUC--")] + public static void Test () + { + TestLambda (); + TestLambdaWithRUC (); + TestLambdaInMethodWithRUC (); + } + } + + static async Task<int> MethodAsync () + { + return await Task.FromResult (0); + } + + class TypeWithMethodWithRequires + { + [RequiresUnreferencedCode ("--TypeWithMethodWithRequires.MethodWithRequires--")] + [RequiresAssemblyFiles ("--TypeWithMethodWithRequires.MethodWithRequires--")] + [RequiresDynamicCode ("--TypeWithMethodWithRequires.MethodWithRequires--")] + public static void MethodWithRequires () + { + } + + public static void MethodWithAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type t) { } + + [ExpectedWarning ("IL2026", "--MethodWithLocalFunctionWithRUC.LocalFunction--")] + public static void MethodWithLocalFunctionWithRUC () + { + [RequiresUnreferencedCode ("--MethodWithLocalFunctionWithRUC.LocalFunction--")] + void LocalFunction () + { } + LocalFunction (); + } + + public static void MethodWithLocalFunctionCallsRUC () + { + [ExpectedWarning ("IL2026", "--MethodWithRUC--")] + void LocalFunction () => MethodWithRUC (); + LocalFunction (); + } + } + + [RequiresUnreferencedCode ("--MethodWithRUC--")] + static void MethodWithRUC () { } + } +} diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs index d3f277902..79b795c66 100644 --- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; @@ -618,7 +618,8 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { LocalFunction (); - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--MethodWithRequires--", + ProducedBy = ProducedBy.Trimmer)] void LocalFunction () => typeof (RequiresInCompilerGeneratedCode) .GetMethod ("MethodWithRequires", System.Reflection.BindingFlags.NonPublic) .Invoke (null, new object[] { }); @@ -656,7 +657,8 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { LocalFunction (); - [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", + ProducedBy = ProducedBy.Trimmer)] void LocalFunction () => typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods (); } @@ -869,19 +871,38 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability } } - class DynamicallyAccessedLocalFunctionUnused + class DynamicallyAccessedLocalFunctionUnusedShouldWarn + { + [ExpectedWarning ("IL2118", nameof (TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction), "LocalFunction", ProducedBy = ProducedBy.Trimmer)] + public static void TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction () + { + typeof (DynamicallyAccessedLocalFunctionUnusedShouldWarn).RequiresNonPublicMethods (); + + // The linker isn't able to figure out which user method this local function + // belongs to, but it doesn't warn because it is only accessed via reflection. + // Instead this warns on the reflection access. + [ExpectedWarning ("IL2026", "--MethodWithRequires--", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3002", "--MethodWithRequires--", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--MethodWithRequires--", + ProducedBy = ProducedBy.Analyzer)] + void LocalFunction () => MethodWithRequires (); + } + } + + class DynamicallyAccessedLocalFunctionUnusedShouldSuppress { [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] [RequiresDynamicCode ("Suppress in body")] public static void TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction () { - typeof (DynamicallyAccessedLocalFunctionUnused).RequiresNonPublicMethods (); + typeof (DynamicallyAccessedLocalFunctionUnusedShouldSuppress).RequiresNonPublicMethods (); - // This local function is unused except for the dynamic reference above, - // so the linker isn't able to figure out which user method it belongs to, - // and the warning is not suppressed. - [ExpectedWarning ("IL2026", "--MethodWithRequires--", ProducedBy = ProducedBy.Trimmer)] + // The linker isn't able to figure out which user method this local function + // belongs to, but it doesn't warn because it is only accessed via reflection, + // in a RUC scope. void LocalFunction () => MethodWithRequires (); } } @@ -906,6 +927,26 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [ExpectedWarning ("IL2026")] [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer)] [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer)] + static void TestSuppressionOnLocalFunctionWithAssignment () + { + LocalFunction (); // This will produce a warning since the local function has Requires on it + + [RequiresUnreferencedCode ("Suppress in body")] + [RequiresAssemblyFiles ("Suppress in body")] + [RequiresDynamicCode ("Suppress in body")] + void LocalFunction (Type unknownType = null) + { + MethodWithRequires (); + typeWithNonPublicMethods = unknownType; + } + } + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] + static Type typeWithNonPublicMethods; + + [ExpectedWarning ("IL2026")] + [ExpectedWarning ("IL3002", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", ProducedBy = ProducedBy.Analyzer)] static void TestSuppressionOnLocalFunctionWithNestedLocalFunction () { LocalFunction (); // This will produce a warning since the local function has Requires on it @@ -994,8 +1035,10 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability TestGenericLocalFunctionWithAnnotationsAndClosure<TestType> (); TestCallMethodWithRequiresInLtftnLocalFunction (); DynamicallyAccessedLocalFunction.TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction (); - DynamicallyAccessedLocalFunctionUnused.TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction (); + DynamicallyAccessedLocalFunctionUnusedShouldWarn.TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction (); + DynamicallyAccessedLocalFunctionUnusedShouldSuppress.TestCallMethodWithRequiresInDynamicallyAccessedLocalFunction (); TestSuppressionOnLocalFunction (); + TestSuppressionOnLocalFunctionWithAssignment (); TestSuppressionOnLocalFunctionWithNestedLocalFunction (); TestSuppressionOnOuterAndLocalFunction (); TestSuppressionOnOuterWithSameName.Test (); @@ -1043,6 +1086,20 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability lambda (); } + [ExpectedWarning ("IL2026", "--LambdaWithRequires--")] + [ExpectedWarning ("IL3002", "--LambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--LambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)] + static void TestLambdaWithRequires () + { + Action lambda = + [RequiresUnreferencedCodeAttribute ("--LambdaWithRequires--")] + [RequiresAssemblyFiles ("--LambdaWithRequires--")] + [RequiresDynamicCode ("--LambdaWithRequires--")] + () => MethodWithRequires (); + + lambda (); + } + static void TestCallUnused () { Action _ = @@ -1052,6 +1109,18 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability () => MethodWithRequires (); } + [ExpectedWarning ("IL2026", "--LambdaWithRequires--")] + [ExpectedWarning ("IL3002", "--LambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3050", "--LambdaWithRequires--", ProducedBy = ProducedBy.Analyzer)] + static void TestLambdaWithRequiresUnused () + { + Action _ = + [RequiresUnreferencedCode ("--LambdaWithRequires--")] + [RequiresAssemblyFiles ("--LambdaWithRequires--")] + [RequiresDynamicCode ("--LambdaWithRequires--")] + () => MethodWithRequires (); + } + static void TestCallWithClosure (int p = 0) { Action lambda = @@ -1125,6 +1194,8 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { TestCall (); TestCallUnused (); + TestLambdaWithRequires (); + TestLambdaWithRequiresUnused (); TestCallWithClosure (); TestCallWithClosureUnused (); TestReflectionAccess (); @@ -1390,6 +1461,13 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability MethodWithGenericWhichRequiresMethods<TypeWithMethodWithRequires> (); } + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] + static IEnumerable<int> TestDynamicallyAccessedMethodViaGenericTypeParameterInIterator () + { + yield return 1; + new TypeWithGenericWhichRequiresMethods<TypeWithMethodWithRequires> (); + } + static void TestLocalFunctionInIteratorLocalFunction () { IteratorLocalFunction (); @@ -1428,6 +1506,7 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { TestIteratorLocalFunctionInAsync (); TestDynamicallyAccessedMethodViaGenericMethodParameterInIterator (); + TestDynamicallyAccessedMethodViaGenericTypeParameterInIterator (); TestLocalFunctionInIteratorLocalFunction (); TestLocalFunctionCalledFromIteratorLocalFunctionAndMethod (); } @@ -1716,6 +1795,11 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability // state machine members. [ExpectedWarning ("IL2026", "Requires to suppress", ProducedBy = ProducedBy.Trimmer)] [ExpectedWarning ("IL2026", "Requires to suppress", ProducedBy = ProducedBy.Trimmer)] + // Linker warns about reflection access to compiler-generated state machine members. + [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestAsyncOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2118", nameof (StateMachinesOnlyReferencedViaReflection), "<" + nameof (TestIteratorOnlyReferencedViaReflectionWhichShouldWarn) + ">", "MoveNext()", + ProducedBy = ProducedBy.Trimmer)] static void TestAll () { typeof (StateMachinesOnlyReferencedViaReflection).RequiresAll (); @@ -1751,6 +1835,14 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability void LocalFunction () => MethodWithRequires (); } + static void TestLocalFunctionWithRequiresOnlyAccessedViaReflection () + { + [RequiresUnreferencedCode ("--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--")] + [RequiresAssemblyFiles ("--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--")] + [RequiresDynamicCode ("--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--")] + void LocalFunction () => MethodWithRequires (); + } + [ExpectedWarning ("IL2026", "LocalFunction")] [ExpectedWarning ("IL3002", "LocalFunction", ProducedBy = ProducedBy.Analyzer)] [ExpectedWarning ("IL3050", "LocalFunction", ProducedBy = ProducedBy.Analyzer)] @@ -1778,6 +1870,16 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability void LocalFunction () => MethodWithRequires (); } + [RequiresUnreferencedCode ("--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")] + [RequiresAssemblyFiles ("--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")] + [RequiresDynamicCode ("--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")] + static void TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection () + { + // This is unused, except for the reflection access. Don't warn about MethodWithRequires + // because the reflection access will warn about accessing compiler-generated code. + void LocalFunction () => MethodWithRequires (); + } + [RequiresUnreferencedCode ("--TestLocalFunctionWithClosureInMethodWithRequires--")] [RequiresAssemblyFiles ("--TestLocalFunctionWithClosureInMethodWithRequires--")] [RequiresDynamicCode ("--TestLocalFunctionWithClosureInMethodWithRequires--")] @@ -1795,13 +1897,18 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability // Warnings for Reflection access to methods with Requires [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--")] [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--")] + [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")] // The linker correctly emits warnings about reflection access to local functions with Requires // or which inherit Requires from the containing method. The analyzer doesn't bind to local functions // so does not warn here. [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequires--", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--", ProducedBy = ProducedBy.Trimmer)] [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureWithRequires--", ProducedBy = ProducedBy.Trimmer)] [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)] [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)] + // Linker warns about reflection access to compiler-generated code + [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection), + ProducedBy = ProducedBy.Trimmer)] static void TestAll () { typeof (LocalFunctionsReferencedViaReflection).RequiresAll (); @@ -1810,11 +1917,16 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability // Warnings for Reflection access to methods with Requires [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--")] [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--")] + [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection--")] // NonPublicMethods warns for local functions not emitted into display classes. [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequires--", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--TestLocalFunctionWithRequiresOnlyAccessedViaReflection--", ProducedBy = ProducedBy.Trimmer)] [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureWithRequires--", ProducedBy = ProducedBy.Trimmer)] [ExpectedWarning ("IL2026", "--TestLocalFunctionInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)] [ExpectedWarning ("IL2026", "--TestLocalFunctionWithClosureInMethodWithRequires--", ProducedBy = ProducedBy.Trimmer)] + // Linker warns about reflection access to compiler-generated code + [ExpectedWarning ("IL2118", nameof (LocalFunctionsReferencedViaReflection), "<" + nameof (TestLocalFunctionInMethodWithRequiresOnlyAccessedViaReflection) + ">", + ProducedBy = ProducedBy.Trimmer)] static void TestNonPublicMethods () { typeof (LocalFunctionsReferencedViaReflection).RequiresNonPublicMethods (); @@ -2053,6 +2165,10 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { } + class TypeWithGenericWhichRequiresMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] T> + { + } + class TypeWithGenericWhichRequiresNonPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] T> { } class TestType { } diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index 9cb6e8a50..a0ecc2e51 100644 --- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -719,12 +719,30 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability instance.GetType ().GetField ("publicField"); } + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + class DAMAnnotatedClassAccessedFromRUCScope + { + [ExpectedWarning ("IL2112", "DAMAnnotatedClassAccessedFromRUCScope.RUCMethod", ProducedBy = ProducedBy.Trimmer)] + [RequiresUnreferencedCode ("--RUCMethod--")] + public static void RUCMethod () { } + } + + // RUC on the callsite to GetType should not suppress warnings about the + // attribute on the type. + [RequiresUnreferencedCode ("--TestDAMOnTypeAccessInRUCScope--")] + static void TestDAMOnTypeAccessInRUCScope (DAMAnnotatedClassAccessedFromRUCScope instance = null) + { + instance.GetType ().GetMethod ("RUCMethod"); + } + + [ExpectedWarning ("IL2026", "--TestDAMOnTypeAccessInRUCScope--")] public static void Test () { TestDAMAccess (); TestDirectReflectionAccess (); TestDynamicDependencyAccess (); TestDAMOnTypeAccess (null); + TestDAMOnTypeAccessInRUCScope (); } } diff --git a/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs b/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs index d1e1cc5f6..0c9bd06b1 100644 --- a/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs +++ b/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/SuppressWarningsInCompilerGeneratedCode.cs @@ -279,6 +279,7 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression class DynamicallyAccessedLocalFunction { + [ExpectedWarning ("IL2118", "LocalFunction", ProducedBy = ProducedBy.Trimmer)] [UnconditionalSuppressMessage ("Test", "IL2026")] public static void TestCallRUCMethodInDynamicallyAccessedLocalFunction () { @@ -290,21 +291,6 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression } } - class DynamicallyAccessedLocalFunctionUnused - { - [UnconditionalSuppressMessage ("Test", "IL2026")] - public static void TestCallRUCMethodInDynamicallyAccessedLocalFunction () - { - typeof (DynamicallyAccessedLocalFunctionUnused).RequiresNonPublicMethods (); - - // This local function is unused except for the dynamic reference above, - // so the linker isn't able to figure out which user method it belongs to, - // and the warning is not suppressed. - [ExpectedWarning ("IL2026", "--RequiresUnreferencedCodeMethod--", ProducedBy = ProducedBy.Trimmer)] - void LocalFunction () => RequiresUnreferencedCodeMethod (); - } - } - static void TestSuppressionOnLocalFunction () { LocalFunction (); @@ -370,7 +356,6 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression TestGenericLocalFunctionWithAnnotationsAndClosure<TestType> (); TestCallRUCMethodInLtftnLocalFunction (); DynamicallyAccessedLocalFunction.TestCallRUCMethodInDynamicallyAccessedLocalFunction (); - DynamicallyAccessedLocalFunctionUnused.TestCallRUCMethodInDynamicallyAccessedLocalFunction (); TestSuppressionOnLocalFunction (); TestSuppressionOnOuterAndLocalFunction (); TestSuppressionOnOuterWithSameName.Test (); @@ -441,10 +426,11 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression class DynamicallyAccessedLambda { + [ExpectedWarning ("IL2118", nameof (TestCallRUCMethodInDynamicallyAccessedLambda), ProducedBy = ProducedBy.Trimmer)] [UnconditionalSuppressMessage ("Test", "IL2026")] public static void TestCallRUCMethodInDynamicallyAccessedLambda () { - typeof (DynamicallyAccessedLambda).RequiresNonPublicMethods (); + typeof (DynamicallyAccessedLambda).RequiresAll (); Action lambda = () => RequiresUnreferencedCodeMethod (); @@ -454,10 +440,11 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression class DynamicallyAccessedLambdaUnused { + [ExpectedWarning ("IL2118", nameof (TestCallRUCMethodInDynamicallyAccessedLambda), ProducedBy = ProducedBy.Trimmer)] [UnconditionalSuppressMessage ("Test", "IL2026")] public static void TestCallRUCMethodInDynamicallyAccessedLambda () { - typeof (DynamicallyAccessedLambdaUnused).RequiresNonPublicMethods (); + typeof (DynamicallyAccessedLambdaUnused).RequiresAll (); Action _ = () => RequiresUnreferencedCodeMethod (); } |