On 2023-06-02 15:03, Paul Eggert wrote:
How about changing this to use __builtin_constant_p instead of
__OPTIMIZE__? I.e., use the comma expression if __builtin_constant_p
(status), and use the statement expression otherwise.
I gave that a shot by installing the attached.
From cfd41b3ac199a4f95fb78ee251e8c8a7c6f86ad1 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Fri, 2 Jun 2023 22:30:52 -0700
Subject: [PATCH] error: do not evaluate status twice
Do this in a different way, so that the status is evaluated
once even when not optimizing and when using GCC.
* lib/error.in.h (__gl_error_call1) [__GNUC__]: New macro.
(__gl_error_call) [__GNUC__]: Use it.
---
ChangeLog | 8 ++++++++
lib/error.in.h | 27 ++++++++++++---------------
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 3187128c1f..fda2ed0e3f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2023-06-02 Paul Eggert <egg...@cs.ucla.edu>
+
+ error: do not evaluate status twice
+ Do this in a different way, so that the status is evaluated
+ once even when not optimizing and when using GCC.
+ * lib/error.in.h (__gl_error_call1) [__GNUC__]: New macro.
+ (__gl_error_call) [__GNUC__]: Use it.
+
2023-06-02 Bruno Haible <br...@clisp.org>
warnings: Add ability to inhibit all warnings.
diff --git a/lib/error.in.h b/lib/error.in.h
index f37dba170c..279258f63e 100644
--- a/lib/error.in.h
+++ b/lib/error.in.h
@@ -50,23 +50,20 @@
#endif
/* Helper macro for supporting the compiler's control flow analysis better.
+ It evaluates its arguments only once. It uses __builtin_constant_p
+ and comma expressions to work around GCC false positives.
Test case: Compile copy-file.c with "gcc -Wimplicit-fallthrough". */
#ifdef __GNUC__
-/* Avoid evaluating STATUS twice, if this is possible without making the
- "warning: this statement may fall through" reappear. */
-# if __OPTIMIZE__
-# define __gl_error_call(function, status, ...) \
- ({ \
- int const __errstatus = (status); \
- (function) (__errstatus, __VA_ARGS__); \
- __errstatus != 0 ? unreachable () : (void) 0; \
- })
-# else
-# define __gl_error_call(function, status, ...) \
- ((function) (status, __VA_ARGS__), \
- (status) != 0 ? unreachable () : (void)0 \
- )
-# endif
+# define __gl_error_call1(function, status, ...) \
+ ((function) (status, __VA_ARGS__), \
+ (status) != 0 ? unreachable () : (void) 0)
+# define __gl_error_call(function, status, ...) \
+ (__builtin_constant_p (status) \
+ ? __gl_error_call1 (function, status, __VA_ARGS__) \
+ : ({ \
+ int const __errstatus = status; \
+ __gl_error_call1 (function, __errstatus, __VA_ARGS__); \
+ }))
#else
# define __gl_error_call(function, status, ...) \
(function) (status, __VA_ARGS__)
--
2.39.2