Skip to content

Commit

Permalink
Only emit incoming values for the phi when needed (#37285)
Browse files Browse the repository at this point in the history
Fixes a crash when one of the incoming value for a union value phi node is of type `Union{}`.
Incoming value of this type can be generated by try-catch.

Fix #37265

(cherry picked from commit c3a63fc)
  • Loading branch information
yuyichao authored and KristofferC committed Sep 7, 2020
1 parent 38c3e74 commit cffaf55
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
17 changes: 12 additions & 5 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6206,19 +6206,25 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
}
else {
Value *RTindex;
Value *V;
// The branch below is a bit too complex for GCC to realize that
// `V` is always initialized when it is used.
// Ref https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96629
Value *V = nullptr;
if (val.typ == (jl_value_t*)jl_bottom_type) {
V = undef_value_for_type(VN->getType());
if (VN)
V = undef_value_for_type(VN->getType());
RTindex = UndefValue::get(T_int8);
}
else if (jl_is_concrete_type(val.typ) || val.constant) {
size_t tindex = get_box_tindex((jl_datatype_t*)val.typ, phiType);
if (tindex == 0) {
V = boxed(ctx, val);
if (VN)
V = boxed(ctx, val);
RTindex = ConstantInt::get(T_int8, 0x80);
}
else {
V = ConstantPointerNull::get(cast<PointerType>(T_prjlvalue));
if (VN)
V = V_rnull;
Type *lty = julia_type_to_llvm(ctx, val.typ);
if (dest && !type_is_ghost(lty)) // basically, if !ghost union
emit_unbox(ctx, lty, val, val.typ, dest);
Expand All @@ -6238,7 +6244,8 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
}
new_union.TIndex = RTindex;
}
V = new_union.Vboxed ? new_union.Vboxed : ConstantPointerNull::get(cast<PointerType>(T_prjlvalue));
if (VN)
V = new_union.Vboxed ? new_union.Vboxed : V_rnull;
if (dest) { // basically, if !ghost union
Value *skip = NULL;
if (new_union.Vboxed != nullptr)
Expand Down
32 changes: 32 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7233,3 +7233,35 @@ struct X36104; x::Int; end
@test fieldtypes(X36104) == (Int,)
primitive type P36104 8 end
@test_throws ErrorException("invalid redefinition of constant P36104") @eval(primitive type P36104 16 end)

a37265() = 0
b37265() = 0
function c37265(d)
if d == 1
e = a37265
elseif d == 2
e = b37265
else
try
catch
end
end
e
end
@test_throws UndefVarError c37265(0)
@test c37265(1) === a37265
@test c37265(2) === b37265

function c37265_2(d)
if 0
e = a37265
elseif 0
e = b37265
else
try
catch
end
end
e
end
@test_throws TypeError c37265_2(0)

0 comments on commit cffaf55

Please sign in to comment.