diff options
author | Björn Gustavsson <[email protected]> | 2016-05-20 15:18:53 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-05-23 08:39:52 +0200 |
commit | 69bb7b21a552c6e7d0615d4ead0345370deec2a0 (patch) | |
tree | 7ee9634a3e4e22fd3b156b0bf0999af2ffc033c0 /lib/compiler | |
parent | 9ab0dcce5a2bf609917cb09c36cbf63dad6bb679 (diff) | |
download | otp-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.erl | 2 | ||||
-rw-r--r-- | lib/compiler/test/beam_bool_SUITE.erl | 31 |
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. |