diff --git a/eng/Versions.props b/eng/Versions.props
index ea29c2eae231..cef1af03cc2b 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -25,6 +25,7 @@
$(MicrosoftCodeAnalysisVersion)
1.0.1-beta1.*
3.3.2
+ 7.0.0-preview.7.22375.6
diff --git a/external/cecil b/external/cecil
index 2cd569a98964..1840b7410d37 160000
--- a/external/cecil
+++ b/external/cecil
@@ -1 +1 @@
-Subproject commit 2cd569a98964629b8fa88284a8b5af8077d5f9de
+Subproject commit 1840b7410d37a613e684b6f9650e39e2d4950bbb
diff --git a/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs b/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs
index f47097cc475d..c4504332e9b9 100644
--- a/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs
+++ b/src/ILLink.RoslynAnalyzer/RequiresISymbolExtensions.cs
@@ -72,6 +72,15 @@ private static bool IsInRequiresScope (this ISymbol member, string requiresAttri
if (checkAssociatedSymbol && member is IMethodSymbol { AssociatedSymbol: { } associated } && associated.HasAttribute (requiresAttribute))
return true;
+ // When using instance fields suppress the warning if the constructor has already the Requires annotation
+ if (member is IFieldSymbol field && !field.IsStatic) {
+ foreach (var constructor in field.ContainingType.InstanceConstructors) {
+ if (!constructor.HasAttribute (requiresAttribute))
+ return false;
+ }
+ return true;
+ }
+
return false;
}
}
diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs
index 66733c12a402..81b4b5909001 100644
--- a/src/linker/Linker.Steps/MarkStep.cs
+++ b/src/linker/Linker.Steps/MarkStep.cs
@@ -59,7 +59,7 @@ protected LinkContext Context {
}
protected Queue<(MethodDefinition, DependencyInfo, MessageOrigin)> _methods;
- protected List<(MethodDefinition, MarkScopeStack.Scope)> _virtual_methods;
+ protected HashSet<(MethodDefinition, MarkScopeStack.Scope)> _virtual_methods;
protected Queue _assemblyLevelAttributes;
readonly List _ivt_attributes;
protected Queue<(AttributeProviderPair, DependencyInfo, MarkScopeStack.Scope)> _lateMarkedAttributes;
@@ -224,7 +224,7 @@ internal DynamicallyAccessedMembersTypeHierarchy DynamicallyAccessedMembersTypeH
public MarkStep ()
{
_methods = new Queue<(MethodDefinition, DependencyInfo, MessageOrigin)> ();
- _virtual_methods = new List<(MethodDefinition, MarkScopeStack.Scope)> ();
+ _virtual_methods = new HashSet<(MethodDefinition, MarkScopeStack.Scope)> ();
_assemblyLevelAttributes = new Queue ();
_ivt_attributes = new List ();
_lateMarkedAttributes = new Queue<(AttributeProviderPair, DependencyInfo, MarkScopeStack.Scope)> ();
@@ -3352,7 +3352,6 @@ void MarkBaseMethods (MethodDefinition method)
if (base_method.DeclaringType.IsInterface && !method.DeclaringType.IsInterface) {
// These are all virtual, no need to check IsVirtual before adding to list
_virtual_methods.Add ((base_method, ScopeStack.CurrentScope));
- // _virtual_methods is a list and might have duplicates, but it's mostly just used for override validation, so it shouldn't matter
continue;
}
diff --git a/test/Mono.Linker.Tests.Cases/Attributes/GenericAttributes.cs b/test/Mono.Linker.Tests.Cases/Attributes/GenericAttributes.cs
new file mode 100644
index 000000000000..430fbc71417d
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/Attributes/GenericAttributes.cs
@@ -0,0 +1,69 @@
+using System;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+namespace Mono.Linker.Tests.Cases.Attributes
+{
+ class GenericAttributes
+ {
+ static void Main ()
+ {
+ new WithGenericAttribute_OfString ();
+ new WithGenericAttribute_OfInt ();
+ new WithConstrainedGenericAttribute ();
+ }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (GenericAttribute))]
+ [KeptMember (".ctor()")]
+ [GenericAttribute("t", F = "f", P = "p")]
+ class WithGenericAttribute_OfString {
+ }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (GenericAttribute))]
+ [KeptMember (".ctor()")]
+ [GenericAttribute(1, F = 2, P = 3)]
+ class WithGenericAttribute_OfInt {
+ }
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (ConstrainedGenericAttribute))]
+ [KeptMember (".ctor()")]
+ [ConstrainedGenericAttribute()]
+ class WithConstrainedGenericAttribute {
+ }
+
+ [KeptBaseType (typeof (Attribute))]
+ class GenericAttribute : Attribute {
+ [Kept]
+ public GenericAttribute(T t) {}
+
+ [Kept]
+ public T F;
+
+ [Kept]
+ [KeptBackingField]
+ public T P {
+ get;
+ [Kept]
+ set;
+ }
+ }
+
+ [Kept]
+ class ConstraintType {
+ }
+
+ [KeptBaseType (typeof (ConstraintType))]
+ class DerivedFromConstraintType : ConstraintType {
+ }
+
+ [KeptBaseType (typeof (Attribute))]
+ class ConstrainedGenericAttribute : Attribute
+ where T : ConstraintType {
+ [Kept]
+ public ConstrainedGenericAttribute() {}
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs
index 262e9b3f72b4..9e4df4cbcc51 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs
@@ -351,6 +351,7 @@ public static void Test ()
TestWithMultipleArgumentsWithRequirements ();
+ StaticInterfaceMethods.Test ();
NewConstraint.Test ();
StructConstraint.Test ();
UnmanagedConstraint.Test ();
@@ -631,7 +632,6 @@ static void TestWithRequirementsFromGenericParam<
.MakeGenericMethod (typeof (T));
}
-
static void TestWithRequirementsViaRuntimeMethod ()
{
typeof (MakeGenericMethod).GetRuntimeMethod (nameof (GenericWithRequirements), Type.EmptyTypes)
@@ -750,6 +750,36 @@ static void GenericWithMultipleArgumentsWithRequirements<
{
}
+ class StaticInterfaceMethods
+ {
+ public static void Test ()
+ {
+ KnownType ();
+ UnannotatedGenericParam ();
+ AnnotatedGenericParam ();
+ }
+
+ static MethodInfo KnownType ()
+ => typeof (IFoo).GetMethod ("Method")
+ .MakeGenericMethod (new Type[] { typeof (int) });
+
+ [ExpectedWarning ("IL2090", "T", "PublicMethods")]
+ static MethodInfo UnannotatedGenericParam ()
+ => typeof (IFoo).GetMethod ("Method")
+ .MakeGenericMethod (new Type[] { typeof (T) });
+
+ static MethodInfo AnnotatedGenericParam<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ()
+ => typeof (IFoo).GetMethod ("Method")
+ .MakeGenericMethod (new Type[] { typeof (T) });
+
+ interface IFoo
+ {
+ static abstract T Method<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ();
+ }
+ }
+
class NewConstraint
{
static void GenericWithNewConstraint () where T : new()
diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs
index a0ecc2e51a81..44de82e7f7c9 100644
--- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs
+++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs
@@ -25,6 +25,7 @@ public static void Main ()
TestRequiresOnBaseButNotOnDerived ();
TestRequiresOnDerivedButNotOnBase ();
TestRequiresOnBaseAndDerived ();
+ TestInstanceFieldSuppression ();
TestSuppressionsOnClass ();
TestStaticMethodOnRequiresTypeSuppressedByRequiresOnMethod ();
TestStaticConstructorCalls ();
@@ -246,6 +247,22 @@ static void TestInstanceFieldCallDontWarn ()
var _ = instance.field;
}
+ public class ClassWithInstanceFieldWhichInitsDangerousClass
+ {
+ private ClassWithRequires _instanceField = new ClassWithRequires ();
+
+ [RequiresUnreferencedCode ("Calling the constructor is dangerous")]
+ [RequiresDynamicCode ("Calling the constructor is dangerous")]
+ public ClassWithInstanceFieldWhichInitsDangerousClass () { }
+ }
+
+ [ExpectedWarning ("IL2026", "Calling the constructor is dangerous")]
+ [ExpectedWarning ("IL3050", "Calling the constructor is dangerous", ProducedBy = ProducedBy.Analyzer)]
+ static void TestInstanceFieldSuppression ()
+ {
+ _ = new ClassWithInstanceFieldWhichInitsDangerousClass ();
+ }
+
[RequiresUnreferencedCode ("Message for --StaticCtorTriggeredByMethodCall2--")]
[RequiresDynamicCode ("Message for --StaticCtorTriggeredByMethodCall2--")]
class StaticCtorTriggeredByMethodCall2
diff --git a/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj b/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj
index 4a9ea7e7f2ce..448601a8a643 100644
--- a/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj
+++ b/test/Mono.Linker.Tests/Mono.Linker.Tests.csproj
@@ -1,4 +1,4 @@
-
+
true
@@ -32,6 +32,7 @@
+