Skip to content

Commit 611a613

Browse files
authored
Warn on DAM mismatch between overrides (dotnet/linker#2656)
* Warn on DAM mismatch between overrides Commit migrated from dotnet/linker@ac6cfb3
1 parent b6a4a1c commit 611a613

File tree

8 files changed

+208
-46
lines changed

8 files changed

+208
-46
lines changed

src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ static ImmutableArray<DiagnosticDescriptor> GetSupportedDiagnostics ()
3737
diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection));
3838
diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection));
3939
diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.UnrecognizedTypeInRuntimeHelpersRunClassConstructor));
40+
diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides));
41+
diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides));
42+
diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnGenericParameterBetweenOverrides));
43+
diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnImplicitThisBetweenOverrides));
44+
diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersConflictsBetweenPropertyAndAccessor));
4045
diagDescriptorsArrayBuilder.Add (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.PropertyAccessorParameterInLinqExpressionsCannotBeStaticallyDetermined));
41-
4246
return diagDescriptorsArrayBuilder.ToImmutable ();
4347

4448
void AddRange (DiagnosticId first, DiagnosticId last)
@@ -103,7 +107,12 @@ public override void Initialize (AnalysisContext context)
103107
}, SyntaxKind.GenericName);
104108
context.RegisterSymbolAction (context => {
105109
VerifyMemberOnlyApplyToTypesOrStrings (context, context.Symbol);
110+
VerifyDamOnPropertyAndAccessorMatch (context, (IMethodSymbol) context.Symbol);
111+
VerifyDamOnDerivedAndBaseMethodsMatch (context, (IMethodSymbol) context.Symbol);
106112
}, SymbolKind.Method);
113+
context.RegisterSymbolAction (context => {
114+
VerifyDamOnInterfaceAndImplementationMethodsMatch (context, (INamedTypeSymbol) context.Symbol);
115+
}, SymbolKind.NamedType);
107116
context.RegisterSymbolAction (context => {
108117
VerifyMemberOnlyApplyToTypesOrStrings (context, context.Symbol);
109118
}, SymbolKind.Property);
@@ -209,5 +218,75 @@ static void VerifyMemberOnlyApplyToTypesOrStrings (SymbolAnalysisContext context
209218
context.ReportDiagnostic (Diagnostic.Create (DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersOnPropertyCanOnlyApplyToTypesOrStrings), member.Locations[0], member.GetDisplayName ()));
210219
}
211220
}
221+
222+
static void VerifyDamOnDerivedAndBaseMethodsMatch (SymbolAnalysisContext context, IMethodSymbol methodSymbol)
223+
{
224+
if (methodSymbol.TryGetOverriddenMember (out var overriddenSymbol) && overriddenSymbol is IMethodSymbol overriddenMethod
225+
&& context.Symbol is IMethodSymbol method) {
226+
VerifyDamOnMethodsMatch (context, method, overriddenMethod);
227+
}
228+
}
229+
230+
static void VerifyDamOnMethodsMatch (SymbolAnalysisContext context, IMethodSymbol method, IMethodSymbol overriddenMethod)
231+
{
232+
if (FlowAnnotations.GetMethodReturnValueAnnotation (method) != FlowAnnotations.GetMethodReturnValueAnnotation (overriddenMethod))
233+
context.ReportDiagnostic (Diagnostic.Create (
234+
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides),
235+
method.Locations[0], method.GetDisplayName (), overriddenMethod.GetDisplayName ()));
236+
237+
for (int i = 0; i < method.Parameters.Length; i++) {
238+
if (FlowAnnotations.GetMethodParameterAnnotation (method.Parameters[i]) != FlowAnnotations.GetMethodParameterAnnotation (overriddenMethod.Parameters[i]))
239+
context.ReportDiagnostic (Diagnostic.Create (
240+
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides),
241+
method.Parameters[i].Locations[0],
242+
method.Parameters[i].GetDisplayName (), method.GetDisplayName (), overriddenMethod.Parameters[i].GetDisplayName (), overriddenMethod.GetDisplayName ()));
243+
}
244+
245+
for (int i = 0; i < method.TypeParameters.Length; i++) {
246+
if (method.TypeParameters[i].GetDynamicallyAccessedMemberTypes () != overriddenMethod.TypeParameters[i].GetDynamicallyAccessedMemberTypes ())
247+
context.ReportDiagnostic (Diagnostic.Create (
248+
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnGenericParameterBetweenOverrides),
249+
method.TypeParameters[i].Locations[0],
250+
method.TypeParameters[i].GetDisplayName (), method.GetDisplayName (),
251+
overriddenMethod.TypeParameters[i].GetDisplayName (), overriddenMethod.GetDisplayName ()));
252+
}
253+
254+
if (!method.IsStatic && method.GetDynamicallyAccessedMemberTypes () != overriddenMethod.GetDynamicallyAccessedMemberTypes ())
255+
context.ReportDiagnostic (Diagnostic.Create (
256+
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersMismatchOnImplicitThisBetweenOverrides),
257+
method.Locations[0],
258+
method.GetDisplayName (), overriddenMethod.GetDisplayName ()));
259+
}
260+
261+
static void VerifyDamOnInterfaceAndImplementationMethodsMatch (SymbolAnalysisContext context, INamedTypeSymbol type)
262+
{
263+
foreach (var (interfaceMember, implementationMember) in type.GetMemberInterfaceImplementationPairs ()) {
264+
if (implementationMember is IMethodSymbol implementationMethod
265+
&& interfaceMember is IMethodSymbol interfaceMethod)
266+
VerifyDamOnMethodsMatch (context, implementationMethod, interfaceMethod);
267+
}
268+
}
269+
270+
static void VerifyDamOnPropertyAndAccessorMatch (SymbolAnalysisContext context, IMethodSymbol methodSymbol)
271+
{
272+
if ((methodSymbol.MethodKind != MethodKind.PropertyGet && methodSymbol.MethodKind != MethodKind.PropertySet)
273+
|| (methodSymbol.AssociatedSymbol?.GetDynamicallyAccessedMemberTypes () == DynamicallyAccessedMemberTypes.None))
274+
return;
275+
276+
// None on the return type of 'get' matches unannotated
277+
if (methodSymbol.MethodKind == MethodKind.PropertyGet
278+
&& methodSymbol.GetDynamicallyAccessedMemberTypesOnReturnType () != DynamicallyAccessedMemberTypes.None
279+
// None on parameter of 'set' matches unannotated
280+
|| methodSymbol.MethodKind == MethodKind.PropertySet
281+
&& methodSymbol.Parameters[0].GetDynamicallyAccessedMemberTypes () != DynamicallyAccessedMemberTypes.None) {
282+
context.ReportDiagnostic (Diagnostic.Create (
283+
DiagnosticDescriptors.GetDiagnosticDescriptor (DiagnosticId.DynamicallyAccessedMembersConflictsBetweenPropertyAndAccessor),
284+
methodSymbol.AssociatedSymbol!.Locations[0],
285+
methodSymbol.AssociatedSymbol!.GetDisplayName (),
286+
methodSymbol.GetDisplayName ()
287+
));
288+
return;
289+
}
290+
}
212291
}
213292
}

