From daba2833be01f39982742b9bcdbbd1319be157aa Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 17 Aug 2017 01:59:11 +0200 Subject: [PATCH] stdnoreturn: Fix test compilation failure on Cygwin. * m4/stdnoreturn.m4 (gl_STDNORETURN_H): On Cygwin, use gnulib's replacement. * lib/stdnoreturn.in.h (noreturn): Treat Cygwin like MSVC. * doc/posix-headers/stdnoreturn.texi: Mention the Cygwin problem. --- ChangeLog | 8 ++++ doc/posix-headers/stdnoreturn.texi | 14 +++---- lib/stdnoreturn.in.h | 28 ++++++++----- m4/stdnoreturn.m4 | 64 +++++++++++++++++------------- 4 files changed, 71 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce77753c91..d073889887 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2017-08-16 Bruno Haible + + stdnoreturn: Fix test compilation failure on Cygwin. + * m4/stdnoreturn.m4 (gl_STDNORETURN_H): On Cygwin, use gnulib's + replacement. + * lib/stdnoreturn.in.h (noreturn): Treat Cygwin like MSVC. + * doc/posix-headers/stdnoreturn.texi: Mention the Cygwin problem. + 2017-08-16 Bruno Haible thread: Fix conflict with pthread_sigmask module. diff --git a/doc/posix-headers/stdnoreturn.texi b/doc/posix-headers/stdnoreturn.texi index dc20b61729..6574d4a59e 100644 --- a/doc/posix-headers/stdnoreturn.texi +++ b/doc/posix-headers/stdnoreturn.texi @@ -27,13 +27,13 @@ When the macro @code{lint} is defined, standard headers define expands to the empty token sequence on some platforms: Cygwin 2.5.1, FreeBSD 10.3. @item -On MSVC 14, @code{noreturn} expands to the empty token sequence, to avoid -problems with standard headers that use @code{__declspec (noreturn)} -directly. Although the resulting code operates correctly, the -compiler is not informed whether @code{noreturn} functions do not -return, so it may generate incorrect warnings at compile-time, or code -that is slightly less optimized. This problem does not occur with -@code{_Noreturn}. +On Cygwin 1.7.30 and MSVC 14, @code{noreturn} expands to the empty token +sequence, to avoid problems with standard headers that use @code{noreturn} +in combination with @code{__attribute__} or @code{__declspec}. Although +the resulting code operates correctly, the compiler is not informed whether +@code{noreturn} functions do not return, so it may generate incorrect +warnings at compile-time, or code that is slightly less optimized. This +problem does not occur with @code{_Noreturn}. @item Circa 2012 bleeding-edge GCC with @code{-Werror=old-style-declaration} requires @code{_Noreturn} or @code{noreturn} before the returned type diff --git a/lib/stdnoreturn.in.h b/lib/stdnoreturn.in.h index 9b25a56376..445c227c66 100644 --- a/lib/stdnoreturn.in.h +++ b/lib/stdnoreturn.in.h @@ -28,15 +28,25 @@ /* The definition of _Noreturn is copied here. */ -#if 1200 <= _MSC_VER -/* Standard include files on this platform contain declarations like - "__declspec (noreturn) void abort (void);". "#define noreturn - _Noreturn" would cause this declaration to be rewritten to the - invalid "__declspec (__declspec (noreturn)) void abort (void);". - Instead, define noreturn to empty, so that such declarations are - rewritten to "__declspec () void abort (void);", which is - equivalent to "void abort (void);"; this gives up on noreturn's - advice to the compiler but at least it is valid code. */ +#if 1200 <= _MSC_VER || defined __CYGWIN__ +/* On MSVC, standard include files contain declarations like + __declspec (noreturn) void abort (void); + "#define noreturn _Noreturn" would cause this declaration to be rewritten + to the invalid + __declspec (__declspec (noreturn)) void abort (void); + + Similarly, on Cygwin, standard include files contain declarations like + void __cdecl abort (void) __attribute__ ((noreturn)); + "#define noreturn _Noreturn" would cause this declaration to be rewritten + to the invalid + void __cdecl abort (void) __attribute__ ((__attribute__ ((__noreturn__)))); + + Instead, define noreturn to empty, so that such declarations are rewritten to + __declspec () void abort (void); + or + void __cdecl abort (void) __attribute__ (()); + respectively. This gives up on noreturn's advice to the compiler but at + least it is valid code. */ # define noreturn /*empty*/ #else # define noreturn _Noreturn diff --git a/m4/stdnoreturn.m4 b/m4/stdnoreturn.m4 index 9d70b3716b..ea4d73530b 100644 --- a/m4/stdnoreturn.m4 +++ b/m4/stdnoreturn.m4 @@ -9,33 +9,43 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_STDNORETURN_H], [ - AC_CACHE_CHECK([for working stdnoreturn.h], - [gl_cv_header_working_stdnoreturn_h], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #include - /* Do not check for 'noreturn' after the return type. - C11 allows it, but it's rarely done that way - and circa-2012 bleeding-edge GCC rejects it when given - -Werror=old-style-declaration. */ - noreturn void foo1 (void) { exit (0); } - _Noreturn void foo2 (void) { exit (0); } - int testit (int argc, char **argv) { - if (argc & 1) - return 0; - (argv[0][0] ? foo1 : foo2) (); - } - ]])], - [gl_cv_header_working_stdnoreturn_h=yes], - [gl_cv_header_working_stdnoreturn_h=no])]) - - if test $gl_cv_header_working_stdnoreturn_h = yes; then - STDNORETURN_H='' - else - STDNORETURN_H='stdnoreturn.h' - fi - + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + cygwin*) + dnl Regardless whether a working exists or not, + dnl we need our own , because of the definition + dnl of _Noreturn done by gnulib-common.m4. + STDNORETURN_H='stdnoreturn.h' + ;; + *) + AC_CACHE_CHECK([for working stdnoreturn.h], + [gl_cv_header_working_stdnoreturn_h], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + /* Do not check for 'noreturn' after the return type. + C11 allows it, but it's rarely done that way + and circa-2012 bleeding-edge GCC rejects it when given + -Werror=old-style-declaration. */ + noreturn void foo1 (void) { exit (0); } + _Noreturn void foo2 (void) { exit (0); } + int testit (int argc, char **argv) + { + if (argc & 1) + return 0; + (argv[0][0] ? foo1 : foo2) (); + } + ]])], + [gl_cv_header_working_stdnoreturn_h=yes], + [gl_cv_header_working_stdnoreturn_h=no])]) + if test $gl_cv_header_working_stdnoreturn_h = yes; then + STDNORETURN_H='' + else + STDNORETURN_H='stdnoreturn.h' + fi + ;; + esac AC_SUBST([STDNORETURN_H]) AM_CONDITIONAL([GL_GENERATE_STDNORETURN_H], [test -n "$STDNORETURN_H"]) ]) -- 2.39.5