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