xref: /netbsd-src/tests/usr.bin/xlint/lint1/d_c99_bool.c (revision e5eea854b31bf95dbb1c168e919464b9e30aeabf)
1 /*	$NetBSD: d_c99_bool.c,v 1.11 2023/07/03 09:37:14 rillig Exp $	*/
2 # 3 "d_c99_bool.c"
3 
4 /*
5  * C99 6.3.1.2 says: "When any scalar value is converted to _Bool, the result
6  * is 0 if the value compares equal to 0; otherwise the result is 1."
7  *
8  * This is different from the other integer types, which get truncated or
9  * invoke undefined behavior.
10  */
11 
12 /* lint1-extra-flags: -X 351 */
13 
14 /* expect+1: error: negative array dimension (-2) [20] */
15 int int_0[(_Bool)0 ? -1 : -2];
16 
17 /* expect+1: error: negative array dimension (-1) [20] */
18 int int_1[(_Bool)1 ? -1 : -2];
19 
20 /* expect+1: error: negative array dimension (-1) [20] */
21 int int_2[(_Bool)2 ? -1 : -2];
22 
23 /* expect+1: error: negative array dimension (-1) [20] */
24 int int_256[(_Bool)256 ? -1 : -2];
25 
26 /* expect+1: error: negative array dimension (-2) [20] */
27 int null_pointer[(_Bool)(void *)0 ? -1 : -2];
28 
29 /*
30  * XXX: In initializers for global variables, taking the address of a variable
31  * is allowed and may be modified by a constant offset.  This is not a constant
32  * expression though.
33  *
34  * In such a case, the grammar rule array_size_opt calls to_int_constant, which
35  * returns 1 for the array size without reporting an error.  This is why
36  * neither of the following array declarations generates an error message.
37  */
38 char ch;
39 int nonnull_pointer_converts_to_false[(_Bool)&ch ? -1 : 1];
40 int nonnull_pointer_converts_to_true_[(_Bool)&ch ? 1 : -1];
41 
42 /* expect+1: error: negative array dimension (-1) [20] */
43 int double_minus_1_0[(_Bool)-1.0 ? -1 : -2];
44 
45 /* expect+1: error: negative array dimension (-1) [20] */
46 int double_minus_0_5[(_Bool)-0.5 ? -1 : -2];
47 
48 /* expect+1: error: negative array dimension (-2) [20] */
49 int double_minus_0_0[(_Bool)-0.0 ? -1 : -2];
50 
51 /* expect+1: error: negative array dimension (-2) [20] */
52 int double_0_0[(_Bool)0.0 ? -1 : -2];
53 
54 /* The C99 rationale explains in 6.3.1.2 why (_Bool)0.5 is true. */
55 /* expect+1: error: negative array dimension (-1) [20] */
56 int double_0_5_converts_to_false[(_Bool)0.5 ? -1 : -2];
57 
58 /* expect+1: error: negative array dimension (-1) [20] */
59 int double_1_0_converts_to_false[(_Bool)1.0 ? -1 : -2];
60 
61 _Bool
convert_to_bool(int selector)62 convert_to_bool(int selector)
63 {
64 	static struct variant {
65 		_Bool b;
66 		char c;
67 		int i;
68 		double d;
69 		enum color {
70 			RED
71 		} e;
72 		const char *pcc;
73 		void (*f)(void);
74 		double _Complex dc;
75 	} v = { .i = 0 };
76 
77 	switch (selector) {
78 	case 0: return v.b;
79 	case 1: return v.c;
80 	case 2: return v.i;
81 	case 3: return v.d;
82 	case 4: return v.e;
83 	case 5: return v.pcc;
84 	case 6: return v.f;
85 	case 7: return v.dc;
86 	default: return v.b;
87 	}
88 }
89