* [PATCH] string, wchar: avoid some namespace pollution
@ 2021-09-08 0:56 Paul Eggert
2021-09-08 15:14 ` Bruno Haible
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Paul Eggert @ 2021-09-08 0:56 UTC (permalink / raw)
To: bug-gnulib, landfillbaby69; +Cc: Paul Eggert
* lib/string.in.h, lib/wchar.in.h:
(free): Declare by hand instead of including stdlib.h.
This avoids some namespace pollution. It should also avoid some
nested-include problems described by Lucy Phipps in:
https://lists.gnu.org/r/bug-gnulib/2021-09/msg00018.html
* modules/string, modules/wchar:
(Depends-on): Add stdlib, so that REPLACE_FREE has the right value.
(Makefile.am): Replace @REPLACE_FREE@ when creating the include file.
---
ChangeLog | 12 ++++++++++++
lib/attribute.h | 2 +-
lib/stdlib.in.h | 2 +-
lib/string.in.h | 9 ++++++---
lib/wchar.in.h | 9 ++++++---
m4/gnulib-common.m4 | 2 +-
modules/string | 2 ++
modules/wchar | 2 ++
8 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 39a892e28..f73dc5a13 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2021-09-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ string, wchar: avoid some namespace pollution
+ * lib/string.in.h, lib/wchar.in.h:
+ (free): Declare by hand instead of including stdlib.h.
+ This avoids some namespace pollution. It should also avoid some
+ nested-include problems described by Lucy Phipps in:
+ https://lists.gnu.org/r/bug-gnulib/2021-09/msg00018.html
+ * modules/string, modules/wchar:
+ (Depends-on): Add stdlib, so that REPLACE_FREE has the right value.
+ (Makefile.am): Replace @REPLACE_FREE@ when creating the include file.
+
2021-09-04 Paul Eggert <eggert@cs.ucla.edu>
idx: break copying from glibc
diff --git a/lib/attribute.h b/lib/attribute.h
index 26a555655..eb36188d4 100644
--- a/lib/attribute.h
+++ b/lib/attribute.h
@@ -80,7 +80,7 @@
that can be freed by passing them as the Ith argument to the
function F.
ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
- can be freed via 'free'; it can be used only after including <stdlib.h>. */
+ can be freed via 'free'; it can be used only after declaring 'free'. */
/* Applies to: functions. Cannot be used on inline functions. */
#define ATTRIBUTE_DEALLOC(f, i) _GL_ATTRIBUTE_DEALLOC(f, i)
#define ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC_FREE
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index d0ea07f8b..0855112d1 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -111,7 +111,7 @@ struct random_data
#endif
/* _GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
- can be freed via 'free'; it can be used only after including <stdlib.h>. */
+ can be freed via 'free'; it can be used only after declaring 'free'. */
/* Applies to: functions. Cannot be used on inline functions. */
#ifndef _GL_ATTRIBUTE_DEALLOC_FREE
# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1)
diff --git a/lib/string.in.h b/lib/string.in.h
index fa2e40c25..6214b5578 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -47,9 +47,6 @@
/* NetBSD 5.0 mis-defines NULL. */
#include <stddef.h>
-/* Get free(). */
-#include <stdlib.h>
-
/* MirBSD defines mbslen as a macro. */
#if @GNULIB_MBSLEN@ && defined __MirBSD__
# include <wchar.h>
@@ -86,6 +83,12 @@
/* The definition of _GL_WARN_ON_USE is copied here. */
+/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
+#if (@REPLACE_FREE@ && !defined free \
+ && !(defined __cplusplus && defined GNULIB_NAMESPACE))
+# define free rpl_free
+#endif
+_GL_EXTERN_C void free (void *);
/* Clear a block of memory. The compiler will not delete a call to
this function, even if the block is dead after the call. */
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index be5d36c8d..027a14549 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -72,9 +72,6 @@
# include <stddef.h>
#endif
-/* Get free(). */
-#include <stdlib.h>
-
/* Include the original <wchar.h> if it exists.
Some builds of uClibc lack it. */
/* The include_next requires a split double-inclusion guard. */
@@ -149,6 +146,12 @@ typedef int rpl_mbstate_t;
# endif
#endif
+/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
+#if (@REPLACE_FREE@ && !defined free \
+ && !(defined __cplusplus && defined GNULIB_NAMESPACE))
+# define free rpl_free
+#endif
+_GL_EXTERN_C void free (void *);
/* Convert a single-byte character to a wide character. */
#if @GNULIB_BTOWC@
diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index 5d667052d..12b19dbcb 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -174,7 +174,7 @@ AC_DEFUN([gl_COMMON_BODY], [
that can be freed by passing them as the Ith argument to the
function F.
_GL_ATTRIBUTE_DEALLOC_FREE declares that the function returns pointers that
- can be freed via 'free'; it can be used only after including <stdlib.h>. */
+ can be freed via 'free'; it can be used only after declaring 'free'. */
/* Applies to: functions. Cannot be used on inline functions. */
#if _GL_GNUC_PREREQ (11, 0)
# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i)))
diff --git a/modules/string b/modules/string
index e1d9980bb..306834591 100644
--- a/modules/string
+++ b/modules/string
@@ -13,6 +13,7 @@ snippet/arg-nonnull
snippet/c++defs
snippet/warn-on-use
stddef
+stdlib
configure.ac:
gl_STRING_H
@@ -102,6 +103,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's|@''REPLACE_FFSLL''@|$(REPLACE_FFSLL)|g' \
-e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \
-e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \
+ -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \
-e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \
-e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \
-e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \
diff --git a/modules/wchar b/modules/wchar
index d4e6d6933..d34cb6a22 100644
--- a/modules/wchar
+++ b/modules/wchar
@@ -14,6 +14,7 @@ snippet/c++defs
snippet/warn-on-use
inttypes-incomplete
stddef
+stdlib
configure.ac:
gl_WCHAR_H
@@ -126,6 +127,7 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
sed -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \
-e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \
-e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \
+ -e 's|@''REPLACE_FREE''@|$(REPLACE_FREE)|g' \
-e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \
-e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \
-e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \
--
2.30.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] string, wchar: avoid some namespace pollution
2021-09-08 0:56 [PATCH] string, wchar: avoid some namespace pollution Paul Eggert
@ 2021-09-08 15:14 ` Bruno Haible
2021-09-08 15:40 ` Bruno Haible
2021-09-18 14:49 ` Bruno Haible
2022-01-04 12:22 ` Bruno Haible
2 siblings, 1 reply; 6+ messages in thread
From: Bruno Haible @ 2021-09-08 15:14 UTC (permalink / raw)
To: bug-gnulib, landfillbaby69; +Cc: Paul Eggert
Hi Paul,
> * lib/string.in.h, lib/wchar.in.h:
> (free): Declare by hand instead of including stdlib.h.
This does not look right to me. There are two cases:
(A) REPLACE_FREE is 0. Then it is OK to declare it by hand, because gnulib
uses the system's free() function.
(B) REPLACE_FREE is 1. (This is the case on most non-glibc systems.)
Then gnulib's <stdlib.h> overrides 'free', by doing
#define free rpl_free
This means that the system's free() function is no longer visible after
some user code does '#include <stdlib.h>'.
If the user code now does
#include <string.h>
#include <stdlib.h>
then Gnulib's <string.h> will have declared that the result of strdup()
(or rpl_strdup()) must be deallocated through the system's free()
function. But the user cannot access this function any more. So he will
get a GCC (≥ 11) warning always!
This would be avoided if the user code does the includes in the opposite
order:
#include <stdlib.h>
#include <string.h>
because then, strdup() gets associated with 'rpl_free', not the system's
'free'. But the user is free to arrange their #includes in the order
they want (except for <config.h> which must always come first).
> This avoids some namespace pollution.
Yes, avoiding namespace pollution is desirable. But so far I don't see how
to make it coexist with correct rpl_free handling.
Bruno
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] string, wchar: avoid some namespace pollution
2021-09-08 15:14 ` Bruno Haible
@ 2021-09-08 15:40 ` Bruno Haible
0 siblings, 0 replies; 6+ messages in thread
From: Bruno Haible @ 2021-09-08 15:40 UTC (permalink / raw)
To: bug-gnulib, Paul Eggert; +Cc: landfillbaby69
Oops, apologies, Paul. Your patch _does_ look correct.
(I should have read the entire patch, not just the ChangeLog entry.)
Bruno
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] string, wchar: avoid some namespace pollution
2021-09-08 0:56 [PATCH] string, wchar: avoid some namespace pollution Paul Eggert
2021-09-08 15:14 ` Bruno Haible
@ 2021-09-18 14:49 ` Bruno Haible
2021-09-23 14:44 ` Simon Josefsson via Gnulib discussion list
2022-01-04 12:22 ` Bruno Haible
2 siblings, 1 reply; 6+ messages in thread
From: Bruno Haible @ 2021-09-18 14:49 UTC (permalink / raw)
To: bug-gnulib, landfillbaby69; +Cc: Paul Eggert
Paul Eggert did on 2021-09-07:
> diff --git a/lib/string.in.h b/lib/string.in.h
> index fa2e40c25..6214b5578 100644
> --- a/lib/string.in.h
> +++ b/lib/string.in.h
> @@ -47,9 +47,6 @@
> /* NetBSD 5.0 mis-defines NULL. */
> #include <stddef.h>
>
> -/* Get free(). */
> -#include <stdlib.h>
> -
> /* MirBSD defines mbslen as a macro. */
> #if @GNULIB_MBSLEN@ && defined __MirBSD__
> # include <wchar.h>
> @@ -86,6 +83,12 @@
>
> /* The definition of _GL_WARN_ON_USE is copied here. */
>
> +/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
> +#if (@REPLACE_FREE@ && !defined free \
> + && !(defined __cplusplus && defined GNULIB_NAMESPACE))
> +# define free rpl_free
> +#endif
> +_GL_EXTERN_C void free (void *);
>
> /* Clear a block of memory. The compiler will not delete a call to
> this function, even if the block is dead after the call. */
Simon Josefsson reported in
<https://lists.gnu.org/archive/html/bug-gnulib/2021-09/msg00042.html>:
> since a few days libidn fails to
> build with a reference to rpl_free, that looks related to this thread
> and the recent gnulib changes for the free module:
>
> https://oss-fuzz-build-logs.storage.googleapis.com/log-002189ee-3c98-45b8-9bde-3bfb20317e9a.txt
Thanks for the heads-up, Simon. I debugged it, and indeed the cause is
in gnulib, not in libidn. The patch below fixes it.
The situation is as follows:
libidn makes two uses of gnulib-tool:
- one for subdirectory lib/gl/, with module 'free-posix' included
(indirectly),
- one for subdirectory gl/, with module 'free-posix' NOT included.
Accordingly, the stdlib.h files are correctly generated like this:
lib/gl/stdlib.h:
#if 1 /* because here, GNULIB_FREE_POSIX evaluates to 1 */
# if 1
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef free
# define free rpl_free
# endif
gl/stdlib.h:
#if 0 /* because here, GNULIB_FREE_POSIX evaluates to 0 */
# if 1
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef free
# define free rpl_free
# endif
In the compiled library, rpl_free is defined for use inside the library
but not from outside. (This is also correct: the library is namespace-
clean.)
$ nm ../lib/.libs/libidn.so | grep free
U free@@GLIBC_2.2.5
0000000000006ab0 T idn_free
0000000000008380 t rpl_free
The problem is that the generated gl/string.h does a '#define free rpl_free',
although it shouldn't. The "gcc ... -E -dD" output of the compilation unit
(outside the library) has
# 50 "../gl/string.h" 2 3
# 596 "../gl/string.h" 3
extern void free (void *);
#define free rpl_free
The newly added code snippet in string.h should not only test @REPLACE_FREE@
but also @GNULIB_FREE_POSIX@.
In general, the rule to remember is:
=====================================================================
Variables like REPLACE_XYZ can be tested
- in m4 code,
- in configure.ac snippets (that are part of a module),
- and in *.in.h files but *only* when guarded by a test of the
corresponding GNULIB_XYZ symbol.
=====================================================================
2021-09-18 Bruno Haible <bruno@clisp.org>
string, wchar: Don't cause link errors for rpl_free (regr. 2021-09-07).
* lib/string.in.h (free, rpl_free): Consider GNULIB_FREE_POSIX variable.
* lib/wchar.in.h (free, rpl_free): Likewise.
* m4/string_h.m4 (gl_STRING_H_REQUIRE_DEFAULTS): Require module
indicator variable initializations from the stdlib module.
* m4/wchar_h.m4 (gl_WCHAR_H_REQUIRE_DEFAULTS): Likewise.
* modules/string (Makefile.am): Substitute GNULIB_FREE_POSIX in string.h.
* modules/wchar (Makefile.am): Substitute GNULIB_FREE_POSIX in wchar.h.
diff --git a/lib/string.in.h b/lib/string.in.h
index 8977153c8..8d77ae380 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -84,12 +84,14 @@
/* The definition of _GL_WARN_ON_USE is copied here. */
/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
-#if (@REPLACE_FREE@ && !defined free \
- && !(defined __cplusplus && defined GNULIB_NAMESPACE))
_GL_EXTERN_C void free (void *);
-# define free rpl_free
-#endif
+#if @GNULIB_FREE_POSIX@
+# if (@REPLACE_FREE@ && !defined free \
+ && !(defined __cplusplus && defined GNULIB_NAMESPACE))
+# define free rpl_free
_GL_EXTERN_C void free (void *);
+# endif
+#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. */
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index acb9d4ea6..f13379ad8 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -147,12 +147,14 @@ typedef int rpl_mbstate_t;
#endif
/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
-#if (@REPLACE_FREE@ && !defined free \
- && !(defined __cplusplus && defined GNULIB_NAMESPACE))
_GL_EXTERN_C void free (void *);
-# define free rpl_free
-#endif
+#if @GNULIB_FREE_POSIX@
+# if (@REPLACE_FREE@ && !defined free \
+ && !(defined __cplusplus && defined GNULIB_NAMESPACE))
+# define free rpl_free
_GL_EXTERN_C void free (void *);
+# endif
+#endif
/* Convert a single-byte character to a wide character. */
#if @GNULIB_BTOWC@
diff --git a/m4/string_h.m4 b/m4/string_h.m4
index 80d1e5875..9871dac8b 100644
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -5,7 +5,7 @@
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 32
+# serial 33
# Written by Paul Eggert.
@@ -93,6 +93,8 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS],
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_STRDUP], [1])
])
m4_require(GL_MODULE_INDICATOR_PREFIX[_STRING_H_MODULE_INDICATOR_DEFAULTS])
+ dnl Make sure the shell variable for GNULIB_FREE_POSIX is initialized.
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS])
AC_REQUIRE([gl_STRING_H_DEFAULTS])
])
diff --git a/m4/wchar_h.m4 b/m4/wchar_h.m4
index 818b3192e..d69dbe67d 100644
--- a/m4/wchar_h.m4
+++ b/m4/wchar_h.m4
@@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
dnl Written by Eric Blake.
-# wchar_h.m4 serial 53
+# wchar_h.m4 serial 54
AC_DEFUN_ONCE([gl_WCHAR_H],
[
@@ -189,6 +189,8 @@ AC_DEFUN([gl_WCHAR_H_REQUIRE_DEFAULTS],
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_WCSDUP], [1])
])
m4_require(GL_MODULE_INDICATOR_PREFIX[_WCHAR_H_MODULE_INDICATOR_DEFAULTS])
+ dnl Make sure the shell variable for GNULIB_FREE_POSIX is initialized.
+ m4_require(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS])
AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
])
diff --git a/modules/string b/modules/string
index 306834591..e9c315399 100644
--- a/modules/string
+++ b/modules/string
@@ -75,6 +75,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H
-e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \
-e 's/@''GNULIB_MDA_MEMCCPY''@/$(GNULIB_MDA_MEMCCPY)/g' \
-e 's/@''GNULIB_MDA_STRDUP''@/$(GNULIB_MDA_STRDUP)/g' \
+ -e 's/@''GNULIB_FREE_POSIX''@/$(GNULIB_FREE_POSIX)/g' \
< $(srcdir)/string.in.h | \
sed -e 's|@''HAVE_EXPLICIT_BZERO''@|$(HAVE_EXPLICIT_BZERO)|g' \
-e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \
diff --git a/modules/wchar b/modules/wchar
index d34cb6a22..becd7968a 100644
--- a/modules/wchar
+++ b/modules/wchar
@@ -79,6 +79,7 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's/@''GNULIB_WCSWIDTH''@/$(GNULIB_WCSWIDTH)/g' \
-e 's/@''GNULIB_WCSFTIME''@/$(GNULIB_WCSFTIME)/g' \
-e 's/@''GNULIB_MDA_WCSDUP''@/$(GNULIB_MDA_WCSDUP)/g' \
+ -e 's/@''GNULIB_FREE_POSIX''@/$(GNULIB_FREE_POSIX)/g' \
< $(srcdir)/wchar.in.h | \
sed -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \
-e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] string, wchar: avoid some namespace pollution
2021-09-18 14:49 ` Bruno Haible
@ 2021-09-23 14:44 ` Simon Josefsson via Gnulib discussion list
0 siblings, 0 replies; 6+ messages in thread
From: Simon Josefsson via Gnulib discussion list @ 2021-09-23 14:44 UTC (permalink / raw)
To: Bruno Haible; +Cc: bug-gnulib
[-- Attachment #1: Type: text/plain, Size: 209 bytes --]
Bruno Haible <bruno@clisp.org> writes:
> Thanks for the heads-up, Simon. I debugged it, and indeed the cause is
> in gnulib, not in libidn. The patch below fixes it.
Thanks for debugging this Bruno!
/Simon
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 255 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] string, wchar: avoid some namespace pollution
2021-09-08 0:56 [PATCH] string, wchar: avoid some namespace pollution Paul Eggert
2021-09-08 15:14 ` Bruno Haible
2021-09-18 14:49 ` Bruno Haible
@ 2022-01-04 12:22 ` Bruno Haible
2 siblings, 0 replies; 6+ messages in thread
From: Bruno Haible @ 2022-01-04 12:22 UTC (permalink / raw)
To: bug-gnulib, Paul Eggert
Paul Eggert did this on 2021-09-07:
> * lib/string.in.h, lib/wchar.in.h:
> (free): Declare by hand instead of including stdlib.h.
> This avoids some namespace pollution.
Unfortunately, when compiling GNU libiconv (or GNU libunistring)
with MSVC, it causes this compilation error:
/home/bruno/msvc/compile cl -nologo -DHAVE_CONFIG_H -DEXEEXT=\".exe\" -I. -I../../srclib -I.. -I../lib -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1 -D_WIN32_WINNT=_WIN32_WINNT_WINXP -I/usr/local/msvc32/include -MD -c -o stat.obj `cygpath -w '../../srclib/stat.c'`
stat.c
C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\corecrt_malloc.h(85): error C2375: 'rpl_free': redefinition; different linkage
.\string.h(628): note: see declaration of 'rpl_free'
This was first reported in <https://stackoverflow.com/questions/70525755/> .
The problem is that if <stdlib.h> is not included at a certain point,
and we fiddle around with the 'free' declaration, and <stdlib.h> is
included later, we can easily get a compilation error due to inconsistent
declarations of free().
This patch fixes it.
2022-01-04 Bruno Haible <bruno@clisp.org>
string, wchar: Fix compilation error on MSVC (regression 2021-09-07).
* lib/string.in.h (free): Don't redeclare as rpl_free. Instead, redefine
_GL_ATTRIBUTE_DEALLOC_FREE to reference rpl_free directly.
* lib/wchar.in.h (free): Likewise.
diff --git a/lib/string.in.h b/lib/string.in.h
index 0c4aefcce..03e6a17a3 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -112,12 +112,26 @@
/* The definition of _GL_WARN_ON_USE is copied here. */
-/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
-_GL_EXTERN_C void free (void *);
+/* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though <stdlib.h> may not have
+ been included yet. */
#if @GNULIB_FREE_POSIX@
# if (@REPLACE_FREE@ && !defined free \
&& !(defined __cplusplus && defined GNULIB_NAMESPACE))
-# define free rpl_free
+/* We can't do '#define free rpl_free' here. */
+_GL_EXTERN_C void rpl_free (void *);
+# undef _GL_ATTRIBUTE_DEALLOC_FREE
+# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (rpl_free, 1)
+# else
+# if defined _MSC_VER
+_GL_EXTERN_C void __cdecl free (void *);
+# else
+_GL_EXTERN_C void free (void *);
+# endif
+# endif
+#else
+# if defined _MSC_VER
+_GL_EXTERN_C void __cdecl free (void *);
+# else
_GL_EXTERN_C void free (void *);
# endif
#endif
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index 4db98741a..d7792e5fb 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -175,12 +175,26 @@ typedef int rpl_mbstate_t;
# endif
#endif
-/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
-_GL_EXTERN_C void free (void *);
+/* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though <stdlib.h> may not have
+ been included yet. */
#if @GNULIB_FREE_POSIX@
# if (@REPLACE_FREE@ && !defined free \
&& !(defined __cplusplus && defined GNULIB_NAMESPACE))
-# define free rpl_free
+/* We can't do '#define free rpl_free' here. */
+_GL_EXTERN_C void rpl_free (void *);
+# undef _GL_ATTRIBUTE_DEALLOC_FREE
+# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (rpl_free, 1)
+# else
+# if defined _MSC_VER
+_GL_EXTERN_C void __cdecl free (void *);
+# else
+_GL_EXTERN_C void free (void *);
+# endif
+# endif
+#else
+# if defined _MSC_VER
+_GL_EXTERN_C void __cdecl free (void *);
+# else
_GL_EXTERN_C void free (void *);
# endif
#endif
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-01-04 12:23 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-08 0:56 [PATCH] string, wchar: avoid some namespace pollution Paul Eggert
2021-09-08 15:14 ` Bruno Haible
2021-09-08 15:40 ` Bruno Haible
2021-09-18 14:49 ` Bruno Haible
2021-09-23 14:44 ` Simon Josefsson via Gnulib discussion list
2022-01-04 12:22 ` Bruno Haible
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).