Bug 15817 - gmcs generated IL for for array initialization of enums, throws exception when run on dotnet.
Summary: gmcs generated IL for for array initialization of enums, throws exception whe...
Status: RESOLVED FEATURE
Alias: None
Product: Compilers
Classification: Mono
Component: C# ()
Version: 2.10.x
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Marek Safar
URL:
Depends on:
Blocks:
 
Reported: 2013-10-30 10:40 UTC by Tom Hindle
Modified: 2013-11-03 08:00 UTC (History)
1 user (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
C# code showing bug. (212 bytes, text/x-csharp)
2013-10-30 10:41 UTC, Tom Hindle
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FEATURE

Description Tom Hindle 2013-10-30 10:40:32 UTC
Given an enum defined as:

    public enum MyEnum
    {
        a,
 	b,
 	c,
	d,
	e,
    }

The following code compiled with gmcs on Linux and run on windows 7 using dotnet 

    var a = new MyEnum[] { MyEnum.b, MyEnum.d, MyEnum.c};

throws a ArgumentException, like the following:

Unhandled Exception: System.ArgumentException: Value does not fall within the expected range.
   at System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(Array array, RuntimeFieldHandle fldHandle)
   at Program.Main(String[] args)

Running on Linux with mono, or compiling with dmcs does not throw an exception.

I've attached a test case showing C# code that causes the problem.


Given the dmcs and gmcs generate near identical il from this C#. The difference looks like its caused by, differences of behaviour of .dotnets InitializeArray implementation between .dotnet 2.0 and .dotnet 4.0.

Both gmcs and dmcs generate a call to:

call void class [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)

However when the same C# is compiled on window using csc, the generated code doesn't make a call to RuntimeHelpers::InitializeArray.


I aware that some may consider this a bug in the dotnet runtime, but it would be nice if gmcs generated IL that didn't crash the dotnet runtime.



Comparing the IL generated by gmcs and csc for the following C#.
================================================================

var a = new MyEnum[] { MyEnum.b, MyEnum.d, MyEnum.c };


IL Code generated by gmcs (dmcs same apart from GUID's):
==========================

IL_0000:  ldc.i4.3 
	IL_0001:  newarr Program/MyEnum
	IL_0006:  dup 
	IL_0007:  ldtoken field valuetype '<PrivateImplementationDetails>{65080337-f0d2-4a7d-b326-3c3491e60a99}'/'$ArrayType=12' '<PrivateImplementationDetails>{65080337-f0d2-4a7d-b326-3c3491e60a99}'::'$field-0'
	IL_000c:  call void class [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)
	IL_0011:  stloc.0 


IL Code generated by csc:
=========================

IL_0001:  ldc.i4.3 
	IL_0002:  newarr Program/MyEnum
	IL_0007:  stloc.1 
	IL_0008:  ldloc.1 
	IL_0009:  ldc.i4.0 
	IL_000a:  ldc.i4.1 
	IL_000b:  stelem.i4 
	IL_000c:  ldloc.1 
	IL_000d:  ldc.i4.1 
	IL_000e:  ldc.i4.3 
	IL_000f:  stelem.i4 
	IL_0010:  ldloc.1 
	IL_0011:  ldc.i4.2 
	IL_0012:  ldc.i4.2 
	IL_0013:  stelem.i4 
	IL_0014:  ldloc.1 
	IL_0015:  stloc.0
Comment 1 Tom Hindle 2013-10-30 10:41:25 UTC
Created attachment 5279 [details]
C# code showing bug.
Comment 2 Marek Safar 2013-11-03 08:00:50 UTC
This is known .NET x64 bug fixed in IIRC .NET 4.5 (and in their new JIT engine too).

https://connect.microsoft.com/VisualStudio/feedback/details/635365/runtimehelpers-initializearray-fails-on-64b-framework