File 0309-erts-Add-function-attributes-in-APIs-and-internal.patch of Package erlang

From b9ded1603bd6c3fbab63cac642f87b71cf10fc6a Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Tue, 26 Apr 2022 21:42:31 +0200
Subject: [PATCH 2/2] erts: Add function attributes in APIs and internal

---
 erts/emulator/beam/erl_alloc.h         | 10 ++---
 erts/emulator/beam/erl_db.h            | 11 +++--
 erts/emulator/beam/erl_driver.h        | 20 +++++----
 erts/emulator/beam/erl_drv_nif.h       | 54 +++++++++++++++++++++++++
 erts/emulator/beam/erl_message.h       |  3 +-
 erts/emulator/beam/erl_nif.h           | 10 +++++
 erts/emulator/beam/erl_nif_api_funcs.h | 18 ++++-----
 erts/emulator/beam/erl_process.h       |  4 +-
 erts/emulator/beam/erl_utils.h         |  2 +-
 erts/emulator/beam/sys.h               | 56 ++++++++++++++++++++++++++
 10 files changed, 157 insertions(+), 31 deletions(-)

diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h
index d0282e8f2f..00ab6284d7 100644
--- a/erts/emulator/beam/erl_alloc.h
+++ b/erts/emulator/beam/erl_alloc.h
@@ -213,11 +213,11 @@ Eterm erts_alloc_set_dyn_param(struct process*, Eterm);
 
 #if !ERTS_ALC_DO_INLINE
 
-void *erts_alloc(ErtsAlcType_t type, Uint size);
-void *erts_realloc(ErtsAlcType_t type, void *ptr, Uint size);
 void erts_free(ErtsAlcType_t type, void *ptr);
-void *erts_alloc_fnf(ErtsAlcType_t type, Uint size);
-void *erts_realloc_fnf(ErtsAlcType_t type, void *ptr, Uint size);
+void *erts_alloc(ErtsAlcType_t type, Uint size) ERTS_ATTR_MALLOC_USD(2,erts_free,2);
+void *erts_realloc(ErtsAlcType_t type, void *ptr, Uint size) ERTS_ATTR_ALLOC_SIZE(3);
+void *erts_alloc_fnf(ErtsAlcType_t type, Uint size) ERTS_ATTR_MALLOC_USD(2,erts_free,2);
+void *erts_realloc_fnf(ErtsAlcType_t type, void *ptr, Uint size) ERTS_ATTR_ALLOC_SIZE(3);
 int erts_is_allctr_wrapper_prelocked(void);
 #ifdef ERTS_HAVE_IS_IN_LITERAL_RANGE
 int erts_is_in_literal_range(void* ptr);
@@ -227,7 +227,7 @@ int erts_get_thr_alloc_ix(void);
 
 #endif /* #if !ERTS_ALC_DO_INLINE */
 
-void *erts_alloc_permanent_cache_aligned(ErtsAlcType_t type, Uint size);
+void *erts_alloc_permanent_cache_aligned(ErtsAlcType_t type, Uint size) ERTS_ATTR_MALLOC_US(2);
 
 #ifndef ERTS_CACHE_LINE_SIZE
 /* Assumed cache line size */
diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h
index 81eeab1781..34b9b871be 100644
--- a/erts/emulator/beam/erl_db.h
+++ b/erts/emulator/beam/erl_db.h
@@ -173,12 +173,15 @@ do {                                                                    \
 
 ERTS_GLB_INLINE void *erts_db_alloc(ErtsAlcType_t type,
 				    DbTable *tab,
-				    Uint size);
+				    Uint size) ERTS_ATTR_MALLOC_US(3);
 ERTS_GLB_INLINE void *erts_db_alloc_fnf(ErtsAlcType_t type,
 					DbTable *tab,
-					Uint size);
-ERTS_GLB_INLINE void *erts_db_alloc_nt(ErtsAlcType_t type, Uint size);
-ERTS_GLB_INLINE void *erts_db_alloc_fnf_nt(ErtsAlcType_t type, Uint size);
+					Uint size) ERTS_ATTR_MALLOC_US(3);
+ERTS_GLB_INLINE void*
+erts_db_alloc_nt(ErtsAlcType_t type, Uint size) ERTS_ATTR_MALLOC_US(2);
+
+ERTS_GLB_INLINE void*
+erts_db_alloc_fnf_nt(ErtsAlcType_t type, Uint size) ERTS_ATTR_MALLOC_US(2);
 
 #if ERTS_GLB_INLINE_INCL_FUNC_DEF
 
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index 7fc6670ff0..25469de7cc 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -404,9 +404,11 @@ EXTERN int  get_port_flags(ErlDrvPort port);
  * since the binary is a shared object it MUST be written once.
  */
 
