From a854139d97ab14de81bf139f0f761519757ca40e Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Sat, 22 Sep 2018 18:55:40 -0400 Subject: [PATCH] fix #29306, teach effect_free that GotoIfNot with non-Bool can throw (#29322) --- base/compiler/optimize.jl | 10 +++++++--- test/core.jl | 7 +++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index 870b83d50745f..fc59b1d6996af 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -145,10 +145,14 @@ end # These affect control flow within the function (so may not be removed # if there is no usage within the function), but don't affect the purity # of the function as a whole. -function stmt_affects_purity(@nospecialize stmt) - if isa(stmt, GotoIfNot) || isa(stmt, GotoNode) || isa(stmt, ReturnNode) +function stmt_affects_purity(@nospecialize(stmt), ir) + if isa(stmt, GotoNode) || isa(stmt, ReturnNode) return false end + if isa(stmt, GotoIfNot) + t = argextype(stmt.cond, ir, ir.spvals) + return !(t ⊑ Bool) + end if isa(stmt, Expr) return stmt.head != :simdloop && stmt.head != :enter end @@ -173,7 +177,7 @@ function optimize(opt::OptimizationState, @nospecialize(result)) proven_pure = true for i in 1:length(ir.stmts) stmt = ir.stmts[i] - if stmt_affects_purity(stmt) && !stmt_effect_free(stmt, ir.types[i], ir, ir.spvals) + if stmt_affects_purity(stmt, ir) && !stmt_effect_free(stmt, ir.types[i], ir, ir.spvals) proven_pure = false break end diff --git a/test/core.jl b/test/core.jl index 4e3fbc160abec..906da539ec355 100644 --- a/test/core.jl +++ b/test/core.jl @@ -6723,3 +6723,10 @@ function f29175(tuple::T) where {T<:Tuple} return prefix end @test f29175((1,2,3)) === (1,2) + +# issue #29306 +let a = [1,2,3,4,missing,6,7] + @test_throws TypeError [ (x>6 ? missing : x) for x in a] + foo(x) = x > 0 ? x : missing + @test_throws TypeError foo(missing) +end