Browse Source

Fix #1301: casts were unnecessarily marked as unchecked

pull/1317/head
Daniel Grunwald 7 years ago
parent
commit
3cbadb7134
  1. 24
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.cs
  2. 76
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.il
  3. 65
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.opt.il
  4. 61
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.opt.roslyn.il
  5. 83
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.roslyn.il
  6. 4
      ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

24
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.cs

@ -103,5 +103,29 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -103,5 +103,29 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
Console.WriteLine(new int[checked(a + b)]);
}
public short Unbox(TypeCode c, object b)
{
checked {
switch (c) {
case TypeCode.Int32:
return (short)((Box<int>)b).Value;
case TypeCode.UInt32:
return (short)((Box<uint>)b).Value;
case TypeCode.Double: {
float num = (float)((Box<double>)b).Value;
Console.WriteLine(num);
return (short)num;
}
default:
throw new Exception();
}
}
}
}
internal class Box<T>
{
public readonly T Value;
}
}

76
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.il

@ -345,6 +345,66 @@ @@ -345,6 +345,66 @@
IL_000f: ret
} // end of method CheckedUnchecked::CheckedInArrayCreationArgument
.method public hidebysig instance int16
Unbox(valuetype [mscorlib]System.TypeCode c,
object b) cil managed
{
// Code size 92 (0x5c)
.maxstack 2
.locals init (float32 V_0,
int16 V_1,
valuetype [mscorlib]System.TypeCode V_2)
IL_0000: nop
IL_0001: nop
IL_0002: ldarg.1
IL_0003: stloc.2
IL_0004: ldloc.2
IL_0005: ldc.i4.s 9
IL_0007: sub
IL_0008: switch (
IL_001c,
IL_002b)
IL_0015: ldloc.2
IL_0016: ldc.i4.s 14
IL_0018: beq.s IL_003a
IL_001a: br.s IL_0054
IL_001c: ldarg.2
IL_001d: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<int32>
IL_0022: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<int32>::Value
IL_0027: conv.ovf.i2
IL_0028: stloc.1
IL_0029: br.s IL_005a
IL_002b: ldarg.2
IL_002c: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<uint32>
IL_0031: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<uint32>::Value
IL_0036: conv.ovf.i2.un
IL_0037: stloc.1
IL_0038: br.s IL_005a
IL_003a: nop
IL_003b: ldarg.2
IL_003c: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<float64>
IL_0041: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<float64>::Value
IL_0046: conv.r4
IL_0047: stloc.0
IL_0048: ldloc.0
IL_0049: call void [mscorlib]System.Console::WriteLine(float32)
IL_004e: nop
IL_004f: ldloc.0
IL_0050: conv.ovf.i2
IL_0051: stloc.1
IL_0052: br.s IL_005a
IL_0054: newobj instance void [mscorlib]System.Exception::.ctor()
IL_0059: throw
IL_005a: ldloc.1
IL_005b: ret
} // end of method CheckedUnchecked::Unbox
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
@ -440,6 +500,22 @@ @@ -440,6 +500,22 @@
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CheckedUnchecked
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<T>
extends [mscorlib]System.Object
{
.field public initonly !T Value
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Box`1::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1
.class private auto ansi sealed beforefieldinit '<>f__AnonymousType0`2'<'<x>j__TPar','<l>j__TPar'>
extends [mscorlib]System.Object
{

65
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.opt.il

@ -300,6 +300,55 @@ @@ -300,6 +300,55 @@
IL_000d: ret
} // end of method CheckedUnchecked::CheckedInArrayCreationArgument
.method public hidebysig instance int16
Unbox(valuetype [mscorlib]System.TypeCode c,
object b) cil managed
{
// Code size 80 (0x50)
.maxstack 2
.locals init (float32 V_0,
valuetype [mscorlib]System.TypeCode V_1)
IL_0000: ldarg.1
IL_0001: stloc.1
IL_0002: ldloc.1
IL_0003: ldc.i4.s 9
IL_0005: sub
IL_0006: switch (
IL_001a,
IL_0027)
IL_0013: ldloc.1
IL_0014: ldc.i4.s 14
IL_0016: beq.s IL_0034
IL_0018: br.s IL_004a
IL_001a: ldarg.2
IL_001b: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<int32>
IL_0020: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<int32>::Value
IL_0025: conv.ovf.i2
IL_0026: ret
IL_0027: ldarg.2
IL_0028: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<uint32>
IL_002d: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<uint32>::Value
IL_0032: conv.ovf.i2.un
IL_0033: ret
IL_0034: ldarg.2
IL_0035: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<float64>
IL_003a: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<float64>::Value
IL_003f: conv.r4
IL_0040: stloc.0
IL_0041: ldloc.0
IL_0042: call void [mscorlib]System.Console::WriteLine(float32)
IL_0047: ldloc.0
IL_0048: conv.ovf.i2
IL_0049: ret
IL_004a: newobj instance void [mscorlib]System.Exception::.ctor()
IL_004f: throw
} // end of method CheckedUnchecked::Unbox
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
@ -380,6 +429,22 @@ @@ -380,6 +429,22 @@
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CheckedUnchecked
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<T>
extends [mscorlib]System.Object
{
.field public initonly !T Value
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Box`1::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1
.class private auto ansi sealed beforefieldinit '<>f__AnonymousType0`2'<'<x>j__TPar','<l>j__TPar'>
extends [mscorlib]System.Object
{

61
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.opt.roslyn.il

@ -574,6 +574,51 @@ @@ -574,6 +574,51 @@
IL_000d: ret
} // end of method CheckedUnchecked::CheckedInArrayCreationArgument
.method public hidebysig instance int16
Unbox(valuetype [mscorlib]System.TypeCode c,
object b) cil managed
{
// Code size 69 (0x45)
.maxstack 2
IL_0000: ldarg.1
IL_0001: ldc.i4.s 9
IL_0003: beq.s IL_0011
IL_0005: ldarg.1
IL_0006: ldc.i4.s 10
IL_0008: beq.s IL_001e
IL_000a: ldarg.1
IL_000b: ldc.i4.s 14
IL_000d: beq.s IL_002b
IL_000f: br.s IL_003f
IL_0011: ldarg.2
IL_0012: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<int32>
IL_0017: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<int32>::Value
IL_001c: conv.ovf.i2
IL_001d: ret
IL_001e: ldarg.2
IL_001f: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<uint32>
IL_0024: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<uint32>::Value
IL_0029: conv.ovf.i2.un
IL_002a: ret
IL_002b: ldarg.2
IL_002c: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<float64>
IL_0031: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<float64>::Value
IL_0036: conv.r4
IL_0037: dup
IL_0038: call void [mscorlib]System.Console::WriteLine(float32)
IL_003d: conv.ovf.i2
IL_003e: ret
IL_003f: newobj instance void [mscorlib]System.Exception::.ctor()
IL_0044: throw
} // end of method CheckedUnchecked::Unbox
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
@ -586,6 +631,22 @@ @@ -586,6 +631,22 @@
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CheckedUnchecked
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<T>
extends [mscorlib]System.Object
{
.field public initonly !T Value
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Box`1::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1
// =============================================================

83
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.roslyn.il

@ -624,6 +624,72 @@ @@ -624,6 +624,72 @@
IL_000f: ret
} // end of method CheckedUnchecked::CheckedInArrayCreationArgument
.method public hidebysig instance int16
Unbox(valuetype [mscorlib]System.TypeCode c,
object b) cil managed
{
// Code size 89 (0x59)
.maxstack 2
.locals init (valuetype [mscorlib]System.TypeCode V_0,
int16 V_1,
float32 V_2)
IL_0000: nop
IL_0001: nop
IL_0002: ldarg.1
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: ldc.i4.s 9
IL_0007: beq.s IL_0019
IL_0009: br.s IL_000b
IL_000b: ldloc.0
IL_000c: ldc.i4.s 10
IL_000e: beq.s IL_0028
IL_0010: br.s IL_0012
IL_0012: ldloc.0
IL_0013: ldc.i4.s 14
IL_0015: beq.s IL_0037
IL_0017: br.s IL_0051
IL_0019: ldarg.2
IL_001a: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<int32>
IL_001f: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<int32>::Value
IL_0024: conv.ovf.i2
IL_0025: stloc.1
IL_0026: br.s IL_0057
IL_0028: ldarg.2
IL_0029: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<uint32>
IL_002e: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<uint32>::Value
IL_0033: conv.ovf.i2.un
IL_0034: stloc.1
IL_0035: br.s IL_0057
IL_0037: nop
IL_0038: ldarg.2
IL_0039: castclass class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<float64>
IL_003e: ldfld !0 class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<float64>::Value
IL_0043: conv.r4
IL_0044: stloc.2
IL_0045: ldloc.2
IL_0046: call void [mscorlib]System.Console::WriteLine(float32)
IL_004b: nop
IL_004c: ldloc.2
IL_004d: conv.ovf.i2
IL_004e: stloc.1
IL_004f: br.s IL_0057
IL_0051: newobj instance void [mscorlib]System.Exception::.ctor()
IL_0056: throw
IL_0057: ldloc.1
IL_0058: ret
} // end of method CheckedUnchecked::Unbox
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
@ -637,6 +703,23 @@ @@ -637,6 +703,23 @@
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.CheckedUnchecked
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1<T>
extends [mscorlib]System.Object
{
.field public initonly !T Value
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method Box`1::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Box`1
// =============================================================

4
ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

@ -388,8 +388,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -388,8 +388,8 @@ namespace ICSharpCode.Decompiler.CSharp
return this;
}
var castExpr = new CastExpression(expressionBuilder.ConvertType(targetType), Expression);
bool avoidCheckAnnotation = utype.IsKnownType(KnownTypeCode.Single) && targetUType.IsKnownType(KnownTypeCode.Double);
if (!avoidCheckAnnotation) {
bool needsCheckAnnotation = targetUType.GetStackType().IsIntegerType();
if (needsCheckAnnotation) {
castExpr.AddAnnotation(checkForOverflow ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation);
}
return castExpr.WithoutILInstruction().WithRR(rr);

Loading…
Cancel
Save