1/* $NetBSD: gcc_bit_field_types.c,v 1.9 2023/03/28 14:44:34 rillig Exp $ */ 2# 3 "gcc_bit_field_types.c" 3 4/* lint1-extra-flags: -X 351 */ 5 6struct incompatible { 7 int dummy; 8}; 9void reveal_type(struct incompatible); 10 11/* 12 * https://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit-fields-implementation.html 13 * 14 * "Other integer types, such as long int, and enumerated types are permitted 15 * even in strictly conforming mode." 16 * 17 * See msg_035.c. 18 */ 19 20struct example { 21 int int_flag: 1; 22 unsigned int unsigned_int_flag: 1; 23 long long_flag: 1; 24 unsigned long unsigned_long_flag: 1; 25 long long long_long_flag: 1; 26 unsigned long long unsigned_long_long_flag: 1; 27 /* expect+1: warning: illegal bit-field type 'double' [35] */ 28 double double_flag: 1; 29}; 30 31struct large_bit_field { 32 unsigned long long member: 48; 33}; 34 35unsigned long long 36promote_large_bit_field(struct large_bit_field lbf) 37{ 38 /* 39 * Before tree.c 1.281 from 2021-05-04: 40 * lint: assertion "len == size_in_bits(INT)" failed 41 * in promote at tree.c:1698 42 */ 43 return lbf.member & 0xf; 44} 45 46/* 47 * C99 6.7.2.1p4 says: "A bit-field shall have a type that is a qualified or 48 * unqualified version of _Bool, signed int, unsigned int, or some other 49 * implementation-defined type." 50 * 51 * The wording of that constraint does not disambiguate whether it is talking 52 * about the declared underlying type of the storage unit or the expression 53 * type when evaluating a bit-field as an rvalue. 54 */ 55void 56type_of_bit_field(void) 57{ 58 struct { 59 unsigned bits:3; 60 } s; 61 62 /* 63 * Lint interprets the type of the bit-field is 'unsigned:3', which 64 * matches the non-bit-field type 'unsigned' in the _Generic 65 * expression. (XXX: May or may not be intended.) 66 * 67 * The _Generic expression prevents the integer promotions from 68 * getting applied as part of the function argument conversions. 69 * 70 * GCC 11 says: error: '_Generic' selector of type 'unsigned char:3' 71 * is not compatible with any association 72 * 73 * Clang 15 says: error: controlling expression type 'unsigned int' 74 * not compatible with any generic association type 75 * 76 * TCC says: error: type 'unsigned int' does not match any association 77 * 78 * MSVC 19 says: error C7702: no compatible type for 'unsigned int' 79 * in _Generic association list 80 * 81 * ICC 2021.7.1 says: error: no association matches the selector type 82 * "unsigned int" 83 */ 84 /* expect+4: warning: passing 'pointer to unsigned int' to incompatible 'struct incompatible', arg #1 [155] */ 85 reveal_type(_Generic(s.bits, 86 int: (int *)0, 87 unsigned int: (unsigned int *)0 88 )); 89 90 /* 91 * When lint promotes the bit-field as part of the function argument 92 * conversions, the type 'unsigned:3' gets promoted to 'int', as that 93 * is the smallest candidate type that can represent all possible 94 * values from 'unsigned:3', see promote_c90. Maybe that's wrong, 95 * maybe not, the compilers disagree so lint can offer yet another 96 * alternative interpretation. 97 * 98 * GCC 12 says: expected 'struct incompatible' but argument is of 99 * type 'unsigned char:3' 100 * 101 * Clang 15 says: error: passing 'unsigned int' to parameter of 102 * incompatible type 'struct incompatible' 103 * 104 * MSVC 19 says: error C2440: 'function': cannot convert from 105 * 'unsigned int' to 'incompatible' 106 */ 107 /* expect+1: warning: passing 'unsigned int:3' to incompatible 'struct incompatible', arg #1 [155] */ 108 reveal_type(s.bits); 109} 110