From: Bruno Haible Date: Sun, 27 Apr 2025 21:36:52 +0000 (+0200) Subject: Make use of gcc's __nonnull_if_nonzero__ attribute. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=03600605ad3eab5b1a74606498680b013fb89fe3;p=gnulib.git Make use of gcc's __nonnull_if_nonzero__ attribute. * m4/gnulib-common.m4 (gl_COMMON_BODY): Define _GL_ATTR_nonnull_if_nonzero and _GL_ATTRIBUTE_NONNULL_IF_NONZERO. * lib/attribute.h (ATTRIBUTE_NONNULL_IF_NONZERO): new macro. * lib/stdlib.in.h (_GL_ATTRIBUTE_NONNULL_IF_NONZERO): New macro. (bsearch, qsort, qsort_r): Use it. * lib/string.in.h (_GL_ATTRIBUTE_NONNULL_IF_NONZERO): New macro. (memcpy, memccpy, memmove, strncpy, strndup, strncat, memcmp, strncmp, memchr, memrchr, memset, memset_explicit): Use it. * lib/wchar.in.h (_GL_ATTRIBUTE_NONNULL_IF_NONZERO): New macro. (wmemcpy, wmemmove, wcsncpy, wcsncat, wmemcmp, wcsncmp, wmemchr, wmemset): Use it. * lib/string-desc.h (sd_new_addr): Use it. --- diff --git a/ChangeLog b/ChangeLog index c4e4e086a9..930d181551 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2025-04-27 Bruno Haible + + Make use of gcc's __nonnull_if_nonzero__ attribute. + * m4/gnulib-common.m4 (gl_COMMON_BODY): Define + _GL_ATTR_nonnull_if_nonzero and _GL_ATTRIBUTE_NONNULL_IF_NONZERO. + * lib/attribute.h (ATTRIBUTE_NONNULL_IF_NONZERO): new macro. + * lib/stdlib.in.h (_GL_ATTRIBUTE_NONNULL_IF_NONZERO): New macro. + (bsearch, qsort, qsort_r): Use it. + * lib/string.in.h (_GL_ATTRIBUTE_NONNULL_IF_NONZERO): New macro. + (memcpy, memccpy, memmove, strncpy, strndup, strncat, memcmp, strncmp, + memchr, memrchr, memset, memset_explicit): Use it. + * lib/wchar.in.h (_GL_ATTRIBUTE_NONNULL_IF_NONZERO): New macro. + (wmemcpy, wmemmove, wcsncpy, wcsncat, wmemcmp, wcsncmp, wmemchr, + wmemset): Use it. + * lib/string-desc.h (sd_new_addr): Use it. + 2025-04-26 Bruno Haible crc: Fix -Wmissing-variable-declarations warning. diff --git a/lib/attribute.h b/lib/attribute.h index 625195c856..ae7bbe8e2c 100644 --- a/lib/attribute.h +++ b/lib/attribute.h @@ -85,10 +85,10 @@ _GL_ATTRIBUTE_FALLTHROUGH, _GL_ATTRIBUTE_FORMAT, _GL_ATTRIBUTE_LEAF, _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_MAY_ALIAS, _GL_ATTRIBUTE_MAYBE_UNUSED, _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOINLINE, _GL_ATTRIBUTE_NONNULL, - _GL_ATTRIBUTE_NONSTRING, _GL_ATTRIBUTE_NOTHROW, _GL_ATTRIBUTE_PACKED, - _GL_ATTRIBUTE_PURE, _GL_ATTRIBUTE_REPRODUCIBLE, - _GL_ATTRIBUTE_RETURNS_NONNULL, _GL_ATTRIBUTE_SENTINEL, - _GL_ATTRIBUTE_UNSEQUENCED. */ + _GL_ATTRIBUTE_NONNULL_IF_NONZERO, _GL_ATTRIBUTE_NONSTRING, + _GL_ATTRIBUTE_NOTHROW, _GL_ATTRIBUTE_PACKED, _GL_ATTRIBUTE_PURE, + _GL_ATTRIBUTE_REPRODUCIBLE, _GL_ATTRIBUTE_RETURNS_NONNULL, + _GL_ATTRIBUTE_SENTINEL, _GL_ATTRIBUTE_UNSEQUENCED. */ #if !_GL_CONFIG_H_INCLUDED #error "Please include config.h first." #endif @@ -170,6 +170,12 @@ /* Applies to: functions. */ #define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL (args) +/* ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) - Argument NP (a pointer) + must not be NULL if the argument NI (an integer) is != 0. */ +/* Applies to: functions. */ +#define ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (np, ni) + + /* The function's return value is a non-NULL pointer. */ /* Applies to: functions. */ #define ATTRIBUTE_RETURNS_NONNULL _GL_ATTRIBUTE_RETURNS_NONNULL diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index dbe8ebc850..1342db4877 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -168,6 +168,18 @@ _GL_INLINE_HEADER_BEGIN # endif #endif +/* _GL_ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) declares that the argument NP + (a pointer) must not be NULL if the argument NI (an integer) is != 0. */ +/* Applies to: functions. */ +#ifndef _GL_ATTRIBUTE_NONNULL_IF_NONZERO +# if __GNUC__ >= 15 && !defined __clang__ +# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) \ + __attribute__ ((__nonnull_if_nonzero__ (np, ni))) +# else +# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) +# endif +#endif + /* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. */ #ifndef _GL_ATTRIBUTE_NOTHROW @@ -223,6 +235,18 @@ _GL_INLINE_HEADER_BEGIN #endif +/* Declarations for ISO C N3322. */ +#if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ +_GL_EXTERN_C void *bsearch (const void *__key, + const void *__base, size_t __nmemb, size_t __size, + int (*__compare) (const void *, const void *)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3) _GL_ARG_NONNULL ((5)); +_GL_EXTERN_C void qsort (void *__base, size_t __nmemb, size_t __size, + int (*__compare) (const void *, const void *)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) _GL_ARG_NONNULL ((4)); +#endif + + #if @GNULIB__EXIT@ /* Terminate the current process with the given return code, without running the 'atexit' handlers. */ @@ -1182,7 +1206,8 @@ typedef int (*_gl_qsort_r_compar_fn) (void const *, void const *, void *); _GL_FUNCDECL_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, _gl_qsort_r_compar_fn compare, void *arg), - _GL_ARG_NONNULL ((1, 4))); + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) + _GL_ARG_NONNULL ((4))); _GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, _gl_qsort_r_compar_fn compare, void *arg)); @@ -1191,7 +1216,8 @@ _GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, _GL_FUNCDECL_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, _gl_qsort_r_compar_fn compare, void *arg), - _GL_ARG_NONNULL ((1, 4))); + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) + _GL_ARG_NONNULL ((4))); # endif _GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, _gl_qsort_r_compar_fn compare, diff --git a/lib/string-desc.h b/lib/string-desc.h index 12a0fb199b..e2de97af51 100644 --- a/lib/string-desc.h +++ b/lib/string-desc.h @@ -20,7 +20,7 @@ #define _STRING_DESC_H 1 /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, - _GL_ATTRIBUTE_NODISCARD. */ + _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NONNULL_IF_NONZERO. */ #if !_GL_CONFIG_H_INCLUDED #error "Please include config.h first." #endif @@ -124,7 +124,8 @@ extern ptrdiff_t sd_contains (string_desc_t haystack, string_desc_t needle); extern string_desc_t sd_new_empty (void); /* Construct and return a string of length N, at the given memory address. */ -extern string_desc_t sd_new_addr (idx_t n, char *addr); +extern string_desc_t sd_new_addr (idx_t n, char *addr) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 1); /* Return a string that represents the C string S, of length strlen (S). */ extern string_desc_t sd_from_c (const char *s); diff --git a/lib/string.in.h b/lib/string.in.h index 44b9497d80..e764221168 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -116,6 +116,18 @@ # endif #endif +/* _GL_ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) declares that the argument NP + (a pointer) must not be NULL if the argument NI (an integer) is != 0. */ +/* Applies to: functions. */ +#ifndef _GL_ATTRIBUTE_NONNULL_IF_NONZERO +# if __GNUC__ >= 15 && !defined __clang__ +# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) \ + __attribute__ ((__nonnull_if_nonzero__ (np, ni))) +# else +# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) +# endif +#endif + /* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. */ #ifndef _GL_ATTRIBUTE_NOTHROW @@ -154,6 +166,7 @@ /* The definition of _GL_WARN_ON_USE is copied here. */ + /* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though may not have been included yet. */ #if @GNULIB_FREE_POSIX@ @@ -198,6 +211,44 @@ _GL_EXTERN_C void free (void *); # endif #endif + +/* Declarations for ISO C N3322. */ +#if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ +_GL_EXTERN_C void *memcpy (void *__dest, const void *__src, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C void *memccpy (void *__dest, const void *__src, int __c, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 4) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 4); +_GL_EXTERN_C void *memmove (void *__dest, const void *__src, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C char *strncpy (char *__dest, const char *__src, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C char *strndup (const char *__s, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2); +_GL_EXTERN_C char *strncat (char *__dest, const char *__src, size_t __n) + _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C int memcmp (const void *__s1, const void *__s2, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C int strncmp (const char *__s1, const char *__s2, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +# ifndef __cplusplus +_GL_EXTERN_C void *memchr (const void *__s, int __c, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); +_GL_EXTERN_C void *memrchr (const void *__s, int __c, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); +# endif +_GL_EXTERN_C void *memset (void *__s, int __c, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); +_GL_EXTERN_C void *memset_explicit (void *__s, int __c, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); +#endif + + /* Clear a block of memory. The compiler will not delete a call to this function, even if the block is dead after the call. */ #if @GNULIB_EXPLICIT_BZERO@ @@ -215,6 +266,7 @@ _GL_WARN_ON_USE (explicit_bzero, "explicit_bzero is unportable - " # endif #endif + /* Find the index of the least-significant set bit. */ #if @GNULIB_FFSL@ # if !@HAVE_FFSL@ @@ -281,7 +333,7 @@ _GL_CXXALIASWARN (memccpy); # endif _GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n), _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); _GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n)); # else /* On some systems, this function is defined as an overloaded function: @@ -388,7 +440,7 @@ _GL_WARN_ON_USE (mempcpy, "mempcpy is unportable - " # if ! @HAVE_DECL_MEMRCHR@ _GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t), _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); # endif /* On some systems, this function is defined as an overloaded function: extern "C++" { const void * std::memrchr (const void *, int, size_t); } @@ -425,12 +477,14 @@ _GL_WARN_ON_USE (memrchr, "memrchr is unportable - " # define memset_explicit rpl_memset_explicit # endif _GL_FUNCDECL_RPL (memset_explicit, void *, - (void *__dest, int __c, size_t __n), _GL_ARG_NONNULL ((1))); + (void *__dest, int __c, size_t __n), + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); _GL_CXXALIAS_RPL (memset_explicit, void *, (void *__dest, int __c, size_t __n)); # else # if !@HAVE_MEMSET_EXPLICIT@ _GL_FUNCDECL_SYS (memset_explicit, void *, - (void *__dest, int __c, size_t __n), _GL_ARG_NONNULL ((1))); + (void *__dest, int __c, size_t __n), + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); # endif _GL_CXXALIAS_SYS (memset_explicit, void *, (void *__dest, int __c, size_t __n)); # endif @@ -697,7 +751,8 @@ _GL_CXXALIASWARN (strdup); # endif _GL_FUNCDECL_RPL (strncat, char *, (char *restrict dest, const char *restrict src, size_t n), - _GL_ARG_NONNULL ((1, 2))); + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); _GL_CXXALIAS_RPL (strncat, char *, (char *restrict dest, const char *restrict src, size_t n)); # else @@ -724,7 +779,7 @@ _GL_WARN_ON_USE (strncat, "strncat is unportable - " # endif _GL_FUNCDECL_RPL (strndup, char *, (char const *__s, size_t __n), - _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n)); # else @@ -733,13 +788,13 @@ _GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n)); # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 _GL_FUNCDECL_SYS (strndup, char *, (char const *__s, size_t __n), - _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) _GL_ATTRIBUTE_NOTHROW; # else _GL_FUNCDECL_SYS (strndup, char *, (char const *__s, size_t __n), - _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); # endif # endif @@ -752,13 +807,13 @@ _GL_CXXALIASWARN (strndup); # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 _GL_FUNCDECL_SYS (strndup, char *, (char const *__s, size_t __n), - _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) _GL_ATTRIBUTE_NOTHROW; # else _GL_FUNCDECL_SYS (strndup, char *, (char const *__s, size_t __n), - _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); # endif # endif diff --git a/lib/wchar.in.h b/lib/wchar.in.h index c20040b22c..8836ed10e6 100644 --- a/lib/wchar.in.h +++ b/lib/wchar.in.h @@ -140,6 +140,18 @@ # endif #endif +/* _GL_ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) declares that the argument NP + (a pointer) must not be NULL if the argument NI (an integer) is != 0. */ +/* Applies to: functions. */ +#ifndef _GL_ATTRIBUTE_NONNULL_IF_NONZERO +# if __GNUC__ >= 15 && !defined __clang__ +# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) \ + __attribute__ ((__nonnull_if_nonzero__ (np, ni))) +# else +# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) +# endif +#endif + /* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. */ #ifndef _GL_ATTRIBUTE_NOTHROW @@ -266,6 +278,34 @@ _GL_EXTERN_C void free (void *); #endif +/* Declarations for ISO C N3322. */ +#if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ +_GL_EXTERN_C wchar_t *wmemcpy (wchar_t *__dest, const wchar_t *__src, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C wchar_t *wmemmove (wchar_t *__dest, const wchar_t *__src, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C wchar_t *wcsncpy (wchar_t *__dest, const wchar_t *__src, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C wchar_t *wcsncat (wchar_t *__dest, const wchar_t *__src, size_t __n) + _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C int wmemcmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +_GL_EXTERN_C int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); +# ifndef __cplusplus +_GL_EXTERN_C wchar_t *wmemchr (const wchar_t *__s, wchar_t __wc, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); +# endif +_GL_EXTERN_C wchar_t *wmemset (wchar_t *__s, wchar_t __wc, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); +#endif + + /* Convert a single-byte character to a wide character. */ #if @GNULIB_BTOWC@ # if @REPLACE_BTOWC@ @@ -850,8 +890,9 @@ _GL_WARN_ON_USE (wcwidth, "wcwidth is unportable - " /* Search N wide characters of S for C. */ #if @GNULIB_WMEMCHR@ # if !@HAVE_WMEMCHR@ -_GL_FUNCDECL_SYS (wmemchr, wchar_t *, (const wchar_t *s, wchar_t c, size_t n), - _GL_ATTRIBUTE_PURE); +_GL_FUNCDECL_SYS (wmemchr, wchar_t *, + (const wchar_t *s, wchar_t c, size_t n), + _GL_ATTRIBUTE_PURE _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); # endif /* On some systems, this function is defined as an overloaded function: extern "C++" { @@ -888,14 +929,18 @@ _GL_WARN_ON_USE (wmemchr, "wmemchr is unportable - " # endif _GL_FUNCDECL_RPL (wmemcmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n), - _GL_ATTRIBUTE_PURE); + _GL_ATTRIBUTE_PURE + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); _GL_CXXALIAS_RPL (wmemcmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n)); # else # if !@HAVE_WMEMCMP@ _GL_FUNCDECL_SYS (wmemcmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n), - _GL_ATTRIBUTE_PURE); + _GL_ATTRIBUTE_PURE + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); # endif _GL_CXXALIAS_SYS (wmemcmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n)); @@ -917,7 +962,9 @@ _GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - " # if !@HAVE_WMEMCPY@ _GL_FUNCDECL_SYS (wmemcpy, wchar_t *, (wchar_t *restrict dest, - const wchar_t *restrict src, size_t n), ); + const wchar_t *restrict src, size_t n), + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); # endif _GL_CXXALIAS_SYS (wmemcpy, wchar_t *, (wchar_t *restrict dest, @@ -939,7 +986,9 @@ _GL_WARN_ON_USE (wmemcpy, "wmemcpy is unportable - " #if @GNULIB_WMEMMOVE@ # if !@HAVE_WMEMMOVE@ _GL_FUNCDECL_SYS (wmemmove, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n), ); + (wchar_t *dest, const wchar_t *src, size_t n), + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); # endif _GL_CXXALIAS_SYS (wmemmove, wchar_t *, (wchar_t *dest, const wchar_t *src, size_t n)); @@ -994,7 +1043,8 @@ _GL_WARN_ON_USE (wmempcpy, "wmempcpy is unportable - " /* Set N wide characters of S to C. */ #if @GNULIB_WMEMSET@ # if !@HAVE_WMEMSET@ -_GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n), ); +_GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n), + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); # endif _GL_CXXALIAS_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); # if __GLIBC__ >= 2 @@ -1093,7 +1143,9 @@ _GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - " # if !@HAVE_WCSNCPY@ _GL_FUNCDECL_SYS (wcsncpy, wchar_t *, (wchar_t *restrict dest, - const wchar_t *restrict src, size_t n), ); + const wchar_t *restrict src, size_t n), + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); # endif _GL_CXXALIAS_SYS (wcsncpy, wchar_t *, (wchar_t *restrict dest, @@ -1163,7 +1215,9 @@ _GL_WARN_ON_USE (wcscat, "wcscat is unportable - " # endif _GL_FUNCDECL_RPL (wcsncat, wchar_t *, (wchar_t *restrict dest, const wchar_t *restrict src, - size_t n), ); + size_t n), + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); _GL_CXXALIAS_RPL (wcsncat, wchar_t *, (wchar_t *restrict dest, const wchar_t *restrict src, size_t n)); @@ -1171,7 +1225,9 @@ _GL_CXXALIAS_RPL (wcsncat, wchar_t *, # if !@HAVE_WCSNCAT@ _GL_FUNCDECL_SYS (wcsncat, wchar_t *, (wchar_t *restrict dest, const wchar_t *restrict src, - size_t n), ); + size_t n), + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); # endif _GL_CXXALIAS_SYS (wcsncat, wchar_t *, (wchar_t *restrict dest, const wchar_t *restrict src, @@ -1227,14 +1283,18 @@ _GL_WARN_ON_USE (wcscmp, "wcscmp is unportable - " # endif _GL_FUNCDECL_RPL (wcsncmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n), - _GL_ATTRIBUTE_PURE); + _GL_ATTRIBUTE_PURE + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); _GL_CXXALIAS_RPL (wcsncmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n)); # else # if !@HAVE_WCSNCMP@ _GL_FUNCDECL_SYS (wcsncmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n), - _GL_ATTRIBUTE_PURE); + _GL_ATTRIBUTE_PURE + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); # endif _GL_CXXALIAS_SYS (wcsncmp, int, (const wchar_t *s1, const wchar_t *s2, size_t n)); diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index 4dd3b16f1d..d5bf2fb358 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -1,5 +1,5 @@ # gnulib-common.m4 -# serial 109 +# serial 110 dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -140,6 +140,7 @@ AC_DEFUN([gl_COMMON_BODY], [ # endif # define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1) # define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3) +# define _GL_ATTR_nonnull_if_nonzero _GL_GNUC_PREREQ (15, 1) # define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0) # define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3) # define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7) @@ -684,6 +685,17 @@ AC_DEFUN([gl_COMMON_BODY], [ # endif #endif +/* _GL_ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) declares that the argument NP + (a pointer) must not be NULL if the argument NI (an integer) is != 0. */ +/* Applies to: functions. */ +#ifndef _GL_ATTRIBUTE_NONNULL_IF_NONZERO +# if _GL_HAS_ATTRIBUTE (nonnull_if_nonzero) +# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) __attribute__ ((__nonnull_if_nonzero__ (np, ni))) +# else +# define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) +# endif +#endif + /* _GL_ATTRIBUTE_NONSTRING declares that the contents of a character array is not meant to be NUL-terminated. */ /* Applies to: struct/union members and variables that are arrays of element