File 0345-Fix-miscompilation-of-guard-with-or.patch of Package erlang
From c17f5de254be9dc3cb911c5b9e573291b1bd6928 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Thu, 1 Jun 2023 10:41:49 +0200
Subject: [PATCH] Fix miscompilation of guard with `or`
Closes #7370
---
lib/compiler/src/beam_ssa_bool.erl | 5 ++++-
lib/compiler/test/guard_SUITE.erl | 11 +++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/lib/compiler/src/beam_ssa_bool.erl b/lib/compiler/src/beam_ssa_bool.erl
index b0d4ab04ff..7d267dc072 100644
--- a/lib/compiler/src/beam_ssa_bool.erl
+++ b/lib/compiler/src/beam_ssa_bool.erl
@@ -366,7 +366,10 @@ pre_opt_is([#b_set{op={succeeded,_},dst=Dst,args=Args0}=I0|Is],
Sub = Sub0#{Dst=>#b_literal{val=true}},
pre_opt_is(Is, Reached, Sub, Acc);
false ->
- pre_opt_is(Is, Reached, Sub0, [I|Acc])
+ %% Don't remember boolean expressions that can potentially fail,
+ %% because that can cause unsafe optimizations.
+ Sub = maps:remove(Arg, Sub0),
+ pre_opt_is(Is, Reached, Sub, [I|Acc])
end;
pre_opt_is([#b_set{dst=Dst,args=Args0}=I0|Is], Reached, Sub0, Acc) ->
Args = sub_args(Args0, Sub0),
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 047bebe978..88c6e70bd6 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -2619,6 +2619,7 @@ beam_bool_SUITE(_Config) ->
gh_6184(),
gh_7252(),
gh_7339(),
+ gh_7370(),
ok.
before_and_inside_if() ->
@@ -3177,6 +3178,16 @@ do_gh_7339(M) when is_number(M) or (not is_map(M#{a => b})) ->
do_gh_7339(_) ->
b.
+gh_7370() ->
+ b = gh_7370(id(42)),
+ b = gh_7370(id(42.0)),
+ ok.
+
+gh_7370(A) when (not (not is_float(A))) =/= ((ok and ok) or true) ->
+ a;
+gh_7370(_) ->
+ b.
+
%%%
%%% End of beam_bool_SUITE tests.
%%%
--
2.35.3