aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-05-20 15:18:53 +0200
committerBjörn Gustavsson <[email protected]>2016-05-23 08:39:52 +0200
commit69bb7b21a552c6e7d0615d4ead0345370deec2a0 (patch)
tree7ee9634a3e4e22fd3b156b0bf0999af2ffc033c0 /lib/compiler
parent9ab0dcce5a2bf609917cb09c36cbf63dad6bb679 (diff)
downloadotp-69bb7b21a552c6e7d0615d4ead0345370deec2a0.tar.gz
otp-69bb7b21a552c6e7d0615d4ead0345370deec2a0.tar.bz2
otp-69bb7b21a552c6e7d0615d4ead0345370deec2a0.zip
beam_bool: Reject potentially unsafe optimization
When calculating the sets of registers that must be killed or unused, registers set in a {protected,_,_,_} block were not considered. That could result in a crash in the assertion in beam_utils:live_opt_block/4.
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_bool.erl2
-rw-r--r--lib/compiler/test/beam_bool_SUITE.erl31
2 files changed, 31 insertions, 2 deletions
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index 359fdb6d3c..99e4ccb1e9 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.erl
@@ -311,6 +311,8 @@ dst_regs([{set,[D],_,{bif,_,{f,_}}}|Is], Acc) ->
dst_regs(Is, [D|Acc]);
dst_regs([{set,[D],_,{alloc,_,{gc_bif,_,{f,_}}}}|Is], Acc) ->
dst_regs(Is, [D|Acc]);
+dst_regs([{protected,_,Bl,_}|Is], Acc) ->
+ dst_regs(Bl, dst_regs(Is, Acc));
dst_regs([_|Is], Acc) ->
dst_regs(Is, Acc);
dst_regs([], Acc) -> ordsets:from_list(Acc).
diff --git a/lib/compiler/test/beam_bool_SUITE.erl b/lib/compiler/test/beam_bool_SUITE.erl
index 84d634e5ca..a07d010879 100644
--- a/lib/compiler/test/beam_bool_SUITE.erl
+++ b/lib/compiler/test/beam_bool_SUITE.erl
@@ -22,7 +22,7 @@
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
before_and_inside_if/1,
- scotland/1,y_registers/1]).
+ scotland/1,y_registers/1,protected/1]).
suite() ->
[{ct_hooks,[ts_install_cth]}].
@@ -35,7 +35,8 @@ groups() ->
[{p,[parallel],
[before_and_inside_if,
scotland,
- y_registers
+ y_registers,
+ protected
]}].
init_per_suite(Config) ->
@@ -158,3 +159,29 @@ potter(Modes) ->
_ -> not_ok
end,
{Final,Raw}.
+
+protected(_Config) ->
+ {'EXIT',{if_clause,_}} = (catch photographs({1, surprise, true}, opinions)),
+
+ {{true}} = welcome({perfect, true}),
+ {'EXIT',{if_clause,_}} = (catch welcome({perfect, false})),
+ ok.
+
+photographs({_Violation, surprise, Deep}, opinions) ->
+ {if
+ 0; "here", Deep ->
+ Deep = Deep
+ end}.
+
+welcome({perfect, Profit}) ->
+ if
+ Profit, Profit, Profit; 0 ->
+ {id({Profit})}
+ end.
+
+%%%
+%%% Common utilities.
+%%%
+
+id(I) ->
+ I.