decl.c revision 1.35 1 1.35 rillig /* $NetBSD: decl.c,v 1.35 2025/04/12 15:49:49 rillig Exp $ */
2 1.1 rillig # 3 "decl.c"
3 1.1 rillig
4 1.1 rillig /*
5 1.1 rillig * Tests for declarations, especially the distinction between the
6 1.1 rillig * declaration-specifiers and the declarators.
7 1.1 rillig */
8 1.1 rillig
9 1.22 rillig /* lint1-extra-flags: -X 191,351 */
10 1.21 rillig
11 1.1 rillig /*
12 1.1 rillig * Even though 'const' comes after 'char' and is therefore quite close to the
13 1.1 rillig * first identifier, it applies to both identifiers.
14 1.1 rillig */
15 1.1 rillig void
16 1.1 rillig specifier_qualifier(void)
17 1.1 rillig {
18 1.1 rillig char const a = 1, b = 2;
19 1.1 rillig
20 1.1 rillig /* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */
21 1.1 rillig a = 1;
22 1.1 rillig /* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */
23 1.1 rillig b = 2;
24 1.1 rillig }
25 1.1 rillig
26 1.1 rillig /*
27 1.1 rillig * Since 'const' comes before 'char', there is no ambiguity whether the
28 1.1 rillig * 'const' applies to all variables or just to the first.
29 1.1 rillig */
30 1.1 rillig void
31 1.1 rillig qualifier_specifier(void)
32 1.1 rillig {
33 1.1 rillig const char a = 1, b = 2;
34 1.1 rillig
35 1.1 rillig /* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */
36 1.1 rillig a = 3;
37 1.1 rillig /* expect+1: warning: left operand of '=' must be modifiable lvalue [115] */
38 1.1 rillig b = 5;
39 1.1 rillig }
40 1.1 rillig
41 1.1 rillig void
42 1.1 rillig declarator_with_prefix_qualifier(void)
43 1.1 rillig {
44 1.17 rillig /* expect+1: error: syntax error 'const' [249] */
45 1.1 rillig char a = 1, const b = 2;
46 1.1 rillig
47 1.1 rillig a = 1;
48 1.1 rillig /* expect+1: error: 'b' undefined [99] */
49 1.1 rillig b = 2;
50 1.1 rillig }
51 1.1 rillig
52 1.1 rillig void
53 1.1 rillig declarator_with_postfix_qualifier(void)
54 1.1 rillig {
55 1.17 rillig /* expect+1: error: syntax error 'const' [249] */
56 1.1 rillig char a = 1, b const = 2;
57 1.1 rillig
58 1.1 rillig a = 1;
59 1.1 rillig b = 2;
60 1.1 rillig }
61 1.1 rillig
62 1.1 rillig void sink(double *);
63 1.1 rillig
64 1.1 rillig void
65 1.1 rillig declarators(void)
66 1.1 rillig {
67 1.1 rillig char *pc = 0, c = 0, **ppc = 0;
68 1.1 rillig
69 1.17 rillig /* expect+1: warning: converting 'pointer to char' to incompatible 'pointer to double' for argument 1 [153] */
70 1.1 rillig sink(pc);
71 1.35 rillig /* expect+1: warning: invalid combination of pointer 'pointer to double' and integer 'char', arg #1 [154] */
72 1.1 rillig sink(c);
73 1.17 rillig /* expect+1: warning: converting 'pointer to pointer to char' to incompatible 'pointer to double' for argument 1 [153] */
74 1.1 rillig sink(ppc);
75 1.1 rillig }
76 1.2 rillig
77 1.2 rillig _Bool
78 1.2 rillig enum_error_handling(void)
79 1.2 rillig {
80 1.2 rillig enum {
81 1.17 rillig /* expect+1: error: syntax error '"' [249] */
82 1.2 rillig "error 1"
83 1.2 rillig : /* still the same error */
84 1.2 rillig , /* back on track */
85 1.2 rillig A,
86 1.2 rillig B
87 1.2 rillig } x = A;
88 1.2 rillig
89 1.2 rillig return x == B;
90 1.2 rillig }
91 1.3 rillig
92 1.4 rillig /*
93 1.4 rillig * An __attribute__ at the beginning of a declaration may become ambiguous
94 1.4 rillig * since a GCC fallthrough statement starts with __attribute__ as well.
95 1.4 rillig */
96 1.3 rillig void
97 1.3 rillig unused_local_variable(void)
98 1.3 rillig {
99 1.3 rillig __attribute__((unused)) _Bool unused_var;
100 1.3 rillig
101 1.3 rillig __attribute__((unused))
102 1.3 rillig __attribute__((unused)) _Bool unused_twice;
103 1.3 rillig }
104 1.5 rillig
105 1.5 rillig int
106 1.5 rillig declaration_without_type_specifier(void)
107 1.5 rillig {
108 1.5 rillig const i = 3;
109 1.20 rillig /* expect-1: error: old-style declaration; add 'int' [1] */
110 1.5 rillig return i;
111 1.5 rillig }
112 1.5 rillig
113 1.16 rillig
114 1.16 rillig /* expect+2: warning: static function 'unused' unused [236] */
115 1.5 rillig static void
116 1.5 rillig unused(void)
117 1.5 rillig {
118 1.5 rillig }
119 1.5 rillig
120 1.5 rillig /*
121 1.5 rillig * The attribute 'used' does not influence static functions, it only
122 1.5 rillig * applies to function parameters.
123 1.5 rillig */
124 1.5 rillig /* LINTED */
125 1.5 rillig static void
126 1.5 rillig unused_linted(void)
127 1.5 rillig {
128 1.5 rillig }
129 1.6 rillig
130 1.6 rillig /* covers 'type_qualifier_list: type_qualifier_list type_qualifier' */
131 1.6 rillig int *const volatile cover_type_qualifier_list;
132 1.7 rillig
133 1.8 rillig _Bool bool;
134 1.8 rillig char plain_char;
135 1.8 rillig signed char signed_char;
136 1.8 rillig unsigned char unsigned_char;
137 1.8 rillig short signed_short;
138 1.8 rillig unsigned short unsigned_short;
139 1.8 rillig int signed_int;
140 1.8 rillig unsigned int unsigned_int;
141 1.8 rillig long signed_long;
142 1.8 rillig unsigned long unsigned_long;
143 1.9 rillig struct {
144 1.9 rillig int member;
145 1.9 rillig } unnamed_struct;
146 1.8 rillig
147 1.8 rillig /*
148 1.8 rillig * Before decl.c 1.201 from 2021-07-15, lint crashed with an internal error
149 1.19 rillig * in dcs_end_type (named end_type back then).
150 1.8 rillig */
151 1.8 rillig unsigned long sizes =
152 1.8 rillig sizeof(const typeof(bool)) +
153 1.8 rillig sizeof(const typeof(plain_char)) +
154 1.8 rillig sizeof(const typeof(signed_char)) +
155 1.8 rillig sizeof(const typeof(unsigned_char)) +
156 1.8 rillig sizeof(const typeof(signed_short)) +
157 1.8 rillig sizeof(const typeof(unsigned_short)) +
158 1.8 rillig sizeof(const typeof(signed_int)) +
159 1.8 rillig sizeof(const typeof(unsigned_int)) +
160 1.8 rillig sizeof(const typeof(signed_long)) +
161 1.9 rillig sizeof(const typeof(unsigned_long)) +
162 1.9 rillig sizeof(const typeof(unnamed_struct));
163 1.10 rillig
164 1.20 rillig /* expect+2: error: old-style declaration; add 'int' [1] */
165 1.17 rillig /* expect+1: error: syntax error 'int' [249] */
166 1.10 rillig thread int thread_int;
167 1.10 rillig __thread int thread_int;
168 1.20 rillig /* expect+2: error: old-style declaration; add 'int' [1] */
169 1.17 rillig /* expect+1: error: syntax error 'int' [249] */
170 1.10 rillig __thread__ int thread_int;
171 1.12 rillig
172 1.12 rillig static
173 1.28 rillig /* expect+1: warning: static function 'cover_func_declarator' unused [236] */
174 1.12 rillig cover_func_declarator(void)
175 1.28 rillig /* expect+1: error: old-style declaration; add 'int' [1] */
176 1.12 rillig {
177 1.12 rillig }
178 1.13 rillig
179 1.13 rillig /*
180 1.13 rillig * Before decl.c 1.268 from 2022-04-03, lint ran into an assertion failure for
181 1.13 rillig * "elsz > 0" in 'length'.
182 1.13 rillig */
183 1.13 rillig /* expect+2: error: syntax error 'goto' [249] */
184 1.18 rillig /* expect+1: warning: empty array declaration for 'void_array_error' [190] */
185 1.13 rillig void void_array_error[] goto;
186 1.23 rillig
187 1.23 rillig const volatile int
188 1.23 rillig /* expect+1: warning: duplicate 'const' [10] */
189 1.23 rillig *const volatile const
190 1.23 rillig /* expect+1: warning: duplicate 'volatile' [10] */
191 1.23 rillig *volatile const volatile
192 1.23 rillig *duplicate_ptr;
193 1.24 rillig
194 1.24 rillig
195 1.24 rillig /*
196 1.24 rillig * Since tree.c 1.573 from 2023-07-15 and before decl.c 1.370 from 2023-07-31,
197 1.24 rillig * lint crashed due to a failed assertion in find_member. The assertion states
198 1.24 rillig * that every member of a struct or union must link back to its containing
199 1.24 rillig * type, which had not been the case for unnamed bit-fields.
200 1.24 rillig */
201 1.24 rillig struct bit_and_data {
202 1.24 rillig unsigned int :0;
203 1.24 rillig unsigned int bit:1;
204 1.24 rillig unsigned int :0;
205 1.24 rillig
206 1.24 rillig void *data;
207 1.24 rillig };
208 1.24 rillig
209 1.24 rillig static inline void *
210 1.24 rillig bit_and_data(struct bit_and_data *node)
211 1.24 rillig {
212 1.24 rillig return node->data;
213 1.24 rillig }
214 1.25 rillig
215 1.25 rillig
216 1.25 rillig // See cgram.y, rule 'notype_member_declarator'.
217 1.25 rillig void
218 1.25 rillig symbol_type_in_unnamed_bit_field_member(void)
219 1.25 rillig {
220 1.25 rillig enum {
221 1.25 rillig bits = 4,
222 1.25 rillig };
223 1.25 rillig
224 1.25 rillig struct s {
225 1.25 rillig // Since there is no name in the declarator, the next symbol
226 1.25 rillig // after the ':' must not be interpreted as a member name, but
227 1.27 rillig // instead as a variable, type or function (SK_VCFT).
228 1.25 rillig unsigned int :bits;
229 1.25 rillig int named_member;
230 1.25 rillig };
231 1.25 rillig }
232 1.26 rillig
233 1.26 rillig // Symbols that are defined in the parameter list of a function definition can
234 1.26 rillig // be accessed in the body of the function, even if they are nested.
235 1.26 rillig int
236 1.26 rillig get_x(struct point3d { struct point3d_number { int v; } x, y, z; } arg)
237 1.26 rillig {
238 1.26 rillig /* expect-1: warning: dubious tag declaration 'struct point3d' [85] */
239 1.26 rillig /* expect-2: warning: dubious tag declaration 'struct point3d_number' [85] */
240 1.26 rillig static struct point3d local;
241 1.26 rillig static struct point3d_number z;
242 1.26 rillig return arg.x.v + local.x.v + z.v;
243 1.26 rillig }
244 1.29 rillig
245 1.29 rillig // Expressions of the form '(size_t)&null_ptr->member' are used by several
246 1.30 rillig // C implementations to implement the offsetof macro.
247 1.29 rillig void
248 1.29 rillig offsetof_on_array_member(void)
249 1.29 rillig {
250 1.30 rillig typedef struct {
251 1.29 rillig int padding, plain, arr[2];
252 1.30 rillig } s1;
253 1.29 rillig
254 1.30 rillig // Bit-fields must have a constant number of bits.
255 1.29 rillig struct s2 {
256 1.30 rillig unsigned int off_plain:(unsigned long)&((s1 *)0)->plain;
257 1.30 rillig unsigned int off_arr:(unsigned long)&((s1 *)0)->arr;
258 1.30 rillig unsigned int off_arr_0:(unsigned long)&((s1 *)0)->arr[0];
259 1.30 rillig unsigned int off_arr_3:(unsigned long)&((s1 *)0)->arr[3];
260 1.29 rillig };
261 1.30 rillig
262 1.30 rillig // Arrays may be variable-width, but the diagnostic reveals the size.
263 1.30 rillig /* expect+1: error: negative array dimension (-4) [20] */
264 1.30 rillig typedef int off_plain[-(int)(unsigned long)&((s1 *)0)->plain];
265 1.30 rillig /* expect+1: error: negative array dimension (-8) [20] */
266 1.30 rillig typedef int off_arr[-(int)(unsigned long)&((s1 *)0)->arr];
267 1.30 rillig /* expect+1: error: negative array dimension (-8) [20] */
268 1.30 rillig typedef int off_arr_0[-(int)(unsigned long)&((s1 *)0)->arr[0]];
269 1.30 rillig /* expect+1: error: negative array dimension (-20) [20] */
270 1.30 rillig typedef int off_arr_3[-(int)(unsigned long)&((s1 *)0)->arr[3]];
271 1.29 rillig }
272 1.31 rillig
273 1.31 rillig /* PR bin/39639: writing "long double" gave "long int" */
274 1.31 rillig int
275 1.31 rillig long_double_vs_long_int(long double *a, long int *b)
276 1.31 rillig {
277 1.35 rillig /* expect+1: warning: invalid combination of 'pointer to long double' and 'pointer to long', op '==' [124] */
278 1.31 rillig return a == b;
279 1.31 rillig }
280 1.31 rillig
281 1.31 rillig struct zero_sized_array {
282 1.31 rillig int member[0];
283 1.31 rillig };
284 1.31 rillig
285 1.31 rillig void
286 1.31 rillig type_name_as_member_name(void)
287 1.31 rillig {
288 1.31 rillig typedef char h[10];
289 1.31 rillig
290 1.31 rillig typedef struct {
291 1.31 rillig int i;
292 1.31 rillig char *c;
293 1.31 rillig } fh;
294 1.31 rillig
295 1.31 rillig struct foo {
296 1.31 rillig fh h;
297 1.31 rillig struct {
298 1.31 rillig int x;
299 1.31 rillig int y;
300 1.31 rillig } fl;
301 1.31 rillig };
302 1.31 rillig }
303 1.32 rillig
304 1.32 rillig
305 1.32 rillig // When query 16 is not enabled, don't produce a 'previous declaration' message
306 1.32 rillig // without a preceding main diagnostic.
307 1.32 rillig static void static_function(void) __attribute__((__used__));
308 1.32 rillig
309 1.32 rillig // The definition is without 'static'.
310 1.32 rillig void
311 1.32 rillig static_function(void)
312 1.32 rillig {
313 1.32 rillig }
314 1.33 rillig
315 1.33 rillig
316 1.33 rillig typedef void (*fprint_function)(int, const char *, ...);
317 1.33 rillig typedef fprint_function (*change_logger)
318 1.33 rillig (fprint_function, fprint_function, fprint_function, fprint_function);
319 1.33 rillig
320 1.33 rillig // Provoke a long type name to test reallocation in type_name.
321 1.33 rillig /* expect+1: error: redeclaration of 'static_function' with type 'function(pointer to function(pointer to function(int, pointer to const char, ...) returning void, pointer to function(int, pointer to const char, ...) returning void, pointer to function(int, pointer to const char, ...) returning void, pointer to function(int, pointer to const char, ...) returning void) returning pointer to function(int, pointer to const char, ...) returning void) returning void', expected 'function(void) returning void' [347] */
322 1.33 rillig void static_function(change_logger);
323 1.34 rillig
324 1.34 rillig
325 1.34 rillig void no_prototype_declaration();
326 1.34 rillig void prototype_declaration(void);
327 1.34 rillig
328 1.34 rillig // TODO: Warn about the missing 'void', for C99 and later.
329 1.34 rillig void
330 1.34 rillig no_prototype_definition()
331 1.34 rillig {
332 1.34 rillig }
333 1.34 rillig
334 1.34 rillig void
335 1.34 rillig prototype_definition(void)
336 1.34 rillig {
337 1.34 rillig }
338