File mono-6.12-unsafe-nullref.diff of Package mono

diff --git a/mcs/class/corlib/System.Runtime.CompilerServices/Unsafe.cs b/mcs/class/corlib/System.Runtime.CompilerServices/Unsafe.cs
index 318bf290b74..4173be89f79 100644
--- a/mcs/class/corlib/System.Runtime.CompilerServices/Unsafe.cs
+++ b/mcs/class/corlib/System.Runtime.CompilerServices/Unsafe.cs
@@ -158,5 +158,39 @@ public static bool IsAddressLessThan<T>(ref T left, ref T right)
 		{
 			return ref AddByteOffset (ref source, (IntPtr)(void*)byteOffset);
 		}
+
+	        /// <summary>
+		/// Returns a by-ref to type <typeparamref name="T"/> that is a null reference.
+		/// </summary>
+		[Intrinsic]
+		[MethodImpl(MethodImplOptions.AggressiveInlining)]
+		public static ref T NullRef<T>()
+		{
+			return ref Unsafe.AsRef<T>(null);
+
+			// ldc.i4.0
+			// conv.u
+			// ret
+		}
+
+		/// <summary>
+		/// Returns if a given by-ref to type <typeparamref name="T"/> is a null reference.
+		/// </summary>
+		/// <remarks>
+		/// This check is conceptually similar to "(void*)(&amp;source) == nullptr".
+		/// </remarks>
+		[Intrinsic]
+		[MethodImpl(MethodImplOptions.AggressiveInlining)]
+		public static bool IsNullRef<T>(ref T source)
+		{
+			return Unsafe.AsPointer(ref source) == null;
+
+			// ldarg.0
+			// ldc.i4.0
+			// conv.u
+			// ceq
+			// ret
+		}
+
 	}
 }
diff --git a/mcs/class/corlib/System.Runtime.CompilerServices/Unsafe.il b/mcs/class/corlib/System.Runtime.CompilerServices/Unsafe.il
index c432c6229e6..a9a0ddbfdd9 100644
--- a/mcs/class/corlib/System.Runtime.CompilerServices/Unsafe.il
+++ b/mcs/class/corlib/System.Runtime.CompilerServices/Unsafe.il
@@ -373,4 +373,22 @@
         unbox !!T
         ret
   }
-}
\ No newline at end of file
+
+  .method public hidebysig static !!T& NullRef<T> () cil managed aggressiveinlining
+  {
+	.maxstack 1
+	ldc.i4.0
+	conv.u
+	ret
+  }
+
+  .method public hidebysig static bool IsNullRef<T> (!!T& 'source') cil managed aggressiveinlining
+  {
+	.maxstack 2
+	ldarg.0
+	ldc.i4.0
+	conv.u
+	ceq
+	ret
+  }
+}
diff --git a/mono/mini/intrinsics.c b/mono/mini/intrinsics.c
index f0a7b694045..7ee98cc5c87 100644
--- a/mono/mini/intrinsics.c
+++ b/mono/mini/intrinsics.c
@@ -573,6 +573,32 @@ emit_unsafe_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignatu
 		EMIT_NEW_BIALU (cfg, ins, OP_PSUB, dreg, args [1]->dreg, args [0]->dreg);
 		ins->type = STACK_PTR;
 		return ins;
+#if 0
+	} else if (!strcmp (cmethod->name, "NullRef")) {
+		g_assert (ctx);
+		g_assert (ctx->method_inst);
+		g_assert (ctx->method_inst->type_argc == 1);
+		g_assert (fsig->param_count == 0);
+
+		dreg = alloc_preg (cfg);
+		EMIT_NEW_ICONST (cfg, ins, 0); //< ldc.i4.0
+		EMIT_NEW_UNALU (cfg, ins, OP_MOVE, dreg, args [0]->dreg); //< conv.u
+		ins->type = STACK_OBJ;
+		ins->klass = mono_get_object_class ();
+		return ins;
+	} else if (!strcmp (cmethod->name, "IsNullRef")) {
+		g_assert (ctx);
+		g_assert (ctx->method_inst);
+		g_assert (ctx->method_inst->type_argc == 1);
+		g_assert (fsig->param_count == 1);
+
+		dreg = alloc_preg (cfg);
+		EMIT_NEW_ICONST (cfg, ins, 0); //< ldc.i4.0
+		EMIT_NEW_UNALU (cfg, ins, OP_MOVE, dreg, args [0]->dreg); //< conv.u
+		EMIT_NEW_BIALU (cfg, ins, OP_COMPARE, -1, args [0]->dreg, args [1]->dreg); //< ceq
+		EMIT_NEW_UNALU (cfg, ins, OP_PCEQ, dreg, -1); //< ceq over *pointer size
+		return ins;
+#endif
 	}
 #ifdef ENABLE_NETCORE
 	else if (!strcmp (cmethod->name, "InitBlockUnaligned")) {
openSUSE Build Service is sponsored by