-EXTERN ErlDrvBinary* driver_alloc_binary(ErlDrvSizeT size);
-EXTERN ErlDrvBinary* driver_realloc_binary(ErlDrvBinary *bin, ErlDrvSizeT size);
 EXTERN void driver_free_binary(ErlDrvBinary *bin);
+EXTERN ErlDrvBinary* driver_alloc_binary(ErlDrvSizeT size)
+    ERL_NAPI_ATTR_MALLOC_UD(driver_free_binary,1);
+EXTERN ErlDrvBinary* driver_realloc_binary(ErlDrvBinary *bin, ErlDrvSizeT size)
+    ERL_NAPI_ATTR_WUR;
 
 /* Reference count on driver binaries */
 EXTERN ErlDrvSInt driver_binary_get_refc(ErlDrvBinary *dbp);
@@ -414,9 +416,11 @@ EXTERN ErlDrvSInt driver_binary_inc_refc(ErlDrvBinary *dbp);
 EXTERN ErlDrvSInt driver_binary_dec_refc(ErlDrvBinary *dbp);
 
 /* Allocation interface */
-EXTERN void *driver_alloc(ErlDrvSizeT size);
-EXTERN void *driver_realloc(void *ptr, ErlDrvSizeT size);
 EXTERN void driver_free(void *ptr);
+EXTERN void *driver_alloc(ErlDrvSizeT size)
+    ERL_NAPI_ATTR_MALLOC_USD(1, driver_free, 1);
+EXTERN void *driver_realloc(void *ptr, ErlDrvSizeT size)
+    ERL_NAPI_ATTR_ALLOC_SIZE(2);
 
 /* Queue interface */
 EXTERN int driver_enq(ErlDrvPort port, char* buf, ErlDrvSizeT len);
@@ -448,18 +452,18 @@ EXTERN void driver_system_info(ErlDrvSysInfo *sip, size_t si_size);
  * erl driver thread functions.
  */
 
-EXTERN ErlDrvMutex *erl_drv_mutex_create(char *name);
 EXTERN void erl_drv_mutex_destroy(ErlDrvMutex *mtx);
+EXTERN ErlDrvMutex *erl_drv_mutex_create(char *name) ERL_NAPI_ATTR_MALLOC_D(erl_drv_mutex_destroy,1);
 EXTERN int erl_drv_mutex_trylock(ErlDrvMutex *mtx);
 EXTERN void erl_drv_mutex_lock(ErlDrvMutex *mtx);
 EXTERN void erl_drv_mutex_unlock(ErlDrvMutex *mtx);
-EXTERN ErlDrvCond *erl_drv_cond_create(char *name);
 EXTERN void erl_drv_cond_destroy(ErlDrvCond *cnd);
+EXTERN ErlDrvCond *erl_drv_cond_create(char *name) ERL_NAPI_ATTR_MALLOC_D(erl_drv_cond_destroy,1);
 EXTERN void erl_drv_cond_signal(ErlDrvCond *cnd);
 EXTERN void erl_drv_cond_broadcast(ErlDrvCond *cnd);
 EXTERN void erl_drv_cond_wait(ErlDrvCond *cnd, ErlDrvMutex *mtx);
-EXTERN ErlDrvRWLock *erl_drv_rwlock_create(char *name);
 EXTERN void erl_drv_rwlock_destroy(ErlDrvRWLock *rwlck);