src/tools/illink/src/ILLink.RoslynAnalyzer/INamedTypeSymbolExtensions.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Collections.Generic;
56
using Microsoft.CodeAnalysis;
67

78
namespace ILLink.RoslynAnalyzer
@@ -28,5 +29,30 @@ internal static bool HasName (this INamedTypeSymbol type, string typeName)
2829

2930
return true;
3031
}
32+
33+
internal static IEnumerable<(ISymbol InterfaceMember, ISymbol ImplementationMember)> GetMemberInterfaceImplementationPairs (this INamedTypeSymbol namedType)
34+
{
35+
var interfaces = namedType.Interfaces;
36+
foreach (INamedTypeSymbol iface in interfaces) {
37+
foreach (var pair in GetMatchingMembers (namedType, iface)) {
38+
yield return pair;
39+
}
40+
}
41+
}
42+
43+
private static IEnumerable<(ISymbol InterfaceMember, ISymbol ImplementationMember)> GetMatchingMembers (INamedTypeSymbol implementationSymbol, INamedTypeSymbol interfaceSymbol)
44+
{
45+
var members = interfaceSymbol.GetMembers ();
46+
foreach (ISymbol interfaceMember in members) {
47+
if (implementationSymbol.FindImplementationForInterfaceMember (interfaceMember) is ISymbol implementationMember) {
48+
yield return (InterfaceMember: interfaceMember, ImplementationMember: implementationMember);
49+
}
50+
}
51+
foreach (var iface in interfaceSymbol.Interfaces) {
52+
foreach (var pair in GetMatchingMembers (implementationSymbol, iface)) {
53+
yield return pair;
54+
}
55+
}
56+
}
3157
}
3258
}

