xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_132.c (revision 5685e47f6f29ba1fd654aaf86baf90bc2b72a6b5)
1*5685e47fSrillig /*	$NetBSD: msg_132.c,v 1.53 2025/01/03 01:27:35 rillig Exp $	*/
2a0a15c14Srillig # 3 "msg_132.c"
3a0a15c14Srillig 
4a0a15c14Srillig // Test for message: conversion from '%s' to '%s' may lose accuracy [132]
5a0a15c14Srillig 
684a7228eSrillig /*
784a7228eSrillig  * NetBSD's default lint flags only include a single -a, which only flags
884a7228eSrillig  * narrowing conversions from long.  To get warnings for all narrowing
902710ffeSrillig  * conversions, -a needs to be given more than once.
1084a7228eSrillig  *
1184a7228eSrillig  * https://gnats.netbsd.org/14531
1284a7228eSrillig  */
1384a7228eSrillig 
14a1937910Srillig /* lint1-extra-flags: -aa -X 351 */
1584a7228eSrillig 
1628cc4da3Srillig typedef unsigned char u8_t;
1728cc4da3Srillig typedef unsigned short u16_t;
1828cc4da3Srillig typedef unsigned int u32_t;
1928cc4da3Srillig typedef unsigned long long u64_t;
2028cc4da3Srillig typedef signed char s8_t;
2128cc4da3Srillig typedef signed short s16_t;
2228cc4da3Srillig typedef signed int s32_t;
2328cc4da3Srillig typedef signed long long s64_t;
2484a7228eSrillig 
25815f75fcSrillig _Bool cond;
26815f75fcSrillig char ch;
2741da170bSrillig 
2828cc4da3Srillig u8_t u8;
2928cc4da3Srillig u16_t u16;
3028cc4da3Srillig u32_t u32;
3128cc4da3Srillig u64_t u64;
3228cc4da3Srillig 
3328cc4da3Srillig s8_t s8;
3428cc4da3Srillig s16_t s16;
3528cc4da3Srillig s32_t s32;
3628cc4da3Srillig s64_t s64;
3784a7228eSrillig 
38a1937910Srillig const char *ptr;
39a1937910Srillig 
4041da170bSrillig struct bit_fields {
4141da170bSrillig 	unsigned u1:1;
4241da170bSrillig 	unsigned u2:2;
4341da170bSrillig 	unsigned u3:3;
4441da170bSrillig 	unsigned u4:4;
4541da170bSrillig 	unsigned u5:5;
4641da170bSrillig 	unsigned u6:6;
4741da170bSrillig 	unsigned u7:7;
4841da170bSrillig 	unsigned u8:8;
4941da170bSrillig 	unsigned u9:9;
5041da170bSrillig 	unsigned u10:10;
5141da170bSrillig 	unsigned u11:11;
5241da170bSrillig 	unsigned u12:12;
5341da170bSrillig 	unsigned u32:32;
5441da170bSrillig } bits;
5541da170bSrillig 
5641da170bSrillig 
5784a7228eSrillig void
5802710ffeSrillig unsigned_to_unsigned(void)
5984a7228eSrillig {
6065e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned short' to 'unsigned char' may lose accuracy [132] */
6165e5c21bSrillig 	u8 = u16;
6265e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
6365e5c21bSrillig 	u8 = u32;
6465e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
6565e5c21bSrillig 	u8 = u64;
6684a7228eSrillig 
6702710ffeSrillig 	u16 = u8;
6865e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
6965e5c21bSrillig 	u16 = u32;
7065e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned short' may lose accuracy [132] */
7165e5c21bSrillig 	u16 = u64;
7284a7228eSrillig 
7302710ffeSrillig 	u32 = u8;
7402710ffeSrillig 	u32 = u16;
7565e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
7665e5c21bSrillig 	u32 = u64;
7784a7228eSrillig 
7802710ffeSrillig 	u64 = u8;
7902710ffeSrillig 	u64 = u16;
8002710ffeSrillig 	u64 = u32;
8184a7228eSrillig }
8284a7228eSrillig 
8384a7228eSrillig void
8402710ffeSrillig unsigned_to_signed(void)
8584a7228eSrillig {
8665e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned short' to 'signed char' may lose accuracy [132] */
8765e5c21bSrillig 	s8 = u16;
8865e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned int' to 'signed char' may lose accuracy [132] */
8965e5c21bSrillig 	s8 = u32;
9065e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
9165e5c21bSrillig 	s8 = u64;
9284a7228eSrillig 
9302710ffeSrillig 	s16 = u8;
9465e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */
9565e5c21bSrillig 	s16 = u32;
9665e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'short' may lose accuracy [132] */
9765e5c21bSrillig 	s16 = u64;
9884a7228eSrillig 
9902710ffeSrillig 	s32 = u8;
10002710ffeSrillig 	s32 = u16;
10165e5c21bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
10265e5c21bSrillig 	s32 = u64;
10384a7228eSrillig 
10402710ffeSrillig 	s64 = u8;
10502710ffeSrillig 	s64 = u16;
10602710ffeSrillig 	s64 = u32;
10702710ffeSrillig }
10802710ffeSrillig 
10902710ffeSrillig void
11002710ffeSrillig signed_to_unsigned(void)
11102710ffeSrillig {
11265e5c21bSrillig 	/* expect+1: warning: conversion from 'short' to 'unsigned char' may lose accuracy [132] */
11365e5c21bSrillig 	u8 = s16;
11465e5c21bSrillig 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
11565e5c21bSrillig 	u8 = s32;
11665e5c21bSrillig 	/* expect+1: warning: conversion from 'long long' to 'unsigned char' may lose accuracy [132] */
11765e5c21bSrillig 	u8 = s64;
11802710ffeSrillig 
11902710ffeSrillig 	u16 = s8;
12065e5c21bSrillig 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
12165e5c21bSrillig 	u16 = s32;
12265e5c21bSrillig 	/* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */
12365e5c21bSrillig 	u16 = s64;
12402710ffeSrillig 
12502710ffeSrillig 	u32 = s8;
12602710ffeSrillig 	u32 = s16;
12765e5c21bSrillig 	/* expect+1: warning: conversion from 'long long' to 'unsigned int' may lose accuracy [132] */
12865e5c21bSrillig 	u32 = s64;
12902710ffeSrillig 
13002710ffeSrillig 	u64 = s8;
13102710ffeSrillig 	u64 = s16;
13202710ffeSrillig 	u64 = s32;
13302710ffeSrillig }
13402710ffeSrillig 
13502710ffeSrillig void
13602710ffeSrillig signed_to_signed(void)
13702710ffeSrillig {
13865e5c21bSrillig 	/* expect+1: warning: conversion from 'short' to 'signed char' may lose accuracy [132] */
13965e5c21bSrillig 	s8 = s16;
14065e5c21bSrillig 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
14165e5c21bSrillig 	s8 = s32;
14265e5c21bSrillig 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
14365e5c21bSrillig 	s8 = s64;
14402710ffeSrillig 
14502710ffeSrillig 	s16 = s8;
14665e5c21bSrillig 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
14765e5c21bSrillig 	s16 = s32;
14865e5c21bSrillig 	/* expect+1: warning: conversion from 'long long' to 'short' may lose accuracy [132] */
14965e5c21bSrillig 	s16 = s64;
15002710ffeSrillig 
15102710ffeSrillig 	s32 = s8;
15202710ffeSrillig 	s32 = s16;
15365e5c21bSrillig 	/* expect+1: warning: conversion from 'long long' to 'int' may lose accuracy [132] */
15465e5c21bSrillig 	s32 = s64;
15502710ffeSrillig 
15602710ffeSrillig 	s64 = s8;
15702710ffeSrillig 	s64 = s16;
15802710ffeSrillig 	s64 = s32;
15984a7228eSrillig }
160483f849cSrillig 
16143290293Srillig /*
16202710ffeSrillig  * Before tree.c 1.268 from 2021-04-06, lint wrongly warned that conversion
16302710ffeSrillig  * to _Bool might lose accuracy.  C99 6.3.1.2 defines a special conversion
16402710ffeSrillig  * rule from scalar to _Bool though by comparing the value to 0.
16543290293Srillig  */
166483f849cSrillig _Bool
167483f849cSrillig to_bool(long a, long b)
168483f849cSrillig {
169483f849cSrillig 	/* seen in fp_lib.h, function wideRightShiftWithSticky */
17043290293Srillig 	return a | b;
171483f849cSrillig }
17292de156fSrillig 
17392de156fSrillig /* ARGSUSED */
17492de156fSrillig const char *
17592de156fSrillig cover_build_plus_minus(const char *arr, double idx)
17692de156fSrillig {
17792de156fSrillig 	if (idx > 0.0)
178d2c16d57Srillig 		/* expect+2: error: operands of '+' have incompatible types 'pointer to const char' and 'double' [107] */
179d2c16d57Srillig 		/* expect+1: error: function 'cover_build_plus_minus' expects to return value [214] */
18092de156fSrillig 		return arr + idx;
18192de156fSrillig 	return arr + (unsigned int)idx;
18292de156fSrillig }
1835242bed2Srillig 
1845242bed2Srillig int
1855242bed2Srillig non_constant_expression(void)
1865242bed2Srillig {
1875242bed2Srillig 	/*
1885242bed2Srillig 	 * Even though this variable definition looks like a constant, it
1895242bed2Srillig 	 * does not fall within C's definition of an integer constant
1905242bed2Srillig 	 * expression.  Due to that, lint does not perform constant folding
1915242bed2Srillig 	 * on the expression built from this variable and thus doesn't know
1925242bed2Srillig 	 * that the conversion will always succeed.
1935242bed2Srillig 	 */
1945242bed2Srillig 	const int not_a_constant = 8;
19565a6a5edSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
19665a6a5edSrillig 	return not_a_constant * 8ULL;
1975242bed2Srillig }
198975e3550Srillig 
199975e3550Srillig /*
200975e3550Srillig  * PR 36668 notices that lint wrongly complains about the possible loss.
201b3f015e1Srillig  *
202b3f015e1Srillig  * The expression 'u8_t << 8' is guaranteed to fit into an 'u16_t', and its
203b3f015e1Srillig  * lower 8 bits are guaranteed to be clear.  'u16_t | u8_t' is guaranteed to
204b3f015e1Srillig  * fit into 'u16_t'.
205b3f015e1Srillig  *
206b3f015e1Srillig  * Since tree.c 1.444 from 2022-05-26, lint tracks simple bitwise and
207b3f015e1Srillig  * arithmetic constraints across a single expression.
208975e3550Srillig  */
2092c46d03eSrillig void
2102c46d03eSrillig be16dec(void)
211975e3550Srillig {
212b3f015e1Srillig 	/*
213b3f015e1Srillig 	 * Before tree.c 1.444 from 2022-05-26, lint complained that the
214b3f015e1Srillig 	 * conversion from 'int' to 'unsigned short' may lose accuracy.
215b3f015e1Srillig 	 */
2162c46d03eSrillig 	u16 = (u16_t)u8 << 8 | u8;
217975e3550Srillig }
218975e3550Srillig 
219975e3550Srillig /*
220975e3550Srillig  * Since tree.c 1.434 from 2022-04-19, lint infers the possible values of
221975e3550Srillig  * expressions of the form 'integer & constant', see can_represent.
222975e3550Srillig  */
2232c46d03eSrillig void
2242c46d03eSrillig be32enc(void)
225975e3550Srillig {
2262c46d03eSrillig 	u8 = u32 >> 24 & 0xff;
2272c46d03eSrillig 	u8 = u32 >> 16 & 0xff;
2282c46d03eSrillig 	u8 = u32 >> 8 & 0xff;
2292c46d03eSrillig 	u8 = u32 & 0xff;
230975e3550Srillig }
23177552b5dSrillig 
2325a79ef8cSrillig void
2335a79ef8cSrillig test_ic_mult(void)
2345a79ef8cSrillig {
2352c46d03eSrillig 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
2362c46d03eSrillig 	u8 = u8 * u8;
2372c46d03eSrillig 	u16 = u8 * u8;
2382c46d03eSrillig 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
2392c46d03eSrillig 	u16 = u16 * u8;
2402c46d03eSrillig 	u32 = u16 * u16;
2412c46d03eSrillig 
2425a79ef8cSrillig 	u32 = u16 * 65537ULL;
24324ea2fe9Srillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
24424ea2fe9Srillig 	u32 = u16 * 65538ULL;
2455a79ef8cSrillig 
2465a79ef8cSrillig 	u16 = 0 * u16;
2475a79ef8cSrillig 	u16 = 1 * u16;
2485a79ef8cSrillig 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
2495a79ef8cSrillig 	u16 = 2 * u16;
2505a79ef8cSrillig 
2512c46d03eSrillig 	// from __BITS, __SHIFTIN, __SHIFTOUT
2525a79ef8cSrillig 	u32 = (u16 & 1023ULL) / 1ULL * 1024ULL | (u16 & 1023ULL) / 1ULL * 1ULL;
25385d6c072Srillig 
25485d6c072Srillig 	s8 = 1 * s8;
25585d6c072Srillig 	s16 = 1 * s16;
25685d6c072Srillig 	s32 = 1 * s32;
25785d6c072Srillig 	s64 = 1 * s64;
258fbc150b1Srillig 
259fbc150b1Srillig 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
260fbc150b1Srillig 	s8 = 2 * s8;
261fbc150b1Srillig 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
262fbc150b1Srillig 	s16 = 2 * s16;
263fbc150b1Srillig 	// No warning, as there is no narrowing conversion.
264fbc150b1Srillig 	s32 = 2 * s32;
265fbc150b1Srillig 	// No warning, as there is no narrowing conversion.
266fbc150b1Srillig 	s64 = 2 * s64;
267fbc150b1Srillig 
268fbc150b1Srillig 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
269fbc150b1Srillig 	s8 = -1 * s8;
270fbc150b1Srillig 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
271fbc150b1Srillig 	s16 = -1 * s16;
272fbc150b1Srillig 	// No warning, as there is no narrowing conversion.
273fbc150b1Srillig 	s32 = -1 * s32;
274fbc150b1Srillig 	// No warning, as there is no narrowing conversion.
275fbc150b1Srillig 	s64 = -1 * s64;
2765a79ef8cSrillig }
2775a79ef8cSrillig 
2782c46d03eSrillig void
2792c46d03eSrillig test_ic_div(void)
28077552b5dSrillig {
2812c46d03eSrillig 	u8 = u8 / u8;
2822c46d03eSrillig 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
2832c46d03eSrillig 	u8 = u16 / u8;
2842c46d03eSrillig 	u16 = u8 / u8;
2852c46d03eSrillig 	u16 = u32 / 65536;
2862c46d03eSrillig 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
2872c46d03eSrillig 	u16 = u32 / 65535;
28885d6c072Srillig 
28985d6c072Srillig 	s8 = s8 / 1;
29085d6c072Srillig 	s16 = s16 / 1;
29185d6c072Srillig 	s32 = s32 / 1;
29285d6c072Srillig 	s64 = s64 / 1;
293fbc150b1Srillig 
294fbc150b1Srillig 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
295fbc150b1Srillig 	s8 = s8 / -1;
296fbc150b1Srillig 	/* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
297fbc150b1Srillig 	s16 = s16 / -1;
298fbc150b1Srillig 	// No warning, as there is no narrowing conversion.
299fbc150b1Srillig 	s32 = s32 / -1;
300fbc150b1Srillig 	// No warning, as there is no narrowing conversion.
301fbc150b1Srillig 	s64 = s64 / -1;
30228cc4da3Srillig }
30341da170bSrillig 
30441da170bSrillig void
30541da170bSrillig test_ic_mod(void)
30641da170bSrillig {
30741da170bSrillig 	/* The result is between 0 and 254. */
30841da170bSrillig 	u8 = u64 % u8;
30941da170bSrillig 
3105158c388Srillig 	/* The result is between 0 and 255. */
3115158c388Srillig 	u8 = u64 % 256;
3125158c388Srillig 
3135158c388Srillig 	/* The result is between 0 and 256. */
3145158c388Srillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
3155158c388Srillig 	u8 = u64 % 257;
3165158c388Srillig 
31741da170bSrillig 	/* The result is between 0 and 1000. */
31841da170bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
31941da170bSrillig 	u8 = u64 % 1000;
32041da170bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:9' may lose accuracy [132] */
32141da170bSrillig 	bits.u9 = u64 % 1000;
32241da170bSrillig 	bits.u10 = u64 % 1000;
3235158c388Srillig 	u16 = u64 % 1000;
32441da170bSrillig 
3255158c388Srillig 	s8 = s16 % s8;
32647afd8c9Srillig 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
32747afd8c9Srillig 	s8 = s16 % s16;
3285158c388Srillig 	s8 = s64 % 1;
32947afd8c9Srillig 	s8 = s64 % (s16 & 1);
33047afd8c9Srillig 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
33147afd8c9Srillig 	s8 = s64 % (s16 & 0);
33247afd8c9Srillig 	s8 = (s64 & 0x7f) % s64;
33347afd8c9Srillig 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
33447afd8c9Srillig 	s8 = (s64 & 0xff) % s64;
33541da170bSrillig }
336881bc412Srillig 
337881bc412Srillig void
338852d653bSrillig test_ic_plus(void)
339852d653bSrillig {
340852d653bSrillig 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
341852d653bSrillig 	s8 = -129 + s64 % 1;
342852d653bSrillig 	s8 = -128 + s64 % 1;
343852d653bSrillig 	s8 = 127 + s64 % 1;
344852d653bSrillig 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
345852d653bSrillig 	s8 = 128 + s64 % 1;
346852d653bSrillig 
347852d653bSrillig 	/* expect+2: warning: conversion of negative constant -129 to unsigned type 'unsigned long long' [222] */
348852d653bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
349852d653bSrillig 	s8 = -129 + u64 % 1;
350852d653bSrillig 	/* expect+2: warning: conversion of negative constant -128 to unsigned type 'unsigned long long' [222] */
351852d653bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
352852d653bSrillig 	s8 = -128 + u64 % 1;
353852d653bSrillig 	s8 = 127 + u64 % 1;
354852d653bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
355852d653bSrillig 	s8 = 128 + u64 % 1;
356852d653bSrillig 
357852d653bSrillig 	u8 = 0 + u64 % 1;
358852d653bSrillig 	u8 = 255 + u64 % 1;
359852d653bSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
360852d653bSrillig 	u8 = 256 + u64 % 1;
361852d653bSrillig 
36285d6c072Srillig 	u8 = s8 + 0x80;
36385d6c072Srillig 	u16 = s16 + 0x8000;
36485d6c072Srillig 	u32 = s32 + 0x80000000;
36585d6c072Srillig 	u64 = s64 + 0x8000000000000000;
36685d6c072Srillig 
3670ce249d8Srillig 	// XXX: No warnings since portable_rank_cmp is the same for both sides.
3680ce249d8Srillig 	bits.u11 = bits.u10 + bits.u10 + 1;
3690ce249d8Srillig 	bits.u11 = bits.u10 + bits.u10 + 2;
3700ce249d8Srillig 	bits.u11 = bits.u10 + 1024;
3710ce249d8Srillig 	bits.u11 = bits.u10 + 1025;
3720ce249d8Srillig 
3730ce249d8Srillig 	u8 = bits.u7 + bits.u7 + 1;
3740ce249d8Srillig 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
3750ce249d8Srillig 	u8 = bits.u7 + bits.u7 + 2;
3760ce249d8Srillig 	u8 = bits.u7 + 128;
3770ce249d8Srillig 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
3780ce249d8Srillig 	u8 = bits.u7 + 129;
3790ce249d8Srillig 
3800ce249d8Srillig 	// The result of the second '+' wraps around, thus the warning,
3810ce249d8Srillig 	// even though the final result fits in a u16.
3820ce249d8Srillig 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
3830ce249d8Srillig 	u16 = u32 % 0x00010000 + 0x80000000 + 0x80000000;
3840ce249d8Srillig 
3850ce249d8Srillig 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
3860ce249d8Srillig 	u16 = u32 % 0x00010000 + 0xffff8000;
3870ce249d8Srillig 	/* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */
3880ce249d8Srillig 	s16 = u32 % 0x00010000 + 0xffff8000;
3890ce249d8Srillig 
3900ce249d8Srillig 	/* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */
3910ce249d8Srillig 	u16 = s64 % 0x00010000 + 0xffffffffLL + -0xffffffffLL;
3920ce249d8Srillig 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
3930ce249d8Srillig 	u16 = s32 % 0x00010000 + 0x7fff0000 + -0x7fff0000;
3940ce249d8Srillig 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
3950ce249d8Srillig 	u16 = u32 % 0x00010000 + 0xffff0000 + 0x00010000;
3960ce249d8Srillig 
397852d653bSrillig 	s8 = '0' + s64 % 10;
398a1937910Srillig 
399a1937910Srillig 	ptr = ptr + 3;
400852d653bSrillig }
401852d653bSrillig 
402852d653bSrillig void
4030ce249d8Srillig test_ic_minus(void)
4040ce249d8Srillig {
4050ce249d8Srillig 	// Shift the range [0x00 to 0xff] to [-0x80 to 0x7f].
4060ce249d8Srillig 	s8 = (s64 & 0xff) - 0x80;
4070ce249d8Srillig 
4080ce249d8Srillig 	// Sign-extend the lowest bits.
4090ce249d8Srillig 	s8 = ((s64 & 0xff) ^ 0x80) - 0x80;
4100ce249d8Srillig 	s16 = ((s64 & 0xffff) ^ 0x8000) - 0x8000;
4110ce249d8Srillig 	/* expect+1: warning: extra bits set to 0 in conversion of 'unsigned int' to 'long long', op '&' [309] */
4120ce249d8Srillig 	s32 = ((s64 & 0xffffffff) ^ 0x80000000) - 0x80000000;
4130ce249d8Srillig 
4140ce249d8Srillig 	// Trying to sign-extend, but with off-by-one errors.
4150ce249d8Srillig 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
4160ce249d8Srillig 	s8 = ((s64 & 0xff) ^ 0x80) - 0x7f;
4170ce249d8Srillig 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
4180ce249d8Srillig 	s8 = ((s64 & 0xff) ^ 0x80) - 0x81;
41985d6c072Srillig 
42085d6c072Srillig 	u8 = s8 - -0x80;
42185d6c072Srillig 	u16 = s16 - -0x8000;
42285d6c072Srillig 	u32 = s32 - -0x80000000;
42385d6c072Srillig 	u64 = s64 - -0x8000000000000000;
424a1937910Srillig 
425a1937910Srillig 	ptr = ptr - 3;
426a1937910Srillig 	s64 = ptr + 3 - ptr;
4270ce249d8Srillig }
4280ce249d8Srillig 
4290ce249d8Srillig void
4302c46d03eSrillig test_ic_shl(void)
4312c46d03eSrillig {
4322c46d03eSrillig 	u64 = u64 << u64;
4332c46d03eSrillig 	s64 = s64 << s64;
4342c46d03eSrillig 
4352c46d03eSrillig 	u16 = u8 << 8;
4362c46d03eSrillig 	/* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
4372c46d03eSrillig 	u16 = u8 << 9;
4382c46d03eSrillig 	u32 = u16 << 16;
4392c46d03eSrillig 	// XXX: missing warning as UINT has the same rank as INT, see portable_rank_cmp.
4402c46d03eSrillig 	u32 = u16 << 17;
4412c46d03eSrillig 	/* expect+1: warning: shift amount 56 is greater than bit-size 32 of 'int' [122] */
4422c46d03eSrillig 	u64 = u8 << 56;
4432c46d03eSrillig 	u64 = (u64_t)u8 << 56;
4442c46d03eSrillig 	// XXX: missing warning, as the operand types of '=' are the same, thus no conversion.
4452c46d03eSrillig 	u64 = (u64_t)u8 << 57;
4462c46d03eSrillig 	/* expect+1: warning: shift amount 48 is greater than bit-size 32 of 'int' [122] */
4472c46d03eSrillig 	u64 = u16 << 48;
4482c46d03eSrillig 	u64 = (u64_t)u16 << 48;
4492c46d03eSrillig 	// XXX: missing warning, as the operand types of '=' are the same, thus no conversion.
4502c46d03eSrillig 	u64 = (u64_t)u16 << 49;
4512c46d03eSrillig 	/* expect+1: warning: shift amount 32 equals bit-size of 'unsigned int' [267] */
4522c46d03eSrillig 	u64 = u32 << 32;
4532c46d03eSrillig 	u64 = (u64_t)u32 << 32;
4542c46d03eSrillig 	// XXX: missing warning, as the operand types of '=' are the same, thus no conversion.
4552c46d03eSrillig 	u64 = (u64_t)u32 << 33;
4562c46d03eSrillig }
4572c46d03eSrillig 
4582c46d03eSrillig void
4592c46d03eSrillig test_ic_shr(void)
4602c46d03eSrillig {
4612c46d03eSrillig 	u64 = u64 >> u64;
4622c46d03eSrillig 	s64 = s64 >> s64;
4632c46d03eSrillig 
4642c46d03eSrillig 	u32 = u64 >> 32;
4652c46d03eSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
4662c46d03eSrillig 	u32 = u64 >> 31;
4672c46d03eSrillig 	u16 = u64 >> 48;
4682c46d03eSrillig 	u16 = u32 >> 16;
4692c46d03eSrillig 	u8 = u64 >> 56;
4702c46d03eSrillig 	u8 = u32 >> 24;
4712c46d03eSrillig 	u8 = u16 >> 8;
4722c46d03eSrillig 
4732c46d03eSrillig 	/*
4742c46d03eSrillig 	 * No matter whether the big integer is signed or unsigned, the
4752c46d03eSrillig 	 * result of '&' is guaranteed to be an unsigned value.
4762c46d03eSrillig 	 */
4772c46d03eSrillig 	u8 = (s64 & 0xf0) >> 4;
4782c46d03eSrillig 	u8 = (s8 & 0xf0) >> 4;
4792c46d03eSrillig }
4802c46d03eSrillig 
4812c46d03eSrillig void
482881bc412Srillig test_ic_bitand(void)
483881bc412Srillig {
484881bc412Srillig 	u8 = u8 & u16;
485881bc412Srillig 
486881bc412Srillig 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
487881bc412Srillig 	u8 = u16 & u32;
488881bc412Srillig }
489815f75fcSrillig 
490815f75fcSrillig void
4910ce249d8Srillig test_ic_bitxor(void)
4920ce249d8Srillig {
4930ce249d8Srillig 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
4940ce249d8Srillig 	u8 = u8 ^ u16;
4950ce249d8Srillig 	u16 = u8 ^ u16;
4960ce249d8Srillig 
4970ce249d8Srillig 	// Sign-extend.
4980ce249d8Srillig 	s8 = (u8 ^ 0x80) - 0x80;
4990ce249d8Srillig 	s16 = (u16 ^ 0x8000) - 0x8000;
5000ce249d8Srillig 	s32 = (u32 ^ 0x80000000) - 0x80000000;
5010ce249d8Srillig 	s64 = (u64 ^ 0x8000000000000000) - 0x8000000000000000;
5020ce249d8Srillig }
5030ce249d8Srillig 
5040ce249d8Srillig void
5052c46d03eSrillig test_ic_bitor(void)
506b889b215Srillig {
5072c46d03eSrillig 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
5082c46d03eSrillig 	u8 = u8 | u16;
5092c46d03eSrillig 	u16 = u8 | u16;
5102c46d03eSrillig 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
5112c46d03eSrillig 	u16 = u8 | u32;
5122c46d03eSrillig 	u32 = u8 | u32;
5132c46d03eSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
5142c46d03eSrillig 	u32 = u8 | u64;
5152c46d03eSrillig 	u64 = u8 | u64;
516b889b215Srillig }
517b889b215Srillig 
518b889b215Srillig void
5192c46d03eSrillig test_ic_quest_colon(char c1, char c2)
520815f75fcSrillig {
521815f75fcSrillig 	/* Both operands are representable as char. */
522815f75fcSrillig 	ch = cond ? '?' : ':';
523815f75fcSrillig 
524815f75fcSrillig 	/*
525815f75fcSrillig 	 * Both operands are representable as char. Clang-Tidy 17 wrongly
526815f75fcSrillig 	 * warns about a narrowing conversion from 'int' to signed type
527815f75fcSrillig 	 * 'char'.
528815f75fcSrillig 	 */
529815f75fcSrillig 	ch = cond ? c1 : c2;
530815f75fcSrillig 
531a48523a6Srillig 	/*
5322c46d03eSrillig 	 * Mixing s8 and u8 results in a number from -128 to 255, which neither
5332c46d03eSrillig 	 * fits in s8 nor u8.
534a48523a6Srillig 	 */
535815f75fcSrillig 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
536815f75fcSrillig 	s8 = cond ? s8 : u8;
537815f75fcSrillig 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
538815f75fcSrillig 	u8 = cond ? s8 : u8;
539815f75fcSrillig }
540fc2f5e14Srillig 
541fc2f5e14Srillig void
5422c46d03eSrillig test_ic_con(void)
5432c46d03eSrillig {
5442c46d03eSrillig 	/* expect+1: warning: assignment of negative constant -1 to unsigned type 'unsigned char' [164] */
5452c46d03eSrillig 	u8 = -1;
5462c46d03eSrillig 	u8 = 0;
5472c46d03eSrillig 	u8 = 255;
5482c46d03eSrillig 	/* expect+1: warning: constant truncated by assignment [165] */
5492c46d03eSrillig 	u8 = 256;
5502c46d03eSrillig 
5512c46d03eSrillig 	/* expect+1: warning: conversion of 'int' to 'signed char' is out of range [119] */
5522c46d03eSrillig 	s8 = -129;
5532c46d03eSrillig 	s8 = -128;
5542c46d03eSrillig 	s8 = 127;
5552c46d03eSrillig 	/* expect+1: warning: conversion of 'int' to 'signed char' is out of range [119] */
5562c46d03eSrillig 	s8 = 128;
5572c46d03eSrillig }
5582c46d03eSrillig 
5592c46d03eSrillig void
5602c46d03eSrillig test_ic_cvt(void)
5612c46d03eSrillig {
5622c46d03eSrillig 	u16 = (u32 & 0x0000ff00);
5632c46d03eSrillig 	u16 = (u32_t)(u32 & 0x0000ff00);
5642c46d03eSrillig 	u16 = (u16_t)u32;
5652c46d03eSrillig 	u16 = (u8_t)(u32 & 0xffff) << 8;
56685d6c072Srillig 	u16 = (int)3.0;
56785d6c072Srillig 
56885d6c072Srillig 	u8 = (u8_t)(u64 & 0x0f);
56985d6c072Srillig 	u8 = (u8_t)(u64 & 0x0f) << 4;
57085d6c072Srillig 	/* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
57185d6c072Srillig 	u8 = (u8_t)(u64 & 0x0f) << 5;
5722c46d03eSrillig }
5732c46d03eSrillig 
5742c46d03eSrillig unsigned char
5752c46d03eSrillig test_bit_fields(unsigned long long m)
5762c46d03eSrillig {
5772c46d03eSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:3' may lose accuracy [132] */
5782c46d03eSrillig 	bits.u3 = bits.u32 & m;
5792c46d03eSrillig 
5802c46d03eSrillig 	bits.u5 = bits.u3 & m;
5812c46d03eSrillig 	bits.u32 = bits.u5 & m;
5822c46d03eSrillig 
5832c46d03eSrillig 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
5842c46d03eSrillig 	return bits.u32 & m;
5852c46d03eSrillig }
5862c46d03eSrillig 
5872c46d03eSrillig void
5889ed4dea2Srillig compare_bit_field_to_integer_constant(void)
589fc2f5e14Srillig {
5909ed4dea2Srillig 	static _Bool b;
5919ed4dea2Srillig 	static struct {
5929ed4dea2Srillig 		short s16:15;
5939ed4dea2Srillig 		unsigned short u16:15;
5949ed4dea2Srillig 		int s32:15;
5959ed4dea2Srillig 		unsigned u32:15;
5969ed4dea2Srillig 		long long s64:15;
5979ed4dea2Srillig 		unsigned long long u64:15;
5989ed4dea2Srillig 	} s;
599fc2f5e14Srillig 
6009b239cc7Srillig 	// Since decl.c 1.180 from 2021-05-02 and before tree.c 1.624 from
6019b239cc7Srillig 	// 2024-03-12, lint warned about a possible loss of accuracy [132]
6029ed4dea2Srillig 	// when promoting an 'unsigned long long' bit-field to 'int'.
6039ed4dea2Srillig 	b = s.s16 == 0;
6049ed4dea2Srillig 	b = s.u16 == 0;
6059ed4dea2Srillig 	b = s.s32 == 0;
6069ed4dea2Srillig 	b = s.u32 == 0;
6079ed4dea2Srillig 	b = s.s64 == 0;
6089ed4dea2Srillig 	b = s.u64 == 0;
6099ed4dea2Srillig 	b = !b;
610fc2f5e14Srillig }
6116167e0ccSrillig 
612216c89c0Srillig /*
613216c89c0Srillig  * Before tree.c 1.626 from 2024-03-26, the usual arithmetic conversions for
614216c89c0Srillig  * bit-field types with the same base type but different widths simply took
615216c89c0Srillig  * the type of the left operand, leading to wrong warnings about loss of
616216c89c0Srillig  * accuracy when the right operand was wider than the left operand.
617216c89c0Srillig  */
618216c89c0Srillig void
6196167e0ccSrillig binary_operators_on_bit_fields(void)
6206167e0ccSrillig {
6216167e0ccSrillig 	struct {
622216c89c0Srillig 		u64_t u15:15;
623216c89c0Srillig 		u64_t u48:48;
624216c89c0Srillig 		u64_t u64;
6256167e0ccSrillig 	} s = { 0, 0, 0 };
6266167e0ccSrillig 
6276167e0ccSrillig 	u64 = s.u15 | s.u48;
628216c89c0Srillig 	u64 = s.u48 | s.u15;
6296167e0ccSrillig 	u64 = s.u15 | s.u48 | s.u64;
630216c89c0Srillig 	u64 = s.u64 | s.u48 | s.u15;
631216c89c0Srillig 	cond = (s.u15 | s.u48 | s.u64) != 0;
632216c89c0Srillig 	cond = (s.u64 | s.u48 | s.u15) != 0;
633ce8bf3c3Srillig 
634de44edfcSrillig 	// Before tree.c from 1.638 from 2024-05-01, lint wrongly warned:
635de44edfcSrillig 	// warning: conversion of 'int' to 'int:4' is out of range [119]
636ce8bf3c3Srillig 	s32 = 8 - bits.u3;
6376167e0ccSrillig }
6388c221091Srillig 
6398c221091Srillig unsigned char
6405a79ef8cSrillig combine_arithmetic_and_bit_operations(void)
6418c221091Srillig {
6425a79ef8cSrillig 	return 0xc0 | (u32 & 0x07c0) / 64;
6438c221091Srillig }
644