+EXTERN ErlDrvRWLock *erl_drv_rwlock_create(char *name) ERL_NAPI_ATTR_MALLOC_D(erl_drv_rwlock_destroy,1);
 EXTERN int erl_drv_rwlock_tryrlock(ErlDrvRWLock *rwlck);
 EXTERN void erl_drv_rwlock_rlock(ErlDrvRWLock *rwlck);
 EXTERN void erl_drv_rwlock_runlock(ErlDrvRWLock *rwlck);
@@ -470,8 +474,8 @@ EXTERN int erl_drv_tsd_key_create(char *name, ErlDrvTSDKey *key);
 EXTERN void erl_drv_tsd_key_destroy(ErlDrvTSDKey key);
 EXTERN void erl_drv_tsd_set(ErlDrvTSDKey key, void *data);
 EXTERN void *erl_drv_tsd_get(ErlDrvTSDKey key);
-EXTERN ErlDrvThreadOpts *erl_drv_thread_opts_create(char *name);
 EXTERN void erl_drv_thread_opts_destroy(ErlDrvThreadOpts *opts);
+EXTERN ErlDrvThreadOpts *erl_drv_thread_opts_create(char *name) ERL_NAPI_ATTR_MALLOC_D(erl_drv_thread_opts_destroy,1);
 EXTERN int erl_drv_thread_create(char *name,
 				 ErlDrvTid *tid,
 				 void * (*func)(void *),
diff --git a/erts/emulator/beam/erl_drv_nif.h b/erts/emulator/beam/erl_drv_nif.h
index 53d1a3a531..ee27953f7f 100644
--- a/erts/emulator/beam/erl_drv_nif.h
+++ b/erts/emulator/beam/erl_drv_nif.h
@@ -168,4 +168,58 @@ typedef struct {
 #  endif
 #endif
 
+#define ERL_NAPI_ATTR_WUR
+#define ERL_NAPI_ATTR_ALLOC_SIZE(SZPOS)
+#define ERL_NAPI_ATTR_MALLOC_U
+#define ERL_NAPI_ATTR_MALLOC_US(SZPOS)
+#define ERL_NAPI_ATTR_MALLOC_UD(DTOR, PTRPOS)
+#define ERL_NAPI_ATTR_MALLOC_USD(SZPOS, DTOR, PTRPOS)
+#define ERL_NAPI_ATTR_MALLOC_D(DTOR, PTRPOS)
+
+/* ERL_NAPI_ATTR_MALLOC_xxx:
+ * U: Returns pointer to Undefined data. ((malloc))
+ * S: Has Size argument with nr of bytes of returned data. ((alloc_size(SZPOS)))
+ * D: Has 1-to-1 Deallocator function with ptr argument. ((malloc(DTOR,PTRPOS)))
+ */
+
+#ifdef __has_attribute
+#  if __has_attribute(warn_unused_result)
+#    undef  ERL_NAPI_ATTR_WUR
+#    define ERL_NAPI_ATTR_WUR __attribute__((warn_unused_result))
+#  endif
+#  if __has_attribute(alloc_size)
+#    undef  ERL_NAPI_ATTR_ALLOC_SIZE
+#    define ERL_NAPI_ATTR_ALLOC_SIZE(SZPOS)                                \
+         __attribute__((alloc_size(SZPOS))) ERL_NAPI_ATTR_WUR
+#  endif
+#  if __has_attribute(malloc)
+#    undef  ERL_NAPI_ATTR_MALLOC_U
+#    define ERL_NAPI_ATTR_MALLOC_U __attribute__((malloc)) ERL_NAPI_ATTR_WUR
+
+#    undef  ERL_NAPI_ATTR_MALLOC_US
+#    define ERL_NAPI_ATTR_MALLOC_US(SZPOS)                                 \
+         __attribute__((malloc)) ERL_NAPI_ATTR_ALLOC_SIZE(SZPOS)
+
+#    undef  ERL_NAPI_ATTR_MALLOC_D
+#    if defined(__GNUC__) && __GNUC__ >= 11
+#      define ERL_NAPI_ATTR_MALLOC_D(DTOR, PTRPOS)                         \
+         __attribute__((malloc(DTOR,PTRPOS)))                              \
+         ERL_NAPI_ATTR_WUR
+#    else
+#      define ERL_NAPI_ATTR_MALLOC_D(DTOR, PTRPOS)                         \
+         ERL_NAPI_ATTR_WUR
+#    endif
+
+#    undef  ERL_NAPI_ATTR_MALLOC_UD
+#    define ERL_NAPI_ATTR_MALLOC_UD(DTOR, PTRPOS)                          \
+       ERL_NAPI_ATTR_MALLOC_U                                              \
+       ERL_NAPI_ATTR_MALLOC_D(DTOR, PTRPOS)
+
+#    undef  ERL_NAPI_ATTR_MALLOC_USD
+#    define ERL_NAPI_ATTR_MALLOC_USD(SZPOS, DTOR, PTRPOS)                  \
+       ERL_NAPI_ATTR_MALLOC_US(SZPOS)                                      \
+       ERL_NAPI_ATTR_MALLOC_D(DTOR, PTRPOS)
+#  endif
+#endif
+
 #endif  /* __ERL_DRV_NIF_H__ */
diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h
index c54cad5b88..218b3b6df8 100644
--- a/erts/emulator/beam/erl_message.h
+++ b/erts/emulator/beam/erl_message.h
@@ -514,9 +514,8 @@ Eterm erts_change_message_queue_management(Process *c_p, Eterm new_state);
 
 void erts_cleanup_messages(ErtsMessage *mp);
 
-void *erts_alloc_message_ref(void);
 void erts_free_message_ref(void *);
-
+void *erts_alloc_message_ref(void) ERTS_ATTR_MALLOC_D(erts_free_message_ref,1);
 
 ErtsMessage *erts_try_alloc_message_on_heap(Process *pp,
 					    erts_aint32_t *psp,
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index b2984eac0c..a9a81483f6 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -346,6 +346,16 @@ extern TWinDynNifCallbacks WinDynNifCallbacks;
 
 #else /* non windows or included from emulator itself */
 
+/* Redundant declaration of deallocator functions as they are referred to by
+ * __attribute__(malloc) of allocator functions and we cannot change
+ * the declaration order in erl_nif_api_funcs.h due to Windows. */
+extern void enif_free(void* ptr);
+extern void enif_mutex_destroy(ErlNifMutex *mtx);
+extern void enif_cond_destroy(ErlNifCond *cnd);
+extern void enif_rwlock_destroy(ErlNifRWLock *rwlck);
+extern void enif_thread_opts_destroy(ErlNifThreadOpts *opts);
+extern void enif_ioq_destroy(ErlNifIOQueue *q);
+
 #  define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) extern RET_TYPE NAME ARGS
 #  include "erl_nif_api_funcs.h"
 #  undef ERL_NIF_API_FUNC_DECL
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 27fa953099..05ad83dfdd 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -31,7 +31,7 @@
 */
 #ifdef ERL_NIF_API_FUNC_DECL
 ERL_NIF_API_FUNC_DECL(void*,enif_priv_data,(ErlNifEnv*));
-ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(size_t size));
+ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(size_t size) ERL_NAPI_ATTR_MALLOC_USD(1,enif_free,1));
 ERL_NIF_API_FUNC_DECL(void,enif_free,(void* ptr));
 ERL_NIF_API_FUNC_DECL(int,enif_is_atom,(ErlNifEnv*, ERL_NIF_TERM term));
 ERL_NIF_API_FUNC_DECL(int,enif_is_binary,(ErlNifEnv*, ERL_NIF_TERM term));
@@ -60,17 +60,17 @@ ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_cell,(ErlNifEnv* env, ERL_NIF_
 ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string,(ErlNifEnv* env, const char* string, ErlNifCharEncoding));
 ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ref,(ErlNifEnv* env));
 
