aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-02-12 12:47:26 +0100
committerBjörn Gustavsson <[email protected]>2015-03-09 09:59:36 +0100
commit5a6c78379cbbdf945d78a6b9d3c2c8d37db71607 (patch)
tree78946ea93cb9309cb5eca423d7660b6ab897dbdd
parent86fbd6d76d342906e2a77df877013ea68de73cfb (diff)
downloadotp-5a6c78379cbbdf945d78a6b9d3c2c8d37db71607.tar.gz
otp-5a6c78379cbbdf945d78a6b9d3c2c8d37db71607.tar.bz2
otp-5a6c78379cbbdf945d78a6b9d3c2c8d37db71607.zip
Update type information based on BIFs that returns integers
-rw-r--r--lib/compiler/src/sys_core_fold.erl24
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl1
2 files changed, 24 insertions, 1 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index f0f58c767d..570b943a40 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -96,7 +96,7 @@
t=[], %Types
in_guard=false}). %In guard or not.
--type type_info() :: cerl:cerl() | 'bool'.
+-type type_info() :: cerl:cerl() | 'bool' | 'integer'.
-type yes_no_maybe() :: 'yes' | 'no' | 'maybe'.
-type sub() :: #sub{}.
@@ -2511,6 +2511,7 @@ is_boolean_type(Var, Sub) ->
is_int_type(Var, Sub) ->
case get_type(Var, Sub) of
none -> maybe;
+ integer -> yes;
C -> yes_no(cerl:is_c_int(C))
end.
@@ -2545,12 +2546,33 @@ update_types_from_expr(V, Expr, Sub) ->
Type = extract_type(Expr, Sub),
update_types(V, [Type], Sub).
+extract_type(#c_call{module=#c_literal{val=erlang},
+ name=#c_literal{val=Name},
+ args=Args}=Call, Sub) ->
+ case returns_integer(Name, Args) of
+ true -> integer;
+ false -> extract_type_1(Call, Sub)
+ end;
extract_type(Expr, Sub) ->
+ extract_type_1(Expr, Sub).
+
+extract_type_1(Expr, Sub) ->
case is_bool_expr(Expr, Sub) of
false -> Expr;
true -> bool
end.
+returns_integer(bit_size, [_]) -> true;
+returns_integer('bsl', [_,_]) -> true;
+returns_integer('bsr', [_,_]) -> true;
+returns_integer(byte_size, [_]) -> true;
+returns_integer(length, [_]) -> true;
+returns_integer('rem', [_,_]) -> true;
+returns_integer(size, [_]) -> true;
+returns_integer(tuple_size, [_]) -> true;
+returns_integer(trunc, [_]) -> true;
+returns_integer(_, _) -> false.
+
%% update_types(Expr, Pattern, Sub) -> Sub'
%% Update the type database.
diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index 512aada203..9228aa7fd1 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.erl
@@ -88,6 +88,7 @@ t_element(Config) when is_list(Config) ->
{_,_,_}=Tup ->
?line {'EXIT',{badarg,_}} = (catch element(4, Tup))
end,
+ {'EXIT',{badarg,_}} = (catch element(1, tuple_size(Tuple))),
ok.