Home | History | Annotate | Line # | Download | only in lint1
msg_132.c revision 1.52
      1 /*	$NetBSD: msg_132.c,v 1.52 2025/01/02 20:02:59 rillig Exp $	*/
      2 # 3 "msg_132.c"
      3 
      4 // Test for message: conversion from '%s' to '%s' may lose accuracy [132]
      5 
      6 /*
      7  * NetBSD's default lint flags only include a single -a, which only flags
      8  * narrowing conversions from long.  To get warnings for all narrowing
      9  * conversions, -a needs to be given more than once.
     10  *
     11  * https://gnats.netbsd.org/14531
     12  */
     13 
     14 /* lint1-extra-flags: -aa -X 351 */
     15 
     16 typedef unsigned char u8_t;
     17 typedef unsigned short u16_t;
     18 typedef unsigned int u32_t;
     19 typedef unsigned long long u64_t;
     20 typedef signed char s8_t;
     21 typedef signed short s16_t;
     22 typedef signed int s32_t;
     23 typedef signed long long s64_t;
     24 
     25 _Bool cond;
     26 char ch;
     27 
     28 u8_t u8;
     29 u16_t u16;
     30 u32_t u32;
     31 u64_t u64;
     32 
     33 s8_t s8;
     34 s16_t s16;
     35 s32_t s32;
     36 s64_t s64;
     37 
     38 const char *ptr;
     39 
     40 struct bit_fields {
     41 	unsigned u1:1;
     42 	unsigned u2:2;
     43 	unsigned u3:3;
     44 	unsigned u4:4;
     45 	unsigned u5:5;
     46 	unsigned u6:6;
     47 	unsigned u7:7;
     48 	unsigned u8:8;
     49 	unsigned u9:9;
     50 	unsigned u10:10;
     51 	unsigned u11:11;
     52 	unsigned u12:12;
     53 	unsigned u32:32;
     54 } bits;
     55 
     56 
     57 void
     58 unsigned_to_unsigned(void)
     59 {
     60 	/* expect+1: warning: conversion from 'unsigned short' to 'unsigned char' may lose accuracy [132] */
     61 	u8 = u16;
     62 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
     63 	u8 = u32;
     64 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
     65 	u8 = u64;
     66 
     67 	u16 = u8;
     68 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
     69 	u16 = u32;
     70 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned short' may lose accuracy [132] */
     71 	u16 = u64;
     72 
     73 	u32 = u8;
     74 	u32 = u16;
     75 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
     76 	u32 = u64;
     77 
     78 	u64 = u8;
     79 	u64 = u16;
     80 	u64 = u32;
     81 }
     82 
     83 void
     84 unsigned_to_signed(void)
     85 {
     86 	/* expect+1: warning: conversion from 'unsigned short' to 'signed char' may lose accuracy [132] */
     87 	s8 = u16;
     88 	/* expect+1: warning: conversion from 'unsigned int' to 'signed char' may lose accuracy [132] */
     89 	s8 = u32;
     90 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
     91 	s8 = u64;
     92 
     93 	s16 = u8;
     94 	/* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */
     95 	s16 = u32;
     96 	/* expect+1: warning: conversion from 'unsigned long long' to 'short' may lose accuracy [132] */
     97 	s16 = u64;
     98 
     99 	s32 = u8;
    100 	s32 = u16;
    101 	/* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
    102 	s32 = u64;
    103 
    104 	s64 = u8;
    105 	s64 = u16;
    106 	s64 = u32;
    107 }
    108 
    109 void
    110 signed_to_unsigned(void)
    111 {
    112 	/* expect+1: warning: conversion from 'short' to 'unsigned char' may lose accuracy [132] */
    113 	u8 = s16;
    114 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
    115 	u8 = s32;
    116 	/* expect+1: warning: conversion from 'long long' to 'unsigned char' may lose accuracy [132] */
    117 	u8 = s64;
    118 
    119 	u16 = s8;
    120 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
    121 	u16 = s32;
    122 	/* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */
    123 	u16 = s64;
    124 
    125 	u32 = s8;
    126 	u32 = s16;
    127 	/* expect+1: warning: conversion from 'long long' to 'unsigned int' may lose accuracy [132] */
    128 	u32 = s64;
    129 
    130 	u64 = s8;
    131 	u64 = s16;
    132 	u64 = s32;
    133 }
    134 
    135 void
    136 signed_to_signed(void)
    137 {
    138 	/* expect+1: warning: conversion from 'short' to 'signed char' may lose accuracy [132] */
    139 	s8 = s16;
    140 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
    141 	s8 = s32;
    142 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
    143 	s8 = s64;
    144 
    145 	s16 = s8;
    146 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
    147 	s16 = s32;
    148 	/* expect+1: warning: conversion from 'long long' to 'short' may lose accuracy [132] */
    149 	s16 = s64;
    150 
    151 	s32 = s8;
    152 	s32 = s16;
    153 	/* expect+1: warning: conversion from 'long long' to 'int' may lose accuracy [132] */
    154 	s32 = s64;
    155 
    156 	s64 = s8;
    157 	s64 = s16;
    158 	s64 = s32;
    159 }
    160 
    161 /*
    162  * Before tree.c 1.268 from 2021-04-06, lint wrongly warned that conversion
    163  * to _Bool might lose accuracy.  C99 6.3.1.2 defines a special conversion
    164  * rule from scalar to _Bool though by comparing the value to 0.
    165  */
    166 _Bool
    167 to_bool(long a, long b)
    168 {
    169 	/* seen in fp_lib.h, function wideRightShiftWithSticky */
    170 	return a | b;
    171 }
    172 
    173 /* ARGSUSED */
    174 const char *
    175 cover_build_plus_minus(const char *arr, double idx)
    176 {
    177 	if (idx > 0.0)
    178 		/* expect+2: error: operands of '+' have incompatible types 'pointer to const char' and 'double' [107] */
    179 		/* expect+1: error: function 'cover_build_plus_minus' expects to return value [214] */
    180 		return arr + idx;
    181 	return arr + (unsigned int)idx;
    182 }
    183 
    184 int
    185 non_constant_expression(void)
    186 {
    187 	/*
    188 	 * Even though this variable definition looks like a constant, it
    189 	 * does not fall within C's definition of an integer constant
    190 	 * expression.  Due to that, lint does not perform constant folding
    191 	 * on the expression built from this variable and thus doesn't know
    192 	 * that the conversion will always succeed.
    193 	 */
    194 	const int not_a_constant = 8;
    195 	/* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
    196 	return not_a_constant * 8ULL;
    197 }
    198 
    199 /*
    200  * PR 36668 notices that lint wrongly complains about the possible loss.
    201  *
    202  * The expression 'u8_t << 8' is guaranteed to fit into an 'u16_t', and its
    203  * lower 8 bits are guaranteed to be clear.  'u16_t | u8_t' is guaranteed to
    204  * fit into 'u16_t'.
    205  *
    206  * Since tree.c 1.444 from 2022-05-26, lint tracks simple bitwise and
    207  * arithmetic constraints across a single expression.
    208  */
    209 void
    210 be16dec(void)
    211 {
    212 	/*
    213 	 * Before tree.c 1.444 from 2022-05-26, lint complained that the
    214 	 * conversion from 'int' to 'unsigned short' may lose accuracy.
    215 	 */
    216 	u16 = (u16_t)u8 << 8 | u8;
    217 }
    218 
    219 /*
    220  * Since tree.c 1.434 from 2022-04-19, lint infers the possible values of
    221  * expressions of the form 'integer & constant', see can_represent.
    222  */
    223 void
    224 be32enc(void)
    225 {
    226 	u8 = u32 >> 24 & 0xff;
    227 	u8 = u32 >> 16 & 0xff;
    228 	u8 = u32 >> 8 & 0xff;
    229 	u8 = u32 & 0xff;
    230 }
    231 
    232 void
    233 test_ic_mult(void)
    234 {
    235 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
    236 	u8 = u8 * u8;
    237 	u16 = u8 * u8;
    238 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
    239 	u16 = u16 * u8;
    240 	u32 = u16 * u16;
    241 
    242 	u32 = u16 * 65537ULL;
    243 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
    244 	u32 = u16 * 65538ULL;
    245 
    246 	u16 = 0 * u16;
    247 	u16 = 1 * u16;
    248 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
    249 	u16 = 2 * u16;
    250 
    251 	// from __BITS, __SHIFTIN, __SHIFTOUT
    252 	u32 = (u16 & 1023ULL) / 1ULL * 1024ULL | (u16 & 1023ULL) / 1ULL * 1ULL;
    253 
    254 	s8 = 1 * s8;
    255 	s16 = 1 * s16;
    256 	s32 = 1 * s32;
    257 	s64 = 1 * s64;
    258 
    259 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
    260 	s8 = 2 * s8;
    261 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
    262 	s16 = 2 * s16;
    263 	// No warning, as there is no narrowing conversion.
    264 	s32 = 2 * s32;
    265 	// No warning, as there is no narrowing conversion.
    266 	s64 = 2 * s64;
    267 
    268 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
    269 	s8 = -1 * s8;
    270 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
    271 	s16 = -1 * s16;
    272 	// No warning, as there is no narrowing conversion.
    273 	s32 = -1 * s32;
    274 	// No warning, as there is no narrowing conversion.
    275 	s64 = -1 * s64;
    276 }
    277 
    278 void
    279 test_ic_div(void)
    280 {
    281 	u8 = u8 / u8;
    282 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
    283 	u8 = u16 / u8;
    284 	u16 = u8 / u8;
    285 	u16 = u32 / 65536;
    286 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
    287 	u16 = u32 / 65535;
    288 
    289 	s8 = s8 / 1;
    290 	s16 = s16 / 1;
    291 	s32 = s32 / 1;
    292 	s64 = s64 / 1;
    293 
    294 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
    295 	s8 = s8 / -1;
    296 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
    297 	s16 = s16 / -1;
    298 	// No warning, as there is no narrowing conversion.
    299 	s32 = s32 / -1;
    300 	// No warning, as there is no narrowing conversion.
    301 	s64 = s64 / -1;
    302 }
    303 
    304 void
    305 test_ic_mod(void)
    306 {
    307 	/* The result is between 0 and 254. */
    308 	u8 = u64 % u8;
    309 
    310 	/* The result is between 0 and 255. */
    311 	u8 = u64 % 256;
    312 
    313 	/* The result is between 0 and 256. */
    314 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
    315 	u8 = u64 % 257;
    316 
    317 	/* The result is between 0 and 1000. */
    318 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
    319 	u8 = u64 % 1000;
    320 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:9' may lose accuracy [132] */
    321 	bits.u9 = u64 % 1000;
    322 	bits.u10 = u64 % 1000;
    323 	u16 = u64 % 1000;
    324 
    325 	s8 = s16 % s8;
    326 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
    327 	s8 = s16 % s16;
    328 	s8 = s64 % 1;
    329 	s8 = s64 % (s16 & 1);
    330 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
    331 	s8 = s64 % (s16 & 0);
    332 	s8 = (s64 & 0x7f) % s64;
    333 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
    334 	s8 = (s64 & 0xff) % s64;
    335 }
    336 
    337 void
    338 test_ic_plus(void)
    339 {
    340 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
    341 	s8 = -129 + s64 % 1;
    342 	s8 = -128 + s64 % 1;
    343 	s8 = 127 + s64 % 1;
    344 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
    345 	s8 = 128 + s64 % 1;
    346 
    347 	/* expect+2: warning: conversion of negative constant -129 to unsigned type 'unsigned long long' [222] */
    348 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
    349 	s8 = -129 + u64 % 1;
    350 	/* expect+2: warning: conversion of negative constant -128 to unsigned type 'unsigned long long' [222] */
    351 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
    352 	s8 = -128 + u64 % 1;
    353 	s8 = 127 + u64 % 1;
    354 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
    355 	s8 = 128 + u64 % 1;
    356 
    357 	u8 = 0 + u64 % 1;
    358 	u8 = 255 + u64 % 1;
    359 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
    360 	u8 = 256 + u64 % 1;
    361 
    362 	u8 = s8 + 0x80;
    363 	u16 = s16 + 0x8000;
    364 	u32 = s32 + 0x80000000;
    365 	u64 = s64 + 0x8000000000000000;
    366 
    367 	// XXX: No warnings since portable_rank_cmp is the same for both sides.
    368 	bits.u11 = bits.u10 + bits.u10 + 1;
    369 	bits.u11 = bits.u10 + bits.u10 + 2;
    370 	bits.u11 = bits.u10 + 1024;
    371 	bits.u11 = bits.u10 + 1025;
    372 
    373 	u8 = bits.u7 + bits.u7 + 1;
    374 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
    375 	u8 = bits.u7 + bits.u7 + 2;
    376 	u8 = bits.u7 + 128;
    377 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
    378 	u8 = bits.u7 + 129;
    379 
    380 	// The result of the second '+' wraps around, thus the warning,
    381 	// even though the final result fits in a u16.
    382 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
    383 	u16 = u32 % 0x00010000 + 0x80000000 + 0x80000000;
    384 
    385 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
    386 	u16 = u32 % 0x00010000 + 0xffff8000;
    387 	/* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */
    388 	s16 = u32 % 0x00010000 + 0xffff8000;
    389 
    390 	/* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */
    391 	u16 = s64 % 0x00010000 + 0xffffffffLL + -0xffffffffLL;
    392 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
    393 	u16 = s32 % 0x00010000 + 0x7fff0000 + -0x7fff0000;
    394 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
    395 	u16 = u32 % 0x00010000 + 0xffff0000 + 0x00010000;
    396 
    397 	s8 = '0' + s64 % 10;
    398 
    399 	ptr = ptr + 3;
    400 }
    401 
    402 void
    403 test_ic_minus(void)
    404 {
    405 	// Shift the range [0x00 to 0xff] to [-0x80 to 0x7f].
    406 	s8 = (s64 & 0xff) - 0x80;
    407 
    408 	// Sign-extend the lowest bits.
    409 	s8 = ((s64 & 0xff) ^ 0x80) - 0x80;
    410 	s16 = ((s64 & 0xffff) ^ 0x8000) - 0x8000;
    411 	/* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'long long', op '&' [309] */
    412 	s32 = ((s64 & 0xffffffff) ^ 0x80000000) - 0x80000000;
    413 
    414 	// Trying to sign-extend, but with off-by-one errors.
    415 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
    416 	s8 = ((s64 & 0xff) ^ 0x80) - 0x7f;
    417 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
    418 	s8 = ((s64 & 0xff) ^ 0x80) - 0x81;
    419 
    420 	u8 = s8 - -0x80;
    421 	u16 = s16 - -0x8000;
    422 	u32 = s32 - -0x80000000;
    423 	u64 = s64 - -0x8000000000000000;
    424 
    425 	ptr = ptr - 3;
    426 	s64 = ptr + 3 - ptr;
    427 	/* expect+1: warning: conversion from 'long' to 'unsigned int' may lose accuracy [132] */
    428 	u32 = ptr + 3 - ptr;
    429 }
    430 
    431 void
    432 test_ic_shl(void)
    433 {
    434 	u64 = u64 << u64;
    435 	s64 = s64 << s64;
    436 
    437 	u16 = u8 << 8;
    438 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
    439 	u16 = u8 << 9;
    440 	u32 = u16 << 16;
    441 	// XXX: missing warning as UINT has the same rank as INT, see portable_rank_cmp.
    442 	u32 = u16 << 17;
    443 	/* expect+1: warning: shift amount 56 is greater than bit-size 32 of 'int' [122] */
    444 	u64 = u8 << 56;
    445 	u64 = (u64_t)u8 << 56;
    446 	// XXX: missing warning, as the operand types of '=' are the same, thus no conversion.
    447 	u64 = (u64_t)u8 << 57;
    448 	/* expect+1: warning: shift amount 48 is greater than bit-size 32 of 'int' [122] */
    449 	u64 = u16 << 48;
    450 	u64 = (u64_t)u16 << 48;
    451 	// XXX: missing warning, as the operand types of '=' are the same, thus no conversion.
    452 	u64 = (u64_t)u16 << 49;
    453 	/* expect+1: warning: shift amount 32 equals bit-size of 'unsigned int' [267] */
    454 	u64 = u32 << 32;
    455 	u64 = (u64_t)u32 << 32;
    456 	// XXX: missing warning, as the operand types of '=' are the same, thus no conversion.
    457 	u64 = (u64_t)u32 << 33;
    458 }
    459 
    460 void
    461 test_ic_shr(void)
    462 {
    463 	u64 = u64 >> u64;
    464 	s64 = s64 >> s64;
    465 
    466 	u32 = u64 >> 32;
    467 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
    468 	u32 = u64 >> 31;
    469 	u16 = u64 >> 48;
    470 	u16 = u32 >> 16;
    471 	u8 = u64 >> 56;
    472 	u8 = u32 >> 24;
    473 	u8 = u16 >> 8;
    474 
    475 	/*
    476 	 * No matter whether the big integer is signed or unsigned, the
    477 	 * result of '&' is guaranteed to be an unsigned value.
    478 	 */
    479 	u8 = (s64 & 0xf0) >> 4;
    480 	u8 = (s8 & 0xf0) >> 4;
    481 }
    482 
    483 void
    484 test_ic_bitand(void)
    485 {
    486 	u8 = u8 & u16;
    487 
    488 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
    489 	u8 = u16 & u32;
    490 }
    491 
    492 void
    493 test_ic_bitxor(void)
    494 {
    495 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
    496 	u8 = u8 ^ u16;
    497 	u16 = u8 ^ u16;
    498 
    499 	// Sign-extend.
    500 	s8 = (u8 ^ 0x80) - 0x80;
    501 	s16 = (u16 ^ 0x8000) - 0x8000;
    502 	s32 = (u32 ^ 0x80000000) - 0x80000000;
    503 	s64 = (u64 ^ 0x8000000000000000) - 0x8000000000000000;
    504 }
    505 
    506 void
    507 test_ic_bitor(void)
    508 {
    509 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
    510 	u8 = u8 | u16;
    511 	u16 = u8 | u16;
    512 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
    513 	u16 = u8 | u32;
    514 	u32 = u8 | u32;
    515 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
    516 	u32 = u8 | u64;
    517 	u64 = u8 | u64;
    518 }
    519 
    520 void
    521 test_ic_quest_colon(char c1, char c2)
    522 {
    523 	/* Both operands are representable as char. */
    524 	ch = cond ? '?' : ':';
    525 
    526 	/*
    527 	 * Both operands are representable as char. Clang-Tidy 17 wrongly
    528 	 * warns about a narrowing conversion from 'int' to signed type
    529 	 * 'char'.
    530 	 */
    531 	ch = cond ? c1 : c2;
    532 
    533 	/*
    534 	 * Mixing s8 and u8 results in a number from -128 to 255, which neither
    535 	 * fits in s8 nor u8.
    536 	 */
    537 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
    538 	s8 = cond ? s8 : u8;
    539 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
    540 	u8 = cond ? s8 : u8;
    541 }
    542 
    543 void
    544 test_ic_con(void)
    545 {
    546 	/* expect+1: warning: assignment of negative constant -1 to unsigned type 'unsigned char' [164] */
    547 	u8 = -1;
    548 	u8 = 0;
    549 	u8 = 255;
    550 	/* expect+1: warning: constant truncated by assignment [165] */
    551 	u8 = 256;
    552 
    553 	/* expect+1: warning: conversion of 'int' to 'signed char' is out of range [119] */
    554 	s8 = -129;
    555 	s8 = -128;
    556 	s8 = 127;
    557 	/* expect+1: warning: conversion of 'int' to 'signed char' is out of range [119] */
    558 	s8 = 128;
    559 }
    560 
    561 void
    562 test_ic_cvt(void)
    563 {
    564 	u16 = (u32 & 0x0000ff00);
    565 	u16 = (u32_t)(u32 & 0x0000ff00);
    566 	u16 = (u16_t)u32;
    567 	u16 = (u8_t)(u32 & 0xffff) << 8;
    568 	u16 = (int)3.0;
    569 
    570 	u8 = (u8_t)(u64 & 0x0f);
    571 	u8 = (u8_t)(u64 & 0x0f) << 4;
    572 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
    573 	u8 = (u8_t)(u64 & 0x0f) << 5;
    574 }
    575 
    576 unsigned char
    577 test_bit_fields(unsigned long long m)
    578 {
    579 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:3' may lose accuracy [132] */
    580 	bits.u3 = bits.u32 & m;
    581 
    582 	bits.u5 = bits.u3 & m;
    583 	bits.u32 = bits.u5 & m;
    584 
    585 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
    586 	return bits.u32 & m;
    587 }
    588 
    589 void
    590 compare_bit_field_to_integer_constant(void)
    591 {
    592 	static _Bool b;
    593 	static struct {
    594 		short s16:15;
    595 		unsigned short u16:15;
    596 		int s32:15;
    597 		unsigned u32:15;
    598 		long long s64:15;
    599 		unsigned long long u64:15;
    600 	} s;
    601 
    602 	// Since decl.c 1.180 from 2021-05-02 and before tree.c 1.624 from
    603 	// 2024-03-12, lint warned about a possible loss of accuracy [132]
    604 	// when promoting an 'unsigned long long' bit-field to 'int'.
    605 	b = s.s16 == 0;
    606 	b = s.u16 == 0;
    607 	b = s.s32 == 0;
    608 	b = s.u32 == 0;
    609 	b = s.s64 == 0;
    610 	b = s.u64 == 0;
    611 	b = !b;
    612 }
    613 
    614 /*
    615  * Before tree.c 1.626 from 2024-03-26, the usual arithmetic conversions for
    616  * bit-field types with the same base type but different widths simply took
    617  * the type of the left operand, leading to wrong warnings about loss of
    618  * accuracy when the right operand was wider than the left operand.
    619  */
    620 void
    621 binary_operators_on_bit_fields(void)
    622 {
    623 	struct {
    624 		u64_t u15:15;
    625 		u64_t u48:48;
    626 		u64_t u64;
    627 	} s = { 0, 0, 0 };
    628 
    629 	u64 = s.u15 | s.u48;
    630 	u64 = s.u48 | s.u15;
    631 	u64 = s.u15 | s.u48 | s.u64;
    632 	u64 = s.u64 | s.u48 | s.u15;
    633 	cond = (s.u15 | s.u48 | s.u64) != 0;
    634 	cond = (s.u64 | s.u48 | s.u15) != 0;
    635 
    636 	// Before tree.c from 1.638 from 2024-05-01, lint wrongly warned:
    637 	// warning: conversion of 'int' to 'int:4' is out of range [119]
    638 	s32 = 8 - bits.u3;
    639 }
    640 
    641 unsigned char
    642 combine_arithmetic_and_bit_operations(void)
    643 {
    644 	return 0xc0 | (u32 & 0x07c0) / 64;
    645 }
    646