bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

stdnoreturn: fix for Cygwin


From: Bruno Haible
Subject: stdnoreturn: fix for Cygwin
Date: Thu, 17 Aug 2017 02:01:31 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-91-generic; KDE/5.18.0; x86_64; ; )

On Cygwin 1.7.30, I'm seeing this testdir build failure, when compiling
test-stdnoreturn.c:

/usr/include/stdlib.h:66:28: error: expected ‘,’ or ‘;’ before ‘)’ token
 _VOID _EXFUN(abort,(_VOID) _ATTRIBUTE ((noreturn)));
                            ^

Similarly on Cygwin 1.5.25:

In file included from ../gllib/stdlib.h:36,
                 from ../../gltests/test-stdnoreturn.c:23:
/usr/include/stdlib.h:61: error: parse error before "__attribute__"
/usr/include/stdlib.h:61: error: parse error before ')' token

However, the situation is not exactly the same:
  * On Cygwin 1.5.25, there is no standard <stdnoreturn.h>, so gnulib provides
    its own one.
  * On Cygwin 1.7.30, GCC comes with a <stdnoreturn.h>, but it does the same
    thing: "#define noreturn _Noreturn".
In both cases, the problem is the definition introduced by gnulib
(through config.h):
  #define _Noreturn __attribute__ ((__noreturn__))

This patch fixes both cases.


2017-08-16  Bruno Haible  <address@hidden>

        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.

diff --git a/doc/posix-headers/stdnoreturn.texi 
b/doc/posix-headers/stdnoreturn.texi
index dc20b61..6574d4a 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
address@hidden
+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
address@hidden 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 9b25a56..445c227 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 9d70b37..ea4d735 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 <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"])
 ])




reply via email to

[Prev in Thread] Current Thread [Next in Thread]