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