diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2022-11-07 05:33:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-07 05:33:34 +0100 |
commit | d0f071a9e634c6fdd6fea353a7d331fd31a517fb (patch) | |
tree | c592920c3f25fa64efa070686429540c1a7476c3 | |
parent | 41f02c135673f5939ae648f45ba3a963a2e8113b (diff) | |
parent | 0cff4a3636f80c6b2ec037f80f8fe78ea163e2c5 (diff) | |
download | erlang-d0f071a9e634c6fdd6fea353a7d331fd31a517fb.tar.gz |
Merge pull request #6430 from bjorng/bjorn/compiler/ssa_opt_ranges/GH-6427
Eliminate internal error in sub pass ssa_opt_ranges
-rw-r--r-- | lib/compiler/src/beam_ssa_type.erl | 14 | ||||
-rw-r--r-- | lib/compiler/test/beam_type_SUITE.erl | 34 |
2 files changed, 47 insertions, 1 deletions
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl index 7e74e7e3f7..b293250365 100644 --- a/lib/compiler/src/beam_ssa_type.erl +++ b/lib/compiler/src/beam_ssa_type.erl @@ -920,8 +920,20 @@ update_anno_types_1([#b_var{}=V|As], Ts, Index, ArgTypes) -> case beam_types:meet(T0, T1) of any -> update_anno_types_1(As, Ts, Index + 1, ArgTypes); + none -> + %% This instruction will never be reached. This happens when + %% compiling code such as the following: + %% + %% f(X) when is_integer(X), 0 =< X, X < 64 -> + %% (X = bnot X) + 1. + %% + %% The main type optimization sub pass will not find out + %% that `(X = bnot X)` will never succeed and that the `+` + %% operator is never executed, but this sub pass will. + %% This happens very rarely; therefore, don't bother removing + %% the unreachable instruction. + update_anno_types_1(As, Ts, Index + 1, ArgTypes); T -> - true = T =/= none, %Assertion. update_anno_types_1(As, Ts, Index + 1, ArgTypes#{Index => T}) end; update_anno_types_1([_|As], Ts, Index, ArgTypes) -> diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl index 3439e36236..8bdce54543 100644 --- a/lib/compiler/test/beam_type_SUITE.erl +++ b/lib/compiler/test/beam_type_SUITE.erl @@ -119,6 +119,11 @@ integers(_Config) -> {'EXIT',{system_limit,_}} = catch do_integers_12(42), {'EXIT',{system_limit,_}} = catch do_integers_12([]), + {'EXIT',{{badmatch,42},_}} = catch do_integers_13(-43), + {'EXIT',{{badmatch,0},_}} = catch do_integers_13(-1), + {'EXIT',{{badmatch,-1},_}} = catch do_integers_13(0), + {'EXIT',{{badmatch,-18},_}} = catch do_integers_13(17), + ok. do_integers_1(B0) -> @@ -202,6 +207,35 @@ do_integers_11(V) -> do_integers_12(X) -> (1 bsl (1 bsl 100)) + X. +%% GH-6427. +do_integers_13(X) -> + try do_integers_13_1(<<X>>) of + _ -> error(should_fail) + catch + C:R:_ -> + try do_integers_13_2(X) of + _ -> error(should_fail) + catch + C:R:_ -> + try do_integers_13_3(X) of + _ -> error(should_fail) + catch + C:R:Stk -> + erlang:raise(C, R, Stk) + end + end + end. + +do_integers_13_1(<<X>>) -> + <<(X = bnot X)>>. + +do_integers_13_2(X) when is_integer(X), -64 < X, X < 64 -> + (X = bnot X) + 1. + +do_integers_13_3(X) when is_integer(X), -64 < X, X < 64 -> + X = bnot X, + X + 1. + numbers(_Config) -> Int = id(42), true = is_integer(Int), |