msg_309.c revision 1.6 1 /* $NetBSD: msg_309.c,v 1.6 2022/10/15 21:19:15 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 int
7 scale(unsigned long long x) {
8
9 /*
10 * Both operands of '&' have the same type, therefore no conversion
11 * is necessary and no bits can get lost.
12 */
13 if ((x & 0xffffffff00000000ULL) != 0)
14 return 32;
15
16 /*
17 * The constant has type 'unsigned 32-bit'. The usual arithmetic
18 * conversions of '&' convert this constant to unsigned 64-bit.
19 * The programmer may or may not have intended to sign-extend the
20 * bit mask here. This situation may occur during migration from a
21 * 32-bit to a 64-bit platform.
22 */
23 /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op '&' [309] */
24 if ((x & 0xffff0000) != 0)
25 return 16;
26
27 /*
28 * The integer constant is explicitly unsigned. Even in this case,
29 * the code may have originated on a platform where 'x' had 32 bits
30 * originally, and the intention may have been to clear the lower 16
31 * bits.
32 */
33 /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op '&' [309] */
34 if ((x & 0xffff0000U) != 0)
35 return 16;
36
37 /*
38 * Even if the expression is written as '& ~', which makes the
39 * intention of clearing the lower 16 bits clear, on a 32-bit
40 * platform the integer constant stays at 32 bits, and when porting
41 * the code to a 64-bit platform, the upper 32 bits are preserved.
42 */
43 /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op '&' [309] */
44 if ((x & ~0xffffU) != 0)
45 return 16;
46
47 /*
48 * Casting the integer constant to the proper type removes all
49 * ambiguities about the programmer's intention.
50 */
51 if ((x & (unsigned long long)~0xffffU) != 0)
52 return 16;
53
54 /*
55 * In the remaining cases, the constant does not have its most
56 * significant bit set, therefore there is no ambiguity.
57 */
58 if ((x & 0xff00) != 0)
59 return 8;
60 if ((x & 0xf0) != 0)
61 return 4;
62 if ((x & 0xc) != 0)
63 return 2;
64 if ((x & 0x2) != 0)
65 return 1;
66 return (int)(x & 0x1);
67 }
68