diff options
author | Björn Gustavsson <[email protected]> | 2018-11-21 10:21:51 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2018-11-21 10:21:51 +0100 |
commit | f8183c3949b3da11fafac4e5b7737fb75e0d0f11 (patch) | |
tree | 620da7a332562f8acb79771c8ce73ce5c61c5072 | |
parent | c0812d51fbb550d4a53df128e4ec322746f015ca (diff) | |
parent | 8be2c32fe0534d863c6ce6d7665011a162fc39ec (diff) | |
download | otp-f8183c3949b3da11fafac4e5b7737fb75e0d0f11.tar.gz otp-f8183c3949b3da11fafac4e5b7737fb75e0d0f11.tar.bz2 otp-f8183c3949b3da11fafac4e5b7737fb75e0d0f11.zip |
Merge branch 'bjorn/compiler/is_function/ERL-778/OTP-15435' into maint
* bjorn/compiler/is_function/ERL-778/OTP-15435:
Fix internal consistency failure for is_function/2
-rw-r--r-- | lib/compiler/src/beam_utils.erl | 5 | ||||
-rw-r--r-- | lib/compiler/test/beam_utils_SUITE.erl | 23 |
2 files changed, 25 insertions, 3 deletions
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index 6e23003fc7..6b2ab5a2a4 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -745,8 +745,11 @@ check_liveness_block_2(R, {gc_bif,Op,{f,Lbl}}, Ss, St) -> check_liveness_block_3(R, Lbl, {Op,length(Ss)}, St); check_liveness_block_2(R, {bif,Op,{f,Lbl}}, Ss, St) -> Arity = length(Ss), + + %% Note that is_function/2 is a type test but is not safe. case erl_internal:comp_op(Op, Arity) orelse - erl_internal:new_type_test(Op, Arity) of + (erl_internal:new_type_test(Op, Arity) andalso + erl_bifs:is_safe(erlang, Op, Arity)) of true -> {killed,St}; false -> diff --git a/lib/compiler/test/beam_utils_SUITE.erl b/lib/compiler/test/beam_utils_SUITE.erl index ac19305d69..ff0f72d519 100644 --- a/lib/compiler/test/beam_utils_SUITE.erl +++ b/lib/compiler/test/beam_utils_SUITE.erl @@ -26,7 +26,7 @@ select/1,y_catch/1,otp_8949_b/1,liveopt/1,coverage/1, y_registers/1,user_predef/1,scan_f/1,cafu/1, receive_label/1,read_size_file_version/1,not_used/1, - is_used_fr/1]). + is_used_fr/1,unsafe_is_function/1]). -export([id/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -53,7 +53,8 @@ groups() -> cafu, read_size_file_version, not_used, - is_used_fr + is_used_fr, + unsafe_is_function ]}]. init_per_suite(Config) -> @@ -570,6 +571,24 @@ is_used_fr(X, Y) -> end, X ! 1. +%% ERL-778. +unsafe_is_function(Config) -> + {undefined,any} = unsafe_is_function(undefined, any), + {ok,any} = unsafe_is_function(fun() -> ok end, any), + {'EXIT',{{case_clause,_},_}} = (catch unsafe_is_function(fun(_) -> ok end, any)), + ok. + +unsafe_is_function(F, M) -> + %% There would be an internal consistency failure: + %% Instruction: {bif,is_function,{f,0},[{x,0},{integer,0}],{x,2}} + %% Error: {uninitialized_reg,{y,0}}: + + NewValue = case is_function(F, 0) of + true -> F(); + false when F =:= undefined -> undefined + end, + {NewValue,M}. + %% The identity function. id(I) -> I. |