/* $NetBSD: msg_309.c,v 1.8 2025/02/24 19:49:00 rillig Exp $ */ # 3 "msg_309.c" // Test for message: extra bits set to 0 in conversion of '%s' to '%s', op '%s' [309] /* lint1-extra-flags: -X 351 */ typedef unsigned char u8_t; typedef unsigned int u32_t; typedef unsigned long long u64_t; u8_t u8; u32_t u32; u64_t u64; void test(void) { /* * Both operands of '&' have the same type, therefore no conversion * is necessary and no bits can get lost. */ u64 = u64 & 0xffffffff00000000ULL; /* * The constant has type 'unsigned 32-bit'. The usual arithmetic * conversions of '&' convert this constant to unsigned 64-bit. * The programmer may or may not have intended to sign-extend the * bit mask here. This situation may occur during migration from a * 32-bit to a 64-bit platform. */ /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op '&' [309] */ u64 = u64 & 0xffff0000; /* * The integer constant is explicitly unsigned. Even in this case, * the code may have originated on a platform where 'x' had 32 bits * originally, and the intention may have been to clear the lower 16 * bits. */ /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op '&' [309] */ u64 = u64 & 0xffff0000U; /* * Even if the expression is written as '& ~', which makes the * intention of clearing the lower 16 bits clear, on a 32-bit * platform the integer constant stays at 32 bits, and when porting * the code to a 64-bit platform, the upper 32 bits are preserved. */ /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op '&' [309] */ u64 = u64 & ~0xffffU; /* * Casting the integer constant to the proper type removes all * ambiguities about the programmer's intention. */ u64 = u64 & (unsigned long long)~0xffffU; /* * In the remaining cases, the constant does not have its most * significant bit set, therefore there is no ambiguity. */ u64 = u64 & 0xff00; u64 = u64 & 0xf0; u64 = u64 & 0xc; u64 = u64 & 0x2; u64 = u64 & 0x1; u8 = u8 & 0x7f; u8 = u8 & 0x80; u8 = u8 & -0x80; /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned char' to 'int', op '&' [309] */ u8 = u8 & (u8_t)-0x80; /* expect+1: warning: extra bits set to 0 in conversion of 'unsigned char' to 'int', op '&' [309] */ u8 = u8 & (u8_t)-0x80U; }