2021-08-07 Bruno Haible <br...@clisp.org> stdlib, string, wchar: Improve GCC 11 allocation-deallocation checking. * lib/stdlib.in.h (free): Move declaration up. (aligned_alloc, calloc, canonicalize_file_name, malloc, realloc): Declare that deallocation must happen through 'free' (which may actually be 'rpl_free'). * lib/string.in.h: Include <stdlib.h>. (strdup): Declare deallocation. * lib/wchar.in.h: Include <stdlib.h>. (wcsdup): Declare deallocation. * lib/malloc.in.h: Include <stdlib.h>. (memalign): Declare deallocation.
diff --git a/lib/malloc.in.h b/lib/malloc.in.h index 851abb1..a7394d2 100644 --- a/lib/malloc.in.h +++ b/lib/malloc.in.h @@ -21,6 +21,10 @@ #endif @PRAGMA_COLUMNS@ +#if @GNULIB_MEMALIGN@ +# include <stdlib.h> /* for free() */ +#endif + /* The include_next requires a split double-inclusion guard. */ #if @HAVE_MALLOC_H@ # @INCLUDE_NEXT@ @NEXT_MALLOC_H@ @@ -46,7 +50,9 @@ # undef memalign # define memalign rpl_memalign # endif -_GL_FUNCDECL_RPL (memalign, void *, (size_t alignment, size_t size)); +_GL_FUNCDECL_RPL (memalign, void *, + (size_t alignment, size_t size) + _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (memalign, void *, (size_t alignment, size_t size)); # else # if @HAVE_MEMALIGN@ diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 652062d..0e030f1 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -149,6 +149,28 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - " #endif +#if @GNULIB_FREE_POSIX@ +# if @REPLACE_FREE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef free +# define free rpl_free +# endif +_GL_FUNCDECL_RPL (free, void, (void *ptr)); +_GL_CXXALIAS_RPL (free, void, (void *ptr)); +# else +_GL_CXXALIAS_SYS (free, void, (void *ptr)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (free); +# endif +#elif defined GNULIB_POSIXCHECK +# undef free +/* Assume free is always declared. */ +_GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - " + "use gnulib module free for portability"); +#endif + + /* Allocate memory with indefinite extent and specified alignment. */ #if @GNULIB_ALIGNED_ALLOC@ # if @REPLACE_ALIGNED_ALLOC@ @@ -156,7 +178,9 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - " # undef aligned_alloc # define aligned_alloc rpl_aligned_alloc # endif -_GL_FUNCDECL_RPL (aligned_alloc, void *, (size_t alignment, size_t size)); +_GL_FUNCDECL_RPL (aligned_alloc, void *, + (size_t alignment, size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (aligned_alloc, void *, (size_t alignment, size_t size)); # else # if @HAVE_ALIGNED_ALLOC@ @@ -198,9 +222,17 @@ _GL_WARN_ON_USE (atoll, "atoll is unportable - " # undef calloc # define calloc rpl_calloc # endif -_GL_FUNCDECL_RPL (calloc, void *, (size_t nmemb, size_t size)); +_GL_FUNCDECL_RPL (calloc, void *, + (size_t nmemb, size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size)); # else +# if @GNULIB_FREE_POSIX@ && @REPLACE_FREE@ && __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate calloc with rpl_free. */ +_GL_FUNCDECL_SYS (calloc, void *, + (size_t nmemb, size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif _GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size)); # endif # if __GLIBC__ >= 2 @@ -218,13 +250,17 @@ _GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - " # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define canonicalize_file_name rpl_canonicalize_file_name # endif -_GL_FUNCDECL_RPL (canonicalize_file_name, char *, (const char *name) - _GL_ARG_NONNULL ((1))); +_GL_FUNCDECL_RPL (canonicalize_file_name, char *, + (const char *name) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name)); # else # if !@HAVE_CANONICALIZE_FILE_NAME@ -_GL_FUNCDECL_SYS (canonicalize_file_name, char *, (const char *name) - _GL_ARG_NONNULL ((1))); +_GL_FUNCDECL_SYS (canonicalize_file_name, char *, + (const char *name) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); # endif _GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name)); # endif @@ -288,27 +324,6 @@ _GL_CXXALIASWARN (fcvt); # endif #endif -#if @GNULIB_FREE_POSIX@ -# if @REPLACE_FREE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef free -# define free rpl_free -# endif -_GL_FUNCDECL_RPL (free, void, (void *ptr)); -_GL_CXXALIAS_RPL (free, void, (void *ptr)); -# else -_GL_CXXALIAS_SYS (free, void, (void *ptr)); -# endif -# if __GLIBC__ >= 2 -_GL_CXXALIASWARN (free); -# endif -#elif defined GNULIB_POSIXCHECK -# undef free -/* Assume free is always declared. */ -_GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - " - "use gnulib module free for portability"); -#endif - #if @GNULIB_MDA_GCVT@ /* On native Windows, map 'gcvt' to '_gcvt', so that -loldnames is not required. In C++ with GNULIB_NAMESPACE, avoid differences between @@ -404,9 +419,17 @@ _GL_WARN_ON_USE (grantpt, "grantpt is not portable - " # undef malloc # define malloc rpl_malloc # endif -_GL_FUNCDECL_RPL (malloc, void *, (size_t size)); +_GL_FUNCDECL_RPL (malloc, void *, + (size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (malloc, void *, (size_t size)); # else +# if @GNULIB_FREE_POSIX@ && @REPLACE_FREE@ && __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate malloc with rpl_free. */ +_GL_FUNCDECL_SYS (malloc, void *, + (size_t size) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); +# endif _GL_CXXALIAS_SYS (malloc, void *, (size_t size)); # endif # if __GLIBC__ >= 2 @@ -1015,9 +1038,15 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - " # undef realloc # define realloc rpl_realloc # endif -_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size)); +_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size) + _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size)); # else +# if @GNULIB_FREE_POSIX@ && @REPLACE_FREE@ && __GNUC__ >= 11 +/* For -Wmismatched-dealloc: Associate realloc with rpl_free. */ +_GL_FUNCDECL_SYS (realloc, void *, (void *ptr, size_t size) + _GL_ATTRIBUTE_DEALLOC_FREE); +# endif _GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size)); # endif # if __GLIBC__ >= 2 diff --git a/lib/string.in.h b/lib/string.in.h index cb964bc..c67c8c0 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -47,6 +47,10 @@ /* NetBSD 5.0 mis-defines NULL. */ #include <stddef.h> +#if @GNULIB_STRDUP@ +# include <stdlib.h> /* for free() */ +#endif + /* MirBSD defines mbslen as a macro. */ #if @GNULIB_MBSLEN@ && defined __MirBSD__ # include <wchar.h> @@ -418,7 +422,10 @@ _GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - " # undef strdup # define strdup rpl_strdup # endif -_GL_FUNCDECL_RPL (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1))); +_GL_FUNCDECL_RPL (strdup, char *, + (char const *__s) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); _GL_CXXALIAS_RPL (strdup, char *, (char const *__s)); # elif defined _WIN32 && !defined __CYGWIN__ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) @@ -432,7 +439,10 @@ _GL_CXXALIAS_MDA (strdup, char *, (char const *__s)); # undef strdup # endif # if !(@HAVE_DECL_STRDUP@ || defined strdup) -_GL_FUNCDECL_SYS (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1))); +_GL_FUNCDECL_SYS (strdup, char *, + (char const *__s) + _GL_ARG_NONNULL ((1)) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); # endif _GL_CXXALIAS_SYS (strdup, char *, (char const *__s)); # endif diff --git a/lib/wchar.in.h b/lib/wchar.in.h index 919a5a3..64e5538 100644 --- a/lib/wchar.in.h +++ b/lib/wchar.in.h @@ -72,6 +72,10 @@ # include <stddef.h> #endif +#if @GNULIB_WCSDUP@ +# include <stdlib.h> /* for free() */ +#endif + /* Include the original <wchar.h> if it exists. Some builds of uClibc lack it. */ /* The include_next requires a split double-inclusion guard. */ @@ -942,7 +946,9 @@ _GL_WARN_ON_USE (wcsxfrm, "wcsxfrm is unportable - " _GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s)); # else # if !@HAVE_WCSDUP@ -_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s)); +_GL_FUNCDECL_SYS (wcsdup, wchar_t *, + (const wchar_t *s) + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); # endif _GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s)); # endif