Home | History | Annotate | Line # | Download | only in lint1
msg_309.c revision 1.7
      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