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