File 0438-Validate-the-left-operand-for-andalso-orelse-in-guar.patch of Package erlang
From a431f3316c704cdaf8e7f6e92005c39d1695bd66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Thu, 27 Feb 2020 14:26:40 +0100
Subject: [PATCH 18/30] Validate the left operand for andalso/orelse in guards
The left operand for andalso/orelse must be a boolean, but that
was not verified in a guard. Example:
bar() when whatever =/= (program andalso []) -> ...
This guard should fail because the left operand of andalso is not
a boolean.
---
lib/compiler/src/v3_core.erl | 24 +++++-------------------
lib/compiler/test/guard_SUITE.erl | 7 +++++++
2 files changed, 12 insertions(+), 19 deletions(-)
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 659ddc71cc..488e55cea5 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -340,7 +340,7 @@ gexpr({op,_,'andalso',_,_}=E0, Bools, St0) ->
{#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
False = {atom,L,false},
- E = make_bool_switch_guard(L, E1, V, E2, False),
+ E = make_bool_switch(L, E1, V, E2, False),
gexpr(E, Bools, St);
gexpr({op,_,'orelse',_,_}=E0, Bools, St0) ->
{op,L,'orelse',E1,E2} = right_assoc(E0, 'orelse'),
@@ -348,7 +348,7 @@ gexpr({op,_,'orelse',_,_}=E0, Bools, St0) ->
{#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
True = {atom,L,true},
- E = make_bool_switch_guard(L, E1, V, True, E2),
+ E = make_bool_switch(L, E1, V, True, E2),
gexpr(E, Bools, St);
gexpr({op,Line,Op,L,R}=E, Bools, St) ->
case erl_internal:bool_op(Op, 2) of
@@ -790,7 +790,7 @@ expr({op,_,'andalso',_,_}=E0, St0) ->
{#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
False = {atom,L,false},
- E = make_bool_switch(L, E1, V, E2, False, St0),
+ E = make_bool_switch(L, E1, V, E2, False),
expr(E, St);
expr({op,_,'orelse',_,_}=E0, St0) ->
{op,L,'orelse',E1,E2} = right_assoc(E0, 'orelse'),
@@ -798,7 +798,7 @@ expr({op,_,'orelse',_,_}=E0, St0) ->
{#c_var{name=V0},St} = new_var(Anno, St0),
V = {var,L,V0},
True = {atom,L,true},
- E = make_bool_switch(L, E1, V, True, E2, St0),
+ E = make_bool_switch(L, E1, V, True, E2),
expr(E, St);
expr({op,L,Op,A0}, St0) ->
{A1,Aps,St1} = safe(A0, St0),
@@ -841,12 +841,7 @@ sanitize({op,L,_Name,P1,P2}) ->
{tuple,L,[sanitize(P1),sanitize(P2)]};
sanitize(P) -> P.
-make_bool_switch(L, E, V, T, F, #core{in_guard=true}) ->
- make_bool_switch_guard(L, E, V, T, F);
-make_bool_switch(L, E, V, T, F, #core{}) ->
- make_bool_switch_body(L, E, V, T, F).
-
-make_bool_switch_body(L, E, V, T, F) ->
+make_bool_switch(L, E, V, T, F) ->
NegL = no_compiler_warning(L),
Error = {tuple,NegL,[{atom,NegL,badarg},V]},
{'case',NegL,E,
@@ -856,15 +851,6 @@ make_bool_switch_body(L, E, V, T, F) ->
[{call,NegL,{remote,NegL,{atom,NegL,erlang},{atom,NegL,error}},
[Error]}]}]}.
-make_bool_switch_guard(_, E, _, {atom,_,true}, {atom,_,false}) -> E;
-make_bool_switch_guard(L, E, V, T, F) ->
- NegL = no_compiler_warning(L),
- {'case',NegL,E,
- [{clause,NegL,[{atom,NegL,true}],[],[T]},
- {clause,NegL,[{atom,NegL,false}],[],[F]},
- {clause,NegL,[V],[],[V]}
- ]}.
-
expr_map(M0, Es0, L, St0) ->
{M1,Eps0,St1} = safe(M0, St0),
Badmap = badmap_term(M1, St1),
--
2.16.4