src/tools/illink/src/ILLink.RoslynAnalyzer/RequiresAnalyzerBase.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,9 @@ void CheckMatchingAttributesInInterfaces (
263263
SymbolAnalysisContext symbolAnalysisContext,
264264
INamedTypeSymbol type)
265265
{
266-
ImmutableArray<INamedTypeSymbol> interfaces = type.Interfaces;
267-
foreach (INamespaceOrTypeSymbol iface in interfaces) {
268-
var members = iface.GetMembers ();
269-
foreach (var member in members) {
270-
var implementation = type.FindImplementationForInterfaceMember (member);
271-
// In case the implementation is null because the user code is missing an implementation, we dont provide diagnostics.
272-
// The compiler will provide an error
273-
if (implementation != null && HasMismatchingAttributes (member, implementation))
274-
ReportMismatchInAttributesDiagnostic (symbolAnalysisContext, implementation, member, isInterface: true);
266+
foreach (var memberpair in type.GetMemberInterfaceImplementationPairs ()) {
267+
if (HasMismatchingAttributes (memberpair.InterfaceMember, memberpair.ImplementationMember)) {
268+
ReportMismatchInAttributesDiagnostic (symbolAnalysisContext, memberpair.ImplementationMember, memberpair.InterfaceMember, isInterface: true);
275269
}
276270
}
277271
}

src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ public Task UnresolvedMembers ()
211211
return RunTest (allowMissingWarnings: true);
212212
}
213213

214-
[Fact (Skip = "https://github.com/dotnet/linker/issues/2273")]
214+
[Fact]
215215
public Task VirtualMethodHierarchyDataflowAnnotationValidation ()
216216
{
217217
return RunTest (nameof (VirtualMethodHierarchyDataflowAnnotationValidation));

src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ static string GetSystemTypeBase ()
511511
512512
using System.Globalization;
513513
using System.Reflection;
514+
using System.Diagnostics.CodeAnalysis;
514515
515516
namespace System
516517
{
@@ -534,6 +535,8 @@ public class TestSystemTypeBase : Type
534535
535536
public override string Name => throw new NotImplementedException ();
536537
538+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors
539+
| DynamicallyAccessedMemberTypes.NonPublicConstructors)]
537540
public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
538541
{
539542
throw new NotImplementedException ();
@@ -554,61 +557,76 @@ public override Type GetElementType ()
554557
throw new NotImplementedException ();
555558
}
556559
560+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents
561+
| DynamicallyAccessedMemberTypes.NonPublicEvents)]
557562
public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
558563
{
559564
throw new NotImplementedException ();
560565
}
561566
567+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
562568
public override EventInfo[] GetEvents (BindingFlags bindingAttr)
563569
{
564570
throw new NotImplementedException ();
565571
}
566572
573+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
567574
public override FieldInfo GetField (string name, BindingFlags bindingAttr)
568575
{
569576
throw new NotImplementedException ();
570577
}
571578
579+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields
580+
| DynamicallyAccessedMemberTypes.NonPublicFields)]
572581
public override FieldInfo[] GetFields (BindingFlags bindingAttr)
573582
{
574583
throw new NotImplementedException ();
575584
}
576585
586+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
587+
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
577588
public override Type GetInterface (string name, bool ignoreCase)
578589
{
579590
throw new NotImplementedException ();
580591
}
581592
593+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
582594
public override Type[] GetInterfaces ()
583595
{
584596
throw new NotImplementedException ();
585597
}
586598
599+
[DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)0x1FFF)]
587600
public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
588601
{
589602
throw new NotImplementedException ();
590603
}
591604
605+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
592606
public override MethodInfo[] GetMethods (BindingFlags bindingAttr)
593607
{
594608
throw new NotImplementedException ();
595609
}
596610
611+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
597612
public override Type GetNestedType (string name, BindingFlags bindingAttr)
598613
{
599614
throw new NotImplementedException ();
600615
}
601616
617+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
602618
public override Type[] GetNestedTypes (BindingFlags bindingAttr)
603619
{
604620
throw new NotImplementedException ();
605621
}
606622
623+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
607624
public override PropertyInfo[] GetProperties (BindingFlags bindingAttr)
608625
{
609626
throw new NotImplementedException ();
610627
}
611628
629+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
612630
public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
613631
{
614632
throw new NotImplementedException ();
@@ -624,16 +642,20 @@ protected override TypeAttributes GetAttributeFlagsImpl ()
624642
throw new NotImplementedException ();
625643
}
626644
645+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors
646+
| DynamicallyAccessedMemberTypes.NonPublicConstructors)]
627647
protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
628648
{
629649
throw new NotImplementedException ();
630650
}
631651
652+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
632653
protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
633654
{
634655
throw new NotImplementedException ();
635656
}
636657
658+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
637659
protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
638660
{
639661
throw new NotImplementedException ();
@@ -698,12 +720,12 @@ private static void M2(
698720
}
699721
}";
700722

