Hi Paul,
On 5/16/24 10:16 PM, Paul Eggert wrote:
>> +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) \
>> + || (defined __has_builtin && __has_builtin (__builtin_bswap32))
>
> Unfortunately this usage is not portable, not for __has_builtin or for any of
> the other __has_XX primitives. This is because older compilers will replace
> "defined __has_builtin && __has_builtin (__builtin_bswap32)" with "1 && 0
> (__builtin_bswap32)" and then complain about the bad syntax.
Oops, I wasn't aware of this. Was that a bug in old versions?
> You can safely use __has_builtin (X) only inside a block that is protected by
> checking that __has_builtin is defined. See stdbit.in.h for an example.
I've applied the attached patch. It should be pretty the same method
as stdbit.in.h.
I'm assuming that _GL_[module-name]_(rest-of-macro) can be assumed
safe?
Collin
From 73541d459cdd964e71f40ad447e50a7253a6f20d Mon Sep 17 00:00:00 2001
From: Collin Funk <collin.fu...@gmail.com>
Date: Thu, 16 May 2024 23:18:16 -0700
Subject: [PATCH] byteswap: Use __has_builtin portably.
Reported by Paul Eggert in
<https://lists.gnu.org/archive/html/bug-gnulib/2024-05/msg00249.html>.
* lib/byteswap.in.h (_GL_BYTESWAP_HAS_BUILTIN_BSWAP16)
(_GL_BYTESWAP_HAS_BUILTIN_BSWAP32)
(_GL_BYTESWAP_HAS_BUILTIN_BSWAP64): Define using the GCC version or
__has_builtin after checking that it is defined.
(bswap_16, bswap_32, bswap_64): Use the macros.
* modules/byteswap (Depends-on): Add stdbool as a conditional
dependency.
---
ChangeLog | 13 +++++++++++++
lib/byteswap.in.h | 29 +++++++++++++++++++++++------
modules/byteswap | 1 +
3 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5238067cf9..742a20d012 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2024-05-16 Collin Funk <collin.fu...@gmail.com>
+
+ byteswap: Use __has_builtin portably.
+ Reported by Paul Eggert in
+ <https://lists.gnu.org/archive/html/bug-gnulib/2024-05/msg00249.html>.
+ * lib/byteswap.in.h (_GL_BYTESWAP_HAS_BUILTIN_BSWAP16)
+ (_GL_BYTESWAP_HAS_BUILTIN_BSWAP32)
+ (_GL_BYTESWAP_HAS_BUILTIN_BSWAP64): Define using the GCC version or
+ __has_builtin after checking that it is defined.
+ (bswap_16, bswap_32, bswap_64): Use the macros.
+ * modules/byteswap (Depends-on): Add stdbool as a conditional
+ dependency.
+
2024-05-16 Paul Eggert <egg...@cs.ucla.edu>
putenv-tests: pacify gcc -Wdiscarded-qualifiers
diff --git a/lib/byteswap.in.h b/lib/byteswap.in.h
index cfa3f04031..ae05d59441 100644
--- a/lib/byteswap.in.h
+++ b/lib/byteswap.in.h
@@ -34,13 +34,32 @@ _GL_INLINE_HEADER_BEGIN
extern "C" {
#endif
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP16 true
+#elif defined __has_builtin
+# if __has_builtin (__builtin_bswap16)
+# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP16 true
+# endif
+#endif
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP32 true
+# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP64 true
+#elif defined __has_builtin
+# if __has_builtin (__builtin_bswap32)
+# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP32 true
+# endif
+# if __has_builtin (__builtin_bswap64)
+# define _GL_BYTESWAP_HAS_BUILTIN_BSWAP64 true
+# endif
+#endif
+
/* Given an unsigned 16-bit argument X, return the value corresponding to
X with reversed byte order. */
_GL_BYTESWAP_INLINE uint16_t
bswap_16 (uint16_t x)
{
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) \
- || (defined __has_builtin && __has_builtin (__builtin_bswap16))
+#ifdef _GL_BYTESWAP_HAS_BUILTIN_BSWAP16
return __builtin_bswap16 (x);
#else
return (((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)));
@@ -52,8 +71,7 @@ bswap_16 (uint16_t x)
_GL_BYTESWAP_INLINE uint32_t
bswap_32 (uint32_t x)
{
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) \
- || (defined __has_builtin && __has_builtin (__builtin_bswap32))
+#ifdef _GL_BYTESWAP_HAS_BUILTIN_BSWAP32
return __builtin_bswap32 (x);
#else
return ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8)
@@ -66,8 +84,7 @@ bswap_32 (uint32_t x)
_GL_BYTESWAP_INLINE uint64_t
bswap_64 (uint64_t x)
{
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) \
- || (defined __has_builtin && __has_builtin (__builtin_bswap64))
+#ifdef _GL_BYTESWAP_HAS_BUILTIN_BSWAP64
return __builtin_bswap64 (x);
#else
return ((((x) & 0xff00000000000000ull) >> 56)
diff --git a/modules/byteswap b/modules/byteswap
index 82fe424a61..6e777a699b 100644
--- a/modules/byteswap
+++ b/modules/byteswap
@@ -9,6 +9,7 @@ m4/byteswap.m4
Depends-on:
gen-header
extern-inline [$GL_GENERATE_BYTESWAP_H]
+stdbool [$GL_GENERATE_BYTESWAP_H]
stdint [$GL_GENERATE_BYTESWAP_H]
configure.ac:
--
2.45.0