From 8b21ff255996a518244a5635e36ea58e21f818be Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 30 May 2023 12:49:20 -0700 Subject: [PATCH] =?utf8?q?error:=20don=E2=80=99t=20evaluate=20status=20arg?= =?utf8?q?=20twice?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This avoids potential issues if the first argument has a side effect. * lib/error.in.h (__gl_error_call): New macro, which evaluates its status arg only once, by using a statement expression if GNU C - the only platform we need to worry about pacifying - and by simply calling ‘error’ otherwise. (error, error_at_line): Use it. --- ChangeLog | 10 ++++++++++ lib/error.in.h | 20 ++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91a6135f8a..f70eeef893 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2023-05-30 Paul Eggert + + error: don’t evaluate status arg twice + This avoids potential issues if the first argument has a side effect. + * lib/error.in.h (__gl_error_call): New macro, which evaluates its + status arg only once, by using a statement expression if GNU C - + the only platform we need to worry about pacifying - and by simply + calling ‘error’ otherwise. + (error, error_at_line): Use it. + 2023-05-28 Bruno Haible warnings, manywarnings: Assume autoconf >= 2.64. diff --git a/lib/error.in.h b/lib/error.in.h index 70fb132133..a5f49e4143 100644 --- a/lib/error.in.h +++ b/lib/error.in.h @@ -49,6 +49,18 @@ # define _GL_ATTRIBUTE_SPEC_PRINTF_ERROR _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM #endif +#ifdef __GNUC__ +# define __gl_error_call(function, status, ...) \ + ({ \ + int const __errstatus = status; \ + (function) (0, __VA_ARGS__); \ + __errstatus != 0 ? exit (__errstatus) : (void) 0; \ + }) +#else +# define __gl_error_call(function, status, ...) \ + (function) (status, __VA_ARGS__) +#endif + #ifdef __cplusplus extern "C" { #endif @@ -69,7 +81,7 @@ _GL_CXXALIAS_RPL (error, void, # ifndef _GL_NO_INLINE_ERROR # undef error # define error(status, ...) \ - ((rpl_error)(0, __VA_ARGS__), (status) != 0 ? exit (status) : (void)0) + __gl_error_call (rpl_error, status, __VA_ARGS) # endif #else # if ! @HAVE_ERROR@ @@ -81,7 +93,7 @@ _GL_CXXALIAS_SYS (error, void, (int __status, int __errnum, const char *__format, ...)); # ifndef _GL_NO_INLINE_ERROR # define error(status, ...) \ - ((error)(0, __VA_ARGS__), (status) != 0 ? exit (status) : (void)0) + __gl_error_call (error, status, __VA_ARGS__) # endif #endif #if __GLIBC__ >= 2 @@ -105,7 +117,7 @@ _GL_CXXALIAS_RPL (error_at_line, void, # ifndef _GL_NO_INLINE_ERROR # undef error_at_line # define error_at_line(status, ...) \ - ((rpl_error_at_line)(0, __VA_ARGS__), (status) != 0 ? exit (status) : (void)0) + __gl_error_call (rpl_error_at_line, status, __VA_ARGS__) # endif #else # if ! @HAVE_ERROR_AT_LINE@ @@ -119,7 +131,7 @@ _GL_CXXALIAS_SYS (error_at_line, void, unsigned int __lineno, const char *__format, ...)); # ifndef _GL_NO_INLINE_ERROR # define error_at_line(status, ...) \ - ((error_at_line)(0, __VA_ARGS__), (status) != 0 ? exit (status) : (void)0) + __gl_error_call (error_at_line, status, __VA_ARGS__) # endif #endif _GL_CXXALIASWARN (error_at_line); -- 2.39.5