diff --git a/src/mono/mono/mini/iltests.il b/src/mono/mono/mini/iltests.il index 12e7a845589c54..f2806c76229d63 100644 --- a/src/mono/mono/mini/iltests.il +++ b/src/mono/mono/mini/iltests.il @@ -3224,6 +3224,56 @@ L_3: IL_000c: ret } + .class nested private auto ansi beforefieldinit MissingFieldCarrier`1 + extends [mscorlib]System.Object + { + .method public hidebysig specialname rtspecialname instance default void .ctor () cil managed + { + .maxstack 8 + ldarg.0 + call instance void object::.ctor() + ret + } + } + + // After lowering the missing-field access into a runtime throw, AOT must also + // consume the recoverable metadata error so the later accepted inline does not + // trip inline_method()'s cfg->error assert. + .method private hidebysig static void missing_field_then_inline () cil managed + { + .maxstack 8 + ldnull + ldfld !0 class Tests/MissingFieldCarrier`1::missing + pop + ldc.i4.2 + call int32 Tests::always_inline(int32) + pop + ret + } + + .method public hidebysig static int32 test_0_missing_field_then_inline () cil managed + { + .maxstack 8 + .locals init (int32 V_0) + .try + { + call void class Tests::missing_field_then_inline () + ldc.i4.1 + stloc.0 + leave.s IL_0011 + } + catch [mscorlib]System.MissingFieldException + { + pop + ldc.i4.0 + stloc.0 + leave.s IL_0011 + } + + IL_0011: ldloc.0 + ret + } + .method public hidebysig static int32 test_104_conv_u_and_string() cil managed { .maxstack 8 diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index f4e661edd4eea2..c1ace95e11c54e 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -10167,9 +10167,14 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (!field || CLASS_HAS_FAILURE (klass)) { HANDLE_TYPELOAD_ERROR (cfg, klass); - // Reached only in AOT. Cannot turn a token into a class. We silence the compilation error - // and generate a runtime exception. - if (cfg->error->error_code == MONO_ERROR_BAD_IMAGE) + /* + * Reached only in AOT. After lowering the field resolution failure into a runtime + * throw, consume the expected recoverable metadata errors as well. Memberref field + * resolution can report MissingField/BadImage directly through cfg->error without + * setting cfg->exception_type, and leaving one of those live lets an accepted inline + * trip the inline_method () cfg->error assert later on. + */ + if (cfg->error->error_code == MONO_ERROR_BAD_IMAGE || cfg->error->error_code == MONO_ERROR_MISSING_FIELD) clear_cfg_error (cfg); // We need to push a dummy value onto the stack, respecting the intended type.