Skip to content

Commit

Permalink
codegen: add missing jl_get_fieldtypes calls
Browse files Browse the repository at this point in the history
Fixes #42645
  • Loading branch information
vtjnash committed Oct 15, 2021
1 parent b3c268c commit 485495f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 12 deletions.
24 changes: 13 additions & 11 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ static DIType *_julia_type_to_di(jl_codegen_params_t *ctx, jl_value_t *jt, DIBui
size_t ntypes = jl_datatype_nfields(jdt);
std::vector<llvm::Metadata*> Elements(ntypes);
for (unsigned i = 0; i < ntypes; i++) {
jl_value_t *el = jl_svecref(jdt->types, i);
jl_value_t *el = jl_field_type_concrete(jdt, i);
DIType *di;
if (jl_field_isptr(jdt, i))
di = jl_pvalue_dillvmt;
Expand Down Expand Up @@ -2039,9 +2039,10 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
if (!strct.ispointer()) { // unboxed
assert(jl_is_concrete_immutable((jl_value_t*)stt));
bool isboxed = is_datatype_all_pointers(stt);
bool issame = is_tupletype_homogeneous(stt->types);
jl_svec_t *types = stt->types;
bool issame = is_tupletype_homogeneous(types);
if (issame) {
jl_value_t *jft = jl_svecref(stt->types, 0);
jl_value_t *jft = jl_svecref(types, 0);
if (strct.isghost) {
(void)idx0();
*ret = ghostValue(jft);
Expand Down Expand Up @@ -2081,7 +2082,7 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
ctx.builder.CreateExtractValue(strct.V, makeArrayRef(i)),
fld);
}
jl_value_t *jft = issame ? jl_svecref(stt->types, 0) : (jl_value_t*)jl_any_type;
jl_value_t *jft = issame ? jl_svecref(types, 0) : (jl_value_t*)jl_any_type;
if (isboxed && maybe_null)
null_pointer_check(ctx, fld);
*ret = mark_julia_type(ctx, fld, isboxed, jft);
Expand Down Expand Up @@ -2123,9 +2124,9 @@ static bool emit_getfield_unknownidx(jl_codectx_t &ctx,
*ret = mark_julia_type(ctx, fld, true, jl_any_type);
return true;
}
else if (is_tupletype_homogeneous(stt->types)) {
else if (is_tupletype_homogeneous(jl_get_fieldtypes(stt))) {
assert(nfields > 0); // nf == 0 trapped by all_pointers case
jl_value_t *jft = jl_svecref(stt->types, 0);
jl_value_t *jft = jl_svecref(stt->types, 0); // n.b. jl_get_fieldtypes assigned stt->types for here
assert(jl_is_concrete_type(jft));
idx = idx0();
Value *ptr = maybe_decay_tracked(ctx, data_pointer(ctx, strct));
Expand Down Expand Up @@ -3255,9 +3256,10 @@ static void find_perm_offsets(jl_datatype_t *typ, SmallVector<unsigned,4> &res,
// This is a inlined field at `offset`.
if (!typ->layout || typ->layout->npointers == 0)
return;
size_t nf = jl_svec_len(typ->types);
jl_svec_t *types = jl_get_fieldtypes(typ);
size_t nf = jl_svec_len(types);
for (size_t i = 0; i < nf; i++) {
jl_value_t *_fld = jl_svecref(typ->types, i);
jl_value_t *_fld = jl_svecref(types, i);
if (!jl_is_datatype(_fld))
continue;
jl_datatype_t *fld = (jl_datatype_t*)_fld;
Expand Down Expand Up @@ -3306,7 +3308,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
emit_bitcast(ctx, maybe_decay_tracked(ctx, addr), T_pint8),
ConstantInt::get(T_size, byte_offset)); // TODO: use emit_struct_gep
}
jl_value_t *jfty = jl_svecref(sty->types, idx0);
jl_value_t *jfty = jl_field_type(sty, idx0);
if (!jl_field_isptr(sty, idx0) && jl_is_uniontype(jfty)) {
size_t fsz = 0, al = 0;
bool isptr = !jl_islayout_inline(jfty, &fsz, &al);
Expand Down Expand Up @@ -3431,7 +3433,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
}

for (unsigned i = 0; i < na; i++) {
jl_value_t *jtype = jl_svecref(sty->types, i);
jl_value_t *jtype = jl_svecref(sty->types, i); // n.b. ty argument must be concrete
jl_cgval_t fval_info = argv[i];
emit_typecheck(ctx, fval_info, jtype, "new");
fval_info = update_julia_type(ctx, fval_info, jtype);
Expand Down Expand Up @@ -3566,7 +3568,7 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
need_wb = !rhs.isboxed;
else
need_wb = false;
emit_typecheck(ctx, rhs, jl_svecref(sty->types, i), "new");
emit_typecheck(ctx, rhs, jl_svecref(sty->types, i), "new"); // n.b. ty argument must be concrete
emit_setfield(ctx, sty, strctinfo, i, rhs, jl_cgval_t(), false, need_wb, AtomicOrdering::NotAtomic, AtomicOrdering::NotAtomic, false, true, false, false, false, nullptr, "");
}
return strctinfo;
Expand Down
2 changes: 1 addition & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2688,7 +2688,7 @@ static bool emit_f_opfield(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
idx = i - 1;
}
if (idx != -1) {
jl_value_t *ft = jl_svecref(uty->types, idx);
jl_value_t *ft = jl_field_type(uty, idx);
if (!jl_has_free_typevars(ft)) {
if (!ismodifyfield && !jl_subtype(val.typ, ft)) {
emit_typecheck(ctx, val, ft, fname);
Expand Down
1 change: 1 addition & 0 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ int jl_struct_try_layout(jl_datatype_t *dt)
return 1;
else if (!jl_has_fixed_layout(dt))
return 0;
// jl_has_fixed_layout also ensured that dt->types is assigned now
jl_compute_field_offsets(dt);
assert(dt->layout);
return 1;
Expand Down
21 changes: 21 additions & 0 deletions test/compiler/codegen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -644,3 +644,24 @@ mktempdir() do pfx
run(`rm -rf $pfx/lib/julia/libjulia-codegen\*`)
@test readchomp(`$pfx/bin/$(Base.julia_exename()) -e 'println("no codegen!")'`) == "no codegen!"
end

# issue #42645
mutable struct A42645{T}
x::Bool
function A42645(a::Vector{T}) where T
r = new{T}()
r.x = false
return r
end
end
mutable struct B42645{T}
y::A42645{T}
end
x42645 = 1
function f42645()
res = B42645(A42645([x42645]))
res.y = A42645([x42645])
res.y.x = true
res
end
@test ((f42645()::B42645).y::A42645{Int}).x

0 comments on commit 485495f

Please sign in to comment.