diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index b07662b78517..081c851d5dfa 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -225,6 +225,7 @@ typedef enum { MONO_EXCEPTION_OUT_OF_MEMORY = 14, MONO_EXCEPTION_INLINE_FAILED = 15, MONO_EXCEPTION_MONO_ERROR = 16, + MONO_EXCEPTION_MEMBER_ACCESS = 17, /* add other exception type */ } MonoExceptionType; diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index ed9001779cf9..c85f78df9119 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -3653,6 +3653,14 @@ handle_alloc (MonoCompile *cfg, MonoClass *klass, gboolean for_box, int context_ MonoInst *iargs [2]; void *alloc_ftn; + if (mono_class_get_flags (klass) & TYPE_ATTRIBUTE_ABSTRACT) { + char* full_name = mono_type_get_full_name (klass); + cfg->exception_message = g_strdup_printf ("Cannot create an abstract class: %s", full_name); + g_free (full_name); + mono_cfg_set_exception (cfg, MONO_EXCEPTION_MEMBER_ACCESS); + return NULL; + } + if (context_used) { MonoInst *data; MonoRgctxInfoType rgctx_info; diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 0b7283612b31..2d3e0a3f9ee5 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -4187,6 +4187,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in case MONO_EXCEPTION_TYPE_LOAD: case MONO_EXCEPTION_MISSING_FIELD: case MONO_EXCEPTION_MISSING_METHOD: + case MONO_EXCEPTION_MEMBER_ACCESS: case MONO_EXCEPTION_FILE_NOT_FOUND: case MONO_EXCEPTION_BAD_IMAGE: case MONO_EXCEPTION_INVALID_PROGRAM: { @@ -4206,6 +4207,8 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in ex = mono_get_exception_bad_image_format (cfg->exception_message); else if (cfg->exception_type == MONO_EXCEPTION_INVALID_PROGRAM) ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", cfg->exception_message); + else if (cfg->exception_type == MONO_EXCEPTION_MEMBER_ACCESS) + ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MemberAccessException", cfg->exception_message); else g_assert_not_reached (); } diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am index cff377fc0276..27adedd99182 100755 --- a/mono/tests/Makefile.am +++ b/mono/tests/Makefile.am @@ -608,7 +608,8 @@ TESTS_IL_SRC= \ gsharing-valuetype-layout.il \ invalid_generic_instantiation.il \ bug-45841-fpstack-exceptions.il \ - instance_tailrec.il + instance_tailrec.il \ + newobj-abstract.il TESTS_GSHARED_SRC = \ generics-sharing.2.cs \ diff --git a/mono/tests/newobj-abstract.il b/mono/tests/newobj-abstract.il new file mode 100644 index 000000000000..52d5913cc27d --- /dev/null +++ b/mono/tests/newobj-abstract.il @@ -0,0 +1,61 @@ +.assembly extern mscorlib {} + +.assembly 'newobj-abstract' {} + +.class private auto ansi beforefieldinit Program + extends [mscorlib]System.Object +{ + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + .locals init (int32 V_0) + + ldc.i4.1 + stloc.0 + .try + { + call void Program::NewAbstract() + leave.s leavetarget + + } // end .try + catch [mscorlib]System.MemberAccessException + { + pop + ldc.i4.0 + stloc.0 + leave.s leavetarget + } +leavetarget: + ldloc.0 + ret + } // end of method Program::Main + + .method public hidebysig static void NewAbstract() cil managed + { + newobj instance void Foo::.ctor() + call void [mscorlib]System.GC::KeepAlive(object) + ret + } + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + +} + +.class private abstract auto ansi beforefieldinit Foo + extends [mscorlib]System.Object +{ + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + +}