From 1b2cea397131a36a39b18c6ce8c6944bf11db4c7 Mon Sep 17 00:00:00 2001 From: Filipe David Manana Date: Mon, 16 May 2011 17:00:25 +0100 Subject: Add erlang:external_size/2 BIF This BIF's second parameter is a list of options. Currently the only allowed option is {minor_version, Version} where version is either 0 (default) or 1. --- lib/hipe/cerl/erl_bif_types.erl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/hipe/cerl/erl_bif_types.erl') diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index 82e3675938..acc7366d6b 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -739,6 +739,7 @@ type(erlang, element, 2, Xs) -> type(erlang, erase, 0, _) -> t_any(); type(erlang, erase, 1, _) -> t_any(); type(erlang, external_size, 1, _) -> t_integer(); +type(erlang, external_size, 2, _) -> t_integer(); type(erlang, finish_after_on_load, 2, Xs) -> %% Internal BIF used by on_load. strict(arg_types(erlang, finish_after_on_load, 2), Xs, @@ -3446,6 +3447,8 @@ arg_types(erlang, exit, 2) -> [t_sup(t_pid(), t_port()), t_any()]; arg_types(erlang, external_size, 1) -> [t_any()]; % takes any term as input +arg_types(erlang, external_size, 2) -> + [t_any(), t_list()]; % takes any term as input and a list of options arg_types(erlang, finish_after_on_load, 2) -> [t_atom(), t_boolean()]; arg_types(erlang, float, 1) -> -- cgit v1.2.3 From e7f7a3052096286a3df0b6c2217a9fe3248be7f4 Mon Sep 17 00:00:00 2001 From: Stavros Aronis Date: Thu, 21 Jul 2011 00:29:58 +0200 Subject: Enhance Dialyzer's inference on comparisons This patch makes Dialyzer aware of Erlang's total ordering of terms, enabling discrepancy detection in cases where e.g. integer() < tuple() is treated as a comparison that might also return false (when it is certain to always return true). --- lib/hipe/cerl/erl_bif_types.erl | 52 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) (limited to 'lib/hipe/cerl/erl_bif_types.erl') diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index 82e3675938..cd5d23c50c 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -366,7 +366,7 @@ type(erlang, '>', 2, Xs = [Lhs, Rhs]) -> is_integer(LhsMax), is_integer(RhsMin), RhsMin >= LhsMax -> F; true -> t_boolean() end; - false -> t_boolean() + false -> compare('>', Lhs, Rhs) end, strict(Xs, Ans); type(erlang, '>=', 2, Xs = [Lhs, Rhs]) -> @@ -384,7 +384,7 @@ type(erlang, '>=', 2, Xs = [Lhs, Rhs]) -> is_integer(LhsMax), is_integer(RhsMin), RhsMin > LhsMax -> F; true -> t_boolean() end; - false -> t_boolean() + false -> compare('>=', Lhs, Rhs) end, strict(Xs, Ans); type(erlang, '<', 2, Xs = [Lhs, Rhs]) -> @@ -402,7 +402,7 @@ type(erlang, '<', 2, Xs = [Lhs, Rhs]) -> is_integer(LhsMin), is_integer(RhsMax), RhsMax =< LhsMin -> F; true -> t_boolean() end; - false -> t_boolean() + false -> compare('<', Lhs, Rhs) end, strict(Xs, Ans); type(erlang, '=<', 2, Xs = [Lhs, Rhs]) -> @@ -420,7 +420,7 @@ type(erlang, '=<', 2, Xs = [Lhs, Rhs]) -> is_integer(LhsMin), is_integer(RhsMax), RhsMax < LhsMin -> F; true -> t_boolean() end; - false -> t_boolean() + false -> compare('=<', Lhs, Rhs) end, strict(Xs, Ans); type(erlang, '+', 1, Xs) -> @@ -3177,6 +3177,50 @@ arith(Op, X1, X2) -> end end. +%%============================================================================= +%% Comparison of terms +%%============================================================================= + +compare(Op, Lhs, Rhs) -> + case t_is_none(t_inf(Lhs, Rhs)) of + false -> t_boolean(); + true -> + case Op of + '<' -> always_smaller(Lhs, Rhs); + '>' -> always_smaller(Rhs, Lhs); + '=<' -> always_smaller(Lhs, Rhs); + '>=' -> always_smaller(Rhs, Lhs) + end + end. + +always_smaller(Type1, Type2) -> + {Min1, Max1} = type_ranks(Type1), + {Min2, Max2} = type_ranks(Type2), + if Max1 < Min2 -> t_atom('true'); + Min1 > Max2 -> t_atom('false'); + true -> t_boolean() + end. + +type_ranks(Type) -> + type_ranks(Type, 1, 0, 0, type_order()). + +type_ranks(_Type, _I, Min, Max, []) -> {Min, Max}; +type_ranks(Type, I, Min, Max, [TypeClass|Rest]) -> + {NewMin, NewMax} = + case t_is_none(t_inf(Type, TypeClass)) of + true -> {Min, Max}; + false -> case Min of + 0 -> {I, I}; + _ -> {Min, I} + end + end, + type_ranks(Type, I+1, NewMin, NewMax, Rest). + +type_order() -> + [t_number(), t_atom(), t_reference(), t_fun(), t_port(), t_pid(), t_tuple(), + t_list(), t_binary()]. + + %%============================================================================= -spec arg_types(atom(), atom(), arity()) -> [erl_types:erl_type()] | 'unknown'. -- cgit v1.2.3