diff options
author | Anthony Ramine <[email protected]> | 2014-03-08 01:49:13 +0100 |
---|---|---|
committer | Anthony Ramine <[email protected]> | 2014-03-08 01:58:39 +0100 |
commit | 3abbbeec85268f243b7c97f569ad4da40babd8c9 (patch) | |
tree | 40c26095020a3a75d7d5f19491bcd6f071ea2521 | |
parent | 870737ab657433c5e8751255fe3c4d298202d142 (diff) | |
download | otp-3abbbeec85268f243b7c97f569ad4da40babd8c9.tar.gz otp-3abbbeec85268f243b7c97f569ad4da40babd8c9.tar.bz2 otp-3abbbeec85268f243b7c97f569ad4da40babd8c9.zip |
Properly detect reused boolean values in beam_bool
The following code could crash the compiler:
f(X = true) when X or true or X -> ok.
Reported-by: Ulf Norell
-rw-r--r-- | lib/compiler/src/beam_bool.erl | 7 | ||||
-rw-r--r-- | lib/compiler/test/andor_SUITE.erl | 2 |
2 files changed, 6 insertions, 3 deletions
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl index d01f9ee13d..5a4621dc37 100644 --- a/lib/compiler/src/beam_bool.erl +++ b/lib/compiler/src/beam_bool.erl @@ -438,9 +438,10 @@ bopt_bool_args(As, Forest) -> mapfoldl(fun bopt_bool_arg/2, Forest, As). bopt_bool_arg({T,_}=R, Forest) when T =:= x; T =:= y; T =:= tmp -> - Val = case gb_trees:get(R, Forest) of - any -> {test,is_eq_exact,fail,[R,{atom,true}]}; - Val0 -> Val0 + Val = case gb_trees:lookup(R, Forest) of + {value,any} -> {test,is_eq_exact,fail,[R,{atom,true}]}; + {value,Val0} -> Val0; + none -> throw(mixed) end, {Val,gb_trees:delete(R, Forest)}; bopt_bool_arg(Term, Forest) -> diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl index d79696df38..b5408ecd8f 100644 --- a/lib/compiler/test/andor_SUITE.erl +++ b/lib/compiler/test/andor_SUITE.erl @@ -171,6 +171,8 @@ t_and_or(Config) when is_list(Config) -> false = ?GUARD(erlang:'not'(erlang:'and'(bar, True))), false = ?GUARD(erlang:'not'(erlang:'not'(erlang:'and'(bar, True)))), + true = (fun (X = true) when X or true or X -> true end)(True), + ok. t_andalso(Config) when is_list(Config) -> |