[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: stdlib, string, wchar: Improve GCC 11 allocation-deallocation checki
From: |
Bruno Haible |
Subject: |
Re: stdlib, string, wchar: Improve GCC 11 allocation-deallocation checking |
Date: |
Sun, 08 Aug 2021 18:19:35 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-210-generic; KDE/5.18.0; x86_64; ; ) |
Yesterday I pushed this:
> 2021-08-07 Bruno Haible <bruno@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').
It is not fully correct. When a package uses Gnulib module 'free-posix' but
does *not* use Gnulib module 'malloc', and it is built on a platform where
Gnulib does
#define free rpl_free
then
* If the platforms has an enhanced 'malloc' declaration with
__attribute__ ((__malloc__ (free, 1))),
* Or if GCC has built-in knowledge that 'malloc' matches 'free',
then code that calls malloc() and then rpl_free() will get warnings from
-Wmismatched-dealloc.
To avoid this, we need to provide a declaration of malloc() with
__attribute__ ((__malloc__ (rpl_free, 1))),
even though the platform would not otherwise need a declaration of
malloc(). And *even* if the Gnulib 'malloc' module is not in use.
Similarly for the other functions.
This patch fixes it.
2021-08-08 Bruno Haible <bruno@clisp.org>
stdlib, string, wchar: Improve GCC 11 allocation-deallocation checking.
* lib/stdlib.in.h (aligned_alloc): For GCC >= 11: Declare also when the
platform already declares the function or when the module
'aligned_alloc' is not in use.
(calloc): For GCC >= 11: Declare nearly always.
(canonicalize_file_name): For GCC >= 11: Declare also when the platform
already declares the function or when the module 'canonicalize-lgpl' is
not in use.
(malloc, realloc): For GCC >= 11: Declare nearly always.
* lib/malloc.in.h: Remove redundant include.
(memalign): For GCC >= 11: Declare also when the platform already
declares the function or when the module 'memalign' is not in use.
* lib/string.in.h: Include <stdlib.h> always.
(strdup): For GCC >= 11: Declare also when the platform already declares
the function or when the module 'strdup' or 'strdup-posix' is not in
use.
* lib/wchar.in.h: Include <stdlib.h> always.
(wcsdup): For GCC >= 11: Declare also when the platform already declares
the function or when the module 'wcsdup' is not in use.
* modules/free-posix (Depends-on): Add string, wchar.
diff --git a/lib/malloc.in.h b/lib/malloc.in.h
index a7394d2..f2be49d 100644
--- a/lib/malloc.in.h
+++ b/lib/malloc.in.h
@@ -21,10 +21,6 @@
#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@
@@ -34,7 +30,7 @@
#define _@GUARD_PREFIX@_MALLOC_H
/* Solaris declares memalign() in <stdlib.h>, not in <malloc.h>.
- Also get size_t. */
+ Also get size_t and free(). */
#include <stdlib.h>
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
@@ -56,17 +52,31 @@ _GL_FUNCDECL_RPL (memalign, void *,
_GL_CXXALIAS_RPL (memalign, void *, (size_t alignment, size_t size));
# else
# if @HAVE_MEMALIGN@
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate memalign with free or rpl_free. */
+_GL_FUNCDECL_SYS (memalign, void *,
+ (size_t alignment, size_t size)
+ _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
_GL_CXXALIAS_SYS (memalign, void *, (size_t alignment, size_t size));
# endif
# endif
# if @HAVE_MEMALIGN@
_GL_CXXALIASWARN (memalign);
# endif
-#elif defined GNULIB_POSIXCHECK
-# undef memalign
-# if HAVE_RAW_DECL_MEMALIGN
+#else
+# if __GNUC__ >= 11 && !defined memalign
+/* For -Wmismatched-dealloc: Associate memalign with free or rpl_free. */
+_GL_FUNCDECL_SYS (memalign, void *,
+ (size_t alignment, size_t size)
+ _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef memalign
+# if HAVE_RAW_DECL_MEMALIGN
_GL_WARN_ON_USE (memalign, "memalign is not portable - "
"use gnulib module memalign for portability");
+# endif
# endif
#endif
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 0e030f1..d86a880 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -184,17 +184,31 @@ _GL_FUNCDECL_RPL (aligned_alloc, void *,
_GL_CXXALIAS_RPL (aligned_alloc, void *, (size_t alignment, size_t size));
# else
# if @HAVE_ALIGNED_ALLOC@
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (aligned_alloc, void *,
+ (size_t alignment, size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
_GL_CXXALIAS_SYS (aligned_alloc, void *, (size_t alignment, size_t size));
# endif
# endif
# if @HAVE_ALIGNED_ALLOC@
_GL_CXXALIASWARN (aligned_alloc);
# endif
-#elif defined GNULIB_POSIXCHECK
-# undef aligned_alloc
-# if HAVE_RAW_DECL_ALIGNED_ALLOC
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined aligned_alloc
+/* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (aligned_alloc, void *,
+ (size_t alignment, size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef aligned_alloc
+# if HAVE_RAW_DECL_ALIGNED_ALLOC
_GL_WARN_ON_USE (aligned_alloc, "aligned_alloc is not portable - "
"use gnulib module aligned_alloc for portability");
+# endif
# endif
#endif
@@ -227,8 +241,8 @@ _GL_FUNCDECL_RPL (calloc, void *,
_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. */
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */
_GL_FUNCDECL_SYS (calloc, void *,
(size_t nmemb, size_t size)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
@@ -238,11 +252,19 @@ _GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t
size));
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (calloc);
# endif
-#elif defined GNULIB_POSIXCHECK
-# undef calloc
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined calloc
+/* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (calloc, void *,
+ (size_t nmemb, size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef calloc
/* Assume calloc is always declared. */
_GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - "
"use gnulib module calloc-posix for portability");
+# endif
#endif
#if @GNULIB_CANONICALIZE_FILE_NAME@
@@ -256,7 +278,7 @@ _GL_FUNCDECL_RPL (canonicalize_file_name, char *,
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
_GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name));
# else
-# if !@HAVE_CANONICALIZE_FILE_NAME@
+# if !@HAVE_CANONICALIZE_FILE_NAME@ || __GNUC__ >= 11
_GL_FUNCDECL_SYS (canonicalize_file_name, char *,
(const char *name)
_GL_ARG_NONNULL ((1))
@@ -269,12 +291,22 @@ _GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const
char *name));
(!@HAVE_CANONICALIZE_FILE_NAME@ || @REPLACE_CANONICALIZE_FILE_NAME@)
# endif
_GL_CXXALIASWARN (canonicalize_file_name);
-#elif defined GNULIB_POSIXCHECK
-# undef canonicalize_file_name
-# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined canonicalize_file_name
+/* For -Wmismatched-dealloc: Associate canonicalize_file_name with free or
+ rpl_free. */
+_GL_FUNCDECL_SYS (canonicalize_file_name, char *,
+ (const char *name)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef canonicalize_file_name
+# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME
_GL_WARN_ON_USE (canonicalize_file_name,
"canonicalize_file_name is unportable - "
"use gnulib module canonicalize-lgpl for portability");
+# endif
# endif
#endif
@@ -424,8 +456,8 @@ _GL_FUNCDECL_RPL (malloc, void *,
_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. */
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */
_GL_FUNCDECL_SYS (malloc, void *,
(size_t size)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
@@ -435,11 +467,19 @@ _GL_CXXALIAS_SYS (malloc, void *, (size_t size));
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (malloc);
# endif
-#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
-# undef malloc
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined malloc
+/* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (malloc, void *,
+ (size_t size)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
+# undef malloc
/* Assume malloc is always declared. */
_GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - "
"use gnulib module malloc-posix for portability");
+# endif
#endif
/* Convert a multibyte character to a wide character. */
@@ -1042,8 +1082,8 @@ _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. */
+# if __GNUC__ >= 11
+/* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */
_GL_FUNCDECL_SYS (realloc, void *, (void *ptr, size_t size)
_GL_ATTRIBUTE_DEALLOC_FREE);
# endif
@@ -1052,11 +1092,18 @@ _GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t
size));
# if __GLIBC__ >= 2
_GL_CXXALIASWARN (realloc);
# endif
-#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
-# undef realloc
+#else
+# if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined realloc
+/* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */
+_GL_FUNCDECL_SYS (realloc, void *, (void *ptr, size_t size)
+ _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
+# undef realloc
/* Assume realloc is always declared. */
_GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - "
"use gnulib module realloc-posix for portability");
+# endif
#endif
diff --git a/lib/string.in.h b/lib/string.in.h
index c67c8c0..b043c75 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -47,9 +47,8 @@
/* NetBSD 5.0 mis-defines NULL. */
#include <stddef.h>
-#if @GNULIB_STRDUP@
-# include <stdlib.h> /* for free() */
-#endif
+/* Get free(). */
+#include <stdlib.h>
/* MirBSD defines mbslen as a macro. */
#if @GNULIB_MBSLEN@ && defined __MirBSD__
@@ -438,7 +437,7 @@ _GL_CXXALIAS_MDA (strdup, char *, (char const *__s));
/* strdup exists as a function and as a macro. Get rid of the macro. */
# undef strdup
# endif
-# if !(@HAVE_DECL_STRDUP@ || defined strdup)
+# if (!@HAVE_DECL_STRDUP@ || __GNUC__ >= 11) && !defined strdup
_GL_FUNCDECL_SYS (strdup, char *,
(char const *__s)
_GL_ARG_NONNULL ((1))
@@ -447,29 +446,38 @@ _GL_FUNCDECL_SYS (strdup, char *,
_GL_CXXALIAS_SYS (strdup, char *, (char const *__s));
# endif
_GL_CXXALIASWARN (strdup);
-#elif defined GNULIB_POSIXCHECK
-# undef strdup
-# if HAVE_RAW_DECL_STRDUP
+#else
+# if __GNUC__ >= 11 && !defined strdup
+/* For -Wmismatched-dealloc: Associate strdup with free or rpl_free. */
+_GL_FUNCDECL_SYS (strdup, char *,
+ (char const *__s)
+ _GL_ARG_NONNULL ((1))
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef strdup
+# if HAVE_RAW_DECL_STRDUP
_GL_WARN_ON_USE (strdup, "strdup is unportable - "
"use gnulib module strdup for portability");
-# endif
-#elif @GNULIB_MDA_STRDUP@
+# endif
+# elif @GNULIB_MDA_STRDUP@
/* On native Windows, map 'creat' to '_creat', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::strdup always. */
-# if defined _WIN32 && !defined __CYGWIN__
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef strdup
-# define strdup _strdup
-# endif
+# if defined _WIN32 && !defined __CYGWIN__
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef strdup
+# define strdup _strdup
+# endif
_GL_CXXALIAS_MDA (strdup, char *, (char const *__s));
-# else
-# if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup
-# undef strdup
-# endif
+# else
+# if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup
+# undef strdup
+# endif
_GL_CXXALIAS_SYS (strdup, char *, (char const *__s));
-# endif
+# endif
_GL_CXXALIASWARN (strdup);
+# endif
#endif
/* Append no more than N characters from SRC onto DEST. */
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index 64e5538..be5d36c 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -72,9 +72,8 @@
# include <stddef.h>
#endif
-#if @GNULIB_WCSDUP@
-# include <stdlib.h> /* for free() */
-#endif
+/* Get free(). */
+#include <stdlib.h>
/* Include the original <wchar.h> if it exists.
Some builds of uClibc lack it. */
@@ -945,7 +944,7 @@ _GL_WARN_ON_USE (wcsxfrm, "wcsxfrm is unportable - "
# endif
_GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s));
# else
-# if !@HAVE_WCSDUP@
+# if !@HAVE_WCSDUP@ || __GNUC__ >= 11
_GL_FUNCDECL_SYS (wcsdup, wchar_t *,
(const wchar_t *s)
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
@@ -953,30 +952,40 @@ _GL_FUNCDECL_SYS (wcsdup, wchar_t *,
_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s));
# endif
_GL_CXXALIASWARN (wcsdup);
-#elif defined GNULIB_POSIXCHECK
-# undef wcsdup
-# if HAVE_RAW_DECL_WCSDUP
+#else
+# if __GNUC__ >= 11 && !defined wcsdup
+/* For -Wmismatched-dealloc: Associate wcsdup with free or rpl_free. */
+_GL_FUNCDECL_SYS (wcsdup, wchar_t *,
+ (const wchar_t *s)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# endif
+# if defined GNULIB_POSIXCHECK
+# undef wcsdup
+# if HAVE_RAW_DECL_WCSDUP
_GL_WARN_ON_USE (wcsdup, "wcsdup is unportable - "
"use gnulib module wcsdup for portability");
-# endif
-#elif @GNULIB_MDA_WCSDUP@
+# endif
+# elif @GNULIB_MDA_WCSDUP@
/* On native Windows, map 'wcsdup' to '_wcsdup', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between
platforms by defining GNULIB_NAMESPACE::wcsdup always. */
-# if defined _WIN32 && !defined __CYGWIN__
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef wcsdup
-# define wcsdup _wcsdup
-# endif
+# if defined _WIN32 && !defined __CYGWIN__
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef wcsdup
+# define wcsdup _wcsdup
+# endif
_GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s));
-# else
-_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s));
-# if @HAVE_DECL_WCSDUP@
+# else
+_GL_FUNCDECL_SYS (wcsdup, wchar_t *,
+ (const wchar_t *s)
+ _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
+# if @HAVE_DECL_WCSDUP@
_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s));
+# endif
# endif
-# endif
-# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_WCSDUP@
+# if (defined _WIN32 && !defined __CYGWIN__) || @HAVE_DECL_WCSDUP@
_GL_CXXALIASWARN (wcsdup);
+# endif
# endif
#endif
diff --git a/modules/free-posix b/modules/free-posix
index f48e388..1d00563 100644
--- a/modules/free-posix
+++ b/modules/free-posix
@@ -7,6 +7,8 @@ m4/free.m4
Depends-on:
stdlib
+string
+wchar
configure.ac:
gl_FUNC_FREE