Skip to content

Commit 53432d5

Browse files
vtjnashKristofferC
authored andcommitted
codegen: add missing jl_get_fieldtypes calls
Fixes #42645 (cherry picked from commit 485495f)
1 parent 8269a19 commit 53432d5

File tree

4 files changed

+36
-12
lines changed

4 files changed

+36
-12
lines changed

src/cgutils.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ static DIType *_julia_type_to_di(jl_codegen_params_t *ctx, jl_value_t *jt, DIBui
136136
size_t ntypes = jl_datatype_nfields(jdt);
137137
std::vector<llvm::Metadata*> Elements(ntypes);
138138
for (unsigned i = 0; i < ntypes; i++) {
139-
jl_value_t *el = jl_svecref(jdt->types, i);
139+
jl_value_t *el = jl_field_type_concrete(jdt, i);
140140
DIType *di;
141141
if (jl_field_isptr(jdt, i))
142142
di = jl_pvalue_dillvmt;
@@ -2035,9 +2035,10 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
20352035
if (!strct.ispointer()) { // unboxed
20362036
assert(jl_is_concrete_immutable((jl_value_t*)stt));
20372037
bool isboxed = is_datatype_all_pointers(stt);
2038-
bool issame = is_tupletype_homogeneous(stt->types);
2038+
jl_svec_t *types = stt->types;
2039+
bool issame = is_tupletype_homogeneous(types);
20392040
if (issame) {
2040-
jl_value_t *jft = jl_svecref(stt->types, 0);
2041+
jl_value_t *jft = jl_svecref(types, 0);
20412042
if (strct.isghost) {
20422043
(void)idx0();
20432044
*ret = ghostValue(jft);
@@ -2077,7 +2078,7 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
20772078
ctx.builder.CreateExtractValue(strct.V, makeArrayRef(i)),
20782079
fld);
20792080
}
2080-
jl_value_t *jft = issame ? jl_svecref(stt->types, 0) : (jl_value_t*)jl_any_type;
2081+
jl_value_t *jft = issame ? jl_svecref(types, 0) : (jl_value_t*)jl_any_type;
20812082
if (isboxed && maybe_null)
20822083
null_pointer_check(ctx, fld);
20832084
*ret = mark_julia_type(ctx, fld, isboxed, jft);
@@ -2119,9 +2120,9 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
21192120
*ret = mark_julia_type(ctx, fld, true, jl_any_type);
21202121
return true;
21212122
}
2122-
else if (is_tupletype_homogeneous(stt->types)) {
2123+
else if (is_tupletype_homogeneous(jl_get_fieldtypes(stt))) {
21232124
assert(nfields > 0); // nf == 0 trapped by all_pointers case
2124-
jl_value_t *jft = jl_svecref(stt->types, 0);
2125+
jl_value_t *jft = jl_svecref(stt->types, 0); // n.b. jl_get_fieldtypes assigned stt->types for here
21252126
assert(jl_is_concrete_type(jft));
21262127
idx = idx0();
21272128
Value *ptr = maybe_decay_tracked(ctx, data_pointer(ctx, strct));
@@ -3242,9 +3243,10 @@ static void find_perm_offsets(jl_datatype_t *typ, SmallVector<unsigned,4> &res,
32423243
// This is a inlined field at `offset`.
32433244
if (!typ->layout || typ->layout->npointers == 0)
32443245
return;
3245-
size_t nf = jl_svec_len(typ->types);
3246+
jl_svec_t *types = jl_get_fieldtypes(typ);
3247+
size_t nf = jl_svec_len(types);
32463248
for (size_t i = 0; i < nf; i++) {
3247-
jl_value_t *_fld = jl_svecref(typ->types, i);
3249+
jl_value_t *_fld = jl_svecref(types, i);
32483250
if (!jl_is_datatype(_fld))
32493251
continue;
32503252
jl_datatype_t *fld = (jl_datatype_t*)_fld;
@@ -3293,7 +3295,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
32933295
emit_bitcast(ctx, maybe_decay_tracked(ctx, addr), T_pint8),
32943296
ConstantInt::get(T_size, byte_offset)); // TODO: use emit_struct_gep
32953297
}
3296-
jl_value_t *jfty = jl_svecref(sty->types, idx0);
3298+
jl_value_t *jfty = jl_field_type(sty, idx0);
32973299
if (!jl_field_isptr(sty, idx0) && jl_is_uniontype(jfty)) {
32983300
size_t fsz = 0, al = 0;
32993301
bool isptr = !jl_islayout_inline(jfty, &fsz, &al);
@@ -3418,7 +3420,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
34183420
}
34193421

34203422
for (unsigned i = 0; i < na; i++) {
3421-
jl_value_t *jtype = jl_svecref(sty->types, i);
3423+
jl_value_t *jtype = jl_svecref(sty->types, i); // n.b. ty argument must be concrete
34223424
jl_cgval_t fval_info = argv[i];
34233425
emit_typecheck(ctx, fval_info, jtype, "new");
34243426
fval_info = update_julia_type(ctx, fval_info, jtype);
@@ -3553,7 +3555,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
35533555
need_wb = !rhs.isboxed;
35543556
else
35553557
need_wb = false;
3556-
emit_typecheck(ctx, rhs, jl_svecref(sty->types, i), "new");
3558+
emit_typecheck(ctx, rhs, jl_svecref(sty->types, i), "new"); // n.b. ty argument must be concrete
35573559
emit_setfield(ctx, sty, strctinfo, i, rhs, jl_cgval_t(), false, need_wb, AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, false, true, false, false, false, nullptr, "");
35583560
}
35593561
return strctinfo;

src/codegen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2708,7 +2708,7 @@ static bool emit_f_opfield(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
27082708
idx = i - 1;
27092709
}
27102710
if (idx != -1) {
2711-
jl_value_t *ft = jl_svecref(uty->types, idx);
2711+
jl_value_t *ft = jl_field_type(uty, idx);
27122712
if (!jl_has_free_typevars(ft)) {
27132713
if (!ismodifyfield && !jl_subtype(val.typ, ft)) {
27142714
emit_typecheck(ctx, val, ft, fname);

src/datatype.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ int jl_struct_try_layout(jl_datatype_t *dt)
242242
return 1;
243243
else if (!jl_has_fixed_layout(dt))
244244
return 0;
245+
// jl_has_fixed_layout also ensured that dt->types is assigned now
245246
jl_compute_field_offsets(dt);
246247
assert(dt->layout);
247248
return 1;

test/compiler/codegen.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,3 +637,24 @@ t41096 = Term41096{:t}(Modulate41096(:t, false))
637637
U41096 = Term41096{:U}(Modulate41096(:U, false))
638638

639639
@test !newexpand41096((t=t41096, μ=μ41096, U=U41096), :U)
640+
641+
# issue #42645
642+
mutable struct A42645{T}
643+
x::Bool
644+
function A42645(a::Vector{T}) where T
645+
r = new{T}()
646+
r.x = false
647+
return r
648+
end
649+
end
650+
mutable struct B42645{T}
651+
y::A42645{T}
652+
end
653+
x42645 = 1
654+
function f42645()
655+
res = B42645(A42645([x42645]))
656+
res.y = A42645([x42645])
657+
res.y.x = true
658+
res
659+
end
660+
@test ((f42645()::B42645).y::A42645{Int}).x

0 commit comments

Comments
 (0)