+2023-09-04 Bruno Haible <bruno@clisp.org>
+
+ Use statement-expressions without warnings, even in strict ISO C mode.
+ Suggested by Eric Blake <eblake@redhat.com> in
+ <https://lists.gnu.org/archive/html/bug-gnulib/2023-09/msg00025.html>.
+ * lib/error.in.h (__gl_error_call): Use the variant with obvious control
+ flow also with clang. Use '__extension__' to avoid -Wpedantic warnings.
+ * lib/math.in.h (gl_signbitf, gl_signbitd, gl_signbitl): Define as
+ macros even when __STRICT_ANSI__ is defined. But use '__extension__' to
+ avoid -Wpedantic warnings.
+ * lib/setenv.c (KNOWN_VALUE): Use '__extension__' to avoid -Wpedantic
+ warnings.
+ * lib/xalloc-oversized.h (xalloc_oversized): Use optimized variant even
+ when __STRICT_ANSI__ is defined. But use '__extension__' to avoid
+ -Wpedantic warnings.
+
2023-09-04 Bruno Haible <bruno@clisp.org>
Fix some g++ warnings "has a different exception specifier".
/* Helper macro for supporting the compiler's control flow analysis better.
It evaluates its arguments only once.
Test case: Compile copy-file.c with "gcc -Wimplicit-fallthrough". */
-#ifdef __GNUC__
+#if defined __GNUC__ || defined __clang__
/* Use 'unreachable' to tell the compiler when the function call does not
return. */
# define __gl_error_call1(function, status, ...) \
would trigger a -Wimplicit-fallthrough warning even when STATUS is != 0,
when not optimizing. This causes STATUS to be evaluated twice, but
that's OK since it does not have side effects. */
-# define __gl_error_call(function, status, ...) \
- (__builtin_constant_p (status) \
- ? __gl_error_call1 (function, status, __VA_ARGS__) \
- : ({ \
- int const __errstatus = status; \
+# define __gl_error_call(function, status, ...) \
+ (__builtin_constant_p (status) \
+ ? __gl_error_call1 (function, status, __VA_ARGS__) \
+ : __extension__ \
+ ({ \
+ int const __errstatus = status; \
__gl_error_call1 (function, __errstatus, __VA_ARGS__); \
}))
#else
_GL_EXTERN_C int gl_signbitf (float arg);
_GL_EXTERN_C int gl_signbitd (double arg);
_GL_EXTERN_C int gl_signbitl (long double arg);
-# if (__GNUC__ >= 2 || defined __clang__) && !defined __STRICT_ANSI__
+# if __GNUC__ >= 2 || defined __clang__
# define _GL_NUM_UINT_WORDS(type) \
((sizeof (type) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
# if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT && !defined gl_signbitf
# define gl_signbitf_OPTIMIZED_MACRO
# define gl_signbitf(arg) \
+ __extension__ \
({ union { float _value; \
unsigned int _word[_GL_NUM_UINT_WORDS (float)]; \
} _m; \
# if defined DBL_SIGNBIT_WORD && defined DBL_SIGNBIT_BIT && !defined gl_signbitd
# define gl_signbitd_OPTIMIZED_MACRO
# define gl_signbitd(arg) \
+ __extension__ \
({ union { double _value; \
unsigned int _word[_GL_NUM_UINT_WORDS (double)]; \
} _m; \
# if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT && !defined gl_signbitl
# define gl_signbitl_OPTIMIZED_MACRO
# define gl_signbitl(arg) \
+ __extension__ \
({ union { long double _value; \
unsigned int _word[_GL_NUM_UINT_WORDS (long double)]; \
} _m; \
static void *known_values;
# define KNOWN_VALUE(Str) \
+ __extension__ \
({ \
void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \
value != NULL ? *(char **) value : NULL; \
#if 7 <= __GNUC__ && !defined __clang__ && PTRDIFF_MAX < SIZE_MAX
# define xalloc_oversized(n, s) \
__builtin_mul_overflow_p (n, s, (ptrdiff_t) 1)
-#elif (5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__ \
- && PTRDIFF_MAX < SIZE_MAX)
+#elif 5 <= __GNUC__ && !defined __ICC && PTRDIFF_MAX < SIZE_MAX
# define xalloc_oversized(n, s) \
(__builtin_constant_p (n) && __builtin_constant_p (s) \
? __xalloc_oversized (n, s) \
- : ({ ptrdiff_t __xalloc_count; \
- __builtin_mul_overflow (n, s, &__xalloc_count); }))
+ : __extension__ \
+ ({ ptrdiff_t __xalloc_count; \
+ __builtin_mul_overflow (n, s, &__xalloc_count); }))
/* Other compilers use integer division; this may be slower but is
more portable. */