diff options
author | John Högberg <[email protected]> | 2019-07-04 11:28:03 +0200 |
---|---|---|
committer | John Högberg <[email protected]> | 2019-07-05 15:55:56 +0200 |
commit | 8fcf04006643c70078035c9af5245e3be0c33108 (patch) | |
tree | 1a666dfc864eb51c962b014d31f07b399245f219 /lib/compiler/src/beam_validator.erl | |
parent | b2de9af91c1dc2dc4188986bf7a63fe48c045c33 (diff) | |
download | otp-8fcf04006643c70078035c9af5245e3be0c33108.tar.gz otp-8fcf04006643c70078035c9af5245e3be0c33108.tar.bz2 otp-8fcf04006643c70078035c9af5245e3be0c33108.zip |
beam_ssa_type: Infer types on switch failure
If we know that the checked value is a singleton at the fail
block, it's safe to infer types as if we've made a direct
comparison against that value.
Diffstat (limited to 'lib/compiler/src/beam_validator.erl')
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 923a0b4a4e..afede2b54d 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -1531,8 +1531,21 @@ validate_select_val(Fail, [Val,{f,L}|T], Src, Vst0) -> update_ne_types(Src, Val, FailVst) end), validate_select_val(Fail, T, Src, Vst); -validate_select_val(Fail, [], _, Vst) -> +validate_select_val(Fail, [], Src, Vst) -> branch(Fail, Vst, + fun(FailVst) -> + FailType = get_term_type(Src, FailVst), + case beam_types:get_singleton_value(FailType) of + {ok, Value} -> + %% This is the only possible value at the fail + %% label, so we can infer types as if we matched it + %% directly. + Lit = value_to_literal(Value), + update_eq_types(Src, Lit, FailVst); + error -> + FailVst + end + end, fun(SuccVst) -> %% The next instruction is never executed. kill_state(SuccVst) @@ -1921,6 +1934,13 @@ is_literal({integer,I}) when is_integer(I) -> true; is_literal({literal,_L}) -> true; is_literal(_) -> false. +%% `dialyzer` complains about the float and general literal cases never being +%% matched and I don't like suppressing warnings. Should they become possible +%% I'm sure `dialyzer` will warn about it. +value_to_literal([]) -> nil; +value_to_literal(A) when is_atom(A) -> {atom,A}; +value_to_literal(I) when is_integer(I) -> {integer,I}. + %% These are just wrappers around their equivalents in beam_types, which %% handle the validator-specific #t_abstract{} type. %% |