diff --git a/src/libraries/System.Linq.Expressions/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Linq.Expressions/src/ILLink/ILLink.Suppressions.xml
index 5d2ce5eca2aed5cb845e55a16626fdb6b347f870..ea80eae650ff3d7d40f8667a26acd4b36ecba5ef 100644
--- a/src/libraries/System.Linq.Expressions/src/ILLink/ILLink.Suppressions.xml
+++ b/src/libraries/System.Linq.Expressions/src/ILLink/ILLink.Suppressions.xml
@@ -19,36 +19,6 @@
member
M:System.Dynamic.Utils.TypeExtensions.GetAnyStaticMethodValidated(System.Type,System.String,System.Type[])
-
- ILLink
- IL2070
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitGetArrayElement(System.Type)
-
-
- ILLink
- IL2070
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitLift(System.Linq.Expressions.ExpressionType,System.Type,System.Linq.Expressions.MethodCallExpression,System.Linq.Expressions.ParameterExpression[],System.Linq.Expressions.Expression[])
-
-
- ILLink
- IL2070
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitLiftedBinaryArithmetic(System.Linq.Expressions.ExpressionType,System.Type,System.Type,System.Type)
-
-
- ILLink
- IL2070
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitSetArrayElement(System.Type)
-
-
- ILLink
- IL2070
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitUnaryOperator(System.Linq.Expressions.ExpressionType,System.Type,System.Type)
-
ILLink
IL2072
@@ -79,36 +49,6 @@
member
M:System.Dynamic.Utils.TypeUtils.GetUserDefinedCoercionMethod(System.Type,System.Type)
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.AddressOf(System.Linq.Expressions.IndexExpression,System.Type)
-
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.AddressOf(System.Linq.Expressions.MethodCallExpression,System.Type)
-
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitDynamicExpression(System.Linq.Expressions.Expression)
-
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitInvocationExpression(System.Linq.Expressions.Expression,System.Linq.Expressions.Compiler.LambdaCompiler.CompilationFlags)
-
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Compiler.LambdaCompiler.EmitUnary(System.Linq.Expressions.UnaryExpression,System.Linq.Expressions.Compiler.LambdaCompiler.CompilationFlags)
-
ILLink
IL2075
@@ -139,65 +79,5 @@
member
M:System.Linq.Expressions.Expression.PropertyOrField(System.Linq.Expressions.Expression,System.String)
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.ExpressionStringBuilder.VisitExtension(System.Linq.Expressions.Expression)
-
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Interpreter.LightCompiler.CompileAddress(System.Linq.Expressions.Expression,System.Int32)
-
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Interpreter.LightCompiler.CompileIndexAssignment(System.Linq.Expressions.BinaryExpression,System.Boolean)
-
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Interpreter.LightCompiler.CompileInvocationExpression(System.Linq.Expressions.Expression)
-
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Interpreter.LightCompiler.CompileMultiDimArrayAccess(System.Linq.Expressions.Expression,System.Linq.Expressions.IArgumentProvider,System.Int32)
-
-
- ILLink
- IL2075
- member
- M:System.Linq.Expressions.Interpreter.LightCompiler.EmitIndexGet(System.Linq.Expressions.IndexExpression)
-
-
- ILLink
- IL2077
- member
- M:System.Linq.Expressions.Interpreter.DefaultValueInstruction.Run(System.Linq.Expressions.Interpreter.InterpretedFrame)
-
-
- ILLink
- IL2077
- member
- M:System.Linq.Expressions.Interpreter.InitializeLocalInstruction.MutableBox.Run(System.Linq.Expressions.Interpreter.InterpretedFrame)
-
-
- ILLink
- IL2077
- member
- M:System.Linq.Expressions.Interpreter.InitializeLocalInstruction.MutableValue.Run(System.Linq.Expressions.Interpreter.InterpretedFrame)
-
-
- ILLink
- IL2080
- member
- M:System.Linq.Expressions.Compiler.CompilerScope.ElementBoxStorage.#ctor(System.Linq.Expressions.Compiler.CompilerScope.Storage,System.Int32,System.Linq.Expressions.ParameterExpression)
-
diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs
index e6cb75d8ba03c9ee77d23069c66fe3513fd58fe1..e7296b530fb99df2b84ca24991df4d0bcf2d47fb 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs
@@ -29,6 +29,17 @@ public static Type GetNullableType(this Type type)
return type;
}
+ [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(Nullable<>))]
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
+ Justification = "The Nullable ctor will be preserved by the DynamicDependency.")]
+ public static ConstructorInfo GetNullableConstructor(Type nullableType, Type nonNullableType)
+ {
+ Debug.Assert(nullableType.IsNullableType());
+ Debug.Assert(!nonNullableType.IsNullableType() && nonNullableType.IsValueType);
+
+ return nullableType.GetConstructor(new Type[] { nonNullableType })!;
+ }
+
public static bool IsNullableType(this Type type) => type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
public static bool IsNullableOrReferenceType(this Type type) => !type.IsValueType || IsNullableType(type);
@@ -934,5 +945,29 @@ internal static bool IsFloatingPoint(this TypeCode typeCode)
}
#endif
+
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
+ Justification = "The Array 'Get' method is dynamically constructed and is not included in IL. It is not subject to trimming.")]
+ public static MethodInfo GetArrayGetMethod(Type arrayType)
+ {
+ Debug.Assert(arrayType.IsArray);
+ return arrayType.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance)!;
+ }
+
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
+ Justification = "The Array 'Set' method is dynamically constructed and is not included in IL. It is not subject to trimming.")]
+ public static MethodInfo GetArraySetMethod(Type arrayType)
+ {
+ Debug.Assert(arrayType.IsArray);
+ return arrayType.GetMethod("Set", BindingFlags.Public | BindingFlags.Instance)!;
+ }
+
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
+ Justification = "The Array 'Address' method is dynamically constructed and is not included in IL. It is not subject to trimming.")]
+ public static MethodInfo GetArrayAddressMethod(Type arrayType)
+ {
+ Debug.Assert(arrayType.IsArray);
+ return arrayType.GetMethod("Address", BindingFlags.Public | BindingFlags.Instance)!;
+ }
}
}
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/CompilerScope.Storage.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/CompilerScope.Storage.cs
index 67ae2e4a5ca319c20c1cfaaaf6425415b359c3e5..e60561d19b28a5fb8b1275116965957c8bf02d6a 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/CompilerScope.Storage.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/CompilerScope.Storage.cs
@@ -110,8 +110,9 @@ internal ElementBoxStorage(Storage array, int index, ParameterExpression variabl
{
_array = array;
_index = index;
- _boxType = typeof(StrongBox<>).MakeGenericType(variable.Type);
- _boxValueField = _boxType.GetField("Value")!;
+ Type boxType = typeof(StrongBox<>).MakeGenericType(variable.Type);
+ _boxValueField = boxType.GetField("Value")!;
+ _boxType = boxType;
}
internal override void EmitLoad()
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs
index e1bb52cb908e81491f7d68bee7197d05300157d4..673e213432a725110c0c856d40e96b278028ec42 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs
@@ -485,7 +485,7 @@ private static bool TryEmitILConstant(this ILGenerator il, object value, Type ty
if (TryEmitILConstant(il, value, nonNullType))
{
- il.Emit(OpCodes.Newobj, GetNullableConstructor(type, nonNullType));
+ il.Emit(OpCodes.Newobj, TypeUtils.GetNullableConstructor(type, nonNullType));
return true;
}
@@ -826,7 +826,7 @@ private static void EmitNullableToNullableConversion(this ILGenerator il, Type t
Type nnTypeTo = typeTo.GetNonNullableType();
il.EmitConvertToType(nnTypeFrom, nnTypeTo, isChecked, locals);
// construct result type
- ConstructorInfo ci = GetNullableConstructor(typeTo, nnTypeTo);
+ ConstructorInfo ci = TypeUtils.GetNullableConstructor(typeTo, nnTypeTo);
il.Emit(OpCodes.Newobj, ci);
labEnd = il.DefineLabel();
il.Emit(OpCodes.Br_S, labEnd);
@@ -846,21 +846,10 @@ private static void EmitNonNullableToNullableConversion(this ILGenerator il, Typ
Debug.Assert(typeTo.IsNullableType());
Type nnTypeTo = typeTo.GetNonNullableType();
il.EmitConvertToType(typeFrom, nnTypeTo, isChecked, locals);
- ConstructorInfo ci = GetNullableConstructor(typeTo, nnTypeTo);
+ ConstructorInfo ci = TypeUtils.GetNullableConstructor(typeTo, nnTypeTo);
il.Emit(OpCodes.Newobj, ci);
}
- [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(Nullable<>))]
- [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
- Justification = "The Nullable ctor will be preserved by the DynamicDependency.")]
- private static ConstructorInfo GetNullableConstructor(Type nullableType, Type nonNullableType)
- {
- Debug.Assert(nullableType.IsNullableType());
- Debug.Assert(!nonNullableType.IsNullableType() && nonNullableType.IsValueType);
-
- return nullableType.GetConstructor(new Type[] { nonNullableType })!;
- }
-
private static void EmitNullableToNonNullableConversion(this ILGenerator il, Type typeFrom, Type typeTo, bool isChecked, ILocalCache locals)
{
Debug.Assert(typeFrom.IsNullableType());
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Address.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Address.cs
index 29b5b83228662160d13107d62fe1821056e7d0b1..f0587cfd6df5138d86a4e8751202761c9165a712 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Address.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Address.cs
@@ -162,7 +162,6 @@ private void EmitMemberAddress(MemberInfo member, Type? objectType)
_ilg.Emit(OpCodes.Ldloca, temp);
}
-
private void AddressOf(MethodCallExpression node, Type type)
{
// An array index of a multi-dimensional array is represented by a call to Array.Get,
@@ -172,9 +171,9 @@ private void AddressOf(MethodCallExpression node, Type type)
// this situation and replace it with a call to the Address method.
if (!node.Method.IsStatic &&
node.Object!.Type.IsArray &&
- node.Method == node.Object.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance))
+ node.Method == TypeUtils.GetArrayGetMethod(node.Object.Type))
{
- MethodInfo mi = node.Object.Type.GetMethod("Address", BindingFlags.Public | BindingFlags.Instance)!;
+ MethodInfo mi = TypeUtils.GetArrayAddressMethod(node.Object.Type);
EmitMethodCall(node.Object, mi, node);
}
@@ -200,7 +199,7 @@ private void AddressOf(IndexExpression node, Type type)
}
else
{
- MethodInfo address = node.Object!.Type.GetMethod("Address", BindingFlags.Public | BindingFlags.Instance)!;
+ MethodInfo address = TypeUtils.GetArrayAddressMethod(node.Object!.Type);
EmitMethodCall(node.Object, address, node);
}
}
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Binary.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Binary.cs
index c28f740d7f91369332c096d5b39bfe95e0b637f7..5101d8dbdeded9ccff3bc9cc7a59c95810992eed 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Binary.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Binary.cs
@@ -475,10 +475,12 @@ private void EmitLiftedBinaryArithmetic(ExpressionType op, Type leftType, Type r
FreeLocal(locLeft);
FreeLocal(locRight);
- EmitBinaryOperator(op, leftType.GetNonNullableType(), rightType.GetNonNullableType(), resultType.GetNonNullableType(), liftedToNull: false);
+ Type resultNonNullableType = resultType.GetNonNullableType();
+
+ EmitBinaryOperator(op, leftType.GetNonNullableType(), rightType.GetNonNullableType(), resultNonNullableType, liftedToNull: false);
// construct result type
- ConstructorInfo ci = resultType.GetConstructor(new Type[] { resultType.GetNonNullableType() })!;
+ ConstructorInfo ci = TypeUtils.GetNullableConstructor(resultType, resultNonNullableType);
_ilg.Emit(OpCodes.Newobj, ci);
_ilg.Emit(OpCodes.Stloc, locResult);
_ilg.Emit(OpCodes.Br_S, labEnd);
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
index ce0cb7eb032750e07e2eaf6fe4d52fcc1d503cd0..3a1e236cc0e6e6a98168d3aa13bd615805e73d15 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
@@ -4,9 +4,11 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Dynamic.Utils;
using System.Reflection;
using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
namespace System.Linq.Expressions.Compiler
{
@@ -183,7 +185,7 @@ private void EmitInvocationExpression(Expression expr, CompilationFlags flags)
if (typeof(LambdaExpression).IsAssignableFrom(expr.Type))
{
// if the invoke target is a lambda expression tree, first compile it into a delegate
- expr = Expression.Call(expr, expr.Type.GetMethod("Compile", Type.EmptyTypes)!);
+ expr = Expression.Call(expr, LambdaExpression.GetCompileMethod(expr.Type));
}
EmitMethodCall(expr, expr.Type.GetInvokeMethod(), node, CompilationFlags.EmitAsNoTail | CompilationFlags.EmitExpressionStart);
@@ -311,7 +313,7 @@ private void EmitGetArrayElement(Type arrayType)
else
{
// Multidimensional arrays, call get
- _ilg.Emit(OpCodes.Call, arrayType.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance)!);
+ _ilg.Emit(OpCodes.Call, TypeUtils.GetArrayGetMethod(arrayType));
}
}
@@ -339,7 +341,7 @@ private void EmitSetArrayElement(Type arrayType)
else
{
// Multidimensional arrays, call set
- _ilg.Emit(OpCodes.Call, arrayType.GetMethod("Set", BindingFlags.Public | BindingFlags.Instance)!);
+ _ilg.Emit(OpCodes.Call, TypeUtils.GetArraySetMethod(arrayType));
}
}
@@ -602,7 +604,7 @@ private void EmitDynamicExpression(Expression expr)
_ilg.Emit(OpCodes.Dup);
LocalBuilder siteTemp = GetLocal(siteType);
_ilg.Emit(OpCodes.Stloc, siteTemp);
- _ilg.Emit(OpCodes.Ldfld, siteType.GetField("Target")!);
+ _ilg.Emit(OpCodes.Ldfld, GetCallSiteTargetField(siteType));
_ilg.Emit(OpCodes.Ldloc, siteTemp);
FreeLocal(siteTemp);
@@ -611,6 +613,15 @@ private void EmitDynamicExpression(Expression expr)
EmitWriteBack(wb);
}
+ [DynamicDependency("Target", typeof(CallSite<>))]
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
+ Justification = "The 'Target' field will be preserved by the DynamicDependency.")]
+ private static FieldInfo GetCallSiteTargetField(Type siteType)
+ {
+ Debug.Assert(siteType.IsGenericType && siteType.GetGenericTypeDefinition() == typeof(CallSite<>));
+ return siteType.GetField("Target")!;
+ }
+
private void EmitNewExpression(Expression expr)
{
NewExpression node = (NewExpression)expr;
@@ -1160,7 +1171,7 @@ private void EmitLift(ExpressionType nodeType, Type resultType, MethodCallExpres
EmitMethodCallExpression(mc);
if (resultType.IsNullableType() && !TypeUtils.AreEquivalent(resultType, mc.Type))
{
- ConstructorInfo ci = resultType.GetConstructor(new Type[] { mc.Type })!;
+ ConstructorInfo ci = TypeUtils.GetNullableConstructor(resultType, mc.Type);
_ilg.Emit(OpCodes.Newobj, ci);
}
_ilg.Emit(OpCodes.Br_S, exit);
@@ -1264,7 +1275,7 @@ private void EmitLift(ExpressionType nodeType, Type resultType, MethodCallExpres
EmitMethodCallExpression(mc);
if (resultType.IsNullableType() && !TypeUtils.AreEquivalent(resultType, mc.Type))
{
- ConstructorInfo ci = resultType.GetConstructor(new Type[] { mc.Type })!;
+ ConstructorInfo ci = TypeUtils.GetNullableConstructor(resultType, mc.Type);
_ilg.Emit(OpCodes.Newobj, ci);
}
_ilg.Emit(OpCodes.Br_S, exit);
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Unary.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Unary.cs
index c764b7827609b9ffb4d17edc50e4197ded1dae12..e84391a7414992dcd3ef52c3d32215abb9e9e050 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Unary.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Unary.cs
@@ -94,7 +94,7 @@ private void EmitUnary(UnaryExpression node, CompilationFlags flags)
EmitBinaryOperator(ExpressionType.SubtractChecked, nnType, nnType, nnType, liftedToNull: false);
// construct result
- _ilg.Emit(OpCodes.Newobj, type.GetConstructor(new Type[] { nnType })!);
+ _ilg.Emit(OpCodes.Newobj, TypeUtils.GetNullableConstructor(type, nnType));
_ilg.Emit(OpCodes.Br_S, end);
// if null then push back on stack
@@ -164,7 +164,7 @@ private void EmitUnaryOperator(ExpressionType op, Type operandType, Type resultT
EmitUnaryOperator(op, nnOperandType, nnOperandType);
// construct result
- ConstructorInfo ci = resultType.GetConstructor(new Type[] { nnOperandType })!;
+ ConstructorInfo ci = TypeUtils.GetNullableConstructor(resultType, nnOperandType);
_ilg.Emit(OpCodes.Newobj, ci);
_ilg.Emit(OpCodes.Br_S, labEnd);
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionStringBuilder.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionStringBuilder.cs
index 2fd6089db5c51324c7331643787863c4755f1f08..a4c704b6f81853ee5963c2043b432f1c0a1f92da 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionStringBuilder.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/ExpressionStringBuilder.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -786,6 +787,8 @@ protected internal override Expression VisitIndex(IndexExpression node)
return node;
}
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern",
+ Justification = "The 'ToString' method cannot be trimmed on any Expression type because we are calling Expression.ToString() in this method.")]
protected internal override Expression VisitExtension(Expression node)
{
// Prefer an overridden ToString, if available.
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/DefaultValueInstruction.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/DefaultValueInstruction.cs
index 0eb0332753bf3b5c8b7d7e0d6136a0d62dfe16a7..fa243f2834b551009913823879bc239043424d3e 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/DefaultValueInstruction.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/DefaultValueInstruction.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Dynamic.Utils;
namespace System.Linq.Expressions.Interpreter
@@ -21,6 +22,8 @@ internal DefaultValueInstruction(Type type)
public override string InstructionName => "DefaultValue";
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern",
+ Justification = "_type is a ValueType. You can always create an instance of a ValueType.")]
public override int Run(InterpretedFrame frame)
{
frame.Push(Activator.CreateInstance(_type));
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs
index 6f9f915169e4d31a2098244948165207095119cb..b4238cd4711d1d33d8578a1d606caa6f83a702a7 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs
@@ -593,7 +593,7 @@ private void EmitIndexGet(IndexExpression index)
}
else if (index.ArgumentCount != 1)
{
- _instructions.EmitCall(index.Object!.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance)!);
+ _instructions.EmitCall(TypeUtils.GetArrayGetMethod(index.Object!.Type));
}
else
{
@@ -632,7 +632,7 @@ private void CompileIndexAssignment(BinaryExpression node, bool asVoid)
}
else if (index.ArgumentCount != 1)
{
- _instructions.EmitCall(index.Object!.Type.GetMethod("Set", BindingFlags.Public | BindingFlags.Instance)!);
+ _instructions.EmitCall(TypeUtils.GetArraySetMethod(index.Object!.Type));
}
else
{
@@ -2343,7 +2343,7 @@ private static bool ShouldWritebackNode(Expression node)
var call = (MethodCallExpression)node;
if (!call.Method.IsStatic &&
call.Object!.Type.IsArray &&
- call.Method == call.Object.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance))
+ call.Method == TypeUtils.GetArrayGetMethod(call.Object.Type))
{
return CompileMultiDimArrayAccess(
call.Object,
@@ -2380,9 +2380,9 @@ private ByRefUpdater CompileMultiDimArrayAccess(Expression array, IArgumentProvi
indexLocals[i] = argTmp;
}
- _instructions.EmitCall(array.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance)!);
+ _instructions.EmitCall(TypeUtils.GetArrayGetMethod(array.Type));
- return new IndexMethodByRefUpdater(objTmp, indexLocals, array.Type.GetMethod("Set", BindingFlags.Public | BindingFlags.Instance)!, index);
+ return new IndexMethodByRefUpdater(objTmp, indexLocals, TypeUtils.GetArraySetMethod(array.Type), index);
}
private void CompileNewExpression(Expression expr)
@@ -2671,7 +2671,7 @@ private void CompileInvocationExpression(Expression expr)
if (typeof(LambdaExpression).IsAssignableFrom(node.Expression.Type))
{
- MethodInfo compMethod = node.Expression.Type.GetMethod("Compile", Type.EmptyTypes)!;
+ MethodInfo compMethod = LambdaExpression.GetCompileMethod(node.Expression.Type);
CompileMethodCallExpression(
Expression.Call(
node.Expression,
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LocalAccess.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LocalAccess.cs
index 8cc0bf98ee0f040759247bbadd6eb16f87b310dd..713a48da332ab2486e743aa3c89c5da34615034f 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LocalAccess.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LocalAccess.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Dynamic.Utils;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -373,9 +374,13 @@ internal sealed class MutableValue : InitializeLocalInstruction, IBoxableInstruc
internal MutableValue(int index, Type type)
: base(index)
{
+ Debug.Assert(type.IsValueType, "MutableValue only supports value types.");
+
_type = type;
}
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern",
+ Justification = "_type is a ValueType. You can always create an instance of a ValueType.")]
public override int Run(InterpretedFrame frame)
{
try
@@ -406,9 +411,13 @@ internal sealed class MutableBox : InitializeLocalInstruction
internal MutableBox(int index, Type type)
: base(index)
{
+ Debug.Assert(type.IsValueType, "MutableBox only supports value types.");
+
_type = type;
}
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern",
+ Justification = "_type is a ValueType. You can always create an instance of a ValueType.")]
public override int Run(InterpretedFrame frame)
{
object? value;
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs
index 8f50c40fd7d3a9f95e991877165a77c655bb011f..fc45b9c5ff81f872fe3933a124ed23609e21a4a0 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/LambdaExpression.cs
@@ -102,6 +102,39 @@ internal virtual int ParameterCount
}
}
+ ///
+ /// Gets the Compile() MethodInfo on the specified LambdaExpression type.
+ ///
+ ///
+ /// Note that Expression{TDelegate} defines a 'new' Compile() method that hides the base
+ /// LambdaExpression.Compile() method.
+ ///
+ internal static MethodInfo GetCompileMethod(Type lambdaExpressionType)
+ {
+ Debug.Assert(lambdaExpressionType.IsAssignableTo(typeof(LambdaExpression)));
+
+ if (lambdaExpressionType == typeof(LambdaExpression))
+ {
+ // use a hard-coded type directly so the method doesn't get trimmed
+ return typeof(LambdaExpression).GetMethod("Compile", Type.EmptyTypes)!;
+ }
+
+ return GetDerivedCompileMethod(lambdaExpressionType);
+ }
+
+ [DynamicDependency("Compile()", typeof(Expression<>))]
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",
+ Justification = "The 'Compile' method will be preserved by the DynamicDependency.")]
+ private static MethodInfo GetDerivedCompileMethod(Type lambdaExpressionType)
+ {
+ Debug.Assert(lambdaExpressionType.IsAssignableTo(typeof(LambdaExpression)) && lambdaExpressionType != typeof(LambdaExpression));
+
+ MethodInfo result = lambdaExpressionType.GetMethod("Compile", Type.EmptyTypes)!;
+ Debug.Assert(result.DeclaringType!.IsGenericType && result.DeclaringType.GetGenericTypeDefinition() == typeof(Expression<>));
+
+ return result;
+ }
+
///
/// Produces a delegate that represents the lambda expression.
///
diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs
index 248f63dba1d9ffe069b149f4d0fd69f1b218a5bf..b4d871b27fce83343fbcb09db36f4e5b9d3f9713 100644
--- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs
+++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs
@@ -1401,8 +1401,6 @@ public static MethodCallExpression ArrayIndex(Expression array, params Expressio
/// or is null.
///
/// .Type does not represent an array type.-or-The rank of .Type does not match the number of elements in .-or-The property of one or more elements of does not represent the type.
- [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern",
- Justification = "The Array 'Get' method is dynamically constructed and are not included in IL. It is not subject to trimming.")]
public static MethodCallExpression ArrayIndex(Expression array, IEnumerable indexes)
{
ExpressionUtils.RequiresCanRead(array, nameof(array), -1);
@@ -1431,7 +1429,7 @@ public static MethodCallExpression ArrayIndex(Expression array, IEnumerable