mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
Always pass the type system into InferType().
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
@@ -215,17 +216,15 @@ namespace ICSharpCode.Decompiler.IL
|
||||
/// If not returning UnknownType, must return a type that can store
|
||||
/// the result of the instruction without loss of information.
|
||||
/// </remarks>
|
||||
public static IType InferType(this ILInstruction inst, ICompilation? compilation)
|
||||
public static IType InferType(this ILInstruction inst, ICompilation compilation)
|
||||
{
|
||||
Debug.Assert(compilation != null);
|
||||
switch (inst)
|
||||
{
|
||||
case NewObj newObj:
|
||||
return newObj.Method.DeclaringType ?? SpecialType.UnknownType;
|
||||
case NewArr newArr:
|
||||
if (compilation != null)
|
||||
return new ArrayType(compilation, newArr.Type, newArr.Indices.Count);
|
||||
else
|
||||
return SpecialType.UnknownType;
|
||||
return new ArrayType(compilation, newArr.Type, newArr.Indices.Count);
|
||||
case Call call:
|
||||
return call.Method.ReturnType;
|
||||
case CallVirt callVirt:
|
||||
@@ -258,8 +257,6 @@ namespace ICSharpCode.Decompiler.IL
|
||||
}
|
||||
return new ByReferenceType(ldelema.Type);
|
||||
case Comp comp:
|
||||
if (compilation == null)
|
||||
return SpecialType.UnknownType;
|
||||
switch (comp.LiftingKind)
|
||||
{
|
||||
case ComparisonLiftingKind.None:
|
||||
|
||||
@@ -153,10 +153,11 @@ namespace ICSharpCode.Decompiler.IL
|
||||
public bool IsLifted { get; }
|
||||
|
||||
public NumericCompoundAssign(BinaryNumericInstruction binary, ILInstruction target,
|
||||
CompoundTargetKind targetKind, ILInstruction value, IType type, CompoundEvalMode evalMode)
|
||||
CompoundTargetKind targetKind, ILInstruction value, IType type, CompoundEvalMode evalMode,
|
||||
Transforms.ILTransformContext context)
|
||||
: base(OpCode.NumericCompoundAssign, evalMode, target, targetKind, value)
|
||||
{
|
||||
Debug.Assert(IsBinaryCompatibleWithType(binary, type, null));
|
||||
Debug.Assert(IsBinaryCompatibleWithType(binary, type, context));
|
||||
this.CheckForOverflow = binary.CheckForOverflow;
|
||||
this.Sign = binary.Sign;
|
||||
this.LeftInputType = binary.LeftInputType;
|
||||
@@ -166,14 +167,14 @@ namespace ICSharpCode.Decompiler.IL
|
||||
this.IsLifted = binary.IsLifted;
|
||||
this.type = type;
|
||||
this.AddILRange(binary);
|
||||
Debug.Assert(evalMode == CompoundEvalMode.EvaluatesToNewValue || (Operator == BinaryNumericOperator.Add || Operator == BinaryNumericOperator.Sub));
|
||||
Debug.Assert(evalMode == CompoundEvalMode.EvaluatesToNewValue || Operator == BinaryNumericOperator.Add || Operator == BinaryNumericOperator.Sub);
|
||||
Debug.Assert(this.ResultType == (IsLifted ? StackType.O : UnderlyingResultType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the specific binary instruction is compatible with a compound operation on the specified type.
|
||||
/// </summary>
|
||||
internal static bool IsBinaryCompatibleWithType(BinaryNumericInstruction binary, IType type, DecompilerSettings? settings)
|
||||
internal static bool IsBinaryCompatibleWithType(BinaryNumericInstruction binary, IType type, Transforms.ILTransformContext context)
|
||||
{
|
||||
if (binary.IsLifted)
|
||||
{
|
||||
@@ -220,7 +221,7 @@ namespace ICSharpCode.Decompiler.IL
|
||||
// If the LHS is C# 9 IntPtr (but not nint or C# 11 IntPtr):
|
||||
// "target.intptr *= 2;" is compiler error, but
|
||||
// "target.intptr *= (nint)2;" works
|
||||
if (settings != null && !settings.NativeIntegers)
|
||||
if (!context.Settings.NativeIntegers)
|
||||
{
|
||||
// But if native integers are not available, we cannot use compound assignment.
|
||||
return false;
|
||||
@@ -235,7 +236,7 @@ namespace ICSharpCode.Decompiler.IL
|
||||
}
|
||||
if (binary.Sign != Sign.None)
|
||||
{
|
||||
bool signMismatchAllowed = (binary.Sign == Sign.Unsigned && binary.Operator == BinaryNumericOperator.ShiftRight && (settings == null || settings.UnsignedRightShift));
|
||||
bool signMismatchAllowed = binary.Sign == Sign.Unsigned && binary.Operator == BinaryNumericOperator.ShiftRight && context.Settings.UnsignedRightShift;
|
||||
if (type.IsCSharpSmallIntegerType())
|
||||
{
|
||||
// C# will use numeric promotion to int, binary op must be signed
|
||||
@@ -250,7 +251,7 @@ namespace ICSharpCode.Decompiler.IL
|
||||
}
|
||||
}
|
||||
// Can't transform if the RHS value would be need to be truncated for the LHS type.
|
||||
if (Transforms.TransformAssignment.IsImplicitTruncation(binary.Right, type, null, binary.IsLifted))
|
||||
if (Transforms.TransformAssignment.IsImplicitTruncation(binary.Right, type, context.TypeSystem, binary.IsLifted))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
using ICSharpCode.Decompiler.CSharp;
|
||||
using ICSharpCode.Decompiler.CSharp.Transforms;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
|
||||
@@ -263,9 +264,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
||||
return inst;
|
||||
}
|
||||
|
||||
static bool ValidateCompoundAssign(BinaryNumericInstruction binary, Conv? conv, IType targetType, DecompilerSettings settings)
|
||||
static bool ValidateCompoundAssign(BinaryNumericInstruction binary, Conv? conv, IType targetType, ILTransformContext context)
|
||||
{
|
||||
if (!NumericCompoundAssign.IsBinaryCompatibleWithType(binary, targetType, settings))
|
||||
if (!NumericCompoundAssign.IsBinaryCompatibleWithType(binary, targetType, context))
|
||||
return false;
|
||||
if (conv != null && !(conv.TargetType == targetType.ToPrimitiveType() && conv.CheckForOverflow == binary.CheckForOverflow))
|
||||
return false; // conv does not match binary operation
|
||||
@@ -381,13 +382,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
||||
}
|
||||
if (!IsMatchingCompoundLoad(binary.Left, compoundStore, out var target, out var targetKind, out var finalizeMatch, forbiddenVariable: storeInSetter?.Variable))
|
||||
return false;
|
||||
if (!ValidateCompoundAssign(binary, smallIntConv, targetType, context.Settings))
|
||||
if (!ValidateCompoundAssign(binary, smallIntConv, targetType, context))
|
||||
return false;
|
||||
context.Step($"Compound assignment (binary.numeric)", compoundStore);
|
||||
finalizeMatch?.Invoke(context);
|
||||
newInst = new NumericCompoundAssign(
|
||||
binary, target, targetKind, binary.Right,
|
||||
targetType, CompoundEvalMode.EvaluatesToNewValue);
|
||||
targetType, CompoundEvalMode.EvaluatesToNewValue, context);
|
||||
}
|
||||
else if (setterValue is Call operatorCall && operatorCall.Method.IsOperator)
|
||||
{
|
||||
@@ -887,7 +888,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
||||
targetType = SwapSign(targetType, context.TypeSystem);
|
||||
}
|
||||
|
||||
if (!ValidateCompoundAssign(binary, conv, targetType, context.Settings))
|
||||
if (!ValidateCompoundAssign(binary, conv, targetType, context))
|
||||
return false;
|
||||
ldloc = binary.Left as LdLoc;
|
||||
}
|
||||
@@ -920,7 +921,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
||||
if (binary != null)
|
||||
{
|
||||
block.Instructions[pos] = new StLoc(stloc_outer.Variable, new NumericCompoundAssign(
|
||||
binary, target, targetKind, binary.Right, targetType, CompoundEvalMode.EvaluatesToNewValue));
|
||||
binary, target, targetKind, binary.Right, targetType, CompoundEvalMode.EvaluatesToNewValue, context));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -972,7 +973,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
||||
targetType = SwapSign(targetType, context.TypeSystem);
|
||||
}
|
||||
|
||||
if (!ValidateCompoundAssign(binary, conv, targetType, context.Settings))
|
||||
if (!ValidateCompoundAssign(binary, conv, targetType, context))
|
||||
return false;
|
||||
stloc = binary.Left as StLoc;
|
||||
}
|
||||
@@ -1001,7 +1002,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
||||
if (binary != null)
|
||||
{
|
||||
block.Instructions[pos] = new StLoc(stloc.Variable, new NumericCompoundAssign(
|
||||
binary, target, targetKind, binary.Right, targetType, CompoundEvalMode.EvaluatesToOldValue));
|
||||
binary, target, targetKind, binary.Right, targetType, CompoundEvalMode.EvaluatesToOldValue, context));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1080,12 +1081,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
||||
// Change the sign of the type to skip implicit truncation
|
||||
stObj.Type = targetType = SwapSign(targetType, context.TypeSystem);
|
||||
}
|
||||
if (!ValidateCompoundAssign(binary, conv, targetType, context.Settings))
|
||||
if (!ValidateCompoundAssign(binary, conv, targetType, context))
|
||||
return false;
|
||||
context.Step("TransformPostIncDecOperator (builtin)", inst);
|
||||
finalizeMatch?.Invoke(context);
|
||||
inst.Value = new NumericCompoundAssign(binary, target, targetKind, binary.Right,
|
||||
targetType, CompoundEvalMode.EvaluatesToOldValue);
|
||||
targetType, CompoundEvalMode.EvaluatesToOldValue, context);
|
||||
}
|
||||
else if (value is Call operatorCall && operatorCall.Method.IsOperator && operatorCall.Arguments.Count == 1)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user