aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_validator.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-12-29 08:15:02 +0100
committerBjörn Gustavsson <[email protected]>2019-01-14 13:36:01 +0100
commitf548ea888e4c63546160dcb68ee84a167ca38f8f (patch)
tree7257a75df14118e1b43512373f3579b64a77f5a7 /lib/compiler/src/beam_validator.erl
parentfb90ee4a0aab48dca08e9c935b26c4742d4c86ab (diff)
downloadotp-f548ea888e4c63546160dcb68ee84a167ca38f8f.tar.gz
otp-f548ea888e4c63546160dcb68ee84a167ca38f8f.tar.bz2
otp-f548ea888e4c63546160dcb68ee84a167ca38f8f.zip
Infer types from more BIFs
Diffstat (limited to 'lib/compiler/src/beam_validator.erl')
-rw-r--r--lib/compiler/src/beam_validator.erl25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index d01013101a..46c689e034 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -809,6 +809,14 @@ valfun_4({test,has_map_fields,{f,Lbl},Src,{list,List}}, Vst) ->
assert_type(map, Src, Vst),
assert_unique_map_keys(List),
branch_state(Lbl, Vst);
+valfun_4({test,is_list,{f,Lbl},[Src]}, Vst) ->
+ validate_src([Src], Vst),
+ Type = case get_term_type(Src, Vst) of
+ cons -> cons;
+ nil -> nil;
+ _ -> list
+ end,
+ set_aliased_type(Type, Src, branch_state(Lbl, Vst));
valfun_4({test,is_map,{f,Lbl},[Src]}, Vst0) ->
Vst = branch_state(Lbl, Vst0),
case Src of
@@ -820,6 +828,13 @@ 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_eq_exact,{f,Lbl},[Src,Val]=Ss}, Vst0) ->
validate_src(Ss, Vst0),
Infer = infer_types(Src, Vst0),
@@ -1536,6 +1551,8 @@ assert_not_literal(Literal) -> error({literal_not_allowed,Literal}).
%%
%% nil Empty list: []
%%
+%% list List: [] or [_|_]
+%%
%% {tuple,[Sz]} Tuple. An element has been accessed using
%% element/2 or setelement/3 so that it is known that
%% the type is a tuple of size at least Sz.
@@ -2118,6 +2135,14 @@ return_type_1(erlang, setelement, 3, Vst) ->
{integer,I} -> upgrade_tuple_type({tuple,[I]}, TupleType);
_ -> TupleType
end;
+return_type_1(erlang, '++', 2, Vst) ->
+ case get_term_type({x,0}, Vst) =:= cons orelse
+ get_term_type({x,1}, Vst) =:= cons of
+ true -> cons;
+ false -> list
+ end;
+return_type_1(erlang, '--', 2, _Vst) ->
+ list;
return_type_1(erlang, F, A, _) ->
return_type_erl(F, A);
return_type_1(math, F, A, _) ->