Skip to content

Commit aba0e20

Browse files
committed
Revert "Revert "Fix handling of unknown BindingFlags (#2288)""
This reverts commit 02b53c5.
1 parent f74fcd2 commit aba0e20

6 files changed

Lines changed: 129 additions & 8 deletions

File tree

src/linker/Linker.Dataflow/ReflectionMethodBodyScanner.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,8 +1112,7 @@ public override bool HandleCall (MethodBody callingMethodBody, MethodReference c
11121112
reflectionContext.RecordHandledPattern ();
11131113
} else {
11141114
// Otherwise fall back to the bitfield requirements
1115-
var requiredMemberTypes = HasBindingFlag (bindingFlags, BindingFlags.Public) ? DynamicallyAccessedMemberTypes.PublicConstructors : DynamicallyAccessedMemberTypes.None;
1116-
requiredMemberTypes |= HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicConstructors : DynamicallyAccessedMemberTypes.None;
1115+
var requiredMemberTypes = GetDynamicallyAccessedMemberTypesFromBindingFlagsForConstructors (bindingFlags);
11171116
// We can scope down the public constructors requirement if we know the number of parameters is 0
11181117
if (requiredMemberTypes == DynamicallyAccessedMemberTypes.PublicConstructors && ctorParameterCount == 0)
11191118
requiredMemberTypes = DynamicallyAccessedMemberTypes.PublicParameterlessConstructor;
@@ -2401,27 +2400,33 @@ void ValidateGenericMethodInstantiation (
24012400

24022401
static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromBindingFlagsForNestedTypes (BindingFlags? bindingFlags) =>
24032402
(HasBindingFlag (bindingFlags, BindingFlags.Public) ? DynamicallyAccessedMemberTypes.PublicNestedTypes : DynamicallyAccessedMemberTypes.None) |
2404-
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicNestedTypes : DynamicallyAccessedMemberTypes.None);
2403+
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicNestedTypes : DynamicallyAccessedMemberTypes.None) |
2404+
(BindingFlagsAreUnsupported (bindingFlags) ? DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes : DynamicallyAccessedMemberTypes.None);
24052405

24062406
static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromBindingFlagsForConstructors (BindingFlags? bindingFlags) =>
24072407
(HasBindingFlag (bindingFlags, BindingFlags.Public) ? DynamicallyAccessedMemberTypes.PublicConstructors : DynamicallyAccessedMemberTypes.None) |
2408-
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicConstructors : DynamicallyAccessedMemberTypes.None);
2408+
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicConstructors : DynamicallyAccessedMemberTypes.None) |
2409+
(BindingFlagsAreUnsupported (bindingFlags) ? DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors : DynamicallyAccessedMemberTypes.None);
24092410

24102411
static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromBindingFlagsForMethods (BindingFlags? bindingFlags) =>
24112412
(HasBindingFlag (bindingFlags, BindingFlags.Public) ? DynamicallyAccessedMemberTypes.PublicMethods : DynamicallyAccessedMemberTypes.None) |
2412-
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicMethods : DynamicallyAccessedMemberTypes.None);
2413+
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicMethods : DynamicallyAccessedMemberTypes.None) |
2414+
(BindingFlagsAreUnsupported (bindingFlags) ? DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods : DynamicallyAccessedMemberTypes.None);
24132415

24142416
static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromBindingFlagsForFields (BindingFlags? bindingFlags) =>
24152417
(HasBindingFlag (bindingFlags, BindingFlags.Public) ? DynamicallyAccessedMemberTypes.PublicFields : DynamicallyAccessedMemberTypes.None) |
2416-
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicFields : DynamicallyAccessedMemberTypes.None);
2418+
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicFields : DynamicallyAccessedMemberTypes.None) |
2419+
(BindingFlagsAreUnsupported (bindingFlags) ? DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields : DynamicallyAccessedMemberTypes.None);
24172420

24182421
static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromBindingFlagsForProperties (BindingFlags? bindingFlags) =>
24192422
(HasBindingFlag (bindingFlags, BindingFlags.Public) ? DynamicallyAccessedMemberTypes.PublicProperties : DynamicallyAccessedMemberTypes.None) |
2420-
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicProperties : DynamicallyAccessedMemberTypes.None);
2423+
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicProperties : DynamicallyAccessedMemberTypes.None) |
2424+
(BindingFlagsAreUnsupported (bindingFlags) ? DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties : DynamicallyAccessedMemberTypes.None);
24212425