-ERL_NIF_API_FUNC_DECL(ErlNifMutex*,enif_mutex_create,(char *name));
+ERL_NIF_API_FUNC_DECL(ErlNifMutex*,enif_mutex_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_mutex_destroy,1));
 ERL_NIF_API_FUNC_DECL(void,enif_mutex_destroy,(ErlNifMutex *mtx));
 ERL_NIF_API_FUNC_DECL(int,enif_mutex_trylock,(ErlNifMutex *mtx));
 ERL_NIF_API_FUNC_DECL(void,enif_mutex_lock,(ErlNifMutex *mtx));
 ERL_NIF_API_FUNC_DECL(void,enif_mutex_unlock,(ErlNifMutex *mtx));
-ERL_NIF_API_FUNC_DECL(ErlNifCond*,enif_cond_create,(char *name));
+ERL_NIF_API_FUNC_DECL(ErlNifCond*,enif_cond_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_cond_destroy,1));
 ERL_NIF_API_FUNC_DECL(void,enif_cond_destroy,(ErlNifCond *cnd));
 ERL_NIF_API_FUNC_DECL(void,enif_cond_signal,(ErlNifCond *cnd));
 ERL_NIF_API_FUNC_DECL(void,enif_cond_broadcast,(ErlNifCond *cnd));
 ERL_NIF_API_FUNC_DECL(void,enif_cond_wait,(ErlNifCond *cnd, ErlNifMutex *mtx));
