aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-05-29 10:32:09 +0200
committerBjörn Gustavsson <[email protected]>2019-05-29 10:32:09 +0200
commitab027321ccf1098349117bdd07268e3c15eb5db8 (patch)
treeec6b86b8f6b5a85f34e20a69877b27935714dc50 /lib/compiler/src
parent1c05d8815b5aa74c194236249ca3b7f008cf9cc4 (diff)
parent1550304a8857c9eca31dffdb27dcf459d8f11076 (diff)
downloadotp-ab027321ccf1098349117bdd07268e3c15eb5db8.tar.gz
otp-ab027321ccf1098349117bdd07268e3c15eb5db8.tar.bz2
otp-ab027321ccf1098349117bdd07268e3c15eb5db8.zip
Merge branch 'maint'
* maint: Eliminate crash in the beam_ssa_dead compiler pass
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/beam_ssa_dead.erl18
1 files changed, 16 insertions, 2 deletions
diff --git a/lib/compiler/src/beam_ssa_dead.erl b/lib/compiler/src/beam_ssa_dead.erl
index b25685d20b..88767456a3 100644
--- a/lib/compiler/src/beam_ssa_dead.erl
+++ b/lib/compiler/src/beam_ssa_dead.erl
@@ -436,8 +436,22 @@ get_phi_arg([{Val,From}|_], From) -> Val;
get_phi_arg([_|As], From) -> get_phi_arg(As, From).
eval_terminator(#b_br{bool=#b_var{}=Bool}=Br, Bs, _St) ->
- Val = get_value(Bool, Bs),
- beam_ssa:normalize(Br#b_br{bool=Val});
+ case get_value(Bool, Bs) of
+ #b_literal{val=Val}=Lit ->
+ case is_boolean(Val) of
+ true ->
+ beam_ssa:normalize(Br#b_br{bool=Lit});
+ false ->
+ %% Non-boolean literal. This means that this `br`
+ %% terminator will never actually be reached with
+ %% these bindings. (There must be a previous two-way
+ %% branch that branches the other way when Bool
+ %% is bound to a non-boolean literal.)
+ none
+ end;
+ #b_var{}=Var ->
+ beam_ssa:normalize(Br#b_br{bool=Var})
+ end;
eval_terminator(#b_br{bool=#b_literal{}}=Br, _Bs, _St) ->
beam_ssa:normalize(Br);
eval_terminator(#b_switch{arg=Arg,fail=Fail,list=List}=Sw, Bs, St) ->