xref: /netbsd-src/tests/usr.bin/xlint/lint1/lang_level_c99.c (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
1 /*	$NetBSD: lang_level_c99.c,v 1.2 2023/08/06 19:44:50 rillig Exp $	*/
2 # 3 "lang_level_c99.c"
3 
4 /*
5  * Tests that are specific to the C99 language level, in particular, features
6  * that were added in C99.
7  *
8  * In the below comments, [-] means unsupported and [x] means supported.
9  */
10 
11 /* lint1-flags: -S -w -X 351 */
12 
13 /* C99 Foreword */
14 
15 // [-] restricted character set support via digraphs and <iso646.h>
16 //
17 // Lint neither parses digraphs nor trigraphs.
18 
19 // [x] wide character library support in <wchar.h> and <wctype.h>
20 //
21 // On all supported platforms, 'wchar_t' == 'int'.
22 
23 const int wide_string[] = L"wide";
24 
25 // [x] more precise aliasing rules via effective type
26 //
27 // Irrelevant, as lint does not check the runtime behavior.
28 
29 // [x] restricted pointers
30 //
31 // Can be parsed, are otherwise ignored.
32 
33 // [-] variable length arrays
34 //
35 // Variable length arrays are handled as if the number of elements in the array
36 // were always 1.
37 
38 /* FIXME: Parameter 'n' _is_ actually used. */
39 /* expect+2: warning: parameter 'n' unused in function 'variable_length_arrays' [231] */
40 unsigned long long
41 variable_length_arrays(int n)
42 {
43 	int vla[n];
44 	/* FIXME: The array dimension is not constant, but still negative. */
45 	/* expect+1: error: negative array dimension (-4) [20] */
46 	typedef int sizeof_vla[-(int)sizeof(vla)];
47 	return sizeof(vla);
48 }
49 
50 // [x] flexible array members
51 //
52 // Flexible array members are parsed but not validated thoroughly.
53 
54 void
55 flexible_array_members(void)
56 {
57 	struct {
58 		int regular;
59 		int flexible[];
60 	} s = {
61 		0,
62 		// Flexible array member must not be initialized.  Lint does
63 		// not detect this, leaving the job to the C99 compiler.
64 		{ 1, 3, 4, }
65 	};
66 	/* expect+1: error: negative array dimension (-4) [20] */
67 	typedef int sizeof_s[-(int)sizeof(s)];
68 }
69 
70 // [x] static and type qualifiers in parameter array declarators
71 //
72 // Can be parsed, are otherwise ignored.
73 
74 // [-] complex (and imaginary) support in <complex.h>
75 //
76 // Lint does not keep track of which parts of a complex object are initialized.
77 //
78 // Lint does not support '_Imaginary'.
79 
80 // [x] type-generic math macros in <tgmath.h>
81 //
82 // Irrelevant, as lint only sees the preprocessed source code.
83 
84 // [x] the long long int type and library functions
85 //
86 // On all platforms supported by lint, 'long long' is 64 bits wide.  The other
87 // fixed-width types are 'char', 'short', 'int' and (only on 64-bit platforms)
88 // '__int128_t'.
89 //
90 // The lint standard libraries -lstdc and -lposix do not contain the
91 // functions added in C99.
92 
93 /* expect+1: error: negative array dimension (-1) [20] */
94 typedef int sizeof_char[-(int)sizeof(char)];
95 /* expect+1: error: negative array dimension (-2) [20] */
96 typedef int sizeof_short[-(int)sizeof(short)];
97 /* expect+1: error: negative array dimension (-4) [20] */
98 typedef int sizeof_int[-(int)sizeof(int)];
99 /* expect+1: error: negative array dimension (-8) [20] */
100 typedef int sizeof_long_long[-(int)sizeof(long long)];
101 
102 // [x] increased minimum translation limits
103 //
104 // Irrelevant, as lint does not have any hard-coded limits.
105 
106 // [x] additional floating-point characteristics in <float.h>
107 //
108 // Lint has very limited support for floating point numbers, as it fully relies
109 // on the host platform.  This is noticeable when cross-compiling between
110 // platforms with different size or representation of 'long double'.
111 
112 // [x] remove implicit int
113 //
114 // Lint parses old-style declarations and marks them as errors.
115 
116 // [x] reliable integer division
117 //
118 // The lint source code requires a C99 compiler, so when mapping the integer
119 // operations to those from the host platform, lint uses these.
120 
121 // [-] universal character names (\u and \U)
122 //
123 // No, as nothing in the NetBSD source tree uses this feature.
124 
125 // [-] extended identifiers
126 //
127 // No, as nothing in the NetBSD source tree uses this feature.
128 
129 // [x] hexadecimal floating-point constants and %a and %A printf/scanf
130 // conversion specifiers
131 
132 void pf();			/* no prototype parameters */
133 
134 void
135 hexadecimal_floating_point_constants(void)
136 {
137 	double hex = 0x1.0p34;
138 	pf("%s %a\n", "hex", hex);
139 }
140 
141 // [x] compound literals
142 //
143 // See d_c99_compound_literal_comma.c.
144 
145 // [x] designated initializers
146 //
147 // See d_c99_init.c.
148 
149 // [x] // comments
150 //
151 // Also supported in GCC mode.
152 
153 // [?] extended integer types and library functions in <inttypes.h> and
154 // <stdint.h>
155 //
156 // TODO
157 
158 // [x] remove implicit function declaration
159 
160 void
161 call_implicitly_declared_function(void)
162 {
163 	/* expect+1: error: function 'implicitly_declared_function' implicitly declared to return int [215] */
164 	implicitly_declared_function(0);
165 }
166 
167 // [x] preprocessor arithmetic done in intmax_t/uintmax_t
168 //
169 // Irrelevant, as lint only sees the preprocessed source code.
170 
171 // [x] mixed declarations and code
172 
173 // [x] new block scopes for selection and iteration statements
174 
175 // [?] integer constant type rules
176 //
177 // TODO
178 
179 // [?] integer promotion rules
180 //
181 // TODO
182 
183 // [x] macros with a variable number of arguments
184 //
185 // Irrelevant, as lint only sees the preprocessed source code.
186 
187 // [x] the vscanf family of functions in <stdio.h> and <wchar.h>
188 //
189 // Irrelevant, as typical C99 compilers already check these.
190 
191 // [x] additional math library functions in <math.h>
192 //
193 // Irrelevant, as lint does not check arithmetic expressions.
194 //
195 // Lint also does not generate its own standard library definition for libm.
196 
197 // [x] treatment of error conditions by math library functions
198 // (math_errhandling)
199 //
200 // Irrelevant, as lint does not check for error handling.
201 
202 // [x] floating-point environment access in <fenv.h>
203 //
204 // TODO
205 
206 // [x] IEC 60559 (also known as IEC 559 or IEEE arithmetic) support
207 //
208 // On platforms that conform to IEC 60559, lint performs the arithmetic
209 // operations accordingly.  When cross-compiling on a vax host for other target
210 // platforms, no such support is available.
211 
212 // [x] trailing comma allowed in enum declaration
213 //
214 // Yes, see the grammar rule 'enums_with_opt_comma'.
215 
216 // [-] %lf conversion specifier allowed in printf
217 //
218 // TODO: see tests/lint2/msg_013.exp.
219 
220 // [x] inline functions
221 //
222 // Yes, also allowed in GCC mode.
223 
224 // [x] the snprintf family of functions in <stdio.h>
225 //
226 // The snprintf functions are treated like all other functions.  The checks for
227 // matching format strings targets traditional C only and thus does not apply
228 // to these functions, as they have a prototype definition.
229 
230 // [x] boolean type in <stdbool.h>
231 //
232 // Yes.  Conversion to and from boolean follows 6.3.1.2.  See also the -T flag,
233 // which enables 'strict bool mode'.
234 
235 // [x] idempotent type qualifiers
236 //
237 // Lint warns about duplicate type qualifiers but accepts them otherwise.
238 
239 /* expect+1: warning: duplicate 'const' [10] */
240 const const int duplicate_type_qualifier = 2;
241 
242 // [x] empty macro arguments
243 //
244 // Irrelevant, as lint only sees the preprocessed source code.
245 
246 // [?] new structure type compatibility rules (tag compatibility)
247 //
248 // TODO
249 
250 // [x] additional predefined macro names
251 //
252 // Irrelevant, as lint only sees the preprocessed source code.
253 
254 // [-] _Pragma preprocessing operator
255 //
256 // No, not yet asked for.
257 
258 // [-] standard pragmas
259 //
260 // No, not yet asked for.
261 
262 // [x] __func__ predefined identifier
263 //
264 // Yes, see 'fallback_symbol'.
265 
266 // [x] va_copy macro
267 //
268 // Irrelevant, as lint only sees the preprocessed source code.
269 
270 // [x] additional strftime conversion specifiers
271 //
272 // Irrelevant, as lint does not check strftime in depth.
273 
274 // [?] LIA compatibility annex
275 //
276 // TODO
277 
278 // [x] deprecate ungetc at the beginning of a binary file
279 //
280 // Irrelevant, as lint's analysis is not that deep into the runtime behavior.
281 
282 // [x] remove deprecation of aliased array parameters
283 //
284 // Irrelevant, as lint does not check for aliasing.
285 
286 // [?] conversion of array to pointer not limited to lvalues
287 //
288 // TODO
289 
290 // [x] relaxed constraints on aggregate and union initialization
291 //
292 // Yes, struct and union members can be initialized with non-constant
293 // expressions.  Members that have struct or union type can be initialized with
294 // an expression of the same type.
295 
296 // [x] relaxed restrictions on portable header names
297 //
298 // Irrelevant, as lint only sees the preprocessed source code.
299 
300 // [x] return without expression not permitted in function that returns a value
301 // (and vice versa)
302 
303 void
304 return_no_expr(int x)
305 {
306 	x++;
307 	/* expect+1: error: void function 'return_no_expr' cannot return value [213] */
308 	return x;
309 }
310 
311 int
312 return_expr(void)
313 {
314 	/* expect+1: error: function 'return_expr' expects to return value [214] */
315 	return;
316 }
317