24222426
static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromBindingFlagsForEvents (BindingFlags? bindingFlags) =>
24232427
(HasBindingFlag (bindingFlags, BindingFlags.Public) ? DynamicallyAccessedMemberTypes.PublicEvents : DynamicallyAccessedMemberTypes.None) |
2424-
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicEvents : DynamicallyAccessedMemberTypes.None);
2428+
(HasBindingFlag (bindingFlags, BindingFlags.NonPublic) ? DynamicallyAccessedMemberTypes.NonPublicEvents : DynamicallyAccessedMemberTypes.None) |
2429+
(BindingFlagsAreUnsupported (bindingFlags) ? DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents : DynamicallyAccessedMemberTypes.None);
24252430
static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromBindingFlagsForMembers (BindingFlags? bindingFlags) =>
24262431
GetDynamicallyAccessedMemberTypesFromBindingFlagsForConstructors (bindingFlags) |
24272432
GetDynamicallyAccessedMemberTypesFromBindingFlagsForEvents (bindingFlags) |

test/Mono.Linker.Tests.Cases/Reflection/EventUsedViaReflection.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public static void Main ()
1717
TestNameBindingFlags ();
1818
TestNameWrongBindingFlags ();
1919
TestNameUnknownBindingFlags (BindingFlags.Public);
20+
TestNameUnknownBindingFlagsAndName (BindingFlags.Public, "DoesntMatter");
2021
TestNullName ();
2122
TestEmptyName ();
2223
TestNonExistingName ();
@@ -71,6 +72,13 @@ static void TestNameUnknownBindingFlags (BindingFlags bindingFlags)
7172
var eventInfo = typeof (UnknownBindingFlags).GetEvent ("PrivateEvent", bindingFlags);
7273
}
7374

75+
[Kept]
76+
static void TestNameUnknownBindingFlagsAndName (BindingFlags bindingFlags, string name)
77+
{
78+
// Since the binding flags are not known linker should mark all events on the type
79+
var eventInfo = typeof (UnknownBindingFlagsAndName).GetEvent (name, bindingFlags);
80+
}
81+
7482
[Kept]
7583
static void TestNullName ()
7684
{
@@ -221,6 +229,30 @@ class UnknownBindingFlags
221229
public event EventHandler<EventArgs> PublicEvent;
222230
}
223231

232+
class UnknownBindingFlagsAndName
233+
{
234+
[Kept]
235+
[KeptEventAddMethod]
236+
[KeptEventRemoveMethod]
237+
[method: ExpectBodyModified]
238+
internal event EventHandler<EventArgs> InternalEvent;
239+
[Kept]
240+
[KeptBackingField]
241+
[KeptEventAddMethod]
242+
[KeptEventRemoveMethod]
243+
static event EventHandler<EventArgs> Static;
244+
[Kept]
245+
[KeptEventAddMethod]
246+
[KeptEventRemoveMethod]
247+
[method: ExpectBodyModified]
248+
private event EventHandler<EventArgs> PrivateEvent;
249+
[Kept]
250+
[KeptEventAddMethod]
251+
[KeptEventRemoveMethod]
252+
[method: ExpectBodyModified]
253+
public event EventHandler<EventArgs> PublicEvent;
254+
}
255+
224256
class IfClass
225257
{
226258
[Kept]

test/Mono.Linker.Tests.Cases/Reflection/FieldUsedViaReflection.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public static void Main ()
1515
TestNameBindingFlags ();
1616
TestNameWrongBindingFlags ();
1717
TestNameUnknownBindingFlags (BindingFlags.Public);
18+
TestNameUnknownBindingFlagsAndName (BindingFlags.Public, "DoesntMatter");
1819
TestNullName ();
1920
TestEmptyName ();
2021
TestNonExistingName ();
@@ -66,6 +67,13 @@ static void TestNameUnknownBindingFlags (BindingFlags bindingFlags)
6667
var field = typeof (UnknownBindingFlags).GetField ("field", bindingFlags);
6768
}
6869

70+
[Kept]
71+
static void TestNameUnknownBindingFlagsAndName (BindingFlags bindingFlags, string name)
72+
{
73+
// Since the binding flags and name are not known linker should mark all fields on the type
74+
var field = typeof (UnknownBindingFlagsAndName).GetField (name, bindingFlags);
75+
}
76+
6977
[Kept]
7078
static void TestNullName ()
7179
{
@@ -186,6 +194,17 @@ private class UnknownBindingFlags
186194
private static int privatefield;
187195
}
188196

197+
[Kept]
198+
private class UnknownBindingFlagsAndName
199+
{
200+
[Kept]
201+
public static int field;
202+
[Kept]
203+
public int nonStatic;
204+
[Kept]
205+
private static int privatefield;
206+
}
207+
189208
[Kept]
190209
private class IfClass
191210
{

test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public static void Main ()
1717
GetMethod_Name_Types.TestNameAndType ();
1818
GetMethod_Name_BindingAttr.TestExplicitBindingFlags ();
1919
GetMethod_Name_BindingAttr.TestUnknownBindingFlags (BindingFlags.Public);
20+
GetMethod_Name_BindingAttr.TestUnknownBindingFlagsAndName (BindingFlags.Public, "DoesntMatter");
2021
GetMethod_Name_BindingAttr.TestUnknownNullBindingFlags (BindingFlags.Public);
2122
GetMethod_Name_BindingAttr_Binder_Types_Modifiers.TestNameBindingFlagsAndParameterModifier ();
2223
GetMethod_Name_BindingAttr_Binder_CallConvention_Types_Modifiers.TestNameBindingFlagsCallingConventionParameterModifier ();
@@ -199,6 +200,25 @@ public static void TestUnknownBindingFlags (BindingFlags bindingFlags)
199200
method.Invoke (null, new object[] { });
200201
}
201202

