Bug 4672 - Passing an integer value instead of a struct should work
Summary: Passing an integer value instead of a struct should work
Status: RESOLVED NOT_ON_ROADMAP
Alias: None
Product: Runtime
Classification: Mono
Component: JIT ()
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-04-26 14:06 UTC by soywiz
Modified: 2012-04-27 15:24 UTC (History)
3 users (show)

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

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 NOT_ON_ROADMAP

Description soywiz 2012-04-26 14:06:02 UTC
This example works on MS.NET and fails on Mono. It is compiled using UNSAFE code.

It seems that MS.NET allows to pass an integer where you should pass a struct on an UNSAFE context directly without casting to that struct.

This causes some issues on my project:
https://github.com/soywiz/cspspemu/issues/24

Now I'm fixing my own code to avoid this "feature", but mono should either allowing it as MS.NET does (improving compatibility) or at least it would be great if it gives more details about the error.

---

Unhandled Exception: System.InvalidProgramException: Invalid IL code in (wrapper dynamic-method) object:test (): IL_0005: call      0x00000003
  at (wrapper managed-to-native) System.Delegate:CreateDelegate_internal (System.Type,object,System.Reflection.MethodInfo,bool)


// NOTE: This program should be compiled allowing UNSAFE code

#define ALLOW_UNSAFE
//#define USE_OP_IMPLICIT

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection.Emit;
using System.Reflection;

namespace ConsoleApplication1
{
	public class Program
	{
		public struct MyImplicitType
		{
			public int Value;

#if USE_OP_IMPLICIT
			static public implicit operator MyImplicitType(int Value)
			{
				return new MyImplicitType() { Value = Value };
			}

			static public implicit operator int(MyImplicitType Value)
			{
				return Value.Value;
			}
#endif

			public override string  ToString()
			{
				 return "MyImplicitType(" + Value + ")";
			}
		}

		static public int Test()
		{
			return 1;
		}

		static public void Test2(MyImplicitType Value)
		{
			Console.WriteLine("Value: {0}", Value);
		}

		unsafe static public void Main(string[] args)
		{
			var DynamicMethod = new DynamicMethod(
				"test",
				typeof(void),
				new Type[] { }
#if ALLOW_UNSAFE
				// NOTE: This program should be compiled allowing UNSAFE code
				, Assembly.GetExecutingAssembly().ManifestModule
#endif
			);
			var ILGenerator = DynamicMethod.GetILGenerator();
			ILGenerator.Emit(OpCodes.Call, ((Func<int>)Program.Test).Method);
#if USE_OP_IMPLICIT
			ILGenerator.Emit(OpCodes.Call, typeof(MyImplicitType).GetMethod("op_Implicit", new Type[] { typeof(int) }));
#endif
			ILGenerator.Emit(OpCodes.Call, ((Action<MyImplicitType>)Program.Test2).Method);
			ILGenerator.Emit(OpCodes.Ret);
			var Action = (Action)DynamicMethod.CreateDelegate(typeof(Action));
			Action();
			//Console.ReadKey();
		}
	}
}
Comment 1 Zoltan Varga 2012-04-27 15:24:11 UTC
This is not valid IL, and MS.NET shouldn't accept it either.