Skip to content

codegen: add missing jl_get_fieldtypes calls #42668

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 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 @@ -3291,7 +3293,7 @@ static jl_cgval_t emit_setfield(jl_codectx_t &ctx,
const jl_cgval_t *modifyop, const std::string &fname)
{
if (!sty->name->mutabl && checked) {
std::string msg = fname + "immutable struct of type "
std::string msg = fname + ": immutable struct of type "
+ std::string(jl_symbol_name(sty->name->name))
+ " cannot be changed";
emit_error(ctx, msg);
Expand All @@ -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