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