701-
// (178,16): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'.
723+
// (200,16): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'.
702724
// The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations.
703725
// The source value must declare at least the same requirements as those declared on the target location it is assigned to.
704726
return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), TargetParameterWithAnnotations),
705727
VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter)
706-
.WithSpan (178, 13, 178, 21)
728+
.WithSpan (200, 13, 200, 21)
707729
.WithArguments ("type", "System.C.M2(Type)", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'"));
708730
}
709731

@@ -740,7 +762,7 @@ private static void M2(
740762

741763
return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), ConversionOperation),
742764
VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter)
743-
.WithSpan (183, 13, 183, 37)
765+
.WithSpan (205, 13, 205, 37)
744766
.WithArguments ("type", "System.C.M2(Type)", "System.ConvertsToType.implicit operator Type(ConvertsToType)", "'DynamicallyAccessedMemberTypes.PublicMethods'"));
745767
}
746768

@@ -780,7 +802,7 @@ private static void M2(
780802

781803
return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), AnnotatedConversionOperation),
782804
VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter)
783-
.WithSpan (185, 13, 185, 37)
805+
.WithSpan (207, 13, 207, 37)
784806
.WithArguments ("type", "System.C.M2(Type)", "System.ConvertsToType.implicit operator Type(ConvertsToType)", "'DynamicallyAccessedMemberTypes.PublicMethods'"));
785807
}
786808

@@ -843,12 +865,12 @@ private Type M()
843865
}
844866
}";
845867

846-
// (180,13): warning IL2083: 'System.C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements.
868+
// (202,13): warning IL2083: 'System.C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements.
847869
// The implicit 'this' argument of method 'System.C.M()' does not have matching annotations.
848870
// The source value must declare at least the same requirements as those declared on the target location it is assigned to.
849871
return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), TargetMethodReturnTypeWithAnnotations),
850872
VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType)
851-
.WithSpan (180, 20, 180, 24)
873+
.WithSpan (202, 20, 202, 24)
852874
.WithArguments ("System.C.M()", "System.C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'"));
853875
}
854876

@@ -876,12 +898,12 @@ private void M()
876898
}
877899
}";
878900

879-
// (178,13): warning IL2084: value stored in field 'System.C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements.
901+
// (200,13): warning IL2084: value stored in field 'System.C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements.
880902
// The implicit 'this' argument of method 'System.C.M()' does not have matching annotations.
881903
// The source value must declare at least the same requirements as those declared on the target location it is assigned to.
882904
return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), TargetFieldWithAnnotations),
883905
VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsField)
884-
.WithSpan (178, 13, 178, 21)
906+
.WithSpan (200, 13, 200, 21)
885907
.WithArguments ("System.C.f",
886908
"System.C.M()",
887909
"'DynamicallyAccessedMemberTypes.PublicMethods'"));
@@ -907,12 +929,12 @@ private void M()
907929
}
908930
}";
909931

910-
// (178,13): warning IL2085: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'.
932+
// (200,13): warning IL2085: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'.
911933
// The implicit 'this' argument of method 'System.C.M()' does not have matching annotations.
912934
// The source value must declare at least the same requirements as those declared on the target location it is assigned to.
913935
return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), TargetMethodWithAnnotations),
914936
VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter)
915-
.WithSpan (178, 13, 178, 30)
937+
.WithSpan (200, 13, 200, 30)
916938
.WithArguments ("System.Type.GetMethods()", "System.C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'"));
917939
}
918940
#endregion

0 commit comments

Comments
 (0)