* lib/error.in.h: Remove @PRAGMA_SYSTEM_HEADER@. Include <stdlib.h>.
(error): Define as a macro that explicitly invokes exit().
(error_at_line): Likewise.
* lib/error.c (_GL_NO_INLINE_ERROR): Define before including error.h.
* modules/error-h (configure.ac): Don't invoke gl_CONDITIONAL_HEADER.
(Makefile.am): Generate error.h always. Don't substitute
PRAGMA_SYSTEM_HEADER.
* m4/error_h.m4 (gl_ERROR_H): Set COMPILE_ERROR_C instead of
GL_GENERATE_ERROR_H.
* modules/error (configure.ac, Depends-on): Test COMPILE_ERROR_C instead
of GL_GENERATE_ERROR_H.
* lib/copy-file.c: Revert the last change.
+2023-05-27 Bruno Haible <bruno@clisp.org>
+
+ error: Support the compiler's control flow analysis better.
+ * lib/error.in.h: Remove @PRAGMA_SYSTEM_HEADER@. Include <stdlib.h>.
+ (error): Define as a macro that explicitly invokes exit().
+ (error_at_line): Likewise.
+ * lib/error.c (_GL_NO_INLINE_ERROR): Define before including error.h.
+ * modules/error-h (configure.ac): Don't invoke gl_CONDITIONAL_HEADER.
+ (Makefile.am): Generate error.h always. Don't substitute
+ PRAGMA_SYSTEM_HEADER.
+ * m4/error_h.m4 (gl_ERROR_H): Set COMPILE_ERROR_C instead of
+ GL_GENERATE_ERROR_H.
+ * modules/error (configure.ac, Depends-on): Test COMPILE_ERROR_C instead
+ of GL_GENERATE_ERROR_H.
+ * lib/copy-file.c: Revert the last change.
+
2023-05-26 Bruno Haible <bruno@clisp.org>
flexmember: Make it easier to use.
return err;
}
-/* Silence gcc warnings "this statement may fall through".
- gcc cannot know that error(), when invoked with a non-zero status argument,
- will not return. */
-#if __GNUC__ >= 7
-#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
-#endif
-
void
copy_file_preserving (const char *src_filename, const char *dest_filename)
{
#if !_LIBC
# include <config.h>
+# define _GL_NO_INLINE_ERROR
#endif
#include "error.h"
#ifndef _@GUARD_PREFIX@_ERROR_H
-#if __GNUC__ >= 3
-@PRAGMA_SYSTEM_HEADER@
-#endif
+/* No @PRAGMA_SYSTEM_HEADER@ here, because it would prevent
+ -Wimplicit-fallthrough warnings for missing FALLTHROUGH after error(...)
+ or error_at_line(...) invocations. */
/* The include_next requires a split double-inclusion guard. */
#if @HAVE_ERROR_H@
/* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM. */
#include <stdio.h>
+/* Get exit(). */
+#include <stdlib.h>
+
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
#if GNULIB_VFPRINTF_POSIX
_GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4)));
_GL_CXXALIAS_RPL (error, void,
(int __status, int __errnum, const char *__format, ...));
+# ifndef _GL_NO_INLINE_ERROR
+# undef error
+# define error(status, ...) \
+ ((rpl_error)(0, __VA_ARGS__), (status) ? exit (status) : (void)0)
+# endif
#else
# if ! @HAVE_ERROR@
_GL_FUNCDECL_SYS (error, void,
# endif
_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) ? exit (status) : (void)0)
+# endif
#endif
#if __GLIBC__ >= 2
_GL_CXXALIASWARN (error);
_GL_CXXALIAS_RPL (error_at_line, void,
(int __status, int __errnum, const char *__filename,
unsigned int __lineno, const char *__format, ...));
+# ifndef _GL_NO_INLINE_ERROR
+# undef error_at_line
+# define error_at_line(status, ...) \
+ ((rpl_error_at_line)(0, __VA_ARGS__), (status) ? exit (status) : (void)0)
+# endif
#else
# if ! @HAVE_ERROR_AT_LINE@
_GL_FUNCDECL_SYS (error_at_line, void,
_GL_CXXALIAS_SYS (error_at_line, void,
(int __status, int __errnum, const char *__filename,
unsigned int __lineno, const char *__format, ...));
+# ifndef _GL_NO_INLINE_ERROR
+# define error_at_line(status, ...) \
+ ((error_at_line)(0, __VA_ARGS__), (status) ? exit (status) : (void)0)
+# endif
#endif
_GL_CXXALIASWARN (error_at_line);
-# error_h.m4 serial 3
+# error_h.m4 serial 4
dnl Copyright (C) 1996-2023 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
if test $HAVE_ERROR = 0 || test $REPLACE_ERROR = 1 \
|| test $HAVE_ERROR_AT_LINE = 0 || test $REPLACE_ERROR_AT_LINE = 1; then
- dnl Provide a substitute <error.h> file.
- GL_GENERATE_ERROR_H=true
+ COMPILE_ERROR_C=1
else
- GL_GENERATE_ERROR_H=false
+ COMPILE_ERROR_C=0
fi
AC_SUBST([HAVE_ERROR])
error-h
stdio
getprogname
-strerror [test $GL_GENERATE_ERROR_H = true]
-unistd [test $GL_GENERATE_ERROR_H = true]
-msvc-nothrow [test $GL_GENERATE_ERROR_H = true]
+strerror [test $COMPILE_ERROR_C = 1]
+unistd [test $COMPILE_ERROR_C = 1]
+msvc-nothrow [test $COMPILE_ERROR_C = 1]
configure.ac:
AC_REQUIRE([gl_ERROR_H])
gl_ERROR
-gl_CONDITIONAL([GL_COND_OBJ_ERROR], [test $GL_GENERATE_ERROR_H = true])
+gl_CONDITIONAL([GL_COND_OBJ_ERROR], [test $COMPILE_ERROR_C = 1])
AM_COND_IF([GL_COND_OBJ_ERROR], [
gl_PREREQ_ERROR
])
configure.ac:
gl_ERROR_H
-gl_CONDITIONAL_HEADER([error.h])
AC_PROG_MKDIR_P
Makefile.am:
-BUILT_SOURCES += $(ERROR_H)
+BUILT_SOURCES += error.h
-# We need the following in order to create <error.h> when the system
-# doesn't have one that works.
-if GL_GENERATE_ERROR_H
+# We need the following in order to override <error.h>.
error.h: error.in.h $(top_builddir)/config.status $(CXXDEFS_H)
@NMD@ $(AM_V_GEN)$(MKDIR_P) '%reldir%'
$(gl_V_at)$(SED_HEADER_STDOUT) \
-e 's|@''GUARD_PREFIX''@|${gl_include_guard_prefix}|g' \
-e 's|@''HAVE_ERROR_H''@|$(HAVE_ERROR_H)|g' \
-e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
- -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''NEXT_ERROR_H''@|$(NEXT_ERROR_H)|g' \
-e 's|@''HAVE_ERROR''@|$(HAVE_ERROR)|g' \
-e 's|@''HAVE_ERROR_AT_LINE''@|$(HAVE_ERROR_AT_LINE)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
$(srcdir)/error.in.h > $@-t
$(AM_V_at)mv $@-t $@
-else
-error.h: $(top_builddir)/config.status
- rm -f $@
-endif
MOSTLYCLEANFILES += error.h error.h-t
Include: