Skip to content

Commit

Permalink
codegen: fixing union isbits comparison UB (#41046)
Browse files Browse the repository at this point in the history
Fixes #40612
Fixes #40834

(cherry picked from commit 33fa18b)
  • Loading branch information
vtjnash authored and staticfloat committed Dec 22, 2022
1 parent 8129887 commit a347511
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2430,11 +2430,18 @@ static Value *emit_bitsunion_compare(jl_codectx_t &ctx, const jl_cgval_t &arg1,
{
assert(jl_egal(arg1.typ, arg2.typ) && arg1.TIndex && arg2.TIndex && jl_is_uniontype(arg1.typ) && "unimplemented");
Value *tindex = arg1.TIndex;
tindex = ctx.builder.CreateAnd(tindex, ConstantInt::get(T_int8, 0x7f));
Value *tindex2 = arg2.TIndex;
tindex2 = ctx.builder.CreateAnd(tindex2, ConstantInt::get(T_int8, 0x7f));
Value *typeeq = ctx.builder.CreateICmpEQ(tindex, tindex2);
tindex = ctx.builder.CreateSelect(typeeq, tindex, ConstantInt::get(T_int8, 0x00));
BasicBlock *defaultBB = BasicBlock::Create(jl_LLVMContext, "unionbits_is_boxed", ctx.f);
SwitchInst *switchInst = ctx.builder.CreateSwitch(tindex, defaultBB);
BasicBlock *postBB = BasicBlock::Create(jl_LLVMContext, "post_unionbits_is", ctx.f);
ctx.builder.SetInsertPoint(postBB);
PHINode *phi = ctx.builder.CreatePHI(T_int1, 2);
switchInst->addCase(ConstantInt::get(T_int8, 0), postBB);
phi->addIncoming(ConstantInt::get(T_int1, 0), switchInst->getParent());
unsigned counter = 0;
bool allunboxed = for_each_uniontype_small(
[&](unsigned idx, jl_datatype_t *jt) {
Expand All @@ -2458,7 +2465,7 @@ static Value *emit_bitsunion_compare(jl_codectx_t &ctx, const jl_cgval_t &arg1,
ctx.builder.CreateCall(trap_func);
ctx.builder.CreateUnreachable();
ctx.builder.SetInsertPoint(postBB);
return ctx.builder.CreateAnd(phi, ctx.builder.CreateICmpEQ(arg1.TIndex, arg2.TIndex));
return phi;
}

static Value *emit_bits_compare(jl_codectx_t &ctx, jl_cgval_t arg1, jl_cgval_t arg2)
Expand Down
10 changes: 10 additions & 0 deletions test/compiler/codegen.jl
Original file line number Diff line number Diff line change
Expand Up @@ -568,3 +568,13 @@ struct A40855
end
g() = string(A40855(X40855, 1))
@test g() == "$(@__MODULE__).A40855($(@__MODULE__).X40855, 1)"

# issue #40612
f40612(a, b) = a|b === a|b
g40612(a, b) = a[]|a[] === b[]|b[]
@test f40612(true, missing)
@test !g40612(Union{Bool,Missing}[missing], Union{Bool,Missing}[true])
@test !g40612(Union{Bool,Missing}[false], Union{Bool,Missing}[true])
@test g40612(Union{Bool,Missing}[missing], Union{Bool,Missing}[missing])
@test g40612(Union{Bool,Missing}[true], Union{Bool,Missing}[true])
@test g40612(Union{Bool,Missing}[false], Union{Bool,Missing}[false])

0 comments on commit a347511

Please sign in to comment.