diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2023-04-26 05:21:15 +0200 |
---|---|---|
committer | Björn Gustavsson <bjorn@erlang.org> | 2023-04-26 11:52:58 +0200 |
commit | d25bf59b5aea489e770b9ac0228eaa5b2998191d (patch) | |
tree | dfb6702908d0e4b1f4f01fe3e8712105c77695ee /lib/compiler | |
parent | ac956684bdb56630323754aef7b95497d4019b88 (diff) | |
download | erlang-d25bf59b5aea489e770b9ac0228eaa5b2998191d.tar.gz |
Eliminate compiler crash in beam_ssa_codegen
Closes #7170
Diffstat (limited to 'lib/compiler')
-rw-r--r-- | lib/compiler/src/beam_ssa_codegen.erl | 6 | ||||
-rw-r--r-- | lib/compiler/test/bif_SUITE.erl | 43 |
2 files changed, 46 insertions, 3 deletions
diff --git a/lib/compiler/src/beam_ssa_codegen.erl b/lib/compiler/src/beam_ssa_codegen.erl index c4708e9b11..9f6169829b 100644 --- a/lib/compiler/src/beam_ssa_codegen.erl +++ b/lib/compiler/src/beam_ssa_codegen.erl @@ -1450,6 +1450,12 @@ cg_copy_1([], _St) -> []. element(1, Val) =:= atom orelse element(1, Val) =:= literal)). +bif_to_test(min, Args, Fail, St) -> + %% The min/2 and max/2 BIFs can only be rewritten to tests when + %% both arguments are known to be booleans. + bif_to_test('and', Args, Fail, St); +bif_to_test(max, Args, Fail, St) -> + bif_to_test('or', Args, Fail, St); bif_to_test('or', [V1,V2], {f,Lbl}=Fail, St0) when Lbl =/= 0 -> {SuccLabel,St} = new_label(St0), {[{test,is_eq_exact,{f,SuccLabel},[V1,{atom,false}]}, diff --git a/lib/compiler/test/bif_SUITE.erl b/lib/compiler/test/bif_SUITE.erl index fc1d9ddfc0..e58db29114 100644 --- a/lib/compiler/test/bif_SUITE.erl +++ b/lib/compiler/test/bif_SUITE.erl @@ -25,7 +25,8 @@ init_per_group/2,end_per_group/2, beam_validator/1,trunc_and_friends/1,cover_safe_and_pure_bifs/1, cover_trim/1, - head_tail/1]). + head_tail/1, + min_max/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -34,12 +35,13 @@ all() -> [{group,p}]. groups() -> - [{p,[parallel], + [{p,test_lib:parallel(), [beam_validator, trunc_and_friends, cover_safe_and_pure_bifs, cover_trim, - head_tail + head_tail, + min_max ]}]. init_per_suite(Config) -> @@ -192,5 +194,40 @@ tail_case() -> X -> {X, ok} end. +min_max(_Config) -> + False = id(false), + True = id(true), + + false = bool_min_false(False, False), + false = bool_min_false(False, True), + false = bool_min_false(True, False), + true = bool_min_true(True, True), + + false = bool_max_false(False, False), + true = bool_max_true(False, True), + true = bool_max_true(True, False), + true = bool_max_true(True, True), + + ok. + +%% GH-7170: The following functions would cause a crash in +%% beam_ssa_codegen. + +bool_min_false(A, B) when is_boolean(A), is_boolean(B) -> + false = min(A, B). + +bool_min_true(A, B) when is_boolean(A), is_boolean(B) -> + true = min(A, B). + +bool_max_false(A, B) when is_boolean(A), is_boolean(B) -> + false = max(A, B). + +bool_max_true(A, B) when is_boolean(A), is_boolean(B) -> + true = max(A, B). + +%%% +%%% Common utilities. +%%% + id(I) -> I. |