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