msg_309.c revision 1.8 1 /* $NetBSD: msg_309.c,v 1.8 2025/02/24 19:49:00 rillig Exp $ */
2 # 3 "msg_309.c"
3
4 // Test for message: extra bits set to 0 in conversion of '%s' to '%s', op '%s' [309]
5
6 /* lint1-extra-flags: -X 351 */
7
8 typedef unsigned char u8_t;
9 typedef unsigned int u32_t;
10 typedef unsigned long long u64_t;
11
12 u8_t u8;
13 u32_t u32;
14 u64_t u64;
15
16
17 void
18 test(void)
19 {
20
21 /*
22 * Both operands of '&' have the same type, therefore no conversion
23 * is necessary and no bits can get lost.
24 */
25 u64 = u64 & 0xffffffff00000000ULL;
26
27 /*
28 * The constant has type 'unsigned 32-bit'. The usual arithmetic
29 * conversions of '&' convert this constant to unsigned 64-bit.
30 * The programmer may or may not have intended to sign-extend the
31 * bit mask here. This situation may occur during migration from a
32 * 32-bit to a 64-bit platform.
33 */
34 /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op '&' [309] */
35 u64 = u64 & 0xffff0000;
36
37 /*
38 * The integer constant is explicitly unsigned. Even in this case,
39 * the code may have originated on a platform where 'x' had 32 bits
40 * originally, and the intention may have been to clear the lower 16
41 * bits.
42 */
43 /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op '&' [309] */
44 u64 = u64 & 0xffff0000U;
45
46 /*
47 * Even if the expression is written as '& ~', which makes the
48 * intention of clearing the lower 16 bits clear, on a 32-bit
49 * platform the integer constant stays at 32 bits, and when porting
50 * the code to a 64-bit platform, the upper 32 bits are preserved.
51 */
52 /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op '&' [309] */
53 u64 = u64 & ~0xffffU;
54
55 /*
56 * Casting the integer constant to the proper type removes all
57 * ambiguities about the programmer's intention.
58 */
59 u64 = u64 & (unsigned long long)~0xffffU;
60
61 /*
62 * In the remaining cases, the constant does not have its most
63 * significant bit set, therefore there is no ambiguity.
64 */
65 u64 = u64 & 0xff00;
66 u64 = u64 & 0xf0;
67 u64 = u64 & 0xc;
68 u64 = u64 & 0x2;
69 u64 = u64 & 0x1;
70
71 u8 = u8 & 0x7f;
72 u8 = u8 & 0x80;
73 u8 = u8 & -0x80;
74 /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned char' to 'int', op '&' [309] */
75 u8 = u8 & (u8_t)-0x80;
76 /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned char' to 'int', op '&' [309] */
77 u8 = u8 & (u8_t)-0x80U;
78 }
79