Browse Source

Fixed type analysis for right shift operator.

pull/252/head
Daniel Grunwald 14 years ago
parent
commit
3020bc9ce8
  1. 34
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  2. 60
      ICSharpCode.Decompiler/Tests/TypeAnalysisTests.cs

34
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -526,9 +526,36 @@ namespace ICSharpCode.Decompiler.ILAst @@ -526,9 +526,36 @@ namespace ICSharpCode.Decompiler.ILAst
return NumericPromotion(InferTypeForExpression(expr.Arguments[0], null));
case ILCode.Shr:
case ILCode.Shr_Un:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
return NumericPromotion(InferTypeForExpression(expr.Arguments[0], null));
{
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
TypeReference type = NumericPromotion(InferTypeForExpression(expr.Arguments[0], null));
TypeReference expectedInputType = null;
switch (type.MetadataType) {
case MetadataType.Int32:
if (expr.Code == ILCode.Shr_Un)
expectedInputType = typeSystem.UInt32;
break;
case MetadataType.UInt32:
if (expr.Code == ILCode.Shr)
expectedInputType = typeSystem.Int32;
break;
case MetadataType.Int64:
if (expr.Code == ILCode.Shr_Un)
expectedInputType = typeSystem.UInt64;
break;
case MetadataType.UInt64:
if (expr.Code == ILCode.Shr)
expectedInputType = typeSystem.UInt64;
break;
}
if (expectedInputType != null) {
InferTypeForExpression(expr.Arguments[0], expectedInputType);
return expectedInputType;
} else {
return type;
}
}
case ILCode.CompoundAssignment:
{
TypeReference varType = InferTypeForExpression(expr.Arguments[0].Arguments[0], null);
@ -1097,7 +1124,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -1097,7 +1124,6 @@ namespace ICSharpCode.Decompiler.ILAst
return char.MinValue <= num && num <= char.MaxValue;
case MetadataType.UInt16:
return ushort.MinValue <= num && num <= ushort.MaxValue;
break;
default:
return true;
}

60
ICSharpCode.Decompiler/Tests/TypeAnalysisTests.cs

@ -25,9 +25,45 @@ public class TypeAnalysisTests @@ -25,9 +25,45 @@ public class TypeAnalysisTests
return (byte)(256 - (int)b);
}
public int GetHashCode(long num)
#region Shift
public int LShiftInteger(int num1, int num2)
{
return (int)num ^ (int)(num >> 32);
return num1 << num2;
}
public uint LShiftUnsignedInteger(uint num1, uint num2)
{
return num1 << (int)num2;
}
public long LShiftLong(long num1, long num2)
{
return num1 << (int)num2;
}
public ulong LShiftUnsignedLong(ulong num1, ulong num2)
{
return num1 << (int)num2;
}
public int RShiftInteger(int num1, int num2)
{
return num1 >> num2;
}
public uint RShiftUnsignedInteger(uint num1, int num2)
{
return num1 >> num2;
}
public long RShiftLong(long num1, long num2)
{
return num1 >> (int)num2;
}
public ulong RShiftUnsignedLong(ulong num1, ulong num2)
{
return num1 >> (int)num2;
}
public int ShiftByte(byte num)
@ -40,7 +76,12 @@ public class TypeAnalysisTests @@ -40,7 +76,12 @@ public class TypeAnalysisTests
return num >> 8;
}
public int RShiftByteWithSignExtension(byte num)
public uint RShiftByteWithZeroExtension(byte num)
{
return (uint)num >> 8;
}
public int RShiftByteAsSByte(byte num)
{
return (sbyte)num >> 8;
}
@ -50,8 +91,19 @@ public class TypeAnalysisTests @@ -50,8 +91,19 @@ public class TypeAnalysisTests
return num >> 8;
}
public int RShiftSByteWithZeroExtension(sbyte num)
public uint RShiftSByteWithZeroExtension(sbyte num)
{
return (uint)num >> 8;
}
public int RShiftSByteAsByte(sbyte num)
{
return (byte)num >> 8;
}
#endregion
public int GetHashCode(long num)
{
return (int)num ^ (int)(num >> 32);
}
}

Loading…
Cancel
Save