@@ -2491,14 +2491,40 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
24912491 unsigned idx, jl_datatype_t *jt,
24922492 enum jl_memory_order order, Value **nullcheck=nullptr );
24932493
2494+ static bool field_may_be_null (const jl_cgval_t &strct, jl_datatype_t *stt, size_t idx)
2495+ {
2496+ size_t nfields = jl_datatype_nfields (stt);
2497+ if (idx < nfields - (unsigned )stt->name ->n_uninitialized )
2498+ return false ;
2499+ if (!jl_field_isptr (stt, idx) && !jl_type_hasptr (jl_field_type (stt, idx)))
2500+ return false ;
2501+ if (strct.constant ) {
2502+ if ((jl_is_immutable (stt) || jl_field_isconst (stt, idx)) && jl_field_isdefined (strct.constant , idx))
2503+ return false ;
2504+ }
2505+ return true ;
2506+ }
2507+
2508+ static bool field_may_be_null (const jl_cgval_t &strct, jl_datatype_t *stt)
2509+ {
2510+ size_t nfields = jl_datatype_nfields (stt);
2511+ for (size_t i = 0 ; i < (unsigned )stt->name ->n_uninitialized ; i++) {
2512+ size_t idx = nfields - i - 1 ;
2513+ if (field_may_be_null (strct, stt, idx))
2514+ return true ;
2515+ }
2516+ return false ;
2517+ }
2518+
2519+
24942520static bool emit_getfield_unknownidx (jl_codectx_t &ctx,
24952521 jl_cgval_t *ret, jl_cgval_t strct,
24962522 Value *idx, jl_datatype_t *stt, jl_value_t *inbounds,
24972523 enum jl_memory_order order)
24982524{
24992525 ++EmittedGetfieldUnknowns;
25002526 size_t nfields = jl_datatype_nfields (stt);
2501- bool maybe_null = ( unsigned )stt-> name -> n_uninitialized != 0 ;
2527+ bool maybe_null = field_may_be_null (strct, stt) ;
25022528 auto idx0 = [&]() {
25032529 return emit_bounds_check (ctx, strct, (jl_value_t *)stt, idx, ConstantInt::get (ctx.types ().T_size , nfields), inbounds);
25042530 };
@@ -2817,8 +2843,7 @@ static jl_cgval_t emit_getfield_knownidx(jl_codectx_t &ctx, const jl_cgval_t &st
28172843 assert (strct.isboxed );
28182844 needlock = boxed (ctx, strct);
28192845 }
2820- size_t nfields = jl_datatype_nfields (jt);
2821- bool maybe_null = idx >= nfields - (unsigned )jt->name ->n_uninitialized ;
2846+ bool maybe_null = field_may_be_null (strct, jt, idx);
28222847 size_t byte_offset = jl_field_offset (jt, idx);
28232848 if (strct.ispointer ()) {
28242849 auto tbaa = best_field_tbaa (ctx, strct, jt, idx, byte_offset);
@@ -3873,8 +3898,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
38733898 modifyop, fname);
38743899 }
38753900 unsigned align = jl_field_align (sty, idx0);
3876- size_t nfields = jl_datatype_nfields (sty);
3877- bool maybe_null = idx0 >= nfields - (unsigned )sty->name ->n_uninitialized ;
3901+ bool maybe_null = field_may_be_null (strct, sty, idx0);
38783902 return typed_store (ctx, addr, rhs, cmp, jfty, tbaa, nullptr ,
38793903 wb ? boxed (ctx, strct) : nullptr ,
38803904 isboxed, Order, FailOrder, align,
0 commit comments