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