diff options
author | Vitek Karas <vitek.karas@microsoft.com> | 2021-06-17 15:04:44 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-17 15:04:44 +0300 |
commit | bee7f73564e495e6ab8627e7c595dacc32a4b096 (patch) | |
tree | efa4d4c7116898b736223e24b431843f124bb668 /src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs | |
parent | 4f68312aeb4b8b906bee4e06438020ad6721c522 (diff) |
Warning suppressions in compiler generated code (#2075)
This change implements the following high-level functionality:
* `UnconditionalSuppressMessage` applies to the entire method body even for iterators, async methods
* `RequiresUnreferencedCode` automatically suppresses trim analysis warnings from entire method body for iterators, async methods
Solution approach:
* Detect compiler generated code by using the `IteratorStateMachineAttribute`, `AsyncStateMachineAttribute` and `AyncIteratorStateMachineAttribute`.
* When a method which is compiler generated (detected by looing for `<` in its name) is processed the original "user method" is determined by looking for a method with the "state machine" attribute pointing to the compiler generated type.
* This information is cached to avoid duplication of relatively expensive detection logic.
* Looks for `UnconditionalSuppressMessage` and `RequriesUnreferencedCode` in:
* If the warning origin is not a compiler generated code - simply use the warning origin (method) - existing behavior
* If the warning origin is compiler generated use both the origin as well as the user defined method (non-compiler-generated) which is the source of the code for the compiler generated origin
This is done by storing additional `SuppressionContextMember` on `MessageOrigin` which should always point to non-compiler-generated item.
Added lot of new tests for these scenarios.
This implements warning suppression part of https://github.com/mono/linker/issues/2001 for state machines.
Diffstat (limited to 'src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs')
-rw-r--r-- | src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs index a453702d0..582bde492 100644 --- a/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs @@ -59,9 +59,12 @@ namespace Mono.Linker.Dataflow return context.Annotations.FlowAnnotations.RequiresDataFlowAnalysis (fieldDefinition); } - bool ShouldEnableReflectionPatternReporting (MethodDefinition method) + bool ShouldEnableReflectionPatternReporting () { - return !_context.Annotations.HasLinkerAttribute<RequiresUnreferencedCodeAttribute> (method); + if (_markStep.ShouldSuppressAnalysisWarningsForRequiresUnreferencedCode ()) + return false; + + return true; } public ReflectionMethodBodyScanner (LinkContext context, MarkStep parent, MarkScopeStack scopeStack) @@ -79,7 +82,7 @@ namespace Mono.Linker.Dataflow var method = methodBody.Method; var requiredMemberTypes = _context.Annotations.FlowAnnotations.GetReturnParameterAnnotation (method); if (requiredMemberTypes != 0) { - var reflectionContext = new ReflectionPatternContext (_context, ShouldEnableReflectionPatternReporting (method), _scopeStack.CurrentScope.Origin, method.MethodReturnType); + var reflectionContext = new ReflectionPatternContext (_context, ShouldEnableReflectionPatternReporting (), _scopeStack.CurrentScope.Origin, method.MethodReturnType); reflectionContext.AnalyzingPattern (); RequireDynamicallyAccessedMembers (ref reflectionContext, requiredMemberTypes, MethodReturnValue, method.MethodReturnType); reflectionContext.Dispose (); @@ -151,9 +154,8 @@ namespace Mono.Linker.Dataflow ValueNode valueNode = GetTypeValueNodeFromGenericArgument (genericArgument); var currentScopeOrigin = _scopeStack.CurrentScope.Origin; - bool enableReflectionPatternReporting = !(currentScopeOrigin.MemberDefinition is MethodDefinition sourceMethod) || ShouldEnableReflectionPatternReporting (sourceMethod); - var reflectionContext = new ReflectionPatternContext (_context, enableReflectionPatternReporting, currentScopeOrigin, genericParameter); + var reflectionContext = new ReflectionPatternContext (_context, ShouldEnableReflectionPatternReporting (), currentScopeOrigin, genericParameter); reflectionContext.AnalyzingPattern (); RequireDynamicallyAccessedMembers (ref reflectionContext, annotation, valueNode, genericParameter); reflectionContext.Dispose (); @@ -228,7 +230,7 @@ namespace Mono.Linker.Dataflow var requiredMemberTypes = _context.Annotations.FlowAnnotations.GetFieldAnnotation (field); if (requiredMemberTypes != 0) { _scopeStack.UpdateCurrentScopeInstructionOffset (operation.Offset); - var reflectionContext = new ReflectionPatternContext (_context, ShouldEnableReflectionPatternReporting (method), _scopeStack.CurrentScope.Origin, field, operation); + var reflectionContext = new ReflectionPatternContext (_context, ShouldEnableReflectionPatternReporting (), _scopeStack.CurrentScope.Origin, field, operation); reflectionContext.AnalyzingPattern (); RequireDynamicallyAccessedMembers (ref reflectionContext, requiredMemberTypes, valueToStore, field); reflectionContext.Dispose (); @@ -241,7 +243,7 @@ namespace Mono.Linker.Dataflow if (requiredMemberTypes != 0) { ParameterDefinition parameter = method.Parameters[index - (method.HasImplicitThis () ? 1 : 0)]; _scopeStack.UpdateCurrentScopeInstructionOffset (operation.Offset); - var reflectionContext = new ReflectionPatternContext (_context, ShouldEnableReflectionPatternReporting (method), _scopeStack.CurrentScope.Origin, parameter, operation); + var reflectionContext = new ReflectionPatternContext (_context, ShouldEnableReflectionPatternReporting (), _scopeStack.CurrentScope.Origin, parameter, operation); reflectionContext.AnalyzingPattern (); RequireDynamicallyAccessedMembers (ref reflectionContext, requiredMemberTypes, valueToStore, parameter); reflectionContext.Dispose (); @@ -649,7 +651,7 @@ namespace Mono.Linker.Dataflow _scopeStack.UpdateCurrentScopeInstructionOffset (operation.Offset); var reflectionContext = new ReflectionPatternContext ( _context, - ShouldEnableReflectionPatternReporting (callingMethodDefinition), + ShouldEnableReflectionPatternReporting (), _scopeStack.CurrentScope.Origin, calledMethodDefinition, operation); |