Browse Source

Fixed type analysis for right shift operator.

pull/252/head
Daniel Grunwald 15 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
return NumericPromotion(InferTypeForExpression(expr.Arguments[0], null)); return NumericPromotion(InferTypeForExpression(expr.Arguments[0], null));
case ILCode.Shr: case ILCode.Shr:
case ILCode.Shr_Un: case ILCode.Shr_Un:
if (forceInferChildren) {
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32); if (forceInferChildren)
return NumericPromotion(InferTypeForExpression(expr.Arguments[0], null)); 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: case ILCode.CompoundAssignment:
{ {
TypeReference varType = InferTypeForExpression(expr.Arguments[0].Arguments[0], null); TypeReference varType = InferTypeForExpression(expr.Arguments[0].Arguments[0], null);
@ -1097,7 +1124,6 @@ namespace ICSharpCode.Decompiler.ILAst
return char.MinValue <= num && num <= char.MaxValue; return char.MinValue <= num && num <= char.MaxValue;
case MetadataType.UInt16: case MetadataType.UInt16:
return ushort.MinValue <= num && num <= ushort.MaxValue; return ushort.MinValue <= num && num <= ushort.MaxValue;
break;
default: default:
return true; return true;
} }

60
ICSharpCode.Decompiler/Tests/TypeAnalysisTests.cs

@ -25,9 +25,45 @@ public class TypeAnalysisTests
return (byte)(256 - (int)b); 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) public int ShiftByte(byte num)
@ -40,7 +76,12 @@ public class TypeAnalysisTests
return num >> 8; 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; return (sbyte)num >> 8;
} }
@ -50,8 +91,19 @@ public class TypeAnalysisTests
return num >> 8; 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; return (byte)num >> 8;
} }
#endregion
public int GetHashCode(long num)
{
return (int)num ^ (int)(num >> 32);
}
} }

Loading…
Cancel
Save