From 7ff117e24a97ce98ac13671ea140c45a67400b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 21 May 2010 16:00:21 +0200 Subject: Add erlang:nif_error/1,2 A stub function that is supposed to be replaced by a NIF usually calls erlang:error/1 to cause an exception if the NIF library is not loaded. For example: foo() -> erlang:error(nif_not_loaded). The problem is that although erlang:error/1 will normally never be called, Dialyzer will think that any call to the function will fail and thus generate false warnings. Adding a spec for the function will not help because Dialyzer will not believe the spec. Add erlang:nif_error/1,2 that work exactly like erlang:error/1,2. Define the return types for both BIFs to be t_any(). erlang:nif_error is used like this: -spec foo() -> binary(). foo() -> erlang:nif_error(nif_not_loaded). (The -spec is optional but highly recommended, since Dialyzer otherwise has no chance to figure out the types.) --- erts/doc/src/erlang.xml | 31 +++++++++++++++++++++++++++++++ erts/emulator/beam/bif.c | 28 ++++++++++++++++++++++++++++ erts/emulator/beam/bif.tab | 3 +++ 3 files changed, 62 insertions(+) (limited to 'erts') diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index e683f161f1..7ff52c5b50 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -2643,6 +2643,37 @@ os_prompt% option list is malformed.

+ + erlang:nif_error(Reason) + Stop execution with a given reason + + Reason = term() + + +

Works exactly like + erlang:error/1, + but Dialyzer thinks that this BIF will return an arbitrary term. + When used in a stub function for a NIF to generate an + exception when the NIF library is not loaded, Dialyzer + will not generate false warnings.

+
+
+ + erlang:nif_error(Reason, Args) + Stop execution with a given reason + + Reason = term() + Args = [term()] + + +

Works exactly like + erlang:error/2, + but Dialyzer thinks that this BIF will return an arbitrary term. + When used in a stub function for a NIF to generate an + exception when the NIF library is not loaded, Dialyzer + will not generate false warnings.

+
+
node() -> Node Name of the local node diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 85bf584337..7a69dc6eff 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -1131,6 +1131,34 @@ BIF_RETTYPE error_2(Process* p, Eterm value, Eterm args) BIF_ERROR(p, EXC_ERROR_2); } +/**********************************************************************/ +/* + * This is like exactly like error/1. The only difference is + * that Dialyzer thinks that it it will return an arbitrary term. + * It is useful in stub functions for NIFs. + */ + +BIF_RETTYPE nif_error_1(Process* p, Eterm term) +{ + p->fvalue = term; + BIF_ERROR(p, EXC_ERROR); +} + +/**********************************************************************/ +/* + * This is like exactly like error/2. The only difference is + * that Dialyzer thinks that it it will return an arbitrary term. + * It is useful in stub functions for NIFs. + */ + +BIF_RETTYPE nif_error_2(Process* p, Eterm value, Eterm args) +{ + Eterm* hp = HAlloc(p, 3); + + p->fvalue = TUPLE2(hp, value, args); + BIF_ERROR(p, EXC_ERROR_2); +} + /**********************************************************************/ /* this is like throw/1 except that we set freason to EXC_EXIT */ diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index 9feb302a3d..e4713567de 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -793,6 +793,9 @@ bif binary:encode_unsigned/2 bif binary:decode_unsigned/1 bif binary:decode_unsigned/2 +bif erlang:nif_error/1 +bif erlang:nif_error/2 + # # Obsolete # -- cgit v1.2.3