diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS73_StackAllocInitializers.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS73_StackAllocInitializers.cs index 264be7e2a..d082d149a 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS73_StackAllocInitializers.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS73_StackAllocInitializers.cs @@ -212,6 +212,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty return UsePointer((byte*)ptr); } + // Mixed constant/non-constant floating-point initializers go through the constant data + // blob; reading a 'float'/'double' element as the integer of the same width produced the + // raw bit pattern as the literal (e.g. 1f decoded as 1.0653532E+09f). + public unsafe string SimpleStackAllocSingle(float a) + { + float* ptr = stackalloc float[4] { 1f, 2f, 3f, a }; + Console.WriteLine(*ptr); + return UsePointer((byte*)ptr); + } + + public unsafe string SimpleStackAllocDouble(double a) + { + double* ptr = stackalloc double[4] { 1.0, 2.0, 3.0, a }; + Console.WriteLine(*ptr); + return UsePointer((byte*)ptr); + } + public unsafe string SimpleStackAllocInt32NonConstant(int a, int b, int c) { int* ptr = stackalloc int[6] { 0, 1, 0, a, b, c }; diff --git a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs index 7abf46d74..6245920c1 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs @@ -325,6 +325,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms private ILInstruction ReadElement(ref BlobReader blob, IType elementType) { + // Floating-point elements must be read as their actual type: their stored bytes are + // not the integer of the same width, and the resulting constant has to match the + // element type's stack type (see StObj.CheckInvariant). + switch (ReflectionHelper.GetTypeCode(elementType)) + { + case TypeCode.Single: + return new LdcF4(blob.ReadSingle()); + case TypeCode.Double: + return new LdcF8(blob.ReadDouble()); + } switch (elementType.GetSize()) { case 1: