bug-gnulib
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]