stdbool: avoid rejecting clang
[gnulib.git] / m4 / stdbool.m4
1 # Check for stdbool.h that conforms to C99.
2
3 dnl Copyright (C) 2002-2006, 2009-2010 Free Software Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
7
8 #serial 2
9
10 # Prepare for substituting <stdbool.h> if it is not supported.
11
12 AC_DEFUN([AM_STDBOOL_H],
13 [
14   AC_REQUIRE([AC_HEADER_STDBOOL])
15
16   # Define two additional variables used in the Makefile substitution.
17
18   if test "$ac_cv_header_stdbool_h" = yes; then
19     STDBOOL_H=''
20   else
21     STDBOOL_H='stdbool.h'
22   fi
23   AC_SUBST([STDBOOL_H])
24
25   if test "$ac_cv_type__Bool" = yes; then
26     HAVE__BOOL=1
27   else
28     HAVE__BOOL=0
29   fi
30   AC_SUBST([HAVE__BOOL])
31 ])
32
33 # AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future.
34 AC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H])
35
36 # This version of the macro is needed in autoconf <= 2.67.  Autoconf has
37 # it built in since 2.60, but we want the tweaks from the 2.68 version
38 # to avoid rejecting clang due to relying on extensions.
39
40 AC_DEFUN([AC_HEADER_STDBOOL],
41   [AC_CACHE_CHECK([for stdbool.h that conforms to C99],
42      [ac_cv_header_stdbool_h],
43      [AC_TRY_COMPILE(
44         [
45           #include <stdbool.h>
46           #ifndef bool
47            "error: bool is not defined"
48           #endif
49           #ifndef false
50            "error: false is not defined"
51           #endif
52           #if false
53            "error: false is not 0"
54           #endif
55           #ifndef true
56            "error: true is not defined"
57           #endif
58           #if true != 1
59            "error: true is not 1"
60           #endif
61           #ifndef __bool_true_false_are_defined
62            "error: __bool_true_false_are_defined is not defined"
63           #endif
64
65           struct s { _Bool s: 1; _Bool t; } s;
66
67           char a[true == 1 ? 1 : -1];
68           char b[false == 0 ? 1 : -1];
69           char c[__bool_true_false_are_defined == 1 ? 1 : -1];
70           char d[(bool) 0.5 == true ? 1 : -1];
71           bool e = &s;
72           char f[(_Bool) 0.0 == false ? 1 : -1];
73           char g[true];
74           char h[sizeof (_Bool)];
75           char i[sizeof s.t];
76           enum { j = false, k = true, l = false * true, m = true * 256 };
77           _Bool n[m];
78           char o[sizeof n == m * sizeof n[0] ? 1 : -1];
79           char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
80           #ifdef __xlc__
81            /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0
82               reported by James Lemley on 2005-10-05; see
83               http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
84               This test is not quite right, since xlc is allowed to
85               reject this program, as the initializer for xlcbug is
86               not one of the forms that C requires support for.
87               However, doing the test right would require a run-time
88               test, and that would make cross-compilation harder.
89               Let us hope that IBM fixes the xlc bug, and also adds
90               support for this kind of constant expression.  In the
91               meantime, this test will reject xlc, which is OK, since
92               our stdbool.h substitute should suffice.  We also test
93               in test-stdbool.c to ensure nothing else messes up.  */
94            char digs[] = "0123456789";
95            int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : 0);
96           #endif
97           /* Catch a bug in an HP-UX C compiler.  See
98              http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
99              http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
100            */
101           _Bool q = true;
102           _Bool *pq = &q;
103         ],
104         [
105           *pq |= q;
106           *pq |= ! q;
107           /* Refer to every declared value, to avoid compiler optimizations.  */
108           return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
109                   + !m + !n + !o + !p + !q + !pq);
110         ],
111         [ac_cv_header_stdbool_h=yes],
112         [ac_cv_header_stdbool_h=no])])
113    AC_CHECK_TYPES([_Bool])
114    if test $ac_cv_header_stdbool_h = yes; then
115      AC_DEFINE([HAVE_STDBOOL_H], [1], [Define to 1 if stdbool.h conforms to C99.])
116    fi])