aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_validator.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-04-23 19:52:16 +0200
committerBjörn Gustavsson <[email protected]>2018-08-17 09:50:58 +0200
commit316a794b41b2f4173b2b188ac4c91adeaa52c616 (patch)
tree1c467a3c48097f81954fb1ecba2f771bc15e6676 /lib/compiler/src/beam_validator.erl
parent33d07550f0f1922f952a9a9ea747fcbe77a108a0 (diff)
downloadotp-316a794b41b2f4173b2b188ac4c91adeaa52c616.tar.gz
otp-316a794b41b2f4173b2b188ac4c91adeaa52c616.tar.bz2
otp-316a794b41b2f4173b2b188ac4c91adeaa52c616.zip
beam_validator: Don't transfer state to labels that can't be reached
If we transfer state appropriately to labels that can't be reached, the state could taint other labels.
Diffstat (limited to 'lib/compiler/src/beam_validator.erl')
-rw-r--r--lib/compiler/src/beam_validator.erl24
1 files changed, 18 insertions, 6 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 54c6d557ba..8b59746cb6 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -632,7 +632,12 @@ valfun_4({select_val,Src,{f,Fail},{list,Choices}}, Vst0) ->
kill_state(select_val_branches(Src, Choices, Vst));
valfun_4({select_tuple_arity,Tuple,{f,Fail},{list,Choices}}, Vst) ->
assert_type(tuple, Tuple, Vst),
- kill_state(branch_arities(Choices, Tuple, branch_state(Fail, Vst)));
+ TupleType = case get_term_type(Tuple, Vst) of
+ {fragile,TupleType0} -> TupleType0;
+ TupleType0 -> TupleType0
+ end,
+ kill_state(branch_arities(Choices, Tuple, TupleType,
+ branch_state(Fail, Vst)));
%% New bit syntax matching instructions.
valfun_4({test,bs_start_match2,{f,Fail},Live,[Ctx,NeedSlots],Ctx}, Vst0) ->
@@ -1509,13 +1514,20 @@ get_literal({integer,I}) when is_integer(I) -> I;
get_literal({literal,L}) -> L;
get_literal(T) -> error({not_literal,T}).
-
-branch_arities([], _, #vst{}=Vst) -> Vst;
-branch_arities([Sz,{f,L}|T], Tuple, #vst{current=St}=Vst0)
- when is_integer(Sz) ->
+branch_arities([Sz,{f,L}|T], Tuple, {tuple,[_]}=Type0, Vst0) when is_integer(Sz) ->
Vst1 = set_type_reg({tuple,Sz}, Tuple, Vst0),
Vst = branch_state(L, Vst1),
- branch_arities(T, Tuple, Vst#vst{current=St}).
+ branch_arities(T, Tuple, Type0, Vst);
+branch_arities([Sz,{f,L}|T], Tuple, {tuple,Sz}=Type, Vst0) when is_integer(Sz) ->
+ %% The type is already correct. (This test is redundant.)
+ Vst = branch_state(L, Vst0),
+ branch_arities(T, Tuple, Type, Vst);
+branch_arities([Sz0,{f,_}|T], Tuple, {tuple,Sz}=Type, Vst)
+ when is_integer(Sz), Sz0 =/= Sz ->
+ %% We already have an established different exact size for the tuple.
+ %% This label can't possibly be reached.
+ branch_arities(T, Tuple, Type, Vst);
+branch_arities([], _, _, #vst{}=Vst) -> Vst.
branch_state(0, #vst{}=Vst) ->
%% If the instruction fails, the stack may be scanned