diff options
author | Björn Gustavsson <[email protected]> | 2018-04-23 19:52:16 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2018-08-17 09:50:58 +0200 |
commit | 316a794b41b2f4173b2b188ac4c91adeaa52c616 (patch) | |
tree | 1c467a3c48097f81954fb1ecba2f771bc15e6676 /lib | |
parent | 33d07550f0f1922f952a9a9ea747fcbe77a108a0 (diff) | |
download | otp-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')
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 24 |
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 |