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