Browse Source

Fixed type inference for shift operators. Closes #239.

pull/252/head
Daniel Grunwald 15 years ago
parent
commit
8beed6aa70
  1. 33
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  2. 30
      ICSharpCode.Decompiler/Tests/TypeAnalysisTests.cs

33
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -515,14 +515,20 @@ namespace ICSharpCode.Decompiler.ILAst @@ -515,14 +515,20 @@ namespace ICSharpCode.Decompiler.ILAst
case ILCode.Rem_Un:
return InferArgumentsInBinaryOperator(expr, false, expectedType);
case ILCode.Shl:
case ILCode.Shr:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
return InferTypeForExpression(expr.Arguments[0], typeSystem.Int32);
if (expectedType != null && (
expectedType.MetadataType == MetadataType.Int32 || expectedType.MetadataType == MetadataType.UInt32 ||
expectedType.MetadataType == MetadataType.Int64 || expectedType.MetadataType == MetadataType.UInt64)
)
return NumericPromotion(InferTypeForExpression(expr.Arguments[0], expectedType));
else
return NumericPromotion(InferTypeForExpression(expr.Arguments[0], null));
case ILCode.Shr:
case ILCode.Shr_Un:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[1], typeSystem.Int32);
return InferTypeForExpression(expr.Arguments[0], typeSystem.UInt32);
return NumericPromotion(InferTypeForExpression(expr.Arguments[0], null));
case ILCode.CompoundAssignment:
{
TypeReference varType = InferTypeForExpression(expr.Arguments[0].Arguments[0], null);
@ -763,6 +769,27 @@ namespace ICSharpCode.Decompiler.ILAst @@ -763,6 +769,27 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
/// <summary>
/// Promotes primitive types smaller than int32 to int32.
/// </summary>
/// <remarks>
/// Always promotes to signed int32.
/// </remarks>
TypeReference NumericPromotion(TypeReference type)
{
if (type == null)
return null;
switch (type.MetadataType) {
case MetadataType.SByte:
case MetadataType.Int16:
case MetadataType.Byte:
case MetadataType.UInt16:
return typeSystem.Int32;
default:
return type;
}
}
TypeReference HandleConversion(int targetBitSize, bool targetSigned, ILExpression arg, TypeReference expectedType, TypeReference targetType)
{
if (targetBitSize >= NativeInt && expectedType is PointerType) {

30
ICSharpCode.Decompiler/Tests/TypeAnalysisTests.cs

@ -24,4 +24,34 @@ public class TypeAnalysisTests @@ -24,4 +24,34 @@ public class TypeAnalysisTests
{
return (byte)(256 - (int)b);
}
public int GetHashCode(long num)
{
return (int)num ^ (int)(num >> 32);
}
public int ShiftByte(byte num)
{
return (int)num << 8;
}
public int RShiftByte(byte num)
{
return num >> 8;
}
public int RShiftByteWithSignExtension(byte num)
{
return (sbyte)num >> 8;
}
public int RShiftSByte(sbyte num)
{
return num >> 8;
}
public int RShiftSByteWithZeroExtension(sbyte num)
{
return (byte)num >> 8;
}
}

Loading…
Cancel
Save