mirror of
git://git.sv.gnu.org/autoconf
synced 2025-02-11 13:51:04 +08:00
Disentangle HAVE__BOOL from ac_cv_header_stdbool_h.
AC_CHECK_HEADER_STDBOOL is documented to make two checks: whether the C99 header <stdbool.h> is available and fulfills its specification (i.e. including it makes the type ‘bool’ and the constants ‘true’ and ‘false’ available), and, independently, whether the type ‘_Bool’ is available. In C++, the type ‘_Bool’ is usually _not_ available, but <stdbool.h> is still supposed to be include-able and the type ‘bool’ and the constants ‘true’ and ‘false’ are still supposed to be available (unconditionally). However, the test for <stdbool.h> fulfilling its specification freely used _Bool, and would therefore fail spuriously. Correct this by checking for _Bool first, and then refactoring the test program for <stdbool.h> so that it does all its tests using bool, then repeats them with _Bool only when available. * lib/autoconf/headers.m4 (AC_CHECK_HEADER_STDBOOL): Do the test for _Bool before the test for stdbool.h. Test semantics of bool unconditionally; test _Bool only when HAVE__BOOL is defined.
This commit is contained in:
parent
d81861ed01
commit
9886b7a922
@ -574,70 +574,114 @@ AN_IDENTIFIER([bool], [AC_CHECK_HEADER_STDBOOL])
|
||||
AN_IDENTIFIER([true], [AC_CHECK_HEADER_STDBOOL])
|
||||
AN_IDENTIFIER([false],[AC_CHECK_HEADER_STDBOOL])
|
||||
AC_DEFUN([AC_CHECK_HEADER_STDBOOL],
|
||||
[AC_CACHE_CHECK([for stdbool.h that conforms to C99],
|
||||
[AC_CHECK_TYPES([_Bool])
|
||||
AC_CACHE_CHECK([for stdbool.h that conforms to C99],
|
||||
[ac_cv_header_stdbool_h],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[
|
||||
#include <stdbool.h>
|
||||
|
||||
#if __cplusplus < 201103
|
||||
#ifndef bool
|
||||
"error: bool is not defined"
|
||||
#endif
|
||||
#ifndef false
|
||||
"error: false is not defined"
|
||||
#endif
|
||||
#if false
|
||||
"error: false is not 0"
|
||||
#endif
|
||||
#ifndef true
|
||||
"error: true is not defined"
|
||||
#endif
|
||||
#if true != 1
|
||||
"error: true is not 1"
|
||||
#endif
|
||||
#endif
|
||||
[[#include <stdbool.h>
|
||||
|
||||
#ifndef __bool_true_false_are_defined
|
||||
"error: __bool_true_false_are_defined is not defined"
|
||||
#error "__bool_true_false_are_defined is not defined"
|
||||
#endif
|
||||
char a[__bool_true_false_are_defined == 1 ? 1 : -1];
|
||||
|
||||
struct s { _Bool s: 1; _Bool t; } s;
|
||||
/* Regardless of whether this is C++ or "_Bool" is a
|
||||
valid type name, "true" and "false" should be usable
|
||||
in #if expressions and integer constant expressions,
|
||||
and "bool" should be a valid type name. */
|
||||
|
||||
#if !true
|
||||
#error "'true' is not true"
|
||||
#endif
|
||||
#if true != 1
|
||||
#error "'true' is not equal to 1"
|
||||
#endif
|
||||
char b[true == 1 ? 1 : -1];
|
||||
char c[true];
|
||||
|
||||
#if false
|
||||
#error "'false' is not false"
|
||||
#endif
|
||||
#if false != 0
|
||||
#error "'false' is not equal to 0"
|
||||
#endif
|
||||
char d[false == 0 ? 1 : -1];
|
||||
|
||||
enum { e = false, f = true, g = false * true, h = true * 256 };
|
||||
|
||||
char i[(bool) 0.5 == true ? 1 : -1];
|
||||
char j[(bool) 0.0 == false ? 1 : -1];
|
||||
char k[sizeof (bool) > 0 ? 1 : -1];
|
||||
|
||||
struct sb { bool s: 1; bool t; } s;
|
||||
char l[sizeof s.t > 0 ? 1 : -1];
|
||||
|
||||
char a[true == 1 ? 1 : -1];
|
||||
char b[false == 0 ? 1 : -1];
|
||||
char c[__bool_true_false_are_defined == 1 ? 1 : -1];
|
||||
char d[(bool) 0.5 == true ? 1 : -1];
|
||||
/* See body of main program for 'e'. */
|
||||
char f[(_Bool) 0.0 == false ? 1 : -1];
|
||||
char g[true];
|
||||
char h[sizeof (_Bool)];
|
||||
char i[sizeof s.t];
|
||||
enum { j = false, k = true, l = false * true, m = true * 256 };
|
||||
/* The following fails for
|
||||
HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
|
||||
_Bool n[m];
|
||||
char o[sizeof n == m * sizeof n[0] ? 1 : -1];
|
||||
char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
|
||||
bool m[h];
|
||||
char n[sizeof m == h * sizeof m[0] ? 1 : -1];
|
||||
char o[-1 - (bool) 0 < 0 ? 1 : -1];
|
||||
/* Catch a bug in an HP-UX C compiler. See
|
||||
https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
|
||||
https://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
|
||||
https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
|
||||
https://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
|
||||
*/
|
||||
_Bool q = true;
|
||||
_Bool *pq = &q;
|
||||
bool p = true;
|
||||
bool *pp = &p;
|
||||
|
||||
/* C 1999 specifies that bool, true, and false are to be
|
||||
macros, but C++ 2011 and later overrule this. */
|
||||
#if __cplusplus < 201103
|
||||
#ifndef bool
|
||||
#error "bool is not defined"
|
||||
#endif
|
||||
#ifndef false
|
||||
#error "false is not defined"
|
||||
#endif
|
||||
#ifndef true
|
||||
#error "true is not defined"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* If _Bool is available, repeat with it all the tests
|
||||
above that used bool. */
|
||||
#ifdef HAVE__BOOL
|
||||
struct sB { _Bool s: 1; _Bool t; } t;
|
||||
|
||||
char q[(_Bool) 0.5 == true ? 1 : -1];
|
||||
char r[(_Bool) 0.0 == false ? 1 : -1];
|
||||
char u[sizeof (_Bool) > 0 ? 1 : -1];
|
||||
char v[sizeof t.t > 0 ? 1 : -1];
|
||||
|
||||
_Bool w[h];
|
||||
char x[sizeof m == h * sizeof m[0] ? 1 : -1];
|
||||
char y[-1 - (_Bool) 0 < 0 ? 1 : -1];
|
||||
_Bool z = true;
|
||||
_Bool *pz = &p;
|
||||
#endif
|
||||
]],
|
||||
[[
|
||||
bool e = &s;
|
||||
*pq |= q;
|
||||
*pq |= ! q;
|
||||
/* Refer to every declared value, to avoid compiler optimizations. */
|
||||
return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
|
||||
+ !m + !n + !o + !p + !q + !pq);
|
||||
bool ps = &s;
|
||||
*pp |= p;
|
||||
*pp |= ! p;
|
||||
|
||||
#ifdef HAVE__BOOL
|
||||
_Bool pt = &t;
|
||||
*pz |= z;
|
||||
*pz |= ! z;
|
||||
#endif
|
||||
|
||||
/* Refer to every declared value, so they cannot be
|
||||
discarded as unused. */
|
||||
return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !j + !k
|
||||
+ !l + !m + !n + !o + !p + !pp + !ps
|
||||
#ifdef HAVE__BOOL
|
||||
+ !q + !r + !u + !v + !w + !x + !y + !z + !pt
|
||||
#endif
|
||||
);
|
||||
]])],
|
||||
[ac_cv_header_stdbool_h=yes],
|
||||
[ac_cv_header_stdbool_h=no])])
|
||||
AC_CHECK_TYPES([_Bool])
|
||||
])# AC_CHECK_HEADER_STDBOOL
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user