Browse Source

Always pass the type system into InferType().

pull/4089/head
Daniel Grunwald 2 weeks ago
parent
commit
cf4dba7015
  1. 11
      ICSharpCode.Decompiler/IL/ILTypeExtensions.cs
  2. 15
      ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs
  3. 21
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

11
ICSharpCode.Decompiler/IL/ILTypeExtensions.cs

@ -17,6 +17,7 @@ @@ -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 @@ -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 @@ -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:

15
ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs

@ -153,10 +153,11 @@ namespace ICSharpCode.Decompiler.IL @@ -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 @@ -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 @@ -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 @@ -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 @@ -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;
}

21
ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

@ -25,6 +25,7 @@ using System.Linq; @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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)
{

Loading…
Cancel
Save