Skip to content

Commit 24acc68

Browse files
authored
codegen: implement isdefined_tfunc check more similarly to inference (#52069)
1 parent debaa73 commit 24acc68

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

src/cgutils.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
24942520
static 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,

src/codegen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4843,7 +4843,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
48434843
*ret = jl_cgval_t(); // unreachable
48444844
return true;
48454845
}
4846-
else if (fieldidx < nf - stt->name->n_uninitialized) {
4846+
else if (!field_may_be_null(obj, stt, fieldidx)) {
48474847
*ret = mark_julia_const(ctx, jl_true);
48484848
}
48494849
else if (jl_field_isptr(stt, fieldidx) || jl_type_hasptr(jl_field_type(stt, fieldidx))) {

0 commit comments

Comments
 (0)