Skip to content

Commit

Permalink
Add tests for ldtoken analysis and fixes a small bug for a field (#3173)
Browse files Browse the repository at this point in the history
LdToken acts basically as a reflection access and so it needs to warn about the returned member if that has annotations on it.
  • Loading branch information
vitek-karas authored Jan 5, 2023
1 parent 19c7f53 commit beb6d3b
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,7 @@ void ProcessAnalysisAnnotationsForField (FieldDefinition field, DependencyKind d
case DependencyKind.DynamicDependency:
case DependencyKind.DynamicallyAccessedMember:
case DependencyKind.InteropMethodDependency:
case DependencyKind.Ldtoken:
if (isReflectionAccessCoveredByDAM = Annotations.FlowAnnotations.ShouldWarnWhenAccessedForReflection (field))
Context.LogWarning (origin, DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection, field.GetDisplayName ());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ public static void Main ()
AnnotatedGenerics.Test ();
AnnotationOnGenerics.Test ();
AnnotationOnInteropMethod.Test ();
AccessThroughLdToken.Test ();
}

class AnnotatedField
Expand Down Expand Up @@ -128,6 +127,17 @@ static void DynamicallyAccessedMembersNestedTypes2 ()
typeof (AnnotatedField).RequiresNonPublicNestedTypes ();
}

static void PotentialWriteAccess (ref Type type)
{
}

// https://github.com/dotnet/linker/issues/3172
[ExpectedWarning ("IL2110", nameof (AnnotatedField._annotatedField), ProducedBy = ProducedBy.Trimmer)]
static void LdToken ()
{
Expression<Action> a = () => PotentialWriteAccess (ref _annotatedField);
}

[UnconditionalSuppressMessage ("test", "IL2026")]
public static void Test ()
{
Expand All @@ -143,6 +153,7 @@ public static void Test ()
DynamicallyAccessedMembersAll2 ();
DynamicallyAccessedMembersNestedTypes1 ();
DynamicallyAccessedMembersNestedTypes2 ();
LdToken ();
}
}

Expand Down Expand Up @@ -251,6 +262,14 @@ static void DynamicallyAccessedMembersAll2 ()
typeof (AnnotatedMethodParameters).RequiresAll ();
}

// https://github.com/dotnet/linker/issues/3172
[ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = ProducedBy.Trimmer)]
[ExpectedWarning ("IL2067", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = ProducedBy.Analyzer)]
static void LdToken ()
{
Expression<Action<Type>> _ = (Type t) => MethodWithSingleAnnotatedParameter (t);
}

[UnconditionalSuppressMessage ("test", "IL2026")]
public static void Test ()
{
Expand All @@ -265,6 +284,7 @@ public static void Test ()
Ldvirtftn ();
DynamicallyAccessedMembersAll1 ();
DynamicallyAccessedMembersAll2 ();
LdToken ();
}
}

Expand Down Expand Up @@ -363,6 +383,18 @@ static void LdftnOnVirtual ()
var _ = new Func<Type> ((new AnnotatedMethodReturnValue ()).VirtualMethodWithAnnotatedReturnValue);
}

static void LdTokenOnStatic ()
{
Expression<Action> _ = () => StaticMethodWithAnnotatedReturnValue ();
}

// https://github.com/dotnet/linker/issues/3172
[ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = ProducedBy.Trimmer)]
static void LdTokenOnVirtual ()
{
Expression<Action<AnnotatedMethodReturnValue>> _ = (a) => a.VirtualMethodWithAnnotatedReturnValue ();
}

[UnconditionalSuppressMessage ("test", "IL2026")]
public static void Test ()
{
Expand All @@ -380,6 +412,8 @@ public static void Test ()
LdftnOnStatic ();
LdftnOnInstance ();
LdftnOnVirtual ();
LdTokenOnStatic ();
LdTokenOnVirtual ();
}
}

Expand Down Expand Up @@ -563,6 +597,13 @@ static void DynamicallyAccessedFields ()
typeof (AnnotatedProperty).RequiresNonPublicFields ();
}

// Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561
[ExpectedWarning ("IL2111", nameof (Property1WithAnnotation), ProducedBy = ProducedBy.Trimmer)]
static void LdToken ()
{
Expression<Func<Type>> _ = () => Property1WithAnnotation;
}

[UnconditionalSuppressMessage ("test", "IL2026")]
public static void Test ()
{
Expand All @@ -581,6 +622,7 @@ public static void Test ()
DynamicallyAccessedMembersAll1 ();
DynamicallyAccessedMembersAll2 ();
DynamicallyAccessedFields ();
LdToken ();
}
}

Expand Down Expand Up @@ -623,13 +665,20 @@ static void DynamicallyAccessedMembersAll ()
typeof (AnnotatedGenerics).RequiresAll ();
}

[ExpectedWarning ("IL2091", nameof (GenericWithAnnotation))]
static void LdToken<TUnknown> ()
{
Expression<Action> _ = () => GenericWithAnnotation<TUnknown> ();
}

public static void Test ()
{
ReflectionOnly ();
DynamicDependency ();
DynamicallyAccessedMembers ();
InstantiateGeneric ();
DynamicallyAccessedMembersAll ();
LdToken<string> ();
}
}

Expand Down Expand Up @@ -693,6 +742,17 @@ static void DynamicallyAccessedMembersAll2 ()
typeof (AnnotationOnGenerics).RequiresAll ();
}

// https://github.com/dotnet/linker/issues/3172
[ExpectedWarning ("IL2111", "GenericWithAnnotatedMethod", "AnnotatedMethod", ProducedBy = ProducedBy.Trimmer)]
static void LdToken ()
{
// Note that this should warn even though the code looks "Correct"
// That is because under the hood the expression tree create MethodInfo which is accessible by anything
// which gets the expression tree as input (so some queryable) and that could invoke the method
// with a different parameter value and thus violate the requirements.
Expression<Action> _ = () => GenericWithAnnotatedMethod<TestType>.AnnotatedMethod (typeof (TestType));
}

public static void Test ()
{
GenericTypeWithStaticMethodViaLdftn ();
Expand All @@ -702,6 +762,7 @@ public static void Test ()
GenericMethodDynamicallyAccessedMembers ();
DynamicallyAccessedMembersAll1 ();
DynamicallyAccessedMembersAll2 ();
LdToken ();
}
}

Expand All @@ -713,12 +774,12 @@ struct ValueWithAnnotatedField
public Type _typeField;
}

// Analyzer doesnt take into account interop attributes https://github.com/dotnet/linker/issues/2562
// Analyzer doesn't take into account interop attributes https://github.com/dotnet/linker/issues/2562
[ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField), ProducedBy = ProducedBy.Trimmer)]
[DllImport ("nonexistent")]
static extern ValueWithAnnotatedField GetValueWithAnnotatedField ();

// Analyzer doesnt take into account interop attributes https://github.com/dotnet/linker/issues/2562
// Analyzer doesn't take into account interop attributes https://github.com/dotnet/linker/issues/2562
[ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField), ProducedBy = ProducedBy.Trimmer)]
[DllImport ("nonexistent")]
static extern void AcceptValueWithAnnotatedField (ValueWithAnnotatedField value);
Expand All @@ -730,24 +791,6 @@ public static void Test ()
}
}

class AccessThroughLdToken
{
public virtual Type PropertyWithLdToken {
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
get {
return null;
}
}

// Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561
[ExpectedWarning ("IL2111", nameof (PropertyWithLdToken), ProducedBy = ProducedBy.Trimmer)]
[ExpectedWarning ("IL2111", nameof (PropertyWithLdToken), ProducedBy = ProducedBy.Trimmer)]
public static void Test ()
{
Expression<Func<Type>> getter = () => (new AccessThroughLdToken ()).PropertyWithLdToken;
}
}

public class AnnotatedAttributeConstructorAttribute : Attribute
{
public AnnotatedAttributeConstructorAttribute ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type type)
Expand Down

0 comments on commit beb6d3b

Please sign in to comment.