diff options
author | John Högberg <[email protected]> | 2019-02-08 15:46:05 +0100 |
---|---|---|
committer | John Högberg <[email protected]> | 2019-02-18 11:29:07 +0100 |
commit | 8e337c3e25c11dd0a01a99f11e98aa99d9af3451 (patch) | |
tree | b530089242116c0c672eccd2ef493d64f3e9e20f /lib/compiler | |
parent | 6ae2fa3f49e7f4a3cd228dce072065bdc516d62a (diff) | |
download | otp-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.erl | 31 |
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. %%% |