Browse Source

Merge branch 'krauthaufen-Cgt_Un-Cle_Un-fix'

pull/550/head
Siegfried Pammer 10 years ago
parent
commit
90796b20c9
  1. 28
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 35
      ICSharpCode.Decompiler/CecilExtensions.cs
  3. 17
      ICSharpCode.Decompiler/Tests/ValueTypes.cs

28
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -52,8 +52,8 @@ namespace ICSharpCode.Decompiler.Ast @@ -52,8 +52,8 @@ namespace ICSharpCode.Decompiler.Ast
/// These are used to update the parameter names when the decompiler generates names for the parameters.</param>
/// <returns>Block for the method body</returns>
public static BlockStatement CreateMethodBody(MethodDefinition methodDef,
DecompilerContext context,
IEnumerable<ParameterDeclaration> parameters = null)
DecompilerContext context,
IEnumerable<ParameterDeclaration> parameters = null)
{
MethodDefinition oldCurrentMethod = context.CurrentMethod;
Debug.Assert(oldCurrentMethod == null || oldCurrentMethod == methodDef);
@ -103,8 +103,8 @@ namespace ICSharpCode.Decompiler.Ast @@ -103,8 +103,8 @@ namespace ICSharpCode.Decompiler.Ast
if (parameters != null) {
foreach (var pair in (from p in parameters
join v in astBuilder.Parameters on p.Annotation<ParameterDefinition>() equals v.OriginalParameter
select new { p, v.Name }))
join v in astBuilder.Parameters on p.Annotation<ParameterDefinition>() equals v.OriginalParameter
select new { p, v.Name }))
{
pair.p.Name = pair.Name;
}
@ -204,7 +204,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -204,7 +204,7 @@ namespace ICSharpCode.Decompiler.Ast
tryCatchStmt.TryBlock = TransformBlock(tryCatchNode.TryBlock);
foreach (var catchClause in tryCatchNode.CatchBlocks) {
if (catchClause.ExceptionVariable == null
&& (catchClause.ExceptionType == null || catchClause.ExceptionType.MetadataType == MetadataType.Object))
&& (catchClause.ExceptionType == null || catchClause.ExceptionType.MetadataType == MetadataType.Object))
{
tryCatchStmt.CatchClauses.Add(new Ast.CatchClause { Body = TransformBlock(catchClause) });
} else {
@ -460,12 +460,30 @@ namespace ICSharpCode.Decompiler.Ast @@ -460,12 +460,30 @@ namespace ICSharpCode.Decompiler.Ast
// can also mean Inequality, when used with object references
TypeReference arg1Type = byteCode.Arguments[0].InferredType;
if (arg1Type != null && !arg1Type.IsValueType) goto case ILCode.Cne;
// when comparing signed integral values using Cgt_Un with 0
// the Ast should actually contain InEquality since "(uint)a > 0u" is identical to "a != 0"
if (arg1Type.IsSignedIntegralType())
{
var p = arg2 as Ast.PrimitiveExpression;
if (p != null && p.Value.IsZero()) goto case ILCode.Cne;
}
goto case ILCode.Cgt;
}
case ILCode.Cle_Un: {
// can also mean Equality, when used with object references
TypeReference arg1Type = byteCode.Arguments[0].InferredType;
if (arg1Type != null && !arg1Type.IsValueType) goto case ILCode.Ceq;
// when comparing signed integral values using Cle_Un with 0
// the Ast should actually contain Equality since "(uint)a <= 0u" is identical to "a == 0"
if (arg1Type.IsSignedIntegralType())
{
var p = arg2 as Ast.PrimitiveExpression;
if (p != null && p.Value.IsZero()) goto case ILCode.Ceq;
}
goto case ILCode.Cle;
}
case ILCode.Cle: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2);

35
ICSharpCode.Decompiler/CecilExtensions.cs

@ -126,6 +126,41 @@ namespace ICSharpCode.Decompiler @@ -126,6 +126,41 @@ namespace ICSharpCode.Decompiler
return false;
return type.IsValueType || type.IsVoid();
}
/// <summary>
/// checks if the given TypeReference is one of the following types:
/// [sbyte, short, int, long, IntPtr]
/// </summary>
public static bool IsSignedIntegralType(this TypeReference type)
{
return type.MetadataType == MetadataType.SByte ||
type.MetadataType == MetadataType.Int16 ||
type.MetadataType == MetadataType.Int32 ||
type.MetadataType == MetadataType.Int64 ||
type.MetadataType == MetadataType.IntPtr;
}
/// <summary>
/// checks if the given value is a numeric zero-value.
/// NOTE that this only works for types: [sbyte, short, int, long, IntPtr, byte, ushort, uint, ulong, float, double and decimal]
/// </summary>
public static bool IsZero(this object value)
{
return value.Equals((sbyte)0) ||
value.Equals((short)0) ||
value.Equals(0) ||
value.Equals(0L) ||
value.Equals(IntPtr.Zero) ||
value.Equals((byte)0) ||
value.Equals((ushort)0) ||
value.Equals(0u) ||
value.Equals(0UL) ||
value.Equals(0.0f) ||
value.Equals(0.0) ||
value.Equals((decimal)0);
}
#endregion
/// <summary>

17
ICSharpCode.Decompiler/Tests/ValueTypes.cs

@ -168,4 +168,21 @@ public static class ValueTypes @@ -168,4 +168,21 @@ public static class ValueTypes
Console.WriteLine("true");
}
}
public static void CompareNotEqual0IsReallyNotEqual(IComparable<int> a)
{
if (a.CompareTo(0) != 0)
{
Console.WriteLine("true");
}
}
public static void CompareEqual0IsReallyEqual(IComparable<int> a)
{
if (a.CompareTo(0) == 0)
{
Console.WriteLine("true");
}
}
}

Loading…
Cancel
Save