Browse Source

Fixup array indices

pull/863/head
Daniel Grunwald 8 years ago
parent
commit
21717f0fa4
  1. 32
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.cs
  2. 120
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.il
  3. 84
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.opt.il
  4. 79
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.opt.roslyn.il
  5. 115
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.roslyn.il
  6. 3
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  7. 17
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  8. 15
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  9. 18
      ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs

32
ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.cs

@ -22,6 +22,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -22,6 +22,8 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
public class TypeAnalysisTests
{
private byte[] byteArray;
public byte SubtractFrom256(byte b)
{
return (byte)(256 - b);
@ -152,6 +154,36 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -152,6 +154,36 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return new byte[length];
}
public byte UseArrayWithInt(int i)
{
return this.byteArray[i];
}
public byte UseArrayWithUInt(uint i)
{
return this.byteArray[i];
}
public byte UseArrayWithLong(long i)
{
return this.byteArray[i];
}
public byte UseArrayWithULong(ulong i)
{
return this.byteArray[i];
}
public byte UseArrayWithShort(short i)
{
return this.byteArray[i];
}
public byte UseArrayWithUShort(ushort i)
{
return this.byteArray[i];
}
public StringComparison EnumDiffNumber(StringComparison data)
{
return data - 1;

120
ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly atizfkop
.assembly '3ks4sbnu'
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module atizfkop.dll
// MVID: {6E63D5B6-44D4-4BB0-A1F2-26CF3701BD7D}
.module '3ks4sbnu.dll'
// MVID: {8D285D1A-ACBF-41C0-93DE-10526C17A0D8}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x02B60000
// Image base: 0x008C0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -36,6 +36,7 @@ @@ -36,6 +36,7 @@
.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests
extends [mscorlib]System.Object
{
.field private uint8[] byteArray
.method public hidebysig instance uint8
SubtractFrom256(uint8 b) cil managed
{
@ -514,6 +515,117 @@ @@ -514,6 +515,117 @@
IL_000b: ret
} // end of method TypeAnalysisTests::CreateArrayWithUShort
.method public hidebysig instance uint8
UseArrayWithInt(int32 i) cil managed
{
// Code size 14 (0xe)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: ldelem.u1
IL_0009: stloc.0
IL_000a: br.s IL_000c
IL_000c: ldloc.0
IL_000d: ret
} // end of method TypeAnalysisTests::UseArrayWithInt
.method public hidebysig instance uint8
UseArrayWithUInt(uint32 i) cil managed
{
// Code size 15 (0xf)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: conv.u
IL_0009: ldelem.u1
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
} // end of method TypeAnalysisTests::UseArrayWithUInt
.method public hidebysig instance uint8
UseArrayWithLong(int64 i) cil managed
{
// Code size 15 (0xf)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: conv.ovf.i
IL_0009: ldelem.u1
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
} // end of method TypeAnalysisTests::UseArrayWithLong
.method public hidebysig instance uint8
UseArrayWithULong(uint64 i) cil managed
{
// Code size 15 (0xf)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: conv.ovf.i.un
IL_0009: ldelem.u1
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
} // end of method TypeAnalysisTests::UseArrayWithULong
.method public hidebysig instance uint8
UseArrayWithShort(int16 i) cil managed
{
// Code size 14 (0xe)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: ldelem.u1
IL_0009: stloc.0
IL_000a: br.s IL_000c
IL_000c: ldloc.0
IL_000d: ret
} // end of method TypeAnalysisTests::UseArrayWithShort
.method public hidebysig instance uint8
UseArrayWithUShort(uint16 i) cil managed
{
// Code size 14 (0xe)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: ldelem.u1
IL_0009: stloc.0
IL_000a: br.s IL_000c
IL_000c: ldloc.0
IL_000d: ret
} // end of method TypeAnalysisTests::UseArrayWithUShort
.method public hidebysig instance valuetype [mscorlib]System.StringComparison
EnumDiffNumber(valuetype [mscorlib]System.StringComparison data) cil managed
{

84
ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.opt.il

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly '23m0rxdj'
.assembly ucb5gp0y
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
@ -20,15 +20,15 @@ @@ -20,15 +20,15 @@
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module '23m0rxdj.dll'
// MVID: {9DFA58C5-09E0-491E-AD57-5C642A58E0B0}
.module ucb5gp0y.dll
// MVID: {CDCB369D-F3A9-41EF-A248-EFB62F8B25F3}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x01190000
// Image base: 0x00BA0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -36,6 +36,7 @@ @@ -36,6 +36,7 @@
.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests
extends [mscorlib]System.Object
{
.field private uint8[] byteArray
.method public hidebysig instance uint8
SubtractFrom256(uint8 b) cil managed
{
@ -361,6 +362,81 @@ @@ -361,6 +362,81 @@
IL_0006: ret
} // end of method TypeAnalysisTests::CreateArrayWithUShort
.method public hidebysig instance uint8
UseArrayWithInt(int32 i) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: ldelem.u1
IL_0008: ret
} // end of method TypeAnalysisTests::UseArrayWithInt
.method public hidebysig instance uint8
UseArrayWithUInt(uint32 i) cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: conv.u
IL_0008: ldelem.u1
IL_0009: ret
} // end of method TypeAnalysisTests::UseArrayWithUInt
.method public hidebysig instance uint8
UseArrayWithLong(int64 i) cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: conv.ovf.i
IL_0008: ldelem.u1
IL_0009: ret
} // end of method TypeAnalysisTests::UseArrayWithLong
.method public hidebysig instance uint8
UseArrayWithULong(uint64 i) cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: conv.ovf.i.un
IL_0008: ldelem.u1
IL_0009: ret
} // end of method TypeAnalysisTests::UseArrayWithULong
.method public hidebysig instance uint8
UseArrayWithShort(int16 i) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: ldelem.u1
IL_0008: ret
} // end of method TypeAnalysisTests::UseArrayWithShort
.method public hidebysig instance uint8
UseArrayWithUShort(uint16 i) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: ldelem.u1
IL_0008: ret
} // end of method TypeAnalysisTests::UseArrayWithUShort
.method public hidebysig instance valuetype [mscorlib]System.StringComparison
EnumDiffNumber(valuetype [mscorlib]System.StringComparison data) cil managed
{

79
ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.opt.roslyn.il

@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module TypeAnalysisTests.dll
// MVID: {BAEDEF38-6FE3-4BCD-B0E6-F860EA0EEDDB}
// MVID: {45EA12AC-D9D0-4E8D-899F-E860FF165BAF}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x01840000
// Image base: 0x004F0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -40,6 +40,7 @@ @@ -40,6 +40,7 @@
.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests
extends [mscorlib]System.Object
{
.field private uint8[] byteArray
.method public hidebysig instance uint8
SubtractFrom256(uint8 b) cil managed
{
@ -364,6 +365,80 @@ @@ -364,6 +365,80 @@
IL_0006: ret
} // end of method TypeAnalysisTests::CreateArrayWithUShort
.method public hidebysig instance uint8
UseArrayWithInt(int32 i) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: ldelem.u1
IL_0008: ret
} // end of method TypeAnalysisTests::UseArrayWithInt
.method public hidebysig instance uint8
UseArrayWithUInt(uint32 i) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: ldelem.u1
IL_0008: ret
} // end of method TypeAnalysisTests::UseArrayWithUInt
.method public hidebysig instance uint8
UseArrayWithLong(int64 i) cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: conv.ovf.i
IL_0008: ldelem.u1
IL_0009: ret
} // end of method TypeAnalysisTests::UseArrayWithLong
.method public hidebysig instance uint8
UseArrayWithULong(uint64 i) cil managed
{
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: conv.ovf.i.un
IL_0008: ldelem.u1
IL_0009: ret
} // end of method TypeAnalysisTests::UseArrayWithULong
.method public hidebysig instance uint8
UseArrayWithShort(int16 i) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: ldelem.u1
IL_0008: ret
} // end of method TypeAnalysisTests::UseArrayWithShort
.method public hidebysig instance uint8
UseArrayWithUShort(uint16 i) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0006: ldarg.1
IL_0007: ldelem.u1
IL_0008: ret
} // end of method TypeAnalysisTests::UseArrayWithUShort
.method public hidebysig instance valuetype [mscorlib]System.StringComparison
EnumDiffNumber(valuetype [mscorlib]System.StringComparison data) cil managed
{

115
ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.roslyn.il

@ -25,14 +25,14 @@ @@ -25,14 +25,14 @@
.ver 0:0:0:0
}
.module TypeAnalysisTests.dll
// MVID: {FB8CCB77-958F-4BAB-8E8E-E95AD68FFF21}
// MVID: {7D715AC2-86C7-44AA-B6EB-859E68836342}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x024D0000
// Image base: 0x014B0000
// =============== CLASS MEMBERS DECLARATION ===================
@ -40,6 +40,7 @@ @@ -40,6 +40,7 @@
.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests
extends [mscorlib]System.Object
{
.field private uint8[] byteArray
.method public hidebysig instance uint8
SubtractFrom256(uint8 b) cil managed
{
@ -514,6 +515,116 @@ @@ -514,6 +515,116 @@
IL_000b: ret
} // end of method TypeAnalysisTests::CreateArrayWithUShort
.method public hidebysig instance uint8
UseArrayWithInt(int32 i) cil managed
{
// Code size 14 (0xe)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: ldelem.u1
IL_0009: stloc.0
IL_000a: br.s IL_000c
IL_000c: ldloc.0
IL_000d: ret
} // end of method TypeAnalysisTests::UseArrayWithInt
.method public hidebysig instance uint8
UseArrayWithUInt(uint32 i) cil managed
{
// Code size 14 (0xe)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: ldelem.u1
IL_0009: stloc.0
IL_000a: br.s IL_000c
IL_000c: ldloc.0
IL_000d: ret
} // end of method TypeAnalysisTests::UseArrayWithUInt
.method public hidebysig instance uint8
UseArrayWithLong(int64 i) cil managed
{
// Code size 15 (0xf)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: conv.ovf.i
IL_0009: ldelem.u1
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
} // end of method TypeAnalysisTests::UseArrayWithLong
.method public hidebysig instance uint8
UseArrayWithULong(uint64 i) cil managed
{
// Code size 15 (0xf)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: conv.ovf.i.un
IL_0009: ldelem.u1
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
} // end of method TypeAnalysisTests::UseArrayWithULong
.method public hidebysig instance uint8
UseArrayWithShort(int16 i) cil managed
{
// Code size 14 (0xe)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: ldelem.u1
IL_0009: stloc.0
IL_000a: br.s IL_000c
IL_000c: ldloc.0
IL_000d: ret
} // end of method TypeAnalysisTests::UseArrayWithShort
.method public hidebysig instance uint8
UseArrayWithUShort(uint16 i) cil managed
{
// Code size 14 (0xe)
.maxstack 2
.locals init (uint8 V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld uint8[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.TypeAnalysisTests::byteArray
IL_0007: ldarg.1
IL_0008: ldelem.u1
IL_0009: stloc.0
IL_000a: br.s IL_000c
IL_000c: ldloc.0
IL_000d: ret
} // end of method TypeAnalysisTests::UseArrayWithUShort
.method public hidebysig instance valuetype [mscorlib]System.StringComparison
EnumDiffNumber(valuetype [mscorlib]System.StringComparison data) cil managed
{

3
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -655,8 +655,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -655,8 +655,7 @@ namespace ICSharpCode.Decompiler.CSharp
var right = Translate(inst.Right);
Sign sign = inst.Sign;
if (left.Type.IsSmallIntegerType() && sign != Sign.Unsigned
&& left.Type.Kind != TypeKind.Enum && inst.ResultType == StackType.I4) {
if (left.Type.IsCSharpSmallIntegerType() && sign != Sign.Unsigned && inst.ResultType == StackType.I4) {
// With small integer types, C# will promote to int and perform signed shifts.
// We thus don't need any casts in this case.
} else {

17
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -477,7 +477,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -477,7 +477,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return ace;
} else if (rr.IsCompileTimeConstant) {
var expr = ConvertConstantValue(rr.Type, rr.ConstantValue);
if (isBoxing && IsSmallInteger(rr.Type)) {
if (isBoxing && rr.Type.IsCSharpSmallIntegerType()) {
// C# does not have small integer literal types.
// We need to add a cast so that the integer literal gets boxed as the correct type.
expr = new CastExpression(ConvertType(rr.Type), expr);
@ -519,7 +519,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -519,7 +519,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
} else if (type.Kind == TypeKind.Enum) {
return ConvertEnumValue(type, (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false));
} else {
if (IsSmallInteger(type)) {
if (type.IsCSharpSmallIntegerType()) {
// C# does not have integer literals of small integer types,
// use `int` literal instead.
constantValue = CSharpPrimitiveCast.Cast(TypeCode.Int32, constantValue, false);
@ -532,19 +532,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -532,19 +532,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
}
bool IsSmallInteger(IType type)
{
switch (type.GetDefinition()?.KnownTypeCode) {
case KnownTypeCode.Byte:
case KnownTypeCode.SByte:
case KnownTypeCode.Int16:
case KnownTypeCode.UInt16:
return true;
default:
return false;
}
}
bool IsFlagsEnum(ITypeDefinition type)
{
IType flagsAttributeType = type.Compilation.FindType(typeof(System.FlagsAttribute));

15
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -108,15 +108,26 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -108,15 +108,26 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
protected internal override void VisitLdElema(LdElema inst)
{
base.VisitLdElema(inst);
CleanUpArrayIndices(inst.Indices);
}
protected internal override void VisitNewArr(NewArr inst)
{
base.VisitNewArr(inst);
foreach (ILInstruction index in inst.Indices) {
CleanUpArrayIndices(inst.Indices);
}
void CleanUpArrayIndices(InstructionCollection<ILInstruction> indices)
{
foreach (ILInstruction index in indices) {
if (index is Conv conv && conv.ResultType == StackType.I
&& (conv.Kind == ConversionKind.Truncate && conv.CheckForOverflow
|| conv.Kind == ConversionKind.ZeroExtend || conv.Kind == ConversionKind.SignExtend)
) {
context.Step("newarr(conv(X)) => newarr(X)", inst);
context.Step("Remove conv.i from array index", index);
index.ReplaceWith(conv.Argument);
}
}

18
ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs

@ -109,6 +109,24 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -109,6 +109,24 @@ namespace ICSharpCode.Decompiler.TypeSystem
return GetSize(type) < 4;
}
/// <summary>
/// Gets whether the type is a C# small integer type: byte, sbyte, short or ushort.
///
/// Unlike the ILAst, C# does not consider bool or enums to be small integers.
/// </summary>
public static bool IsCSharpSmallIntegerType(this IType type)
{
switch (type.GetDefinition()?.KnownTypeCode) {
case KnownTypeCode.Byte:
case KnownTypeCode.SByte:
case KnownTypeCode.Int16:
case KnownTypeCode.UInt16:
return true;
default:
return false;
}
}
/// <summary>
/// Gets whether the type is an IL integer type.
/// Returns true for I4, I, or I8.

Loading…
Cancel
Save