-ERL_NIF_API_FUNC_DECL(ErlNifRWLock*,enif_rwlock_create,(char *name));
+ERL_NIF_API_FUNC_DECL(ErlNifRWLock*,enif_rwlock_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_rwlock_destroy,1));
 ERL_NIF_API_FUNC_DECL(void,enif_rwlock_destroy,(ErlNifRWLock *rwlck));
 ERL_NIF_API_FUNC_DECL(int,enif_rwlock_tryrlock,(ErlNifRWLock *rwlck));
 ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rlock,(ErlNifRWLock *rwlck));
@@ -82,7 +82,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_tsd_key_create,(char *name, ErlNifTSDKey *key));
 ERL_NIF_API_FUNC_DECL(void,enif_tsd_key_destroy,(ErlNifTSDKey key));
 ERL_NIF_API_FUNC_DECL(void,enif_tsd_set,(ErlNifTSDKey key, void *data));
 ERL_NIF_API_FUNC_DECL(void*,enif_tsd_get,(ErlNifTSDKey key));
-ERL_NIF_API_FUNC_DECL(ErlNifThreadOpts*,enif_thread_opts_create,(char *name));
+ERL_NIF_API_FUNC_DECL(ErlNifThreadOpts*,enif_thread_opts_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_thread_opts_destroy,1));
 ERL_NIF_API_FUNC_DECL(void,enif_thread_opts_destroy,(ErlNifThreadOpts *opts));
 ERL_NIF_API_FUNC_DECL(int,enif_thread_create,(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts));
 ERL_NIF_API_FUNC_DECL(ErlNifTid,enif_thread_self,(void));
@@ -90,7 +90,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_equal_tids,(ErlNifTid tid1, ErlNifTid tid2));
 ERL_NIF_API_FUNC_DECL(void,enif_thread_exit,(void *resp));
 ERL_NIF_API_FUNC_DECL(int,enif_thread_join,(ErlNifTid, void **respp));
 
-ERL_NIF_API_FUNC_DECL(void*,enif_realloc,(void* ptr, size_t size));
+ERL_NIF_API_FUNC_DECL(void*,enif_realloc,(void* ptr, size_t size) ERL_NAPI_ATTR_ALLOC_SIZE(2));
 ERL_NIF_API_FUNC_DECL(void,enif_system_info,(ErlNifSysInfo *sip, size_t si_size));
 ERL_NIF_API_FUNC_DECL(int,enif_fprintf,(FILE* filep, const char *format, ...));
 ERL_NIF_API_FUNC_DECL(int,enif_inspect_iolist_as_binary,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifBinary* bin));
@@ -108,7 +108,7 @@ ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple_from_array,(ErlNifEnv*, const
 ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_from_array,(ErlNifEnv*, const ERL_NIF_TERM arr[], unsigned cnt));
 ERL_NIF_API_FUNC_DECL(int,enif_is_empty_list,(ErlNifEnv*, ERL_NIF_TERM term));
 ERL_NIF_API_FUNC_DECL(ErlNifResourceType*,enif_open_resource_type,(ErlNifEnv*, const char* module_str, const char* name_str, void (*dtor)(ErlNifEnv*,void *), ErlNifResourceFlags flags, ErlNifResourceFlags* tried));
