From ecd72910f9f1a08eefb3e9c5ecdf04e20b8d16c5 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 12 Sep 2018 16:21:41 -0400 Subject: [PATCH] Initialize the union selector of undefined upsilon nodes While we're guaranteed never to look at undefined values, we're not guaranteed that the type information can't change, which in the case of a union generates code to change the layout. As a result, we need to make sure to have the union selectors be valid (the actual data will be junk and no semantic operation will ever look at it, but it shouldn't be ouf of bounds). Ref #29152 --- src/codegen.cpp | 10 +++++++++- test/core.jl | 11 +++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 3067aea2ee74d..d739ebe5a858b 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6184,10 +6184,18 @@ static std::unique_ptr emit_function( // If the val is null, we can ignore the store. // The middle end guarantees that the value from this // upsilon node is not dynamically observed. + jl_varinfo_t &vi = ctx.phic_slots[upsilon_to_phic[cursor+1]]; if (val) { jl_cgval_t rval_info = emit_expr(ctx, val); - jl_varinfo_t &vi = ctx.phic_slots[upsilon_to_phic[cursor+1]]; emit_varinfo_assign(ctx, vi, rval_info); + } else if (vi.pTIndex) { + // We don't care what the contents of the variable are, but it + // does need to satisfy the union invariants (i.e. inbounds + // tindex). + ctx.builder.CreateStore( + vi.boxroot ? ConstantInt::get(T_int8, 0x80) : + ConstantInt::get(T_int8, 0x01), + vi.pTIndex, true); } find_next_stmt(cursor + 1); continue; diff --git a/test/core.jl b/test/core.jl index 3c14f1bcd43d8..03eb64f837e6a 100644 --- a/test/core.jl +++ b/test/core.jl @@ -6794,3 +6794,14 @@ let a = [1,2,3,4,missing,6,7] foo(x) = x > 0 ? x : missing @test_throws TypeError foo(missing) end + +# issue #29152 +function f29152() + try + g29152() + finally + end +end +g29152() = (_true29152 ? error() : _true29152 ? 0 : false) +_true29152 = true; +@test_throws ErrorException f29152()