aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2019-02-08 15:46:05 +0100
committerJohn Högberg <[email protected]>2019-02-18 11:29:07 +0100
commit8e337c3e25c11dd0a01a99f11e98aa99d9af3451 (patch)
treeb530089242116c0c672eccd2ef493d64f3e9e20f /lib/compiler
parent6ae2fa3f49e7f4a3cd228dce072065bdc516d62a (diff)
downloadotp-8e337c3e25c11dd0a01a99f11e98aa99d9af3451.tar.gz
otp-8e337c3e25c11dd0a01a99f11e98aa99d9af3451.tar.bz2
otp-8e337c3e25c11dd0a01a99f11e98aa99d9af3451.zip
beam_validator: Infer types from result of all type test BIFs
The compiler will usually optimize these into test instructions, but they'll nevertheless pop up in some cases.
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_validator.erl31
1 files changed, 27 insertions, 4 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 4f5818ae9f..aa7b190670 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -1350,10 +1350,6 @@ select_val_branches_1([], _, _, Vst) -> Vst.
infer_types(Src, Vst) ->
case get_def(Src, Vst) of
- {bif,is_map,{f,_},[Map],_} ->
- fun({atom,true}, S) -> update_type(fun meet/2, map, Map, S);
- (_, S) -> S
- end;
{bif,tuple_size,{f,_},[Tuple],_} ->
fun({integer,Arity}, S) ->
update_type(fun meet/2, {tuple,Arity,#{}}, Tuple, S);
@@ -1365,10 +1361,37 @@ infer_types(Src, Vst) ->
Infer(Val, S);
(_, S) -> S
end;
+ {bif,is_atom,{f,_},[Src],_} ->
+ infer_type_test_bif({atom,[]}, Src);
+ {bif,is_boolean,{f,_},[Src],_} ->
+ infer_type_test_bif(bool, Src);
+ {bif,is_binary,{f,_},[Src],_} ->
+ infer_type_test_bif(binary, Src);
+ {bif,is_bitstring,{f,_},[Src],_} ->
+ infer_type_test_bif(binary, Src);
+ {bif,is_float,{f,_},[Src],_} ->
+ infer_type_test_bif(float, Src);
+ {bif,is_integer,{f,_},[Src],_} ->
+ infer_type_test_bif({integer,{}}, Src);
+ {bif,is_list,{f,_},[Src],_} ->
+ infer_type_test_bif(list, Src);
+ {bif,is_map,{f,_},[Src],_} ->
+ infer_type_test_bif(map, Src);
+ {bif,is_number,{f,_},[Src],_} ->
+ infer_type_test_bif(number, Src);
+ {bif,is_tuple,{f,_},[Src],_} ->
+ infer_type_test_bif({tuple,[],#{}}, Src);
_ ->
fun(_, S) -> S end
end.
+infer_type_test_bif(Type, Src) ->
+ fun({atom,true}, S) ->
+ update_type(fun meet/2, Type, Src, S);
+ (_, S) ->
+ S
+ end.
+
%%%
%%% Keeping track of types.
%%%