Skip to content

Commit c3c8ffa

Browse files
authored
fix #32843, codegen attempting typeof(NULL) for some union tags (#40365)
also fixes part of #40065
1 parent 8fc38a4 commit c3c8ffa

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

src/cgutils.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2472,6 +2472,27 @@ static Value *compute_box_tindex(jl_codectx_t &ctx, Value *datatype, jl_value_t
24722472
return tindex;
24732473
}
24742474

2475+
// Returns typeof(v), or null if v is a null pointer at run time.
2476+
// This is used when the value might have come from an undefined variable,
2477+
// yet we try to read its type to compute a union index when moving the value.
2478+
static Value *emit_typeof_or_null(jl_codectx_t &ctx, Value *v)
2479+
{
2480+
BasicBlock *nonnull = BasicBlock::Create(jl_LLVMContext, "nonnull", ctx.f);
2481+
BasicBlock *postBB = BasicBlock::Create(jl_LLVMContext, "postnull", ctx.f);
2482+
Value *isnull = ctx.builder.CreateICmpEQ(v, Constant::getNullValue(v->getType()));
2483+
ctx.builder.CreateCondBr(isnull, postBB, nonnull);
2484+
BasicBlock *entry = ctx.builder.GetInsertBlock();
2485+
ctx.builder.SetInsertPoint(nonnull);
2486+
Value *typof = emit_typeof(ctx, v);
2487+
ctx.builder.CreateBr(postBB);
2488+
nonnull = ctx.builder.GetInsertBlock(); // could have changed
2489+
ctx.builder.SetInsertPoint(postBB);
2490+
PHINode *ti = ctx.builder.CreatePHI(typof->getType(), 2);
2491+
ti->addIncoming(Constant::getNullValue(typof->getType()), entry);
2492+
ti->addIncoming(typof, nonnull);
2493+
return ti;
2494+
}
2495+
24752496
// get the runtime tindex value, assuming val is already converted to type typ if it has a TIndex
24762497
static Value *compute_tindex_unboxed(jl_codectx_t &ctx, const jl_cgval_t &val, jl_value_t *typ)
24772498
{
@@ -2482,9 +2503,12 @@ static Value *compute_tindex_unboxed(jl_codectx_t &ctx, const jl_cgval_t &val, j
24822503

24832504
if (val.TIndex)
24842505
return ctx.builder.CreateAnd(val.TIndex, ConstantInt::get(T_int8, 0x7f));
2485-
if (val.isboxed)
2486-
return compute_box_tindex(ctx, emit_typeof_boxed(ctx, val), val.typ, typ);
2487-
return compute_box_tindex(ctx, emit_typeof_boxed(ctx, val), val.typ, typ);
2506+
Value *typof;
2507+
if (val.isboxed && !jl_is_concrete_type(val.typ) && !jl_is_type_type(val.typ))
2508+
typof = emit_typeof_or_null(ctx, val.V);
2509+
else
2510+
typof = emit_typeof_boxed(ctx, val);
2511+
return compute_box_tindex(ctx, typof, val.typ, typ);
24882512
}
24892513

24902514
static void union_alloca_type(jl_uniontype_t *ut,

src/codegen.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,11 +1504,13 @@ static jl_cgval_t convert_julia_type_union(jl_codectx_t &ctx, const jl_cgval_t &
15041504
// actually need it.
15051505
Value *union_box_dt = NULL;
15061506
BasicBlock *union_isaBB = NULL;
1507+
BasicBlock *post_union_isaBB = NULL;
15071508
auto maybe_setup_union_isa = [&]() {
15081509
if (!union_isaBB) {
15091510
union_isaBB = BasicBlock::Create(jl_LLVMContext, "union_isa", ctx.f);
15101511
ctx.builder.SetInsertPoint(union_isaBB);
1511-
union_box_dt = emit_typeof(ctx, v.Vboxed);
1512+
union_box_dt = emit_typeof_or_null(ctx, v.Vboxed);
1513+
post_union_isaBB = ctx.builder.GetInsertBlock();
15121514
}
15131515
};
15141516

@@ -1540,7 +1542,7 @@ static jl_cgval_t convert_julia_type_union(jl_codectx_t &ctx, const jl_cgval_t &
15401542
ctx.builder.SetInsertPoint(postBB);
15411543
PHINode *tindex_phi = ctx.builder.CreatePHI(T_int8, 2);
15421544
tindex_phi->addIncoming(new_tindex, currBB);
1543-
tindex_phi->addIncoming(union_box_tindex, union_isaBB);
1545+
tindex_phi->addIncoming(union_box_tindex, post_union_isaBB);
15441546
new_tindex = tindex_phi;
15451547
}
15461548
}

test/compiler/codegen.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,3 +553,11 @@ end
553553
end
554554
@test occursin("llvm.julia.gc_preserve_begin", get_llvm(f4, Tuple{Bool}, true, false, false))
555555
end
556+
557+
# issue #32843
558+
function f32843(vals0, v)
559+
(length(vals0) > 1) && (vals = v[1])
560+
(length(vals0) == 1 && vals0[1]==1) && (vals = 1:2)
561+
vals
562+
end
563+
@test_throws UndefVarError f32843([6], Vector[[1]])

0 commit comments

Comments
 (0)