1 1.56 rillig /* $NetBSD: d_c99_bool_strict.c,v 1.56 2025/07/07 19:57:17 rillig Exp $ */ 2 1.1 rillig # 3 "d_c99_bool_strict.c" 3 1.1 rillig 4 1.1 rillig /* 5 1.4 rillig * The option -T treats _Bool as incompatible with all other scalar types. 6 1.8 rillig * This is implemented by the following rules: 7 1.1 rillig * 8 1.8 rillig * strict-bool-typedef: 9 1.8 rillig * The type _Bool is compatible with any typedef of _Bool. 10 1.1 rillig * 11 1.8 rillig * Note: Since <stdbool.h> defines bool as textual alias of _Bool, 12 1.8 rillig * having another typedef for bool is unusual. 13 1.1 rillig * 14 1.8 rillig * strict-bool-constant: 15 1.8 rillig * There are 2 bool constants named false and true. 16 1.8 rillig * No other constants are compatible with type _Bool. 17 1.1 rillig * 18 1.8 rillig * Note: Internally these constants are named __lint_false and 19 1.8 rillig * __lint_true. 20 1.1 rillig * 21 1.8 rillig * strict-bool-bit-field: 22 1.8 rillig * A struct or union member that is a bit field with underlying type 23 1.8 rillig * bool is compatible with plain bool. 24 1.1 rillig * 25 1.8 rillig * strict-bool-conversion: 26 1.8 rillig * There is no implicit conversion between _Bool and any other type. 27 1.3 rillig * 28 1.8 rillig * strict-bool-controlling-expression: 29 1.8 rillig * Controlling expressions in 'if', 'while', 'for', '?:' must be of 30 1.49 rillig * type bool, except for a literal 0 in a do-while loop. 31 1.3 rillig * 32 1.8 rillig * strict-bool-operand-unary: 33 1.8 rillig * Operator bool? scalar? 34 1.25 rillig * ! yes - 35 1.25 rillig * & yes yes 36 1.25 rillig * The other unary operators do not accept bool operands. 37 1.8 rillig * 38 1.8 rillig * strict-bool-operand-binary: 39 1.8 rillig * Operator left: bool? other? right: bool? other? 40 1.8 rillig * . - yes yes yes 41 1.8 rillig * -> - yes yes yes 42 1.11 rillig * <=, <, >=, > - yes - yes 43 1.8 rillig * ==, != yes yes yes yes 44 1.8 rillig * & yes yes yes yes 45 1.8 rillig * ^ yes yes yes yes 46 1.8 rillig * | yes yes yes yes 47 1.8 rillig * && yes - yes - 48 1.8 rillig * || yes - yes - 49 1.8 rillig * ? yes - yes yes 50 1.8 rillig * : yes yes yes yes 51 1.8 rillig * = yes yes yes yes 52 1.8 rillig * &=, ^=, |= yes yes yes yes 53 1.8 rillig * , yes yes yes yes 54 1.8 rillig * The other binary operators do not accept bool operands. 55 1.8 rillig * 56 1.8 rillig * strict-bool-operator-result: 57 1.8 rillig * The result type of the operators '!', '<', '<=', '>', '>=', 58 1.8 rillig * '==', '!=', '&&', '||' is _Bool instead of int. 59 1.8 rillig * 60 1.8 rillig * strict-bool-bitwise-and: 61 1.8 rillig * Expressions of the form "flags & FLAG" are compatible with _Bool if 62 1.48 rillig * the resulting value is used in a context where it is implicitly and 63 1.48 rillig * immediately compared to zero. 64 1.8 rillig * 65 1.8 rillig * Note: Examples for such contexts are controlling expressions or the 66 1.8 rillig * operands of the operators '!', '&&', '||'. 67 1.8 rillig * 68 1.49 rillig * Note: Counterexamples for contexts are assignments to a bool variable, 69 1.49 rillig * as without the conversion from C99 6.3.1.2, converting an integer to a 70 1.49 rillig * "bool-like" integer type truncated the value instead of comparing it 71 1.49 rillig * to 0. 72 1.49 rillig * 73 1.49 rillig * Note: These rules ensure that conforming code behaves the same in both 74 1.49 rillig * C99 and in environments that emulate a boolean type using a small 75 1.49 rillig * integer type. 76 1.8 rillig */ 77 1.8 rillig 78 1.8 rillig /* 79 1.8 rillig * The header <stdbool.h> defines the macros bool = _Bool, false = 0 and 80 1.8 rillig * true = 1. Without further hacks, this would mean that constant expressions 81 1.8 rillig * of integer type have to be regarded as possible boolean constants if their 82 1.8 rillig * value is either 0 or 1. 83 1.8 rillig * 84 1.8 rillig * This would not help in migrating old code to use bool consistently. 85 1.8 rillig * Therefore lint provides its own <stdbool.h> header that expands false to 86 1.8 rillig * __lint_false and true to __lint_true, two predefined constant expressions. 87 1.1 rillig */ 88 1.1 rillig 89 1.40 rillig /* lint1-extra-flags: -hT -X 351 */ 90 1.1 rillig 91 1.1 rillig /* 92 1.8 rillig * strict-bool-typedef 93 1.1 rillig */ 94 1.1 rillig 95 1.1 rillig /* 96 1.1 rillig * Using a typedef for bool does not hurt the checks, they all use the 97 1.1 rillig * underlying basic type (see tspec_t), which is BOOL. 98 1.1 rillig */ 99 1.1 rillig typedef _Bool bool; 100 1.1 rillig 101 1.8 rillig extern void accept_bool(bool); 102 1.8 rillig extern void println(const char *); 103 1.8 rillig extern void take_arguments(bool, int, const char *, ...); 104 1.8 rillig extern void do_nothing(void); 105 1.8 rillig 106 1.8 rillig /* 107 1.8 rillig * strict-bool-constant 108 1.8 rillig */ 109 1.8 rillig 110 1.8 rillig void 111 1.8 rillig strict_bool_constant(void) 112 1.8 rillig { 113 1.8 rillig accept_bool(__lint_false); 114 1.8 rillig accept_bool(__lint_true); 115 1.44 rillig /* expect+1: error: parameter 1 expects '_Bool', gets passed 'int' [334] */ 116 1.36 rillig accept_bool(0); 117 1.44 rillig /* expect+1: error: parameter 1 expects '_Bool', gets passed 'int' [334] */ 118 1.36 rillig accept_bool(1); 119 1.44 rillig /* expect+1: error: parameter 1 expects '_Bool', gets passed 'int' [334] */ 120 1.36 rillig accept_bool(2); 121 1.8 rillig } 122 1.8 rillig 123 1.8 rillig enum strict_bool_constant_expressions { 124 1.8 rillig /* Ok: __lint_false is a boolean constant expression. */ 125 1.36 rillig FALSE = __lint_false ? 100 : 101, 126 1.8 rillig 127 1.8 rillig /* Ok: __lint_true is a boolean constant expression. */ 128 1.36 rillig TRUE = __lint_true ? 100 : 101, 129 1.8 rillig 130 1.8 rillig /* Not ok: an integer is not a boolean constant expression. */ 131 1.36 rillig /* expect+1: error: left operand of '?' must be bool, not 'int' [331] */ 132 1.36 rillig INT0 = 0 ? 100 : 101, 133 1.8 rillig 134 1.8 rillig /* Not ok: an integer is not a boolean constant expression. */ 135 1.36 rillig /* expect+1: error: left operand of '?' must be bool, not 'int' [331] */ 136 1.36 rillig INT1 = 1 ? 100 : 101, 137 1.8 rillig 138 1.8 rillig /* Not ok: 2 is not a boolean constant. */ 139 1.36 rillig /* expect+1: error: left operand of '?' must be bool, not 'int' [331] */ 140 1.36 rillig INT2 = 2 ? 100 : 101, 141 1.8 rillig 142 1.8 rillig /* Not ok: compound integer expressions are not bool. */ 143 1.36 rillig /* expect+1: error: left operand of '?' must be bool, not 'int' [331] */ 144 1.36 rillig ARITH = (2 - 2) ? 100 : 101, 145 1.8 rillig 146 1.8 rillig /* 147 1.8 rillig * Without strict bool mode, these two variants of an expression can 148 1.8 rillig * occur when a preprocessor macro is either defined to 1 or left 149 1.45 rillig * empty (since C99). 150 1.8 rillig * 151 1.27 rillig * In strict bool mode, the resulting expression can be compared 152 1.27 rillig * against 0 to achieve the same effect (so +0 != 0 or 1 + 0 != 0). 153 1.8 rillig */ 154 1.36 rillig /* expect+1: error: left operand of '?' must be bool, not 'int' [331] */ 155 1.36 rillig BINARY_PLUS = (1 + 0) ? 100 : 101, 156 1.36 rillig /* expect+1: error: left operand of '?' must be bool, not 'int' [331] */ 157 1.36 rillig UNARY_PLUS = (+0) ? 100 : 101, 158 1.8 rillig 159 1.8 rillig /* The main operator '>' has return type bool. */ 160 1.36 rillig Q1 = (13 > 12) ? 100 : 101, 161 1.8 rillig 162 1.8 rillig /* 163 1.8 rillig * The parenthesized expression has type int and thus cannot be 164 1.8 rillig * used as the controlling expression in the '?:' operator. 165 1.8 rillig */ 166 1.36 rillig /* expect+1: error: left operand of '?' must be bool, not 'int' [331] */ 167 1.36 rillig Q2 = (13 > 12 ? 1 : 7) ? 100 : 101, 168 1.8 rillig 169 1.36 rillig /* expect+1: error: integral constant expression expected [55] */ 170 1.36 rillig BINAND_BOOL = __lint_false & __lint_true, 171 1.8 rillig BINAND_INT = 0 & 1, 172 1.8 rillig 173 1.36 rillig /* expect+1: error: integral constant expression expected [55] */ 174 1.36 rillig BINXOR_BOOL = __lint_false ^ __lint_true, 175 1.8 rillig BINXOR_INT = 0 ^ 1, 176 1.8 rillig 177 1.36 rillig /* expect+1: error: integral constant expression expected [55] */ 178 1.36 rillig BINOR_BOOL = __lint_false | __lint_true, 179 1.8 rillig BINOR_INT = 0 | 1, 180 1.8 rillig 181 1.36 rillig /* expect+1: error: integral constant expression expected [55] */ 182 1.36 rillig LOGOR_BOOL = __lint_false || __lint_true, 183 1.36 rillig /* expect+2: error: left operand of '||' must be bool, not 'int' [331] */ 184 1.36 rillig /* expect+1: error: right operand of '||' must be bool, not 'int' [332] */ 185 1.36 rillig LOGOR_INT = 0 || 1, 186 1.36 rillig 187 1.36 rillig /* expect+1: error: integral constant expression expected [55] */ 188 1.36 rillig LOGAND_BOOL = __lint_false && __lint_true, 189 1.36 rillig /* expect+2: error: left operand of '&&' must be bool, not 'int' [331] */ 190 1.36 rillig /* expect+1: error: right operand of '&&' must be bool, not 'int' [332] */ 191 1.36 rillig LOGAND_INT = 0 && 1, 192 1.8 rillig }; 193 1.8 rillig 194 1.8 rillig /* 195 1.8 rillig * strict-bool-bit-fields 196 1.8 rillig */ 197 1.8 rillig 198 1.8 rillig void 199 1.8 rillig strict_bool_bit_fields(void) 200 1.8 rillig { 201 1.8 rillig struct flags { 202 1.8 rillig bool bool_flag: 1; 203 1.8 rillig unsigned uint_flag: 1; 204 1.8 rillig }; 205 1.8 rillig 206 1.8 rillig struct flags flags = { __lint_false, 0 }; 207 1.8 rillig struct flags *flags_ptr = &flags; 208 1.8 rillig bool b; 209 1.8 rillig 210 1.8 rillig b = flags.bool_flag; 211 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'unsigned int' [107] */ 212 1.36 rillig b = flags.uint_flag; 213 1.8 rillig flags.bool_flag = b; 214 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'unsigned int' and '_Bool' [107] */ 215 1.36 rillig flags.uint_flag = b; 216 1.8 rillig 217 1.8 rillig b = flags_ptr->bool_flag; 218 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'unsigned int' [107] */ 219 1.36 rillig b = flags_ptr->uint_flag; 220 1.8 rillig flags_ptr->bool_flag = b; 221 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'unsigned int' and '_Bool' [107] */ 222 1.36 rillig flags_ptr->uint_flag = b; 223 1.8 rillig } 224 1.8 rillig 225 1.8 rillig void 226 1.8 rillig strict_bool_bit_fields_operand_conversion(void) 227 1.8 rillig { 228 1.8 rillig struct s { 229 1.8 rillig bool ordinary; 230 1.8 rillig bool bit_field: 1; 231 1.8 rillig }; 232 1.8 rillig 233 1.24 rillig struct s s = { 0 > 0 }; 234 1.8 rillig 235 1.8 rillig s.ordinary = s.ordinary | s.ordinary; 236 1.15 rillig s.bit_field = s.bit_field | s.bit_field; 237 1.8 rillig } 238 1.8 rillig 239 1.8 rillig /* 240 1.8 rillig * strict-bool-conversion 241 1.8 rillig */ 242 1.8 rillig 243 1.8 rillig bool 244 1.8 rillig strict_bool_conversion_return_false(void) 245 1.8 rillig { 246 1.8 rillig return __lint_false; 247 1.8 rillig } 248 1.8 rillig 249 1.8 rillig bool 250 1.8 rillig strict_bool_conversion_return_true(void) 251 1.8 rillig { 252 1.8 rillig return __lint_true; 253 1.8 rillig } 254 1.8 rillig 255 1.8 rillig bool 256 1.8 rillig strict_bool_conversion_return_bool(bool b) 257 1.8 rillig { 258 1.8 rillig return b; 259 1.8 rillig } 260 1.8 rillig 261 1.8 rillig bool 262 1.8 rillig strict_bool_conversion_return_0(void) 263 1.8 rillig { 264 1.39 rillig /* expect+1: error: function has return type '_Bool' but returns 'int' [211] */ 265 1.36 rillig return 0; 266 1.8 rillig } 267 1.8 rillig 268 1.8 rillig bool 269 1.8 rillig strict_bool_conversion_return_1(void) 270 1.8 rillig { 271 1.39 rillig /* expect+1: error: function has return type '_Bool' but returns 'int' [211] */ 272 1.36 rillig return 1; 273 1.8 rillig } 274 1.8 rillig 275 1.8 rillig bool 276 1.8 rillig strict_bool_conversion_return_2(void) 277 1.8 rillig { 278 1.39 rillig /* expect+1: error: function has return type '_Bool' but returns 'int' [211] */ 279 1.36 rillig return 2; 280 1.8 rillig } 281 1.8 rillig 282 1.43 rillig /* expect+2: warning: parameter 'p' unused in function 'strict_bool_conversion_return_pointer' [231] */ 283 1.8 rillig bool 284 1.36 rillig strict_bool_conversion_return_pointer(const void *p) 285 1.8 rillig { 286 1.39 rillig /* expect+1: error: function has return type '_Bool' but returns 'pointer' [211] */ 287 1.36 rillig return p; 288 1.8 rillig } 289 1.8 rillig 290 1.8 rillig char 291 1.8 rillig strict_bool_conversion_return_false_as_char(void) 292 1.8 rillig { 293 1.39 rillig /* expect+1: error: function has return type 'char' but returns '_Bool' [211] */ 294 1.36 rillig return __lint_false; 295 1.8 rillig } 296 1.8 rillig 297 1.8 rillig char 298 1.8 rillig strict_bool_conversion_return_true_as_char(void) 299 1.8 rillig { 300 1.39 rillig /* expect+1: error: function has return type 'char' but returns '_Bool' [211] */ 301 1.36 rillig return __lint_true; 302 1.8 rillig } 303 1.8 rillig 304 1.8 rillig 305 1.1 rillig void 306 1.8 rillig strict_bool_conversion_function_argument(void) 307 1.1 rillig { 308 1.8 rillig accept_bool(__lint_false); 309 1.8 rillig accept_bool(__lint_true); 310 1.8 rillig } 311 1.8 rillig 312 1.8 rillig void 313 1.8 rillig strict_bool_conversion_function_argument_pass(bool b, int i, const char *p) 314 1.8 rillig { 315 1.8 rillig /* No conversion necessary. */ 316 1.8 rillig take_arguments(b, i, p); 317 1.8 rillig 318 1.8 rillig /* Implicitly converting bool to other scalar types. */ 319 1.44 rillig /* expect+2: error: parameter 2 expects 'int', gets passed '_Bool' [334] */ 320 1.44 rillig /* expect+1: error: parameter 3 expects 'pointer', gets passed '_Bool' [334] */ 321 1.36 rillig take_arguments(b, b, b); 322 1.8 rillig 323 1.8 rillig /* Implicitly converting int to bool (arg #1). */ 324 1.44 rillig /* expect+2: error: parameter 1 expects '_Bool', gets passed 'int' [334] */ 325 1.55 rillig /* expect+1: warning: invalid combination of pointer 'pointer to const char' and integer 'int', arg #3 [154] */ 326 1.36 rillig take_arguments(i, i, i); 327 1.8 rillig 328 1.8 rillig /* Implicitly converting pointer to bool (arg #1). */ 329 1.44 rillig /* expect+2: error: parameter 1 expects '_Bool', gets passed 'pointer' [334] */ 330 1.55 rillig /* expect+1: warning: invalid combination of integer 'int' and pointer 'pointer to const char', arg #2 [154] */ 331 1.36 rillig take_arguments(p, p, p); 332 1.8 rillig 333 1.8 rillig /* Passing bool as vararg. */ 334 1.36 rillig /* TODO: maybe expect+1: arg#4 should not be bool but scalar */ 335 1.36 rillig take_arguments(b, i, p, b, i, p); 336 1.8 rillig 337 1.8 rillig /* Passing a bool constant. */ 338 1.8 rillig take_arguments(__lint_false, i, p); 339 1.8 rillig 340 1.8 rillig /* Passing a bool constant. */ 341 1.8 rillig take_arguments(__lint_true, i, p); 342 1.8 rillig 343 1.8 rillig /* Trying to pass integer constants. */ 344 1.44 rillig /* expect+1: error: parameter 1 expects '_Bool', gets passed 'int' [334] */ 345 1.36 rillig take_arguments(0, i, p); 346 1.44 rillig /* expect+1: error: parameter 1 expects '_Bool', gets passed 'int' [334] */ 347 1.36 rillig take_arguments(1, i, p); 348 1.44 rillig /* expect+1: error: parameter 1 expects '_Bool', gets passed 'int' [334] */ 349 1.36 rillig take_arguments(2, i, p); 350 1.8 rillig } 351 1.1 rillig 352 1.8 rillig void 353 1.8 rillig strict_bool_conversion_between_bool_and_int(void) 354 1.8 rillig { 355 1.8 rillig bool b; 356 1.8 rillig int i; 357 1.1 rillig 358 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'int' [107] */ 359 1.36 rillig b = 0; 360 1.9 rillig b = __lint_false; 361 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'int' [107] */ 362 1.36 rillig b = 1; 363 1.8 rillig b = __lint_true; 364 1.1 rillig 365 1.8 rillig i = 0; 366 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 367 1.36 rillig i = __lint_false; 368 1.8 rillig i = 1; 369 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 370 1.36 rillig i = __lint_true; 371 1.8 rillig 372 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 373 1.36 rillig i = b; 374 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'int' [107] */ 375 1.36 rillig b = i; 376 1.8 rillig } 377 1.8 rillig 378 1.43 rillig /* expect+2: warning: parameter 'b' unused in function 'strict_bool_conversion_from_bool_to_scalar' [231] */ 379 1.8 rillig void 380 1.36 rillig strict_bool_conversion_from_bool_to_scalar(bool b) 381 1.8 rillig { 382 1.8 rillig int i; 383 1.8 rillig unsigned u; 384 1.8 rillig double d; 385 1.8 rillig void *p; 386 1.8 rillig 387 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 388 1.36 rillig i = b; 389 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'unsigned int' and '_Bool' [107] */ 390 1.36 rillig u = b; 391 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'double' and '_Bool' [107] */ 392 1.36 rillig d = b; 393 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'pointer' and '_Bool' [107] */ 394 1.36 rillig p = b; 395 1.8 rillig } 396 1.8 rillig 397 1.8 rillig /* 398 1.49 rillig * strict-bool-controlling-expression 399 1.8 rillig */ 400 1.8 rillig 401 1.8 rillig void 402 1.8 rillig strict_bool_controlling_expression(bool b, int i, double d, const void *p) 403 1.8 rillig { 404 1.36 rillig if (__lint_false) 405 1.51 rillig /* expect+1: warning: 'call' statement not reached [193] */ 406 1.36 rillig do_nothing(); 407 1.8 rillig 408 1.36 rillig if (__lint_true) 409 1.8 rillig do_nothing(); 410 1.8 rillig 411 1.8 rillig if (b) 412 1.8 rillig do_nothing(); 413 1.8 rillig 414 1.36 rillig /* expect+1: error: controlling expression must be bool, not 'int' [333] */ 415 1.54 rillig if (0) 416 1.51 rillig /* expect+1: warning: 'call' statement not reached [193] */ 417 1.36 rillig do_nothing(); 418 1.8 rillig 419 1.36 rillig /* expect+1: error: controlling expression must be bool, not 'int' [333] */ 420 1.54 rillig if (1) 421 1.8 rillig do_nothing(); 422 1.8 rillig 423 1.36 rillig /* expect+1: error: controlling expression must be bool, not 'int' [333] */ 424 1.54 rillig if (2) 425 1.8 rillig do_nothing(); 426 1.1 rillig 427 1.1 rillig /* Not allowed: There is no implicit conversion from scalar to bool. */ 428 1.36 rillig /* expect+1: error: controlling expression must be bool, not 'int' [333] */ 429 1.36 rillig if (i) 430 1.8 rillig do_nothing(); 431 1.1 rillig if (i != 0) 432 1.8 rillig do_nothing(); 433 1.1 rillig 434 1.1 rillig /* Not allowed: There is no implicit conversion from scalar to bool. */ 435 1.36 rillig /* expect+1: error: controlling expression must be bool, not 'double' [333] */ 436 1.36 rillig if (d) 437 1.8 rillig do_nothing(); 438 1.1 rillig if (d != 0.0) 439 1.8 rillig do_nothing(); 440 1.1 rillig 441 1.1 rillig /* Not allowed: There is no implicit conversion from scalar to bool. */ 442 1.36 rillig /* expect+1: error: controlling expression must be bool, not 'pointer' [333] */ 443 1.36 rillig if (p) 444 1.8 rillig do_nothing(); 445 1.1 rillig if (p != (void *)0) 446 1.8 rillig do_nothing(); 447 1.49 rillig 448 1.49 rillig // An endless loop. The preferred form is 'for (;;)' instead. 449 1.49 rillig do { 450 1.49 rillig } while (__lint_true); 451 1.49 rillig 452 1.49 rillig // A do-once "loop", often used in statement macros. 453 1.49 rillig do { 454 1.49 rillig } while (__lint_false); 455 1.49 rillig 456 1.49 rillig // This form is too unusual to be allowed in strict bool mode. 457 1.49 rillig do { 458 1.52 rillig /* expect+1: error: controlling expression must be bool, not 'int' [333] */ 459 1.49 rillig } while (1); 460 1.49 rillig 461 1.49 rillig // Even though 0 is an integer instead of a bool, this idiom is so 462 1.49 rillig // common that it is frequently used in system headers. Since the 463 1.49 rillig // Clang preprocessor does not mark each token as coming from a system 464 1.49 rillig // header or from user code, this idiom can only be allowed everywhere 465 1.49 rillig // or nowhere. 466 1.49 rillig do { 467 1.49 rillig } while (0); 468 1.8 rillig } 469 1.1 rillig 470 1.8 rillig /* 471 1.49 rillig * strict-bool-operand-unary 472 1.8 rillig */ 473 1.8 rillig 474 1.8 rillig void 475 1.8 rillig strict_bool_operand_unary_not(void) 476 1.8 rillig { 477 1.8 rillig bool b = __lint_false; 478 1.8 rillig 479 1.8 rillig b = !b; 480 1.8 rillig b = !!!b; 481 1.36 rillig b = !__lint_false; 482 1.36 rillig b = !__lint_true; 483 1.8 rillig 484 1.8 rillig int i = 0; 485 1.8 rillig 486 1.36 rillig /* expect+1: error: operand of '!' must be bool, not 'int' [330] */ 487 1.36 rillig i = !i; 488 1.36 rillig /* expect+1: error: operand of '!' must be bool, not 'int' [330] */ 489 1.36 rillig i = !!!i; 490 1.36 rillig /* expect+1: error: operand of '!' must be bool, not 'int' [330] */ 491 1.36 rillig i = !0; 492 1.36 rillig /* expect+1: error: operand of '!' must be bool, not 'int' [330] */ 493 1.36 rillig i = !1; 494 1.8 rillig } 495 1.8 rillig 496 1.8 rillig void 497 1.8 rillig strict_bool_operand_unary_address(void) 498 1.8 rillig { 499 1.8 rillig bool b = __lint_false; 500 1.8 rillig 501 1.8 rillig /* Taking the address of a bool lvalue. */ 502 1.8 rillig bool *bp; 503 1.8 rillig bp = &b; 504 1.8 rillig *bp = b; 505 1.8 rillig b = *bp; 506 1.1 rillig } 507 1.1 rillig 508 1.29 rillig /* see strict_bool_operand_unary_all below for the other unary operators. */ 509 1.29 rillig 510 1.8 rillig /* 511 1.49 rillig * strict-bool-operand-binary 512 1.8 rillig */ 513 1.8 rillig 514 1.8 rillig /* 515 1.8 rillig * Ensure that bool members can be accessed as usual. 516 1.8 rillig */ 517 1.1 rillig void 518 1.8 rillig strict_bool_operand_binary_dot_arrow(void) 519 1.1 rillig { 520 1.8 rillig struct bool_struct { 521 1.8 rillig bool b; 522 1.8 rillig }; 523 1.8 rillig 524 1.8 rillig /* Initialize and assign using boolean constants. */ 525 1.8 rillig bool b = __lint_false; 526 1.8 rillig b = __lint_true; 527 1.1 rillig 528 1.8 rillig /* Access a struct member using the '.' operator. */ 529 1.8 rillig struct bool_struct bs = { __lint_true }; 530 1.8 rillig b = bs.b; 531 1.8 rillig bs.b = b; 532 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'int' [107] */ 533 1.36 rillig bs.b = 0; 534 1.1 rillig 535 1.8 rillig /* Access a struct member using the '->' operator. */ 536 1.8 rillig struct bool_struct *bsp = &bs; 537 1.8 rillig b = bsp->b; 538 1.8 rillig bsp->b = b; 539 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'int' [107] */ 540 1.36 rillig bsp->b = 0; 541 1.1 rillig } 542 1.1 rillig 543 1.4 rillig int 544 1.8 rillig strict_bool_operand_binary(bool b, int i) 545 1.1 rillig { 546 1.1 rillig 547 1.4 rillig /* The right-hand sides of these assignments are ok. */ 548 1.1 rillig b = !b; 549 1.1 rillig b = b && b; 550 1.1 rillig b = b || b; 551 1.1 rillig 552 1.4 rillig /* 553 1.4 rillig * The right-hand sides of these assignments implicitly convert from 554 1.4 rillig * scalar to bool. 555 1.4 rillig */ 556 1.36 rillig /* expect+1: error: operand of '!' must be bool, not 'int' [330] */ 557 1.36 rillig b = !i; 558 1.36 rillig /* expect+2: error: left operand of '&&' must be bool, not 'int' [331] */ 559 1.36 rillig /* expect+1: error: right operand of '&&' must be bool, not 'int' [332] */ 560 1.36 rillig b = i && i; 561 1.36 rillig /* expect+2: error: left operand of '||' must be bool, not 'int' [331] */ 562 1.36 rillig /* expect+1: error: right operand of '||' must be bool, not 'int' [332] */ 563 1.36 rillig b = i || i; 564 1.36 rillig 565 1.36 rillig /* expect+1: error: right operand of '&&' must be bool, not 'int' [332] */ 566 1.36 rillig b = b && 0; 567 1.36 rillig /* expect+1: error: left operand of '&&' must be bool, not 'int' [331] */ 568 1.36 rillig b = 0 && b; 569 1.36 rillig /* expect+1: error: right operand of '||' must be bool, not 'int' [332] */ 570 1.36 rillig b = b || 0; 571 1.36 rillig /* expect+1: error: left operand of '||' must be bool, not 'int' [331] */ 572 1.36 rillig b = 0 || b; 573 1.4 rillig 574 1.4 rillig return i; 575 1.1 rillig } 576 1.1 rillig 577 1.1 rillig void 578 1.29 rillig strict_bool_operand_unary_all(bool b) 579 1.1 rillig { 580 1.8 rillig b = !b; 581 1.36 rillig /* expect+1: error: operand of '~' must not be bool [335] */ 582 1.36 rillig b = ~b; 583 1.36 rillig /* expect+1: error: operand of '++x' must not be bool [335] */ 584 1.36 rillig ++b; 585 1.36 rillig /* expect+1: error: operand of '--x' must not be bool [335] */ 586 1.36 rillig --b; 587 1.36 rillig /* expect+1: error: operand of 'x++' must not be bool [335] */ 588 1.36 rillig b++; 589 1.36 rillig /* expect+1: error: operand of 'x--' must not be bool [335] */ 590 1.36 rillig b--; 591 1.36 rillig /* expect+1: error: operand of '+' must not be bool [335] */ 592 1.36 rillig b = +b; 593 1.36 rillig /* expect+1: error: operand of '-' must not be bool [335] */ 594 1.36 rillig b = -b; 595 1.29 rillig } 596 1.4 rillig 597 1.29 rillig void 598 1.29 rillig strict_bool_operand_binary_all(bool b, unsigned u) 599 1.29 rillig { 600 1.36 rillig /* expect+2: error: left operand of '*' must not be bool [336] */ 601 1.36 rillig /* expect+1: error: right operand of '*' must not be bool [337] */ 602 1.36 rillig b = b * b; 603 1.36 rillig /* expect+2: error: left operand of '/' must not be bool [336] */ 604 1.36 rillig /* expect+1: error: right operand of '/' must not be bool [337] */ 605 1.36 rillig b = b / b; 606 1.36 rillig /* expect+2: error: left operand of '%' must not be bool [336] */ 607 1.36 rillig /* expect+1: error: right operand of '%' must not be bool [337] */ 608 1.36 rillig b = b % b; 609 1.36 rillig /* expect+2: error: left operand of '+' must not be bool [336] */ 610 1.36 rillig /* expect+1: error: right operand of '+' must not be bool [337] */ 611 1.36 rillig b = b + b; 612 1.36 rillig /* expect+2: error: left operand of '-' must not be bool [336] */ 613 1.36 rillig /* expect+1: error: right operand of '-' must not be bool [337] */ 614 1.36 rillig b = b - b; 615 1.36 rillig /* expect+2: error: left operand of '<<' must not be bool [336] */ 616 1.36 rillig /* expect+1: error: right operand of '<<' must not be bool [337] */ 617 1.36 rillig b = b << b; 618 1.36 rillig /* expect+2: error: left operand of '>>' must not be bool [336] */ 619 1.36 rillig /* expect+1: error: right operand of '>>' must not be bool [337] */ 620 1.36 rillig b = b >> b; 621 1.36 rillig 622 1.36 rillig /* expect+2: error: left operand of '<' must not be bool [336] */ 623 1.36 rillig /* expect+1: error: right operand of '<' must not be bool [337] */ 624 1.36 rillig b = b < b; 625 1.36 rillig /* expect+2: error: left operand of '<=' must not be bool [336] */ 626 1.36 rillig /* expect+1: error: right operand of '<=' must not be bool [337] */ 627 1.36 rillig b = b <= b; 628 1.36 rillig /* expect+2: error: left operand of '>' must not be bool [336] */ 629 1.36 rillig /* expect+1: error: right operand of '>' must not be bool [337] */ 630 1.36 rillig b = b > b; 631 1.36 rillig /* expect+2: error: left operand of '>=' must not be bool [336] */ 632 1.36 rillig /* expect+1: error: right operand of '>=' must not be bool [337] */ 633 1.36 rillig b = b >= b; 634 1.8 rillig b = b == b; 635 1.8 rillig b = b != b; 636 1.1 rillig 637 1.8 rillig b = b & b; 638 1.8 rillig b = b ^ b; 639 1.8 rillig b = b | b; 640 1.8 rillig b = b && b; 641 1.8 rillig b = b || b; 642 1.8 rillig b = b ? b : b; 643 1.1 rillig 644 1.8 rillig b = b; 645 1.36 rillig /* expect+2: error: left operand of '*=' must not be bool [336] */ 646 1.36 rillig /* expect+1: error: right operand of '*=' must not be bool [337] */ 647 1.36 rillig b *= b; 648 1.36 rillig /* expect+2: error: left operand of '/=' must not be bool [336] */ 649 1.36 rillig /* expect+1: error: right operand of '/=' must not be bool [337] */ 650 1.36 rillig b /= b; 651 1.36 rillig /* expect+2: error: left operand of '%=' must not be bool [336] */ 652 1.36 rillig /* expect+1: error: right operand of '%=' must not be bool [337] */ 653 1.36 rillig b %= b; 654 1.36 rillig /* expect+2: error: left operand of '+=' must not be bool [336] */ 655 1.36 rillig /* expect+1: error: right operand of '+=' must not be bool [337] */ 656 1.36 rillig b += b; 657 1.36 rillig /* expect+2: error: left operand of '-=' must not be bool [336] */ 658 1.36 rillig /* expect+1: error: right operand of '-=' must not be bool [337] */ 659 1.36 rillig b -= b; 660 1.36 rillig /* expect+2: error: left operand of '<<=' must not be bool [336] */ 661 1.36 rillig /* expect+1: error: right operand of '<<=' must not be bool [337] */ 662 1.36 rillig b <<= b; 663 1.36 rillig /* expect+2: error: left operand of '>>=' must not be bool [336] */ 664 1.36 rillig /* expect+1: error: right operand of '>>=' must not be bool [337] */ 665 1.36 rillig b >>= b; 666 1.8 rillig b &= b; 667 1.8 rillig b ^= b; 668 1.8 rillig b |= b; 669 1.1 rillig 670 1.1 rillig /* Operations with mixed types. */ 671 1.36 rillig /* expect+1: error: left operand of '*' must not be bool [336] */ 672 1.36 rillig u = b * u; 673 1.36 rillig /* expect+1: error: right operand of '*' must not be bool [337] */ 674 1.36 rillig u = u * b; 675 1.36 rillig /* expect+1: error: left operand of '/' must not be bool [336] */ 676 1.36 rillig u = b / u; 677 1.36 rillig /* expect+1: error: right operand of '/' must not be bool [337] */ 678 1.36 rillig u = u / b; 679 1.36 rillig /* expect+1: error: left operand of '%' must not be bool [336] */ 680 1.36 rillig u = b % u; 681 1.36 rillig /* expect+1: error: right operand of '%' must not be bool [337] */ 682 1.36 rillig u = u % b; 683 1.36 rillig /* expect+1: error: left operand of '+' must not be bool [336] */ 684 1.36 rillig u = b + u; 685 1.36 rillig /* expect+1: error: right operand of '+' must not be bool [337] */ 686 1.36 rillig u = u + b; 687 1.36 rillig /* expect+1: error: left operand of '-' must not be bool [336] */ 688 1.36 rillig u = b - u; 689 1.36 rillig /* expect+1: error: right operand of '-' must not be bool [337] */ 690 1.36 rillig u = u - b; 691 1.36 rillig /* expect+1: error: left operand of '<<' must not be bool [336] */ 692 1.36 rillig u = b << u; 693 1.36 rillig /* expect+1: error: right operand of '<<' must not be bool [337] */ 694 1.36 rillig u = u << b; 695 1.36 rillig /* expect+1: error: left operand of '>>' must not be bool [336] */ 696 1.36 rillig u = b >> u; 697 1.36 rillig /* expect+1: error: right operand of '>>' must not be bool [337] */ 698 1.36 rillig u = u >> b; 699 1.8 rillig u = b ? u : u; 700 1.38 rillig /* expect+1: error: operands of ':' have incompatible types '_Bool' and 'unsigned int' [107] */ 701 1.36 rillig u = b ? b : u; 702 1.38 rillig /* expect+1: error: operands of ':' have incompatible types 'unsigned int' and '_Bool' [107] */ 703 1.36 rillig u = b ? u : b; 704 1.1 rillig } 705 1.1 rillig 706 1.8 rillig bool 707 1.8 rillig strict_bool_operand_binary_comma(bool b, int i) 708 1.1 rillig { 709 1.36 rillig /* expect+1: warning: expression has null effect [129] */ 710 1.36 rillig b = (b, !b); 711 1.36 rillig /* expect+1: warning: expression has null effect [129] */ 712 1.36 rillig i = (i, i + 1); 713 1.8 rillig return b; 714 1.1 rillig } 715 1.1 rillig 716 1.8 rillig /* 717 1.49 rillig * strict-bool-operator-result 718 1.8 rillig */ 719 1.1 rillig 720 1.8 rillig void 721 1.8 rillig strict_bool_operator_result(bool b) 722 1.8 rillig { 723 1.38 rillig /* expect+1: error: operands of 'init' have incompatible types 'char' and '_Bool' [107] */ 724 1.36 rillig char c = b; 725 1.38 rillig /* expect+1: error: operands of 'init' have incompatible types 'int' and '_Bool' [107] */ 726 1.36 rillig int i = b; 727 1.38 rillig /* expect+1: error: operands of 'init' have incompatible types 'double' and '_Bool' [107] */ 728 1.36 rillig double d = b; 729 1.38 rillig /* expect+1: error: operands of 'init' have incompatible types 'pointer' and '_Bool' [107] */ 730 1.36 rillig void *p = b; 731 1.1 rillig 732 1.8 rillig /* The right-hand sides of these assignments are all ok. */ 733 1.8 rillig b = !b; 734 1.8 rillig b = i == i; 735 1.8 rillig b = i != i; 736 1.8 rillig b = i < i; 737 1.8 rillig b = i <= i; 738 1.8 rillig b = i >= i; 739 1.8 rillig b = i > i; 740 1.8 rillig b = b && b; 741 1.8 rillig b = b || b; 742 1.1 rillig 743 1.1 rillig /* 744 1.8 rillig * The right-hand sides of these assignments are not ok, they 745 1.8 rillig * implicitly convert from bool to int. 746 1.1 rillig */ 747 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 748 1.36 rillig i = !b; 749 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 750 1.36 rillig i = i == i; 751 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 752 1.36 rillig i = i != i; 753 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 754 1.36 rillig i = i < i; 755 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 756 1.36 rillig i = i <= i; 757 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 758 1.36 rillig i = i >= i; 759 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 760 1.36 rillig i = i > i; 761 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 762 1.36 rillig i = b && b; 763 1.38 rillig /* expect+1: error: operands of '=' have incompatible types 'int' and '_Bool' [107] */ 764 1.36 rillig i = b || b; 765 1.8 rillig } 766 1.1 rillig 767 1.2 rillig 768 1.3 rillig /* 769 1.49 rillig * strict-bool-bitwise-and 770 1.3 rillig */ 771 1.3 rillig 772 1.3 rillig enum Flags { 773 1.3 rillig FLAG0 = 1 << 0, 774 1.3 rillig FLAG1 = 1 << 1, 775 1.3 rillig FLAG28 = 1 << 28 776 1.2 rillig }; 777 1.2 rillig 778 1.43 rillig /* expect+2: warning: parameter 'flags' unused in function 'strict_bool_bitwise_and_enum' [231] */ 779 1.3 rillig void 780 1.36 rillig strict_bool_bitwise_and_enum(enum Flags flags) 781 1.3 rillig { 782 1.3 rillig bool b; 783 1.3 rillig 784 1.3 rillig /* 785 1.4 rillig * FLAG0 has the value 1 and thus can be stored in a bool variable 786 1.4 rillig * without truncation. Nevertheless this special case is not allowed 787 1.4 rillig * because it would be too confusing if FLAG0 would work and all the 788 1.4 rillig * other flags wouldn't. 789 1.3 rillig */ 790 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'int' [107] */ 791 1.36 rillig b = flags & FLAG0; 792 1.3 rillig 793 1.3 rillig /* 794 1.3 rillig * Assuming that FLAG1 is set in flags, a _Bool variable stores this 795 1.4 rillig * as 1, as defined by C99 6.3.1.2. A uint8_t variable would store 796 1.4 rillig * it as 2, as that is the integer value of FLAG1. Since FLAG1 fits 797 1.4 rillig * in a uint8_t, no truncation takes place. 798 1.3 rillig */ 799 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'int' [107] */ 800 1.36 rillig b = flags & FLAG1; 801 1.3 rillig 802 1.3 rillig /* 803 1.4 rillig * In a _Bool variable, FLAG28 is stored as 1, since it is unequal to 804 1.4 rillig * zero. In a uint8_t, the stored value would be 0 since bit 28 is 805 1.4 rillig * out of range for a uint8_t and thus gets truncated. 806 1.3 rillig */ 807 1.38 rillig /* expect+1: error: operands of '=' have incompatible types '_Bool' and 'int' [107] */ 808 1.36 rillig b = flags & FLAG28; 809 1.3 rillig } 810 1.3 rillig 811 1.4 rillig /* 812 1.8 rillig * Demonstrate idiomatic code to query flags from an enum bit set. 813 1.8 rillig * 814 1.8 rillig * In all the controlling expressions in this function, the result of the 815 1.8 rillig * operator '&' is compared against 0. This makes this pattern work, no 816 1.8 rillig * matter whether the bits are in the low-value range or in the high-value 817 1.8 rillig * range (such as FLAG28, which has the value 1073741824, which is more than 818 1.8 rillig * what would fit into an unsigned char). Even if an enum could be extended 819 1.8 rillig * to larger types than int, this pattern would work. 820 1.4 rillig */ 821 1.47 rillig bool 822 1.8 rillig query_flag_from_enum_bit_set(enum Flags flags) 823 1.4 rillig { 824 1.8 rillig if (flags & FLAG0) 825 1.8 rillig println("FLAG0 is set"); 826 1.4 rillig 827 1.8 rillig if ((flags & FLAG1) != 0) 828 1.8 rillig println("FLAG1 is set"); 829 1.4 rillig 830 1.8 rillig if ((flags & (FLAG0 | FLAG1)) == (FLAG0 | FLAG1)) 831 1.8 rillig println("FLAG0 and FLAG1 are both set"); 832 1.4 rillig 833 1.8 rillig if (flags & FLAG0 && flags & FLAG1) 834 1.8 rillig println("FLAG0 and FLAG1 are both set"); 835 1.4 rillig 836 1.8 rillig if ((flags & (FLAG0 | FLAG1)) != 0) 837 1.8 rillig println("At least one of FLAG0 and FLAG1 is set"); 838 1.4 rillig 839 1.8 rillig if (flags & FLAG28) 840 1.8 rillig println("FLAG28 is set"); 841 1.47 rillig 842 1.47 rillig /* expect+1: error: operands of 'init' have incompatible types '_Bool' and 'int' [107] */ 843 1.47 rillig bool b0 = flags & FLAG0; 844 1.47 rillig /* expect+1: error: operands of 'init' have incompatible types '_Bool' and 'int' [107] */ 845 1.47 rillig bool b1 = flags & FLAG1; 846 1.47 rillig /* expect+1: error: operands of 'init' have incompatible types '_Bool' and 'int' [107] */ 847 1.47 rillig bool b28 = flags & FLAG28; 848 1.47 rillig return b0 || b1 || b28; 849 1.7 rillig } 850 1.10 rillig 851 1.47 rillig bool 852 1.46 rillig query_flag_from_int(int flags) 853 1.46 rillig { 854 1.47 rillig 855 1.46 rillig if (flags & FLAG0) 856 1.46 rillig println("FLAG0 is set"); 857 1.46 rillig 858 1.46 rillig if ((flags & FLAG1) != 0) 859 1.46 rillig println("FLAG1 is set"); 860 1.46 rillig 861 1.46 rillig if ((flags & (FLAG0 | FLAG1)) == (FLAG0 | FLAG1)) 862 1.46 rillig println("FLAG0 and FLAG1 are both set"); 863 1.46 rillig 864 1.46 rillig if (flags & FLAG0 && flags & FLAG1) 865 1.46 rillig println("FLAG0 and FLAG1 are both set"); 866 1.46 rillig 867 1.46 rillig if ((flags & (FLAG0 | FLAG1)) != 0) 868 1.46 rillig println("At least one of FLAG0 and FLAG1 is set"); 869 1.46 rillig 870 1.46 rillig if (flags & FLAG28) 871 1.46 rillig println("FLAG28 is set"); 872 1.47 rillig 873 1.47 rillig /* expect+1: error: operands of 'init' have incompatible types '_Bool' and 'int' [107] */ 874 1.47 rillig bool b0 = flags & FLAG0; 875 1.47 rillig /* expect+1: error: operands of 'init' have incompatible types '_Bool' and 'int' [107] */ 876 1.47 rillig bool b1 = flags & FLAG1; 877 1.47 rillig /* expect+1: error: operands of 'init' have incompatible types '_Bool' and 'int' [107] */ 878 1.47 rillig bool b28 = flags & FLAG28; 879 1.47 rillig return b0 || b1 || b28; 880 1.46 rillig } 881 1.46 rillig 882 1.10 rillig 883 1.12 rillig void 884 1.10 rillig strict_bool_operator_eq_bool_int(void) 885 1.10 rillig { 886 1.38 rillig /* expect+1: error: operands of '==' have incompatible types '_Bool' and 'int' [107] */ 887 1.36 rillig (void)(strict_bool_conversion_return_false() == 0); 888 1.10 rillig } 889 1.13 rillig 890 1.13 rillig void 891 1.13 rillig strict_bool_assign_bit_field_then_compare(void) 892 1.13 rillig { 893 1.13 rillig struct s { 894 1.13 rillig bool flag: 1; 895 1.13 rillig }; 896 1.13 rillig 897 1.13 rillig struct s s = { __lint_false }; 898 1.13 rillig 899 1.36 rillig /* expect+1: warning: expression has null effect [129] */ 900 1.36 rillig (void)((s.flag = s.flag) != __lint_false); 901 1.13 rillig } 902 1.18 rillig 903 1.18 rillig void 904 1.18 rillig bool_as_array_index(bool cond) 905 1.18 rillig { 906 1.18 rillig static const char *repr[] = { "no", "yes" }; 907 1.18 rillig /* 908 1.18 rillig * The '+' in the error message reveals that lint internally 909 1.18 rillig * translates 'arr[ind]' to '*(arr + ind)' in an early stage of 910 1.18 rillig * parsing. 911 1.18 rillig */ 912 1.36 rillig /* expect+1: error: right operand of '+' must not be bool [337] */ 913 1.36 rillig println(repr[cond]); 914 1.18 rillig println(cond ? "yes" : "no"); 915 1.18 rillig } 916 1.20 rillig 917 1.20 rillig void 918 1.23 rillig initialization(void) 919 1.23 rillig { 920 1.23 rillig struct { 921 1.23 rillig _Bool b; 922 1.23 rillig } var[] = { 923 1.23 rillig { __lint_false }, 924 1.23 rillig { __lint_true }, 925 1.38 rillig /* expect+1: error: operands of 'init' have incompatible types '_Bool' and 'int' [107] */ 926 1.36 rillig { 0 }, 927 1.38 rillig /* expect+1: error: operands of 'init' have incompatible types '_Bool' and 'int' [107] */ 928 1.36 rillig { 1 }, 929 1.23 rillig }; 930 1.23 rillig } 931