aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-04-26 22:23:04 +0200
committerBjörn Gustavsson <[email protected]>2018-04-27 10:20:41 +0200
commit84150137640481ac139325bf8cc665dd47fca95c (patch)
treede995437272eeb9d736326011eafe5d564f6e3a8
parent9b347a42a23540eab2f3fd8bf75190a69b5ebb31 (diff)
downloadotp-84150137640481ac139325bf8cc665dd47fca95c.tar.gz
otp-84150137640481ac139325bf8cc665dd47fca95c.tar.bz2
otp-84150137640481ac139325bf8cc665dd47fca95c.zip
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.
-rw-r--r--lib/compiler/src/beam_validator.erl7
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl4
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.