Skip to content

Commit 1b64755

Browse files
authored
Merge pull request JuliaLang#42668 from JuliaLang/jn/42645
codegen: add missing jl_get_fieldtypes calls
2 parents 225c543 + a11d804 commit 1b64755

File tree

4 files changed

+37
-13
lines changed

4 files changed

+37
-13
lines changed

src/cgutils.cpp

+14-12
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;
@@ -2039,9 +2039,10 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
20392039
if (!strct.ispointer()) { // unboxed
20402040
assert(jl_is_concrete_immutable((jl_value_t*)stt));
20412041
bool isboxed = is_datatype_all_pointers(stt);
2042-
bool issame = is_tupletype_homogeneous(stt->types);
2042+
jl_svec_t *types = stt->types;
2043+
bool issame = is_tupletype_homogeneous(types);
20432044
if (issame) {
2044-
jl_value_t *jft = jl_svecref(stt->types, 0);
2045+
jl_value_t *jft = jl_svecref(types, 0);
20452046
if (strct.isghost) {
20462047
(void)idx0();
20472048
*ret = ghostValue(jft);
@@ -2081,7 +2082,7 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
20812082
ctx.builder.CreateExtractValue(strct.V, makeArrayRef(i)),
20822083
fld);
20832084
}
2084-
jl_value_t *jft = issame ? jl_svecref(stt->types, 0) : (jl_value_t*)jl_any_type;
2085+
jl_value_t *jft = issame ? jl_svecref(types, 0) : (jl_value_t*)jl_any_type;
20852086
if (isboxed && maybe_null)
20862087
null_pointer_check(ctx, fld);
20872088
*ret = mark_julia_type(ctx, fld, isboxed, jft);
@@ -2123,9 +2124,9 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
21232124
*ret = mark_julia_type(ctx, fld, true, jl_any_type);
21242125
return true;
21252126
}
2126-
else if (is_tupletype_homogeneous(stt->types)) {
2127+
else if (is_tupletype_homogeneous(jl_get_fieldtypes(stt))) {
21272128
assert(nfields > 0); // nf == 0 trapped by all_pointers case
2128-
jl_value_t *jft = jl_svecref(stt->types, 0);
2129+
jl_value_t *jft = jl_svecref(stt->types, 0); // n.b. jl_get_fieldtypes assigned stt->types for here
21292130
assert(jl_is_concrete_type(jft));
21302131
idx = idx0();
21312132
Value *ptr = maybe_decay_tracked(ctx, data_pointer(ctx, strct));
@@ -3255,9 +3256,10 @@ static void find_perm_offsets(jl_datatype_t *typ, SmallVector<unsigned,4> &res,
32553256
// This is a inlined field at `offset`.
32563257
if (!typ->layout || typ->layout->npointers == 0)
32573258
return;
3258-
size_t nf = jl_svec_len(typ->types);
3259+
jl_svec_t *types = jl_get_fieldtypes(typ);
3260+
size_t nf = jl_svec_len(types);
32593261
for (size_t i = 0; i < nf; i++) {
3260-
jl_value_t *_fld = jl_svecref(typ->types, i);
3262+
jl_value_t *_fld = jl_svecref(types, i);
32613263
if (!jl_is_datatype(_fld))
32623264
continue;
32633265
jl_datatype_t *fld = (jl_datatype_t*)_fld;
@@ -3291,7 +3293,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
32913293
const jl_cgval_t *modifyop, const std::string &fname)
32923294
{
32933295
if (!sty->name->mutabl && checked) {
3294-
std::string msg = fname + "immutable struct of type "
3296+
std::string msg = fname + ": immutable struct of type "
32953297
+ std::string(jl_symbol_name(sty->name->name))
32963298
+ " cannot be changed";
32973299
emit_error(ctx, msg);
@@ -3306,7 +3308,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
33063308
emit_bitcast(ctx, maybe_decay_tracked(ctx, addr), T_pint8),
33073309
ConstantInt::get(T_size, byte_offset)); // TODO: use emit_struct_gep
33083310
}
3309-
jl_value_t *jfty = jl_svecref(sty->types, idx0);
3311+
jl_value_t *jfty = jl_field_type(sty, idx0);
33103312
if (!jl_field_isptr(sty, idx0) && jl_is_uniontype(jfty)) {
33113313
size_t fsz = 0, al = 0;
33123314
bool isptr = !jl_islayout_inline(jfty, &fsz, &al);
@@ -3431,7 +3433,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
34313433
}
34323434

34333435
for (unsigned i = 0; i < na; i++) {
3434-
jl_value_t *jtype = jl_svecref(sty->types, i);
3436+
jl_value_t *jtype = jl_svecref(sty->types, i); // n.b. ty argument must be concrete
34353437
jl_cgval_t fval_info = argv[i];
34363438
emit_typecheck(ctx, fval_info, jtype, "new");
34373439
fval_info = update_julia_type(ctx, fval_info, jtype);
@@ -3566,7 +3568,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
35663568
need_wb = !rhs.isboxed;
35673569
else
35683570
need_wb = false;
3569-
emit_typecheck(ctx, rhs, jl_svecref(sty->types, i), "new");
3571+
emit_typecheck(ctx, rhs, jl_svecref(sty->types, i), "new"); // n.b. ty argument must be concrete
35703572
emit_setfield(ctx, sty, strctinfo, i, rhs, jl_cgval_t(), false, need_wb, AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, false, true, false, false, false, nullptr, "");
35713573
}
35723574
return strctinfo;

src/codegen.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2688,7 +2688,7 @@ static bool emit_f_opfield(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
26882688
idx = i - 1;
26892689
}
26902690
if (idx != -1) {
2691-
jl_value_t *ft = jl_svecref(uty->types, idx);
2691+
jl_value_t *ft = jl_field_type(uty, idx);
26922692
if (!jl_has_free_typevars(ft)) {
26932693
if (!ismodifyfield && !jl_subtype(val.typ, ft)) {
26942694
emit_typecheck(ctx, val, ft, fname);

src/datatype.c

+1
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

+21
Original file line numberDiff line numberDiff line change
@@ -644,3 +644,24 @@ mktempdir() do pfx
644644
run(`rm -rf $pfx/lib/julia/libjulia-codegen\*`)
645645
@test readchomp(`$pfx/bin/$(Base.julia_exename()) -e 'println("no codegen!")'`) == "no codegen!"
646646
end
647+
648+
# issue #42645
649+
mutable struct A42645{T}
650+
x::Bool
651+
function A42645(a::Vector{T}) where T
652+
r = new{T}()
653+
r.x = false
654+
return r
655+
end
656+
end
657+
mutable struct B42645{T}
658+
y::A42645{T}
659+
end
660+
x42645 = 1
661+
function f42645()
662+
res = B42645(A42645([x42645]))
663+
res.y = A42645([x42645])
664+
res.y.x = true
665+
res
666+
end
667+
@test ((f42645()::B42645).y::A42645{Int}).x

0 commit comments

Comments
 (0)