Skip to content

Commit fe66832

Browse files
committed
Work to ensure immutable isbits Union fields get set correctly. #23351
1 parent d537999 commit fe66832

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

src/cgutils.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,15 +2268,27 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg
22682268
Type *fty = julia_type_to_llvm(jtype);
22692269
const jl_cgval_t &fval_info = argv[i + 1];
22702270
emit_typecheck(ctx, fval_info, jtype, "new");
2271-
if (!type_is_ghost(fty)) {
2272-
Value *fval = NULL, *dest = NULL;
2273-
if (!init_as_value) {
2271+
Value *dest = NULL;
2272+
if (!init_as_value) {
2273+
bool isunion = jl_is_uniontype(jtype);
2274+
if (!type_is_ghost(fty) || isunion) {
22742275
// avoid unboxing the argument explicitly
22752276
// and use memcpy instead
22762277
dest = ctx.builder.CreateConstInBoundsGEP2_32(lt, strct, 0, i);
22772278
}
2279+
if (isunion) {
2280+
int fsz = jl_field_size(sty, i);
2281+
// compute tindex from rhs
2282+
// jl_cgval_t rhs_union = convert_julia_type(ctx, rhs, jtype);
2283+
Value *tindex = compute_tindex_unboxed(ctx, fval_info, jtype);
2284+
tindex = ctx.builder.CreateNUWSub(tindex, ConstantInt::get(T_int8, 1));
2285+
Value *ptindex = ctx.builder.CreateGEP(T_int8, emit_bitcast(ctx, dest, T_pint8), ConstantInt::get(T_size, fsz - 1));
2286+
ctx.builder.CreateStore(tindex, ptindex);
2287+
}
2288+
}
2289+
if (!type_is_ghost(fty)) {
2290+
Value *fval = NULL;
22782291
fval = emit_unbox(ctx, fty, fval_info, jtype, dest);
2279-
22802292
if (init_as_value) {
22812293
if (lt->isVectorTy())
22822294
strct = ctx.builder.CreateInsertElement(strct, fval, ConstantInt::get(T_int32, idx));

src/datatype.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,8 @@ JL_DLLEXPORT jl_value_t *jl_get_nth_field(jl_value_t *v, size_t i)
781781
if (jl_is_uniontype(ty)) {
782782
uint8_t sel = ((uint8_t*)v)[offs + jl_field_size(st, i) - 1];
783783
ty = jl_nth_union_component(ty, sel);
784+
if (jl_is_datatype_singleton((jl_datatype_t*)ty))
785+
return ((jl_datatype_t*)ty)->instance;
784786
}
785787
return jl_new_bits(ty, (char*)v + offs);
786788
}

0 commit comments

Comments
 (0)