-ERL_NIF_API_FUNC_DECL(void*,enif_alloc_resource,(ErlNifResourceType* type, size_t size));
+ERL_NIF_API_FUNC_DECL(void *, enif_alloc_resource, (ErlNifResourceType *type, size_t size) ERL_NAPI_ATTR_MALLOC_US(2));
 ERL_NIF_API_FUNC_DECL(void,enif_release_resource,(void* obj));
 ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource,(ErlNifEnv*, void* obj));
 ERL_NIF_API_FUNC_DECL(int,enif_get_resource,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp));
@@ -121,7 +121,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_get_list_length,(ErlNifEnv* env, ERL_NIF_TERM ter
 ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM, enif_make_atom_len,(ErlNifEnv* env, const char* name, size_t len));
 ERL_NIF_API_FUNC_DECL(int, enif_make_existing_atom_len,(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding));
 ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string_len,(ErlNifEnv* env, const char* string, size_t len, ErlNifCharEncoding));
-ERL_NIF_API_FUNC_DECL(ErlNifEnv*,enif_alloc_env,(void));
+ERL_NIF_API_FUNC_DECL(ErlNifEnv*,enif_alloc_env,(void) ERL_NAPI_ATTR_WUR);
 ERL_NIF_API_FUNC_DECL(void,enif_free_env,(ErlNifEnv* env));
 ERL_NIF_API_FUNC_DECL(void,enif_clear_env,(ErlNifEnv* env));
 ERL_NIF_API_FUNC_DECL(int,enif_send,(ErlNifEnv* env, const ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg));
