diff options
-rw-r--r-- | src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs | 44 | ||||
-rw-r--r-- | test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs | 17 |
2 files changed, 47 insertions, 14 deletions
diff --git a/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs b/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs index 0225087e8..24b81e832 100644 --- a/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs +++ b/src/ILLink.RoslynAnalyzer/TrimAnalysis/TrimAnalysisVisitor.cs @@ -55,19 +55,8 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis // If the return value is empty (TopValue basically) and the Operation tree // reports it as having a constant value, use that as it will automatically cover // cases we don't need/want to handle. - if (operation != null && returnValue.IsEmpty () && operation.ConstantValue.HasValue) { - object? constantValue = operation.ConstantValue.Value; - if (constantValue == null) - return NullValue.Instance; - else if (operation.Type?.SpecialType == SpecialType.System_String && constantValue is string stringConstantValue) - return new KnownStringValue (stringConstantValue); - else if (operation.Type?.TypeKind == TypeKind.Enum && constantValue is int enumConstantValue) - return new ConstIntValue (enumConstantValue); - else if (operation.Type?.SpecialType == SpecialType.System_Int32 && constantValue is int intConstantValue) - return new ConstIntValue (intConstantValue); - else if (operation.Type?.SpecialType == SpecialType.System_Boolean && constantValue is bool boolConstantValue) - return new ConstIntValue (boolConstantValue ? 1 : 0); - } + if (operation != null && returnValue.IsEmpty () && TryGetConstantValue (operation, out var constValue)) + return constValue; return returnValue; } @@ -139,6 +128,9 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis } } + if (TryGetConstantValue (fieldRef, out var constValue)) + return constValue; + if (fieldRef.Field.Type.IsTypeInterestingForDataflow ()) return new FieldValue (fieldRef.Field); @@ -297,5 +289,31 @@ namespace ILLink.RoslynAnalyzer.TrimAnalysis ); } } + + static bool TryGetConstantValue (IOperation operation, out MultiValue constValue) + { + if (operation.ConstantValue.HasValue) { + object? constantValue = operation.ConstantValue.Value; + if (constantValue == null) { + constValue = NullValue.Instance; + return true; + } else if (operation.Type?.SpecialType == SpecialType.System_String && constantValue is string stringConstantValue) { + constValue = new KnownStringValue (stringConstantValue); + return true; + } else if (operation.Type?.TypeKind == TypeKind.Enum && constantValue is int enumConstantValue) { + constValue = new ConstIntValue (enumConstantValue); + return true; + } else if (operation.Type?.SpecialType == SpecialType.System_Int32 && constantValue is int intConstantValue) { + constValue = new ConstIntValue (intConstantValue); + return true; + } else if (operation.Type?.SpecialType == SpecialType.System_Boolean && constantValue is bool boolConstantValue) { + constValue = new ConstIntValue (boolConstantValue ? 1 : 0); + return true; + } + } + + constValue = default; + return false; + } } } diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs index dff625716..ef58eac31 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs @@ -34,6 +34,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow TestStringEmpty (); TypeWithWarnings.Test (); + OverConstTypeName.Test (); // TODO: // Test multi-value returns @@ -163,7 +164,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow class TypeWithWarnings { - [RequiresUnreferencedCode ("--Method1--")] public void Method1 () { } @@ -179,6 +179,21 @@ namespace Mono.Linker.Tests.Cases.DataFlow } } + class OverConstTypeName + { + private const string s_ConstTypeName = "Mono.Linker.Tests.Cases.DataFlow." + nameof (GetTypeDataFlow) + "+" + nameof (OverConstTypeName); + + [RequiresUnreferencedCode ("--Method1--")] + public void Method1 () { } + + // https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2026", "--Method1--", ProducedBy = ProducedBy.Trimmer)] + public static void Test () + { + Type.GetType (s_ConstTypeName).RequiresPublicMethods (); + } + } + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] private static string GetStringTypeWithPublicParameterlessConstructor () { |