]> Savannah Git Hosting - gnulib.git/commitdiff
stdnoreturn: Fix test compilation failure on Cygwin.
authorBruno Haible <bruno@clisp.org>
Wed, 16 Aug 2017 23:59:11 +0000 (01:59 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 17 Aug 2017 00:00:04 +0000 (02:00 +0200)
* m4/stdnoreturn.m4 (gl_STDNORETURN_H): On Cygwin, use gnulib's
<stdnoreturn.h> replacement.
* lib/stdnoreturn.in.h (noreturn): Treat Cygwin like MSVC.
* doc/posix-headers/stdnoreturn.texi: Mention the Cygwin problem.

ChangeLog
doc/posix-headers/stdnoreturn.texi
lib/stdnoreturn.in.h
m4/stdnoreturn.m4

index ce77753c91809f0e36763879a2a3d6523884ec05..d073889887e29eb0158fc8a4cc8d6a687acc669d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2017-08-16  Bruno Haible  <bruno@clisp.org>
+
+       stdnoreturn: Fix test compilation failure on Cygwin.
+       * m4/stdnoreturn.m4 (gl_STDNORETURN_H): On Cygwin, use gnulib's
+       <stdnoreturn.h> replacement.
+       * lib/stdnoreturn.in.h (noreturn): Treat Cygwin like MSVC.
+       * doc/posix-headers/stdnoreturn.texi: Mention the Cygwin problem.
+
 2017-08-16  Bruno Haible  <bruno@clisp.org>
 
        thread: Fix conflict with pthread_sigmask module.
index dc20b617290b7d340573fa5d228932e260387bcc..6574d4a59ee951b68840ccd3f514a2537c96a717 100644 (file)
@@ -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
index 9b25a563769e23d6803e1b81253a2f6bb353dfa9..445c227c663ae10fb654a6be157dad1dce6b879b 100644 (file)
 
 /* 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
index 9d70b3716b0b5ec4368cfdd956b1f612941df611..ea4d73530b04cb49d067013c1415f2d2ca722ecd 100644 (file)
@@ -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 <stdlib.h>
-            #include <stdnoreturn.h>
-            /* 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 <stdnoreturn.h> exists or not,
+      dnl we need our own <stdnoreturn.h>, 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 <stdlib.h>
+                #include <stdnoreturn.h>
+                /* 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"])
 ])