From a3475111045eaeee555d472fe05aa21a98015bb3 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 2 Jun 2021 16:51:54 -0400 Subject: [PATCH] codegen: fixing union isbits comparison UB (#41046) Fixes #40612 Fixes #40834 (cherry picked from commit 33fa18ba3c4b8ccc058dbfa51c52ab12ce356f7c) --- src/codegen.cpp | 9 ++++++++- test/compiler/codegen.jl | 10 ++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index ddad461154b38a..60a5fb98da25f0 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -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) { @@ -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) diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index 95b83dac5a2107..67238123950f04 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -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])