From 1336d7879f9a722abda1fe8bc520953c5a079c79 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 1 Mar 2014 17:40:15 +0100 Subject: Do not mark all calls to erlang:is_function/2 as safe Calls to erlang:is_function/2 where the second is not a literal nonnegative integer can crash at runtime and thus can't be marked as safe. --- lib/compiler/src/sys_core_fold.erl | 9 +++++++++ lib/compiler/test/guard_SUITE.erl | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index eb9c302334..fb8a6174a7 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -2355,6 +2355,15 @@ is_safe_bool_expr_1(#c_call{module=#c_literal{val=erlang}, %% is a literal atom referring to a defined record, have already %% been rewritten to is_record(Expr, LiteralTag, TupleSize). false; +is_safe_bool_expr_1(#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[A,#c_literal{val=Arity}]}, + Sub, _BoolVars) when is_integer(Arity), Arity >= 0 -> + is_safe_simple(A, Sub); +is_safe_bool_expr_1(#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}}, + _Sub, _BoolVars) -> + false; is_safe_bool_expr_1(#c_call{module=#c_literal{val=erlang}, name=#c_literal{val=Name},args=Args}, Sub, BoolVars) -> diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl index a0a9bb7ddd..2d9e8d1ac0 100644 --- a/lib/compiler/test/guard_SUITE.erl +++ b/lib/compiler/test/guard_SUITE.erl @@ -1023,6 +1023,10 @@ is_function_2(Config) when is_list(Config) -> true = is_function(id(fun() -> ok end), 0), false = is_function(id(fun ?MODULE:all/1), 0), false = is_function(id(fun() -> ok end), 1), + {'EXIT',{badarg,_}} = + (catch is_function(id(fun() -> ok end), -1) orelse error), + {'EXIT',{badarg,_}} = + (catch is_function(id(fun() -> ok end), '') orelse error), F = fun(_) -> ok end, if -- cgit v1.2.3