From 9b347a42a23540eab2f3fd8bf75190a69b5ebb31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 26 Apr 2018 22:22:56 +0200 Subject: Correct beam_utils:is_killed/3 (again) beam_utils:is_killed/3 could incorrectly indicate that a register was killed. The previous fix is 5da6b91ecab6c. --- lib/compiler/src/beam_utils.erl | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index 1ddad30328..f57a7af1ab 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -377,7 +377,7 @@ check_liveness(R, [{test,_,{f,Fail},As}|Is], St0) -> {killed,St1} -> check_liveness(R, Is, St1); {exit_not_used,St1} -> - check_liveness(R, Is, St1); + not_used(check_liveness(R, Is, St1)); {not_used,St1} -> not_used(check_liveness(R, Is, St1)); {used,_}=Used -> @@ -395,14 +395,14 @@ check_liveness(R, [{select,_,_,Fail,Branches}|_], St) -> check_liveness_everywhere(R, [Fail|Branches], St); check_liveness(R, [{jump,{f,F}}|_], St) -> check_liveness_at(R, F, St); -check_liveness(R, [{case_end,Used}|_], St) -> - check_liveness_ret(R, Used, St); +check_liveness(R, [{case_end,Used}|_], St) -> + check_liveness_exit(R, Used, St); check_liveness(R, [{try_case_end,Used}|_], St) -> - check_liveness_ret(R, Used, St); + check_liveness_exit(R, Used, St); check_liveness(R, [{badmatch,Used}|_], St) -> - check_liveness_ret(R, Used, St); -check_liveness(_, [if_end|_], St) -> - {killed,St}; + check_liveness_exit(R, Used, St); +check_liveness(R, [if_end|_], St) -> + check_liveness_exit(R, ignore, St); check_liveness(R, [{func_info,_,_,Ar}|_], St) -> case R of {x,X} when X < Ar -> {used,St}; @@ -658,8 +658,9 @@ check_liveness_at(R, Lbl, #live{lbl=Ll,res=ResMemorized}=St0) -> not_used({used,_}=Res) -> Res; not_used({_,St}) -> {not_used,St}. -check_liveness_ret(R, R, St) -> {used,St}; -check_liveness_ret(_, _, St) -> {killed,St}. +check_liveness_exit(R, R, St) -> {used,St}; +check_liveness_exit({x,_}, _, St) -> {killed,St}; +check_liveness_exit({y,_}, _, St) -> {exit_not_used,St}. %% check_liveness_block(Reg, [Instruction], State) -> %% {killed | not_used | used | alloc_used | transparent,State'} -- cgit v1.2.3 From 84150137640481ac139325bf8cc665dd47fca95c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 26 Apr 2018 22:23:04 +0200 Subject: beam_validator: Verify Y registers in exception-causing instructions When an exception is handled, the stack will be scanned. Therefore all Y registers must be initialized. --- lib/compiler/src/beam_validator.erl | 7 +++++++ lib/compiler/test/beam_validator_SUITE.erl | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 962f17d83c..86aa12e19b 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -267,13 +267,17 @@ valfun_1(_I, #vst{current=none}=Vst) -> Vst; valfun_1({badmatch,Src}, Vst) -> assert_term(Src, Vst), + verify_y_init(Vst), kill_state(Vst); valfun_1({case_end,Src}, Vst) -> assert_term(Src, Vst), + verify_y_init(Vst), kill_state(Vst); valfun_1(if_end, Vst) -> + verify_y_init(Vst), kill_state(Vst); valfun_1({try_case_end,Src}, Vst) -> + verify_y_init(Vst), assert_term(Src, Vst), kill_state(Vst); %% Instructions that can not cause exceptions @@ -375,6 +379,9 @@ valfun_1({call_ext,Live,Func}=I, Vst) -> case return_type(Func, Vst) of exception -> verify_live(Live, Vst), + %% The stack will be scanned, so Y registers + %% must be initialized. + verify_y_init(Vst), kill_state(Vst); _ -> valfun_2(I, Vst) diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 3af71559ae..41f2957dc1 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -157,8 +157,8 @@ call_last(Config) when is_list(Config) -> merge_undefined(Config) when is_list(Config) -> Errors = do_val(merge_undefined, Config), [{{t,handle_call,2}, - {{call_ext,2,{extfunc,debug,filter,2}}, - 22, + {{call_ext,1,{extfunc,erlang,exit,1}}, + 10, {uninitialized_reg,{y,0}}}}] = Errors, ok. -- cgit v1.2.3