aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-01-18 11:26:45 +0100
committerBjörn Gustavsson <[email protected]>2019-01-18 11:26:45 +0100
commit329aff6202d05e5eaa6d0975e6e27b1d121215ee (patch)
treebe70df7b3998157be14be3e46032dbe49990721f /lib
parent75e0c601890d9561b103936479de0483cbcafd9d (diff)
parentf9ea85611faca82c7494449ddb8bcb1ef1d194cb (diff)
downloadotp-329aff6202d05e5eaa6d0975e6e27b1d121215ee.tar.gz
otp-329aff6202d05e5eaa6d0975e6e27b1d121215ee.tar.bz2
otp-329aff6202d05e5eaa6d0975e6e27b1d121215ee.zip
Merge branch 'bjorn/compiler/beam_validator/ERL-832'
* bjorn/compiler/beam_validator/ERL-832: Make the beam_validator smarter (again)
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_validator.erl19
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl27
2 files changed, 37 insertions, 9 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 46c689e034..3d53054f69 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -828,13 +828,14 @@ valfun_4({test,is_map,{f,Lbl},[Src]}, Vst0) ->
_ ->
kill_state(Vst0)
end;
-valfun_4({test,is_nil,{f,Lbl},[Src]}, Vst) ->
- case get_term_type(Src, Vst) of
- list ->
- branch_state(Lbl, set_type_reg(cons, Src, Vst));
- _ ->
- branch_state(Lbl, Vst)
- end;
+valfun_4({test,is_nil,{f,Lbl},[Src]}, Vst0) ->
+ Vst = case get_term_type(Src, Vst0) of
+ list ->
+ branch_state(Lbl, set_type_reg(cons, Src, Vst0));
+ _ ->
+ branch_state(Lbl, Vst0)
+ end,
+ set_aliased_type(nil, Src, Vst);
valfun_4({test,is_eq_exact,{f,Lbl},[Src,Val]=Ss}, Vst0) ->
validate_src(Ss, Vst0),
Infer = infer_types(Src, Vst0),
@@ -1903,6 +1904,10 @@ merge_types({atom,A}, bool) ->
merge_bool(A);
merge_types(cons, {literal,[_|_]}) ->
cons;
+merge_types(cons, nil) ->
+ list;
+merge_types(nil, cons) ->
+ list;
merge_types({literal,[_|_]}, cons) ->
cons;
merge_types({literal,[_|_]}, {literal,[_|_]}) ->
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index 661b48a080..c9df066958 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -579,14 +579,23 @@ receive_stacked(Config) ->
ok.
+aliased_types(Config) ->
+ Seq = lists:seq(1, 5),
+ 1 = aliased_types_1(Seq, Config),
+
+ {1,1} = aliased_types_2(Seq),
+ {42,none} = aliased_types_2([]),
+
+ ok.
+
%% ERL-735: validator failed to track types on aliased registers, rejecting
%% legitimate optimizations.
%%
%% move x0 y0
%% bif hd L1 x0
%% get_hd y0 %% The validator failed to see that y0 was a list
-aliased_types(Config) when is_list(Config) ->
- Bug = lists:seq(1, 5),
+%%
+aliased_types_1(Bug, Config) ->
if
Config =/= [gurka, gaffel] -> %% Pointless branch.
_ = hd(Bug),
@@ -594,6 +603,17 @@ aliased_types(Config) when is_list(Config) ->
hd(Bug)
end.
+%% ERL-832: validator failed to realize that a Y register was a cons.
+aliased_types_2(Bug) ->
+ Res = case Bug of
+ [] -> id(42);
+ _ -> hd(Bug)
+ end,
+ {Res,case Bug of
+ [] -> none;
+ _ -> hd(Bug)
+ end}.
+
%%%-------------------------------------------------------------------------
transform_remove(Remove, Module) ->
@@ -652,3 +672,6 @@ night(Turned) ->
ok.
participating(_, _, _, _) -> ok.
+
+id(I) ->
+ I.