diff --git a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs index 4f96e2b3e..f8a5b79b4 100644 --- a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs @@ -369,7 +369,14 @@ namespace ICSharpCode.Decompiler.Ast case ILCode.Conv_U8: case ILCode.Conv_I: case ILCode.Conv_U: - return arg1; // conversion is handled by Convert() function using the info from type analysis + { + // conversion was handled by Convert() function using the info from type analysis + CastExpression cast = arg1 as CastExpression; + if (cast != null) { + cast.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation); + } + return arg1; + } case ILCode.Conv_R4: return arg1.CastTo(typeof(float)); case ILCode.Conv_R8: return arg1.CastTo(typeof(double)); case ILCode.Conv_R_Un: return arg1.CastTo(typeof(double)); // TODO @@ -389,7 +396,14 @@ namespace ICSharpCode.Decompiler.Ast case ILCode.Conv_Ovf_U2_Un: case ILCode.Conv_Ovf_U4_Un: case ILCode.Conv_Ovf_U8_Un: - return arg1; // conversion was handled by Convert() function using the info from type analysis + { + // conversion was handled by Convert() function using the info from type analysis + CastExpression cast = arg1 as CastExpression; + if (cast != null) { + cast.AddAnnotation(AddCheckedBlocks.CheckedAnnotation); + } + return arg1; + } case ILCode.Conv_Ovf_I: return arg1.CastTo(typeof(IntPtr)); // TODO case ILCode.Conv_Ovf_U: return arg1.CastTo(typeof(UIntPtr)); case ILCode.Conv_Ovf_I_Un: return arg1.CastTo(typeof(IntPtr)); diff --git a/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs b/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs index 768257c06..7eca47d99 100644 --- a/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs +++ b/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs @@ -689,7 +689,9 @@ namespace ICSharpCode.Decompiler.ILAst } else if (targetBitSize >= NativeInt && argType is PointerType) { return argType; } - return (GetInformationAmount(expectedType) == targetBitSize && IsSigned(expectedType) == targetSigned) ? expectedType : targetType; + TypeReference resultType = (GetInformationAmount(expectedType) == targetBitSize && IsSigned(expectedType) == targetSigned) ? expectedType : targetType; + arg.ExpectedType = resultType; // store the expected type in the argument so that AstMethodBodyBuilder will insert a cast + return resultType; } static TypeReference GetFieldType(FieldReference fieldReference) diff --git a/ICSharpCode.Decompiler/Tests/CheckedUnchecked.cs b/ICSharpCode.Decompiler/Tests/CheckedUnchecked.cs index 6a39459c6..21533d69e 100644 --- a/ICSharpCode.Decompiler/Tests/CheckedUnchecked.cs +++ b/ICSharpCode.Decompiler/Tests/CheckedUnchecked.cs @@ -19,6 +19,14 @@ public class CheckedUnchecked int u5 = unchecked(a % b); } + public void Cast(int a) + { + short c1 = checked((short)a); + short u1 = unchecked((short)a); + byte c2 = checked((byte)a); + byte u2 = unchecked((byte)a); + } + public void ForWithCheckedIteratorAndUncheckedBody(int n) { checked {