From 63b46825aa4d2d52d8899dd2c31e94874257a9bb Mon Sep 17 00:00:00 2001 From: quinnj Date: Sun, 20 Aug 2017 07:53:05 -0600 Subject: [PATCH] Work to ensure immutable isbits Union fields get set correctly. #23351 --- src/cgutils.cpp | 20 ++++++++++++++++---- src/datatype.c | 2 ++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 63434b182c0d3..d1216fb447830 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -2268,15 +2268,27 @@ static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t narg Type *fty = julia_type_to_llvm(jtype); const jl_cgval_t &fval_info = argv[i + 1]; emit_typecheck(ctx, fval_info, jtype, "new"); - if (!type_is_ghost(fty)) { - Value *fval = NULL, *dest = NULL; - if (!init_as_value) { + Value *dest = NULL; + if (!init_as_value) { + bool isunion = jl_is_uniontype(jtype); + if (!type_is_ghost(fty) || isunion) { // avoid unboxing the argument explicitly // and use memcpy instead dest = ctx.builder.CreateConstInBoundsGEP2_32(lt, strct, 0, i); } + if (isunion) { + int fsz = jl_field_size(sty, i); + // compute tindex from rhs + // jl_cgval_t rhs_union = convert_julia_type(ctx, rhs, jtype); + Value *tindex = compute_tindex_unboxed(ctx, fval_info, jtype); + tindex = ctx.builder.CreateNUWSub(tindex, ConstantInt::get(T_int8, 1)); + Value *ptindex = ctx.builder.CreateGEP(T_int8, emit_bitcast(ctx, dest, T_pint8), ConstantInt::get(T_size, fsz - 1)); + ctx.builder.CreateStore(tindex, ptindex); + } + } + if (!type_is_ghost(fty)) { + Value *fval = NULL; fval = emit_unbox(ctx, fty, fval_info, jtype, dest); - if (init_as_value) { if (lt->isVectorTy()) strct = ctx.builder.CreateInsertElement(strct, fval, ConstantInt::get(T_int32, idx)); diff --git a/src/datatype.c b/src/datatype.c index 147ea375b6023..d253820ebcab0 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -784,6 +784,8 @@ JL_DLLEXPORT jl_value_t *jl_get_nth_field(jl_value_t *v, size_t i) if (jl_is_uniontype(ty)) { uint8_t sel = ((uint8_t*)v)[offs + jl_field_size(st, i) - 1]; ty = jl_nth_union_component(ty, sel); + if (jl_is_datatype_singleton((jl_datatype_t*)ty)) + return ((jl_datatype_t*)ty)->instance; } return jl_new_bits(ty, (char*)v + offs); }