diff options
author | Sven Boemer <sbomer@gmail.com> | 2022-02-01 03:23:30 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-01 03:23:30 +0300 |
commit | fe0eb5bc3bd99d5aa0dcfad4e7dd3ee7549d724b (patch) | |
tree | c01a6222a3e80d7e26dc71850781c23b8f9dc928 | |
parent | d99b0cc5c3169279350e8da4c0961fc70f95aed6 (diff) |
Fix analyzer nullref on assembly attribute (#2530)
The analyzer runs for property assignment operations, including those in
attributes. To check whether the property assignment should warn, we
look for RUC on the containing symbol. However, assembly-level attributes
are contained in the global namespace, which has a null containing type.
3 files changed, 67 insertions, 4 deletions
diff --git a/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs b/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs index 1c54e3af9..5d9b221c5 100644 --- a/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs +++ b/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs @@ -54,7 +54,8 @@ namespace ILLink.RoslynAnalyzer if (member is ISymbol containingSymbol) { if (containingSymbol.HasAttribute (requiresAttribute) || (containingSymbol is not ITypeSymbol && - containingSymbol.ContainingType.HasAttribute (requiresAttribute))) { + containingSymbol.ContainingType is ITypeSymbol containingType && + containingType.HasAttribute (requiresAttribute))) { return true; } } diff --git a/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs index 501ba16f9..bdd6db8ca 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs @@ -423,5 +423,20 @@ class C return VerifyRequiresUnreferencedCodeAnalyzer (source); } + + [Fact] + public Task TestPropertyAssignmentInAssemblyAttribute () + { + var source = @" +using System; +[assembly: MyAttribute (Value = 5)] + +class MyAttribute : Attribute +{ + public int Value { get; set; } +} +"; + return VerifyRequiresUnreferencedCodeAnalyzer (source); + } } } diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttributeCtor.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttributeCtor.cs index d2c6ec8ff..41733e6c9 100644 --- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttributeCtor.cs +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnAttributeCtor.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -15,7 +15,8 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [ExpectedNoWarnings] public class RequiresOnAttributeCtor { - [ExpectedWarning ("IL2026", "Message from attribute's ctor.")] + [ExpectedWarning ("IL2026", "RUC on MethodAnnotatedWithRequires")] + [ExpectedWarning ("IL2026", "RUC on TestTypeWithRequires")] public static void Main () { var type = new Type (); @@ -27,6 +28,17 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability type.EventAdd -= (sender, e) => { }; type.EventRemove += (sender, e) => { }; Type.Interface annotatedInterface = new Type.NestedType (); + + TestTypeWithRequires (); + } + + [RequiresUnreferencedCode ("RUC on TestTypeWithRequires")] + public static void TestTypeWithRequires () + { + var typeWithRequires = new TypeWithRequires (); + typeWithRequires.Method (); + TypeWithRequires.StaticMethod (); + TypeWithRequires.Interface annotatedInterface = new TypeWithRequires.NestedType (); } [ExpectedWarning ("IL2026", "Message from attribute's ctor.")] @@ -40,7 +52,7 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { } - [RequiresUnreferencedCode ("Message from attribute's ctor.")] + [RequiresUnreferencedCode ("RUC on MethodAnnotatedWithRequires")] [RequiresOnAttributeCtor] public void MethodAnnotatedWithRequires () { @@ -82,6 +94,41 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability { } + [ExpectedWarning ("IL2026", "Message from attribute's ctor.")] + [RequiresOnAttributeCtor] + public class NestedType : Interface + { + } + } + + // https://github.com/dotnet/linker/issues/2529 + [ExpectedWarning ("IL2026", "Message from attribute's ctor.", ProducedBy = ProducedBy.Trimmer)] + [RequiresUnreferencedCode ("RUC on TypeWithRequires")] + [RequiresOnAttributeCtor] + public class TypeWithRequires + { + // https://github.com/dotnet/linker/issues/2529 + [ExpectedWarning ("IL2026", "Message from attribute's ctor.", ProducedBy = ProducedBy.Analyzer)] + [RequiresOnAttributeCtor] + public void Method () + { + } + + // https://github.com/dotnet/linker/issues/2529 + [ExpectedWarning ("IL2026", "Message from attribute's ctor.", ProducedBy = ProducedBy.Analyzer)] + [RequiresOnAttributeCtor] + public static void StaticMethod () + { + } + + [ExpectedWarning ("IL2026", "Message from attribute's ctor.")] + [RequiresOnAttributeCtor] + public interface Interface + { + } + + [ExpectedWarning ("IL2026", "Message from attribute's ctor.")] + [RequiresOnAttributeCtor] public class NestedType : Interface { } |