203+
[Kept]
204+
class UnknownBindingFlagsAndName
205+
{
206+
[Kept]
207+
private static int OnlyCalledViaReflection ()
208+
{
209+
return 42;
210+
}
211+
}
212+
213+
[Kept]
214+
[RecognizedReflectionAccessPattern]
215+
public static void TestUnknownBindingFlagsAndName (BindingFlags bindingFlags, string name)
216+
{
217+
// Since the binding flags and name are not known linker should mark all methods on the type
218+
var method = typeof (UnknownBindingFlagsAndName).GetMethod (name, bindingFlags);
219+
method.Invoke (null, new object[] { });
220+
}
221+
202222
[Kept]
203223
private class NullBindingFlags
204224
{

test/Mono.Linker.Tests.Cases/Reflection/NestedTypeUsedViaReflection.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public static void Main ()
1616
TestPrivateByName ();
1717
TestByBindingFlags ();
1818
TestByUnknownBindingFlags (BindingFlags.Public);
19+
TestByUnknownBindingFlagsAndName (BindingFlags.Public, "DoesntMatter");
1920
TestNonExistingName ();
2021
TestNullType ();
2122
TestIgnoreCaseBindingFlags ();
@@ -80,6 +81,16 @@ static void TestByUnknownBindingFlags (BindingFlags bindingFlags)
8081
_ = typeof (UnknownBindingFlags).GetNestedType (nameof (PublicNestedType), bindingFlags);
8182
}
8283

84+
[Kept]
85+
[RecognizedReflectionAccessPattern (
86+
typeof (Type), nameof (Type.GetNestedType), new Type[] { typeof (string), typeof (BindingFlags) },
87+
typeof (UnknownBindingFlagsAndName.PublicNestedType), null, (Type[]) null)]
88+
static void TestByUnknownBindingFlagsAndName (BindingFlags bindingFlags, string name)
89+
{
90+
// Since the binding flags and name are not known linker should mark all nested types on the type
91+
_ = typeof (UnknownBindingFlagsAndName).GetNestedType (name, bindingFlags);
92+
}
93+
8394
[Kept]
8495
static void TestNonExistingName ()
8596
{
@@ -124,6 +135,16 @@ public static class PublicNestedType { }
124135
private static class PrivateNestedType { }
125136
}
126137

138+
[Kept]
139+
private class UnknownBindingFlagsAndName
140+
{
141+
[Kept]
142+
public static class PublicNestedType { }
143+
144+
[Kept]
145+
private static class PrivateNestedType { }
146+
}
147+
127148
[Kept]
128149
private class IgnoreCaseClass
129150
{

test/Mono.Linker.Tests.Cases/Reflection/PropertyUsedViaReflection.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public static void Main ()
1717
TestGetterOnly ();
1818
TestBindingFlags ();
1919
TestUnknownBindingFlags (BindingFlags.Public);
20+
TestUnknownBindingFlagsAndName (BindingFlags.Public, "IrrelevantName");
2021
TestNullName ();
2122
TestEmptyName ();
2223
TestNonExistingName ();
@@ -89,6 +90,17 @@ static void TestUnknownBindingFlags (BindingFlags bindingFlags)
8990
property.GetValue (null, new object[] { });
9091
}
9192

93+
[Kept]
94+
[RecognizedReflectionAccessPattern (
95+
typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string), typeof (BindingFlags) },
96+
typeof (UnknownBindingFlagsAndName), nameof (UnknownBindingFlagsAndName.SomeProperty), (Type[]) null)]
97+
static void TestUnknownBindingFlagsAndName (BindingFlags bindingFlags, string name)
98+
{
99+
// Since the binding flags and name are not known linker should mark all properties on the type
100+
var property = typeof (UnknownBindingFlagsAndName).GetProperty (name, bindingFlags);
101+
property.GetValue (null, new object[] { });
102+
}
103+
92104
[Kept]
93105
static void TestNullName ()
94106
{
@@ -313,6 +325,18 @@ internal static int SomeProperty {
313325
}
314326
}
315327

328+
[Kept]
329+
class UnknownBindingFlagsAndName
330+
{
331+
[Kept]
332+
internal static int SomeProperty {
333+
[Kept]
334+
private get { return _field; }
335+
[Kept]
336+
set { _field = value; }
337+
}
338+
}
339+
316340
[Kept]
317341
class IgnoreCaseBindingFlagsClass
318342
{

0 commit comments

Comments
 (0)