1 /* Test of <stdbool.h> substitute.
2    Copyright (C) 2002-2007, 2009-2021 Free Software Foundation, Inc.
3 
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16 
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
18 
19 /* Define ADDRESS_CHECK_OKAY if it is OK to assign an address to a 'bool'
20    and this does not generate a warning (because we want this test to succeed
21    even when using gcc's -Werror).  */
22 #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) \
23     || (__clang_major__ >= 4)
24 /* We can silence the warning.  */
25 # pragma GCC diagnostic ignored "-Waddress"
26 # define ADDRESS_CHECK_OKAY
27 #elif defined __GNUC__ || defined __clang__
28 /* There may be a warning.  */
29 #else
30 /* Ignore warnings from other compilers.  */
31 # define ADDRESS_CHECK_OKAY
32 #endif
33 
34 #include <config.h>
35 
36 #include <stdbool.h>
37 
38 #ifndef bool
39  "error: bool is not defined"
40 #endif
41 #ifndef false
42  "error: false is not defined"
43 #endif
44 #if false
45  "error: false is not 0"
46 #endif
47 #ifndef true
48  "error: true is not defined"
49 #endif
50 #if true != 1
51  "error: true is not 1"
52 #endif
53 #ifndef __bool_true_false_are_defined
54  "error: __bool_true_false_are_defined is not defined"
55 #endif
56 
57 /* Several tests cannot be guaranteed with gnulib's <stdbool.h>, at
58    least, not for all compilers and compiler options.  */
59 #if HAVE_STDBOOL_H || 3 <= __GNUC__ || 4 <= __clang_major__
60 struct s { _Bool s: 1; _Bool t; } s;
61 #endif
62 
63 char a[true == 1 ? 1 : -1];
64 char b[false == 0 ? 1 : -1];
65 char c[__bool_true_false_are_defined == 1 ? 1 : -1];
66 #if HAVE_STDBOOL_H || 3 <= __GNUC__ || 4 <= __clang_major__ /* See above.  */
67 char d[(bool) 0.5 == true ? 1 : -1];
68 # ifdef ADDRESS_CHECK_OKAY /* Avoid gcc warning.  */
69 /* C99 may plausibly be interpreted as not requiring support for a cast from
70    a variable's address to bool in a static initializer.  So treat it like a
71    GCC extension.  */
72 #  if defined __GNUC__ || defined __clang__
73 bool e = &s;
74 #  endif
75 # endif
76 char f[(_Bool) 0.0 == false ? 1 : -1];
77 #endif
78 char g[true];
79 char h[sizeof (_Bool)];
80 #if HAVE_STDBOOL_H || 3 <= __GNUC__ || 4 <= __clang_major__ /* See above.  */
81 char i[sizeof s.t];
82 #endif
83 enum { j = false, k = true, l = false * true, m = true * 256 };
84 _Bool n[m];
85 char o[sizeof n == m * sizeof n[0] ? 1 : -1];
86 char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
87 /* Catch a bug in an HP-UX C compiler.  See
88    https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
89    https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html
90  */
91 _Bool q = true;
92 _Bool *pq = &q;
93 
94 int
main()95 main ()
96 {
97   int error = 0;
98 
99 #if HAVE_STDBOOL_H || 3 <= __GNUC_ || 4 <= __clang_major___ /* See above.  */
100 # ifdef ADDRESS_CHECK_OKAY /* Avoid gcc warning.  */
101   /* A cast from a variable's address to bool is valid in expressions.  */
102   {
103     bool e1 = &s;
104     if (!e1)
105       error = 1;
106   }
107 # endif
108 #endif
109 
110   /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0
111      reported by James Lemley on 2005-10-05; see
112      https://lists.gnu.org/r/bug-coreutils/2005-10/msg00086.html
113      This is a runtime test, since a corresponding compile-time
114      test would rely on initializer extensions.  */
115   {
116     char digs[] = "0123456789";
117     if (&(digs + 5)[-2 + (bool) 1] != &digs[4])
118       error = 1;
119   }
120 
121   return error;
122 }
123