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

Reply via email to