xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_132.c (revision 5685e47f6f29ba1fd654aaf86baf90bc2b72a6b5)
1 /*	$NetBSD: msg_132.c,v 1.53 2025/01/03 01:27:35 rillig Exp $	*/
2 # 3 "msg_132.c"
3 
4 // Test for message: conversion from '%s' to '%s' may lose accuracy [132]
5 
6 /*
7  * NetBSD's default lint flags only include a single -a, which only flags
8  * narrowing conversions from long.  To get warnings for all narrowing
9  * conversions, -a needs to be given more than once.
10  *
11  * https://gnats.netbsd.org/14531
12  */
13 
14 /* lint1-extra-flags: -aa -X 351 */
15 
16 typedef unsigned char u8_t;
17 typedef unsigned short u16_t;
18 typedef unsigned int u32_t;
19 typedef unsigned long long u64_t;
20 typedef signed char s8_t;
21 typedef signed short s16_t;
22 typedef signed int s32_t;
23 typedef signed long long s64_t;
24 
25 _Bool cond;
26 char ch;
27 
28 u8_t u8;
29 u16_t u16;
30 u32_t u32;
31 u64_t u64;
32 
33 s8_t s8;
34 s16_t s16;
35 s32_t s32;
36 s64_t s64;
37 
38 const char *ptr;
39 
40 struct bit_fields {
41 	unsigned u1:1;
42 	unsigned u2:2;
43 	unsigned u3:3;
44 	unsigned u4:4;
45 	unsigned u5:5;
46 	unsigned u6:6;
47 	unsigned u7:7;
48 	unsigned u8:8;
49 	unsigned u9:9;
50 	unsigned u10:10;
51 	unsigned u11:11;
52 	unsigned u12:12;
53 	unsigned u32:32;
54 } bits;
55 
56 
57 void
58 unsigned_to_unsigned(void)
59 {
60 	/* expect+1: warning: conversion from 'unsigned short' to 'unsigned char' may lose accuracy [132] */
61 	u8 = u16;
62 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
63 	u8 = u32;
64 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
65 	u8 = u64;
66 
67 	u16 = u8;
68 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
69 	u16 = u32;
70 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned short' may lose accuracy [132] */
71 	u16 = u64;
72 
73 	u32 = u8;
74 	u32 = u16;
75 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
76 	u32 = u64;
77 
78 	u64 = u8;
79 	u64 = u16;
80 	u64 = u32;
81 }
82 
83 void
84 unsigned_to_signed(void)
85 {
86 	/* expect+1: warning: conversion from 'unsigned short' to 'signed char' may lose accuracy [132] */
87 	s8 = u16;
88 	/* expect+1: warning: conversion from 'unsigned int' to 'signed char' may lose accuracy [132] */
89 	s8 = u32;
90 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
91 	s8 = u64;
92 
93 	s16 = u8;
94 	/* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */
95 	s16 = u32;
96 	/* expect+1: warning: conversion from 'unsigned long long' to 'short' may lose accuracy [132] */
97 	s16 = u64;
98 
99 	s32 = u8;
100 	s32 = u16;
101 	/* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
102 	s32 = u64;
103 
104 	s64 = u8;
105 	s64 = u16;
106 	s64 = u32;
107 }
108 
109 void
110 signed_to_unsigned(void)
111 {
112 	/* expect+1: warning: conversion from 'short' to 'unsigned char' may lose accuracy [132] */
113 	u8 = s16;
114 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
115 	u8 = s32;
116 	/* expect+1: warning: conversion from 'long long' to 'unsigned char' may lose accuracy [132] */
117 	u8 = s64;
118 
119 	u16 = s8;
120 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
121 	u16 = s32;
122 	/* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */
123 	u16 = s64;
124 
125 	u32 = s8;
126 	u32 = s16;
127 	/* expect+1: warning: conversion from 'long long' to 'unsigned int' may lose accuracy [132] */
128 	u32 = s64;
129 
130 	u64 = s8;
131 	u64 = s16;
132 	u64 = s32;
133 }
134 
135 void
136 signed_to_signed(void)
137 {
138 	/* expect+1: warning: conversion from 'short' to 'signed char' may lose accuracy [132] */
139 	s8 = s16;
140 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
141 	s8 = s32;
142 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
143 	s8 = s64;
144 
145 	s16 = s8;
146 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
147 	s16 = s32;
148 	/* expect+1: warning: conversion from 'long long' to 'short' may lose accuracy [132] */
149 	s16 = s64;
150 
151 	s32 = s8;
152 	s32 = s16;
153 	/* expect+1: warning: conversion from 'long long' to 'int' may lose accuracy [132] */
154 	s32 = s64;
155 
156 	s64 = s8;
157 	s64 = s16;
158 	s64 = s32;
159 }
160 
161 /*
162  * Before tree.c 1.268 from 2021-04-06, lint wrongly warned that conversion
163  * to _Bool might lose accuracy.  C99 6.3.1.2 defines a special conversion
164  * rule from scalar to _Bool though by comparing the value to 0.
165  */
166 _Bool
167 to_bool(long a, long b)
168 {
169 	/* seen in fp_lib.h, function wideRightShiftWithSticky */
170 	return a | b;
171 }
172 
173 /* ARGSUSED */
174 const char *
175 cover_build_plus_minus(const char *arr, double idx)
176 {
177 	if (idx > 0.0)
178 		/* expect+2: error: operands of '+' have incompatible types 'pointer to const char' and 'double' [107] */
179 		/* expect+1: error: function 'cover_build_plus_minus' expects to return value [214] */
180 		return arr + idx;
181 	return arr + (unsigned int)idx;
182 }
183 
184 int
185 non_constant_expression(void)
186 {
187 	/*
188 	 * Even though this variable definition looks like a constant, it
189 	 * does not fall within C's definition of an integer constant
190 	 * expression.  Due to that, lint does not perform constant folding
191 	 * on the expression built from this variable and thus doesn't know
192 	 * that the conversion will always succeed.
193 	 */
194 	const int not_a_constant = 8;
195 	/* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
196 	return not_a_constant * 8ULL;
197 }
198 
199 /*
200  * PR 36668 notices that lint wrongly complains about the possible loss.
201  *
202  * The expression 'u8_t << 8' is guaranteed to fit into an 'u16_t', and its
203  * lower 8 bits are guaranteed to be clear.  'u16_t | u8_t' is guaranteed to
204  * fit into 'u16_t'.
205  *
206  * Since tree.c 1.444 from 2022-05-26, lint tracks simple bitwise and
207  * arithmetic constraints across a single expression.
208  */
209 void
210 be16dec(void)
211 {
212 	/*
213 	 * Before tree.c 1.444 from 2022-05-26, lint complained that the
214 	 * conversion from 'int' to 'unsigned short' may lose accuracy.
215 	 */
216 	u16 = (u16_t)u8 << 8 | u8;
217 }
218 
219 /*
220  * Since tree.c 1.434 from 2022-04-19, lint infers the possible values of
221  * expressions of the form 'integer & constant', see can_represent.
222  */
223 void
224 be32enc(void)
225 {
226 	u8 = u32 >> 24 & 0xff;
227 	u8 = u32 >> 16 & 0xff;
228 	u8 = u32 >> 8 & 0xff;
229 	u8 = u32 & 0xff;
230 }
231 
232 void
233 test_ic_mult(void)
234 {
235 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
236 	u8 = u8 * u8;
237 	u16 = u8 * u8;
238 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
239 	u16 = u16 * u8;
240 	u32 = u16 * u16;
241 
242 	u32 = u16 * 65537ULL;
243 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
244 	u32 = u16 * 65538ULL;
245 
246 	u16 = 0 * u16;
247 	u16 = 1 * u16;
248 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
249 	u16 = 2 * u16;
250 
251 	// from __BITS, __SHIFTIN, __SHIFTOUT
252 	u32 = (u16 & 1023ULL) / 1ULL * 1024ULL | (u16 & 1023ULL) / 1ULL * 1ULL;
253 
254 	s8 = 1 * s8;
255 	s16 = 1 * s16;
256 	s32 = 1 * s32;
257 	s64 = 1 * s64;
258 
259 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
260 	s8 = 2 * s8;
261 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
262 	s16 = 2 * s16;
263 	// No warning, as there is no narrowing conversion.
264 	s32 = 2 * s32;
265 	// No warning, as there is no narrowing conversion.
266 	s64 = 2 * s64;
267 
268 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
269 	s8 = -1 * s8;
270 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
271 	s16 = -1 * s16;
272 	// No warning, as there is no narrowing conversion.
273 	s32 = -1 * s32;
274 	// No warning, as there is no narrowing conversion.
275 	s64 = -1 * s64;
276 }
277 
278 void
279 test_ic_div(void)
280 {
281 	u8 = u8 / u8;
282 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
283 	u8 = u16 / u8;
284 	u16 = u8 / u8;
285 	u16 = u32 / 65536;
286 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
287 	u16 = u32 / 65535;
288 
289 	s8 = s8 / 1;
290 	s16 = s16 / 1;
291 	s32 = s32 / 1;
292 	s64 = s64 / 1;
293 
294 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
295 	s8 = s8 / -1;
296 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
297 	s16 = s16 / -1;
298 	// No warning, as there is no narrowing conversion.
299 	s32 = s32 / -1;
300 	// No warning, as there is no narrowing conversion.
301 	s64 = s64 / -1;
302 }
303 
304 void
305 test_ic_mod(void)
306 {
307 	/* The result is between 0 and 254. */
308 	u8 = u64 % u8;
309 
310 	/* The result is between 0 and 255. */
311 	u8 = u64 % 256;
312 
313 	/* The result is between 0 and 256. */
314 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
315 	u8 = u64 % 257;
316 
317 	/* The result is between 0 and 1000. */
318 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
319 	u8 = u64 % 1000;
320 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:9' may lose accuracy [132] */
321 	bits.u9 = u64 % 1000;
322 	bits.u10 = u64 % 1000;
323 	u16 = u64 % 1000;
324 
325 	s8 = s16 % s8;
326 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
327 	s8 = s16 % s16;
328 	s8 = s64 % 1;
329 	s8 = s64 % (s16 & 1);
330 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
331 	s8 = s64 % (s16 & 0);
332 	s8 = (s64 & 0x7f) % s64;
333 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
334 	s8 = (s64 & 0xff) % s64;
335 }
336 
337 void
338 test_ic_plus(void)
339 {
340 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
341 	s8 = -129 + s64 % 1;
342 	s8 = -128 + s64 % 1;
343 	s8 = 127 + s64 % 1;
344 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
345 	s8 = 128 + s64 % 1;
346 
347 	/* expect+2: warning: conversion of negative constant -129 to unsigned type 'unsigned long long' [222] */
348 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
349 	s8 = -129 + u64 % 1;
350 	/* expect+2: warning: conversion of negative constant -128 to unsigned type 'unsigned long long' [222] */
351 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
352 	s8 = -128 + u64 % 1;
353 	s8 = 127 + u64 % 1;
354 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
355 	s8 = 128 + u64 % 1;
356 
357 	u8 = 0 + u64 % 1;
358 	u8 = 255 + u64 % 1;
359 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
360 	u8 = 256 + u64 % 1;
361 
362 	u8 = s8 + 0x80;
363 	u16 = s16 + 0x8000;
364 	u32 = s32 + 0x80000000;
365 	u64 = s64 + 0x8000000000000000;
366 
367 	// XXX: No warnings since portable_rank_cmp is the same for both sides.
368 	bits.u11 = bits.u10 + bits.u10 + 1;
369 	bits.u11 = bits.u10 + bits.u10 + 2;
370 	bits.u11 = bits.u10 + 1024;
371 	bits.u11 = bits.u10 + 1025;
372 
373 	u8 = bits.u7 + bits.u7 + 1;
374 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
375 	u8 = bits.u7 + bits.u7 + 2;
376 	u8 = bits.u7 + 128;
377 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
378 	u8 = bits.u7 + 129;
379 
380 	// The result of the second '+' wraps around, thus the warning,
381 	// even though the final result fits in a u16.
382 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
383 	u16 = u32 % 0x00010000 + 0x80000000 + 0x80000000;
384 
385 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
386 	u16 = u32 % 0x00010000 + 0xffff8000;
387 	/* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */
388 	s16 = u32 % 0x00010000 + 0xffff8000;
389 
390 	/* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */
391 	u16 = s64 % 0x00010000 + 0xffffffffLL + -0xffffffffLL;
392 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
393 	u16 = s32 % 0x00010000 + 0x7fff0000 + -0x7fff0000;
394 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
395 	u16 = u32 % 0x00010000 + 0xffff0000 + 0x00010000;
396 
397 	s8 = '0' + s64 % 10;
398 
399 	ptr = ptr + 3;
400 }
401 
402 void
403 test_ic_minus(void)
404 {
405 	// Shift the range [0x00 to 0xff] to [-0x80 to 0x7f].
406 	s8 = (s64 & 0xff) - 0x80;
407 
408 	// Sign-extend the lowest bits.
409 	s8 = ((s64 & 0xff) ^ 0x80) - 0x80;
410 	s16 = ((s64 & 0xffff) ^ 0x8000) - 0x8000;
411 	/* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'long long', op '&' [309] */
412 	s32 = ((s64 & 0xffffffff) ^ 0x80000000) - 0x80000000;
413 
414 	// Trying to sign-extend, but with off-by-one errors.
415 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
416 	s8 = ((s64 & 0xff) ^ 0x80) - 0x7f;
417 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
418 	s8 = ((s64 & 0xff) ^ 0x80) - 0x81;
419 
420 	u8 = s8 - -0x80;
421 	u16 = s16 - -0x8000;
422 	u32 = s32 - -0x80000000;
423 	u64 = s64 - -0x8000000000000000;
424 
425 	ptr = ptr - 3;
426 	s64 = ptr + 3 - ptr;
427 }
428 
429 void
430 test_ic_shl(void)
431 {
432 	u64 = u64 << u64;
433 	s64 = s64 << s64;
434 
435 	u16 = u8 << 8;
436 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
437 	u16 = u8 << 9;
438 	u32 = u16 << 16;
439 	// XXX: missing warning as UINT has the same rank as INT, see portable_rank_cmp.
440 	u32 = u16 << 17;
441 	/* expect+1: warning: shift amount 56 is greater than bit-size 32 of 'int' [122] */
442 	u64 = u8 << 56;
443 	u64 = (u64_t)u8 << 56;
444 	// XXX: missing warning, as the operand types of '=' are the same, thus no conversion.
445 	u64 = (u64_t)u8 << 57;
446 	/* expect+1: warning: shift amount 48 is greater than bit-size 32 of 'int' [122] */
447 	u64 = u16 << 48;
448 	u64 = (u64_t)u16 << 48;
449 	// XXX: missing warning, as the operand types of '=' are the same, thus no conversion.
450 	u64 = (u64_t)u16 << 49;
451 	/* expect+1: warning: shift amount 32 equals bit-size of 'unsigned int' [267] */
452 	u64 = u32 << 32;
453 	u64 = (u64_t)u32 << 32;
454 	// XXX: missing warning, as the operand types of '=' are the same, thus no conversion.
455 	u64 = (u64_t)u32 << 33;
456 }
457 
458 void
459 test_ic_shr(void)
460 {
461 	u64 = u64 >> u64;
462 	s64 = s64 >> s64;
463 
464 	u32 = u64 >> 32;
465 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
466 	u32 = u64 >> 31;
467 	u16 = u64 >> 48;
468 	u16 = u32 >> 16;
469 	u8 = u64 >> 56;
470 	u8 = u32 >> 24;
471 	u8 = u16 >> 8;
472 
473 	/*
474 	 * No matter whether the big integer is signed or unsigned, the
475 	 * result of '&' is guaranteed to be an unsigned value.
476 	 */
477 	u8 = (s64 & 0xf0) >> 4;
478 	u8 = (s8 & 0xf0) >> 4;
479 }
480 
481 void
482 test_ic_bitand(void)
483 {
484 	u8 = u8 & u16;
485 
486 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
487 	u8 = u16 & u32;
488 }
489 
490 void
491 test_ic_bitxor(void)
492 {
493 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
494 	u8 = u8 ^ u16;
495 	u16 = u8 ^ u16;
496 
497 	// Sign-extend.
498 	s8 = (u8 ^ 0x80) - 0x80;
499 	s16 = (u16 ^ 0x8000) - 0x8000;
500 	s32 = (u32 ^ 0x80000000) - 0x80000000;
501 	s64 = (u64 ^ 0x8000000000000000) - 0x8000000000000000;
502 }
503 
504 void
505 test_ic_bitor(void)
506 {
507 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
508 	u8 = u8 | u16;
509 	u16 = u8 | u16;
510 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
511 	u16 = u8 | u32;
512 	u32 = u8 | u32;
513 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
514 	u32 = u8 | u64;
515 	u64 = u8 | u64;
516 }
517 
518 void
519 test_ic_quest_colon(char c1, char c2)
520 {
521 	/* Both operands are representable as char. */
522 	ch = cond ? '?' : ':';
523 
524 	/*
525 	 * Both operands are representable as char. Clang-Tidy 17 wrongly
526 	 * warns about a narrowing conversion from 'int' to signed type
527 	 * 'char'.
528 	 */
529 	ch = cond ? c1 : c2;
530 
531 	/*
532 	 * Mixing s8 and u8 results in a number from -128 to 255, which neither
533 	 * fits in s8 nor u8.
534 	 */
535 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
536 	s8 = cond ? s8 : u8;
537 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
538 	u8 = cond ? s8 : u8;
539 }
540 
541 void
542 test_ic_con(void)
543 {
544 	/* expect+1: warning: assignment of negative constant -1 to unsigned type 'unsigned char' [164] */
545 	u8 = -1;
546 	u8 = 0;
547 	u8 = 255;
548 	/* expect+1: warning: constant truncated by assignment [165] */
549 	u8 = 256;
550 
551 	/* expect+1: warning: conversion of 'int' to 'signed char' is out of range [119] */
552 	s8 = -129;
553 	s8 = -128;
554 	s8 = 127;
555 	/* expect+1: warning: conversion of 'int' to 'signed char' is out of range [119] */
556 	s8 = 128;
557 }
558 
559 void
560 test_ic_cvt(void)
561 {
562 	u16 = (u32 & 0x0000ff00);
563 	u16 = (u32_t)(u32 & 0x0000ff00);
564 	u16 = (u16_t)u32;
565 	u16 = (u8_t)(u32 & 0xffff) << 8;
566 	u16 = (int)3.0;
567 
568 	u8 = (u8_t)(u64 & 0x0f);
569 	u8 = (u8_t)(u64 & 0x0f) << 4;
570 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
571 	u8 = (u8_t)(u64 & 0x0f) << 5;
572 }
573 
574 unsigned char
575 test_bit_fields(unsigned long long m)
576 {
577 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:3' may lose accuracy [132] */
578 	bits.u3 = bits.u32 & m;
579 
580 	bits.u5 = bits.u3 & m;
581 	bits.u32 = bits.u5 & m;
582 
583 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
584 	return bits.u32 & m;
585 }
586 
587 void
588 compare_bit_field_to_integer_constant(void)
589 {
590 	static _Bool b;
591 	static struct {
592 		short s16:15;
593 		unsigned short u16:15;
594 		int s32:15;
595 		unsigned u32:15;
596 		long long s64:15;
597 		unsigned long long u64:15;
598 	} s;
599 
600 	// Since decl.c 1.180 from 2021-05-02 and before tree.c 1.624 from
601 	// 2024-03-12, lint warned about a possible loss of accuracy [132]
602 	// when promoting an 'unsigned long long' bit-field to 'int'.
603 	b = s.s16 == 0;
604 	b = s.u16 == 0;
605 	b = s.s32 == 0;
606 	b = s.u32 == 0;
607 	b = s.s64 == 0;
608 	b = s.u64 == 0;
609 	b = !b;
610 }
611 
612 /*
613  * Before tree.c 1.626 from 2024-03-26, the usual arithmetic conversions for
614  * bit-field types with the same base type but different widths simply took
615  * the type of the left operand, leading to wrong warnings about loss of
616  * accuracy when the right operand was wider than the left operand.
617  */
618 void
619 binary_operators_on_bit_fields(void)
620 {
621 	struct {
622 		u64_t u15:15;
623 		u64_t u48:48;
624 		u64_t u64;
625 	} s = { 0, 0, 0 };
626 
627 	u64 = s.u15 | s.u48;
628 	u64 = s.u48 | s.u15;
629 	u64 = s.u15 | s.u48 | s.u64;
630 	u64 = s.u64 | s.u48 | s.u15;
631 	cond = (s.u15 | s.u48 | s.u64) != 0;
632 	cond = (s.u64 | s.u48 | s.u15) != 0;
633 
634 	// Before tree.c from 1.638 from 2024-05-01, lint wrongly warned:
635 	// warning: conversion of 'int' to 'int:4' is out of range [119]
636 	s32 = 8 - bits.u3;
637 }
638 
639 unsigned char
640 combine_arithmetic_and_bit_operations(void)
641 {
642 	return 0xc0 | (u32 & 0x07c0) / 64;
643 }
644