xref: /netbsd-src/tests/usr.bin/xlint/lint1/decl_arg.c (revision 3d6a50253cd682dca85a66a49baee893251dac65)
1 /*	$NetBSD: decl_arg.c,v 1.17 2025/01/03 03:14:47 rillig Exp $	*/
2 # 3 "decl_arg.c"
3 
4 /*
5  * Tests for declarations of function parameters.
6  *
7  * See arg_declaration in cgram.y.
8  */
9 
10 /* lint1-extra-flags: -X 351 */
11 
12 typedef double number;
13 
14 void no_args(void);
15 void type_unnamed(double );
16 void type_named(double arg);
17 void typedef_unnamed_prototype(number);
18 void typedef_named(number arg);
19 
20 void type_qualifier(const number);
21 void type_qualifier_pointer(const number *const);
22 
23 /*
24  * Just some unrealistic coverage for the grammar rule 'arg_declaration'.
25  */
26 extern void
27 /* expect+6: warning: function definition for 'old_style' with identifier list is obsolete in C23 [384] */
28 /* expect+5: warning: parameter 'an_int' unused in function 'old_style' [231] */
29 /* expect+4: warning: parameter 'a_const_int' unused in function 'old_style' [231] */
30 /* expect+3: warning: parameter 'a_number' unused in function 'old_style' [231] */
31 /* expect+2: warning: parameter 'a_function' unused in function 'old_style' [231] */
32 /* expect+1: warning: parameter 'a_struct' unused in function 'old_style' [231] */
33 old_style(an_int, a_const_int, a_number, a_function, a_struct)
34 /* expect+2: error: only 'register' is valid as storage class in parameter [9] */
35 /* expect+1: warning: empty declaration [2] */
36 static;
37 /* expect+1: error: syntax error '"' [249] */
38 static "error";
39 /* expect+1: warning: empty declaration [2] */
40 const;
41 /* expect+1: error: declared parameter 'undeclared' is missing [53] */
42 const undeclared;
43 /* expect+2: error: declared parameter 'undeclared_initialized' is missing [53] */
44 /* expect+1: error: cannot initialize parameter 'undeclared_initialized' [52] */
45 const undeclared_initialized = 12345;
46 /* expect+1: warning: empty declaration [2] */
47 int;
48 /* expect+1: warning: 'struct arg_struct' declared in parameter declaration list [3] */
49 struct arg_struct { int member; };
50 /* expect+1: error: cannot initialize parameter 'an_int' [52] */
51 int an_int = 12345;
52 const int a_const_int;
53 number a_number;
54 void (a_function) (number);
55 /* expect+1: warning: 'struct a_struct' declared in parameter declaration list [3] */
56 struct a_struct { int member; } a_struct;
57 {
58 }
59 
60 /*
61  * Just some unrealistic coverage for the grammar rule
62  * 'notype_direct_declarator'.
63  */
64 extern int
65 /* expect+1: warning: function definition for 'cover_notype_direct_decl' with identifier list is obsolete in C23 [384] */
66 cover_notype_direct_decl(arg)
67 int arg;
68 /* expect+1: error: declared parameter 'name' is missing [53] */
69 const name;
70 /* expect+1: error: declared parameter 'parenthesized_name' is missing [53] */
71 const (parenthesized_name);
72 /* expect+1: error: declared parameter 'array' is missing [53] */
73 const array[];
74 /* expect+1: error: declared parameter 'array_size' is missing [53] */
75 const array_size[1+1+1];
76 /* expect+2: error: null dimension [17] */
77 /* expect+1: error: declared parameter 'multi_array' is missing [53] */
78 const multi_array[][][][][][];
79 /* expect+1: error: declared parameter 'function' is missing [53] */
80 const function(void);
81 /* expect+1: error: declared parameter 'prefix_attribute' is missing [53] */
82 const __attribute__((deprecated)) prefix_attribute;
83 /* expect+1: error: declared parameter 'postfix_attribute' is missing [53] */
84 const postfix_attribute __attribute__((deprecated));
85 /* expect+1: error: declared parameter 'infix_attribute' is missing [53] */
86 const __attribute__((deprecated)) infix_attribute __attribute__((deprecated));
87 /* The __attribute__ before the '*' is consumed by some other grammar rule. */
88 /* expect+7: error: declared parameter 'pointer_prefix_attribute' is missing [53] */
89 const
90     __attribute__((deprecated))
91     *
92     __attribute__((deprecated))
93     __attribute__((deprecated))
94     __attribute__((deprecated))
95     pointer_prefix_attribute;
96 {
97 	return arg;
98 }
99 
100 // The attribute 'unused' belongs to the parameter.
101 // The attribute 'format' belongs to the function type.
102 void
103 param_func_attr_unused(
104     void (*pr)(const char *, ...)
105 	__attribute__((__unused__))
106 	__attribute__((__format__(__printf__, 1, 2)))
107 )
108 {
109 }
110 
111 // The attribute 'unused' belongs to the parameter.
112 // The attribute 'format' belongs to the function type.
113 void
114 param_func_attr_printf(
115     void (*pr)(const char *, ...)
116 	__attribute__((__unused__))
117 	__attribute__((__format__(__printf__, 1, 2)))
118 )
119 {
120 	// GCC and Clang already warn about the malformed format string,
121 	// so there is nothing left to do for lint.
122 	pr("%");
123 }
124 
125 /*
126  * XXX: To cover the grammar rule 'direct_notype_param_decl', the parameters
127  *  need to be enclosed by one more pair of parentheses than usual.
128  */
129 void cover_direct_notype_param_decl(
130     double (identifier),
131     double ((parenthesized)),
132     double (array[]),
133     double (array_size[3]),
134     double (*)(void (function()))
135 );
136 
137 /*
138  * Just some unrealistic code to cover the grammar rule parameter_declaration.
139  */
140 /* expect+4: error: only 'register' is valid as storage class in parameter [9] */
141 void cover_parameter_declaration(
142     volatile,			/* 1 */
143     double,			/* 2 */
144     static storage_class,	/* 3.1 */
145     const type_qualifier,	/* 3.2 */
146     double (identifier),	/* 4 */
147     const (*),			/* 5 */
148     double *const,		/* 6 */
149     ...
150 );
151 
152 void cover_asm_or_symbolrename_asm(void)
153     __asm("assembly code");
154 
155 void cover_asm_or_symbolrename_symbolrename(void)
156     __symbolrename(alternate_name);
157 
158 
159 double
160 /* expect+1: warning: function definition for 'f' with identifier list is obsolete in C23 [384] */
161 f(e, s, r, a, t, n)
162 	/* expect+1: error: only 'register' is valid as storage class in parameter [9] */
163 	extern double e;
164 	/* expect+1: error: only 'register' is valid as storage class in parameter [9] */
165 	static double s;
166 	register double r;
167 	/* expect+1: error: only 'register' is valid as storage class in parameter [9] */
168 	auto double a;
169 	/* expect+1: error: only 'register' is valid as storage class in parameter [9] */
170 	typedef double t;
171 	double n;
172 {
173 	return e + s + r + a + t + n;
174 }
175 
176 
177 // FIXME: internal error in decl.c:906 near decl_arg.c:134: length(0)
178 //void cover_abstract_declarator_typeof(void (*)(typeof(no_args)));
179