@@ -184,7 +184,7 @@ ERL_NIF_API_FUNC_DECL(ErlNifUInt64,enif_hash,(ErlNifHash type, ERL_NIF_TERM term
 ERL_NIF_API_FUNC_DECL(int, enif_whereis_pid, (ErlNifEnv *env, ERL_NIF_TERM name, ErlNifPid *pid));
 ERL_NIF_API_FUNC_DECL(int, enif_whereis_port, (ErlNifEnv *env, ERL_NIF_TERM name, ErlNifPort *port));
 
-ERL_NIF_API_FUNC_DECL(ErlNifIOQueue *,enif_ioq_create,(ErlNifIOQueueOpts opts));
+ERL_NIF_API_FUNC_DECL(ErlNifIOQueue *,enif_ioq_create,(ErlNifIOQueueOpts opts) ERL_NAPI_ATTR_MALLOC_D(enif_ioq_destroy,1));
 ERL_NIF_API_FUNC_DECL(void,enif_ioq_destroy,(ErlNifIOQueue *q));
 
 ERL_NIF_API_FUNC_DECL(int,enif_ioq_enq_binary,(ErlNifIOQueue *q, ErlNifBinary *bin, size_t skip));
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index f1b218a846..44a1dccbdf 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -1745,9 +1745,9 @@ Uint64 erts_get_proc_interval(void);
 Uint64 erts_ensure_later_proc_interval(Uint64);
 Uint64 erts_step_proc_interval(void);
 
-ErtsProcList *erts_proclist_create(Process *);
-ErtsProcList *erts_proclist_copy(ErtsProcList *);
 void erts_proclist_destroy(ErtsProcList *);
+ErtsProcList *erts_proclist_create(Process *) ERTS_ATTR_MALLOC_D(erts_proclist_destroy,1);
+ErtsProcList *erts_proclist_copy(ErtsProcList *);
 void erts_proclist_dump(fmtfn_t to, void *to_arg, ErtsProcList*);
 
 ERTS_GLB_INLINE int erts_proclist_same(ErtsProcList *, Process *);
diff --git a/erts/emulator/beam/erl_utils.h b/erts/emulator/beam/erl_utils.h
index ae2fb646a1..e83881f52f 100644
--- a/erts/emulator/beam/erl_utils.h
+++ b/erts/emulator/beam/erl_utils.h
@@ -108,8 +108,8 @@ void erts_init_utils(void);
 void erts_init_utils_mem(void);
 void erts_utils_sched_spec_data_init(void);
 
-erts_dsprintf_buf_t *erts_create_tmp_dsbuf(Uint);
 void erts_destroy_tmp_dsbuf(erts_dsprintf_buf_t *);
+erts_dsprintf_buf_t *erts_create_tmp_dsbuf(Uint) ERTS_ATTR_MALLOC_D(erts_destroy_tmp_dsbuf,1);
 
 int eq(Eterm, Eterm);
 
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index fca4e02ab1..20b0571e43 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -1373,4 +1373,60 @@ erts_raw_env_next_char(byte *p, int encoding)
 #define ERTS_SPAWN_DRV_CONTROL_MAGIC_NUMBER  0x04c76a00U
 #define ERTS_FORKER_DRV_CONTROL_MAGIC_NUMBER 0x050a7800U
 
+#define ERTS_ATTR_WUR
+#define ERTS_ATTR_ALLOC_SIZE(SZPOS)
+#define ERTS_ATTR_MALLOC_U
+#define ERTS_ATTR_MALLOC_US(SZPOS)
+#define ERTS_ATTR_MALLOC_UD(DTOR, PTRPOS)
+#define ERTS_ATTR_MALLOC_USD(SZPOS, DTOR, PTRPOS)
+#define ERTS_ATTR_MALLOC_D(DTOR, PTRPOS)
+
+/* ERTS_ATTR_MALLOC_xxx:
+ * U: Returns pointer to Undefined data. ((malloc))
+ * S: Has Size argument with nr of bytes of returned data. ((alloc_size(SZPOS)))
+ * D: Has 1-to-1 Deallocator function with ptr argument. ((malloc(DTOR,PTRPOS)))
+ *    (D does not work on INLINE functions)
+ */
+
+#ifdef __has_attribute
+#  if __has_attribute(warn_unused_result)
+#    undef  ERTS_ATTR_WUR
+#    define ERTS_ATTR_WUR __attribute__((warn_unused_result))
+#  endif
+#  if __has_attribute(alloc_size)
+#    undef  ERTS_ATTR_ALLOC_SIZE
+#    define ERTS_ATTR_ALLOC_SIZE(SZPOS) __attribute__((alloc_size(SZPOS)))
+#  endif
+#  if __has_attribute(malloc)
+#    undef  ERTS_ATTR_MALLOC_U
+#    define ERTS_ATTR_MALLOC_U __attribute__((malloc)) ERTS_ATTR_WUR
+
+#    undef  ERTS_ATTR_MALLOC_US
+#    define ERTS_ATTR_MALLOC_US(SZPOS)                                 \
+         __attribute__((malloc))                                       \
+         ERTS_ATTR_ALLOC_SIZE(SZPOS)                                   \
+         ERTS_ATTR_WUR
+
+#    undef  ERTS_ATTR_MALLOC_D
+#    if defined(__GNUC__) && __GNUC__ >= 11
+#      define ERTS_ATTR_MALLOC_D(DTOR, PTRPOS)                         \
+         __attribute__((malloc(DTOR,PTRPOS)))                          \
+         ERTS_ATTR_WUR
+#    else
+#      define ERTS_ATTR_MALLOC_D(DTOR, PTRPOS)                         \
+         ERTS_ATTR_WUR
+#    endif
+
+#    undef  ERTS_ATTR_MALLOC_UD
+#    define ERTS_ATTR_MALLOC_UD(DTOR, PTRPOS)                          \
+       ERTS_ATTR_MALLOC_U                                              \
+       ERTS_ATTR_MALLOC_D(DTOR, PTRPOS)
+
+#    undef  ERTS_ATTR_MALLOC_USD
+#    define ERTS_ATTR_MALLOC_USD(SZPOS, DTOR, PTRPOS)                  \
+       ERTS_ATTR_MALLOC_US(SZPOS)                                      \
+       ERTS_ATTR_MALLOC_D(DTOR, PTRPOS)
+#  endif
 #endif
+
+#endif /* __SYS_H__ */
-- 
2.35.3

openSUSE Build Service is sponsored by