private readonly NodeFactory _factory;
private readonly FlowAnnotations _annotations;
private readonly MessageOrigin _origin;
+ private readonly DiagnosticContext _diagnosticContext;
public AttributeDataFlow(Logger logger, NodeFactory factory, FlowAnnotations annotations, in MessageOrigin origin)
{
_factory = factory;
_logger = logger;
_origin = origin;
+
+ _diagnosticContext = new DiagnosticContext(
+ _origin,
+ _logger.ShouldSuppressAnalysisWarningsForRequires(_origin.MemberDefinition, DiagnosticUtilities.RequiresUnreferencedCodeAttribute),
+ _logger.ShouldSuppressAnalysisWarningsForRequires(_origin.MemberDefinition, DiagnosticUtilities.RequiresDynamicCodeAttribute),
+ _logger.ShouldSuppressAnalysisWarningsForRequires(_origin.MemberDefinition, DiagnosticUtilities.RequiresAssemblyFilesAttribute),
+ _logger);
}
public DependencyList? ProcessAttributeDataflow(MethodDesc method, CustomAttributeValue arguments)
{
DependencyList? result = null;
+ ReflectionMethodBodyScanner.CheckAndReportAllRequires(_diagnosticContext, method);
+
// First do the dataflow for the constructor parameters if necessary.
if (_annotations.RequiresDataflowAnalysisDueToSignature(method))
{
FieldDesc field = attributeType.GetField(namedArgument.Name);
if (field != null)
{
+ ReflectionMethodBodyScanner.CheckAndReportAllRequires(_diagnosticContext, field);
+
ProcessAttributeDataflow(field, namedArgument.Value, ref result);
}
}
MethodDesc setter = property.SetMethod;
if (setter != null && setter.Signature.Length > 0 && !setter.Signature.IsStatic)
{
+ ReflectionMethodBodyScanner.CheckAndReportAllRequires(_diagnosticContext, setter);
+
ProcessAttributeDataflow(setter, ImmutableArray.Create(namedArgument.Value), ref result);
}
}
if (parameterValue.DynamicallyAccessedMemberTypes != DynamicallyAccessedMemberTypes.None)
{
MultiValue value = GetValueForCustomAttributeArgument(arguments[parameter.MetadataIndex]);
- var diagnosticContext = new DiagnosticContext(_origin, diagnosticsEnabled: true, _logger);
- RequireDynamicallyAccessedMembers(diagnosticContext, value, parameterValue, method.GetDisplayName(), ref result);
+ RequireDynamicallyAccessedMembers(_diagnosticContext, value, parameterValue, method.GetDisplayName(), ref result);
}
}
}
- public void ProcessAttributeDataflow(FieldDesc field, object? value, ref DependencyList? result)
+ private void ProcessAttributeDataflow(FieldDesc field, object? value, ref DependencyList? result)
{
var fieldValueCandidate = _annotations.GetFieldValue(field);
if (fieldValueCandidate is ValueWithDynamicallyAccessedMembers fieldValue
&& fieldValue.DynamicallyAccessedMemberTypes != DynamicallyAccessedMemberTypes.None)
{
MultiValue valueNode = GetValueForCustomAttributeArgument(value);
- var diagnosticContext = new DiagnosticContext(_origin, diagnosticsEnabled: true, _logger);
- RequireDynamicallyAccessedMembers(diagnosticContext, valueNode, fieldValue, field.GetDisplayName(), ref result);
+ RequireDynamicallyAccessedMembers(_diagnosticContext, valueNode, fieldValue, field.GetDisplayName(), ref result);
}
}
using System.Text;
using System.Threading.Tasks;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Helpers;
namespace Mono.Linker.Tests.Cases.RequiresCapability
{
- [IgnoreTestCase ("Ignore in NativeAOT, see https://github.com/dotnet/runtime/issues/82447", IgnoredBy = Tool.NativeAot)]
[SkipKeptItemsValidation]
[ExpectedNoWarnings]
class RequiresOnAttribute
{
+ // Using these as a simple way to suppress all warning in Main
+ // it causes lot of warning due to DAM marking everything in the class.
+ [RequiresUnreferencedCode ("main")]
+ [RequiresDynamicCode ("main")]
+ [RequiresAssemblyFiles ("main")]
public static void Main ()
{
TestRequiresOnAttributeOnGenericParameter ();
_fieldWithAttributeWhichRequires = 0;
PropertyWithAttributeWhichRequires = false;
TestMethodWhichRequiresWithAttributeWhichRequires ();
+ RequiresTriggeredByAttributeUsage.Test ();
+
+ // Accessing the members to test via direct calls/access is not enough
+ // in NativeAOT custom attributes are only looked at if the member is
+ // reflection enabled - so there has to be a reflection access to it somewhere.
+ // On the other hand the analyzer reports RDC/RAF only on direct access. So we need to have "both"
+ typeof (RequiresOnAttribute).RequiresAll ();
}
+
class AttributeWhichRequiresAttribute : Attribute
{
[RequiresUnreferencedCode ("Message for --AttributeWhichRequiresAttribute.ctor--")]
}
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
class GenericTypeWithAttributedParameter<[AttributeWhichRequires] T>
{
public static void TestMethod () { }
}
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
static void GenericMethodWithAttributedParameter<[AttributeWhichRequires] T> () { }
static void TestRequiresOnAttributeOnGenericParameter ()
}
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
[AttributeWhichRequires]
[AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)]
class TypeWithAttributeWhichRequires
}
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
[AttributeWhichRequires]
[AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)]
static void MethodWithAttributeWhichRequires () { }
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
[AttributeWhichRequires]
[AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)]
static int _fieldWithAttributeWhichRequires;
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer)]
+ // https://github.com/dotnet/runtime/issues/83581
+ [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Trimmer)] // Trimmer can produce duplicate warnings for property access
+ [ExpectedWarning ("IL2026", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Trimmer)] // Trimmer can produce duplicate warnings for property access
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresAttribute.ctor--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
[ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--")]
- [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Trimmer)] // Trimmer can produce duplicate warnings for property access
+ [ExpectedWarning ("IL2026", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Trimmer)] // Trimmer can produce duplicate warnings for property access
+ [ExpectedWarning ("IL3002", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--AttributeWhichRequiresOnPropertyAttribute.PropertyWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
[AttributeWhichRequires]
[AttributeWhichRequiresOnProperty (PropertyWhichRequires = true)]
static bool PropertyWithAttributeWhichRequires { get; set; }
static void MethodWhichRequiresWithAttributeWhichRequires () { }
[ExpectedWarning ("IL2026", "--MethodWhichRequiresWithAttributeWhichRequires--")]
- [ExpectedWarning ("IL3002", "--MethodWhichRequiresWithAttributeWhichRequires--", ProducedBy = Tool.Analyzer)]
- [ExpectedWarning ("IL3050", "--MethodWhichRequiresWithAttributeWhichRequires--", ProducedBy = Tool.Analyzer)]
+ [ExpectedWarning ("IL3002", "--MethodWhichRequiresWithAttributeWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--MethodWhichRequiresWithAttributeWhichRequires--", ProducedBy = Tool.Analyzer | Tool.NativeAot)]
static void TestMethodWhichRequiresWithAttributeWhichRequires ()
{
MethodWhichRequiresWithAttributeWhichRequires ();
}
+
+ class RequiresTriggeredByAttributeUsage
+ {
+ class AttributeWhichMarksPublicMethods : Attribute
+ {
+ public AttributeWhichMarksPublicMethods ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { }
+ }
+
+ class TypeWithMethodWhichRequires
+ {
+ [RequiresUnreferencedCode ("--TypeWithMethodWhichRequires--")]
+ [RequiresDynamicCode ("--TypeWithMethodWhichRequires--")]
+ [RequiresAssemblyFiles ("--TypeWithMethodWhichRequires--")]
+ public void MethodWhichRequires () { }
+ }
+
+ [ExpectedWarning ("IL2026", "--TypeWithMethodWhichRequires--")]
+ [ExpectedWarning ("IL3002", "--TypeWithMethodWhichRequires--", ProducedBy = Tool.NativeAot)]
+ [ExpectedWarning ("IL3050", "--TypeWithMethodWhichRequires--", ProducedBy = Tool.NativeAot)]
+ [AttributeWhichMarksPublicMethods (typeof(TypeWithMethodWhichRequires))]
+ static void ShouldWarn()
+ {
+ }
+
+ [RequiresUnreferencedCode ("test")]
+ [RequiresDynamicCode ("test")]
+ [RequiresAssemblyFiles ("test")]
+ [AttributeWhichMarksPublicMethods (typeof (TypeWithMethodWhichRequires))]
+ static void SuppressedDueToRequires()
+ {
+ }
+
+ [UnconditionalSuppressMessage("test", "IL2026")]
+ [UnconditionalSuppressMessage ("test", "IL3002")]
+ [UnconditionalSuppressMessage ("test", "IL3050")]
+ public static void Test()
+ {
+ ShouldWarn ();
+ SuppressedDueToRequires ();
+ }
+ }
}
}