1 1.56 rillig /* $NetBSD: msg_132.c,v 1.56 2025/09/14 14:42:52 rillig 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.51 rillig /* 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.51 rillig const char *ptr; 39 1.51 rillig 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.45 rillig void 210 1.45 rillig 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.45 rillig 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.45 rillig void 224 1.45 rillig be32enc(void) 225 1.10 rillig { 226 1.45 rillig u8 = u32 >> 24 & 0xff; 227 1.45 rillig u8 = u32 >> 16 & 0xff; 228 1.45 rillig u8 = u32 >> 8 & 0xff; 229 1.45 rillig u8 = u32 & 0xff; 230 1.10 rillig } 231 1.12 rillig 232 1.43 rillig void 233 1.43 rillig test_ic_mult(void) 234 1.43 rillig { 235 1.45 rillig /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */ 236 1.45 rillig u8 = u8 * u8; 237 1.45 rillig u16 = u8 * u8; 238 1.45 rillig /* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */ 239 1.45 rillig u16 = u16 * u8; 240 1.45 rillig u32 = u16 * u16; 241 1.45 rillig 242 1.44 rillig u32 = u16 * 65537ULL; 243 1.43 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */ 244 1.44 rillig u32 = u16 * 65538ULL; 245 1.43 rillig 246 1.43 rillig u16 = 0 * u16; 247 1.43 rillig u16 = 1 * u16; 248 1.43 rillig /* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */ 249 1.43 rillig u16 = 2 * u16; 250 1.43 rillig 251 1.45 rillig // from __BITS, __SHIFTIN, __SHIFTOUT 252 1.43 rillig u32 = (u16 & 1023ULL) / 1ULL * 1024ULL | (u16 & 1023ULL) / 1ULL * 1ULL; 253 1.50 rillig 254 1.50 rillig s8 = 1 * s8; 255 1.50 rillig s16 = 1 * s16; 256 1.50 rillig s32 = 1 * s32; 257 1.50 rillig s64 = 1 * s64; 258 1.52 rillig 259 1.52 rillig /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */ 260 1.52 rillig s8 = 2 * s8; 261 1.52 rillig /* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */ 262 1.52 rillig s16 = 2 * s16; 263 1.52 rillig // No warning, as there is no narrowing conversion. 264 1.52 rillig s32 = 2 * s32; 265 1.52 rillig // No warning, as there is no narrowing conversion. 266 1.52 rillig s64 = 2 * s64; 267 1.52 rillig 268 1.52 rillig /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */ 269 1.52 rillig s8 = -1 * s8; 270 1.52 rillig /* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */ 271 1.52 rillig s16 = -1 * s16; 272 1.52 rillig // No warning, as there is no narrowing conversion. 273 1.52 rillig s32 = -1 * s32; 274 1.52 rillig // No warning, as there is no narrowing conversion. 275 1.52 rillig s64 = -1 * s64; 276 1.43 rillig } 277 1.43 rillig 278 1.45 rillig void 279 1.45 rillig test_ic_div(void) 280 1.12 rillig { 281 1.45 rillig u8 = u8 / u8; 282 1.45 rillig /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */ 283 1.45 rillig u8 = u16 / u8; 284 1.45 rillig u16 = u8 / u8; 285 1.45 rillig u16 = u32 / 65536; 286 1.45 rillig /* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */ 287 1.45 rillig u16 = u32 / 65535; 288 1.50 rillig 289 1.50 rillig s8 = s8 / 1; 290 1.50 rillig s16 = s16 / 1; 291 1.50 rillig s32 = s32 / 1; 292 1.50 rillig s64 = s64 / 1; 293 1.52 rillig 294 1.52 rillig /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */ 295 1.52 rillig s8 = s8 / -1; 296 1.52 rillig /* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */ 297 1.52 rillig s16 = s16 / -1; 298 1.52 rillig // No warning, as there is no narrowing conversion. 299 1.52 rillig s32 = s32 / -1; 300 1.52 rillig // No warning, as there is no narrowing conversion. 301 1.52 rillig 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.46 rillig s8 = s16 % s8; 326 1.23 rillig /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */ 327 1.46 rillig s8 = s16 % s16; 328 1.46 rillig s8 = s64 % 1; 329 1.46 rillig s8 = s64 % (s16 & 1); 330 1.46 rillig /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */ 331 1.46 rillig s8 = s64 % (s16 & 0); 332 1.46 rillig s8 = (s64 & 0x7f) % s64; 333 1.23 rillig /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */ 334 1.46 rillig s8 = (s64 & 0xff) % s64; 335 1.22 rillig } 336 1.24 rillig 337 1.24 rillig void 338 1.47 rillig test_ic_plus(void) 339 1.47 rillig { 340 1.47 rillig /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */ 341 1.47 rillig s8 = -129 + s64 % 1; 342 1.47 rillig s8 = -128 + s64 % 1; 343 1.47 rillig s8 = 127 + s64 % 1; 344 1.47 rillig /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */ 345 1.47 rillig s8 = 128 + s64 % 1; 346 1.47 rillig 347 1.47 rillig /* expect+2: warning: conversion of negative constant -129 to unsigned type 'unsigned long long' [222] */ 348 1.47 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */ 349 1.47 rillig s8 = -129 + u64 % 1; 350 1.47 rillig /* expect+2: warning: conversion of negative constant -128 to unsigned type 'unsigned long long' [222] */ 351 1.47 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */ 352 1.47 rillig s8 = -128 + u64 % 1; 353 1.47 rillig s8 = 127 + u64 % 1; 354 1.47 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */ 355 1.47 rillig s8 = 128 + u64 % 1; 356 1.47 rillig 357 1.47 rillig u8 = 0 + u64 % 1; 358 1.47 rillig u8 = 255 + u64 % 1; 359 1.47 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */ 360 1.47 rillig u8 = 256 + u64 % 1; 361 1.47 rillig 362 1.50 rillig u8 = s8 + 0x80; 363 1.50 rillig u16 = s16 + 0x8000; 364 1.50 rillig u32 = s32 + 0x80000000; 365 1.50 rillig u64 = s64 + 0x8000000000000000; 366 1.50 rillig 367 1.49 rillig // XXX: No warnings since portable_rank_cmp is the same for both sides. 368 1.49 rillig bits.u11 = bits.u10 + bits.u10 + 1; 369 1.49 rillig bits.u11 = bits.u10 + bits.u10 + 2; 370 1.49 rillig bits.u11 = bits.u10 + 1024; 371 1.49 rillig bits.u11 = bits.u10 + 1025; 372 1.49 rillig 373 1.49 rillig u8 = bits.u7 + bits.u7 + 1; 374 1.49 rillig /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */ 375 1.49 rillig u8 = bits.u7 + bits.u7 + 2; 376 1.49 rillig u8 = bits.u7 + 128; 377 1.49 rillig /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */ 378 1.49 rillig u8 = bits.u7 + 129; 379 1.49 rillig 380 1.49 rillig // The result of the second '+' wraps around, thus the warning, 381 1.49 rillig // even though the final result fits in a u16. 382 1.49 rillig /* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */ 383 1.49 rillig u16 = u32 % 0x00010000 + 0x80000000 + 0x80000000; 384 1.49 rillig 385 1.49 rillig /* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */ 386 1.49 rillig u16 = u32 % 0x00010000 + 0xffff8000; 387 1.49 rillig /* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */ 388 1.49 rillig s16 = u32 % 0x00010000 + 0xffff8000; 389 1.49 rillig 390 1.49 rillig /* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */ 391 1.49 rillig u16 = s64 % 0x00010000 + 0xffffffffLL + -0xffffffffLL; 392 1.49 rillig /* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */ 393 1.49 rillig u16 = s32 % 0x00010000 + 0x7fff0000 + -0x7fff0000; 394 1.49 rillig /* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */ 395 1.49 rillig u16 = u32 % 0x00010000 + 0xffff0000 + 0x00010000; 396 1.49 rillig 397 1.47 rillig s8 = '0' + s64 % 10; 398 1.51 rillig 399 1.51 rillig ptr = ptr + 3; 400 1.47 rillig } 401 1.47 rillig 402 1.47 rillig void 403 1.49 rillig test_ic_minus(void) 404 1.49 rillig { 405 1.49 rillig // Shift the range [0x00 to 0xff] to [-0x80 to 0x7f]. 406 1.49 rillig s8 = (s64 & 0xff) - 0x80; 407 1.49 rillig 408 1.49 rillig // Sign-extend the lowest bits. 409 1.49 rillig s8 = ((s64 & 0xff) ^ 0x80) - 0x80; 410 1.49 rillig s16 = ((s64 & 0xffff) ^ 0x8000) - 0x8000; 411 1.54 rillig /* expect+1: warning: '&' converts 'unsigned int' with its most significant bit being set to 'long long' [309] */ 412 1.49 rillig s32 = ((s64 & 0xffffffff) ^ 0x80000000) - 0x80000000; 413 1.49 rillig 414 1.49 rillig // Trying to sign-extend, but with off-by-one errors. 415 1.49 rillig /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */ 416 1.49 rillig s8 = ((s64 & 0xff) ^ 0x80) - 0x7f; 417 1.49 rillig /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */ 418 1.49 rillig s8 = ((s64 & 0xff) ^ 0x80) - 0x81; 419 1.50 rillig 420 1.50 rillig u8 = s8 - -0x80; 421 1.50 rillig u16 = s16 - -0x8000; 422 1.50 rillig u32 = s32 - -0x80000000; 423 1.50 rillig u64 = s64 - -0x8000000000000000; 424 1.51 rillig 425 1.51 rillig ptr = ptr - 3; 426 1.51 rillig s64 = ptr + 3 - ptr; 427 1.49 rillig } 428 1.49 rillig 429 1.49 rillig void 430 1.45 rillig test_ic_shl(void) 431 1.45 rillig { 432 1.45 rillig u64 = u64 << u64; 433 1.45 rillig s64 = s64 << s64; 434 1.45 rillig 435 1.45 rillig u16 = u8 << 8; 436 1.45 rillig /* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */ 437 1.45 rillig u16 = u8 << 9; 438 1.56 rillig /* expect+1: warning: bitwise '<<' on signed 'int promoted from unsigned short' possibly nonportable [117] */ 439 1.45 rillig u32 = u16 << 16; 440 1.45 rillig // XXX: missing warning as UINT has the same rank as INT, see portable_rank_cmp. 441 1.45 rillig u32 = u16 << 17; 442 1.55 rillig /* expect+1: warning: shift amount 56 is greater than bit-size 32 of 'int promoted from unsigned char' [122] */ 443 1.45 rillig u64 = u8 << 56; 444 1.45 rillig u64 = (u64_t)u8 << 56; 445 1.45 rillig // XXX: missing warning, as the operand types of '=' are the same, thus no conversion. 446 1.45 rillig u64 = (u64_t)u8 << 57; 447 1.55 rillig /* expect+1: warning: shift amount 48 is greater than bit-size 32 of 'int promoted from unsigned short' [122] */ 448 1.45 rillig u64 = u16 << 48; 449 1.45 rillig u64 = (u64_t)u16 << 48; 450 1.45 rillig // XXX: missing warning, as the operand types of '=' are the same, thus no conversion. 451 1.45 rillig u64 = (u64_t)u16 << 49; 452 1.45 rillig /* expect+1: warning: shift amount 32 equals bit-size of 'unsigned int' [267] */ 453 1.45 rillig u64 = u32 << 32; 454 1.45 rillig u64 = (u64_t)u32 << 32; 455 1.45 rillig // XXX: missing warning, as the operand types of '=' are the same, thus no conversion. 456 1.45 rillig u64 = (u64_t)u32 << 33; 457 1.45 rillig } 458 1.45 rillig 459 1.45 rillig void 460 1.45 rillig test_ic_shr(void) 461 1.24 rillig { 462 1.45 rillig u64 = u64 >> u64; 463 1.45 rillig s64 = s64 >> s64; 464 1.45 rillig 465 1.45 rillig u32 = u64 >> 32; 466 1.45 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */ 467 1.45 rillig u32 = u64 >> 31; 468 1.45 rillig u16 = u64 >> 48; 469 1.45 rillig u16 = u32 >> 16; 470 1.45 rillig u8 = u64 >> 56; 471 1.45 rillig u8 = u32 >> 24; 472 1.45 rillig u8 = u16 >> 8; 473 1.45 rillig 474 1.24 rillig /* 475 1.45 rillig * No matter whether the big integer is signed or unsigned, the 476 1.45 rillig * result of '&' is guaranteed to be an unsigned value. 477 1.24 rillig */ 478 1.45 rillig u8 = (s64 & 0xf0) >> 4; 479 1.45 rillig u8 = (s8 & 0xf0) >> 4; 480 1.45 rillig } 481 1.24 rillig 482 1.45 rillig void 483 1.45 rillig test_ic_bitand(void) 484 1.45 rillig { 485 1.24 rillig u8 = u8 & u16; 486 1.24 rillig 487 1.24 rillig /* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */ 488 1.24 rillig u8 = u16 & u32; 489 1.24 rillig } 490 1.27 rillig 491 1.27 rillig void 492 1.49 rillig test_ic_bitxor(void) 493 1.49 rillig { 494 1.49 rillig /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */ 495 1.49 rillig u8 = u8 ^ u16; 496 1.49 rillig u16 = u8 ^ u16; 497 1.49 rillig 498 1.49 rillig // Sign-extend. 499 1.49 rillig s8 = (u8 ^ 0x80) - 0x80; 500 1.49 rillig s16 = (u16 ^ 0x8000) - 0x8000; 501 1.49 rillig s32 = (u32 ^ 0x80000000) - 0x80000000; 502 1.49 rillig s64 = (u64 ^ 0x8000000000000000) - 0x8000000000000000; 503 1.49 rillig } 504 1.49 rillig 505 1.49 rillig void 506 1.45 rillig test_ic_bitor(void) 507 1.28 rillig { 508 1.45 rillig /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */ 509 1.45 rillig u8 = u8 | u16; 510 1.45 rillig u16 = u8 | u16; 511 1.45 rillig /* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */ 512 1.45 rillig u16 = u8 | u32; 513 1.45 rillig u32 = u8 | u32; 514 1.45 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */ 515 1.45 rillig u32 = u8 | u64; 516 1.45 rillig u64 = u8 | u64; 517 1.28 rillig } 518 1.28 rillig 519 1.28 rillig void 520 1.45 rillig test_ic_quest_colon(char c1, char c2) 521 1.27 rillig { 522 1.27 rillig /* Both operands are representable as char. */ 523 1.27 rillig ch = cond ? '?' : ':'; 524 1.27 rillig 525 1.27 rillig /* 526 1.27 rillig * Both operands are representable as char. Clang-Tidy 17 wrongly 527 1.27 rillig * warns about a narrowing conversion from 'int' to signed type 528 1.27 rillig * 'char'. 529 1.27 rillig */ 530 1.27 rillig ch = cond ? c1 : c2; 531 1.27 rillig 532 1.30 rillig /* 533 1.45 rillig * Mixing s8 and u8 results in a number from -128 to 255, which neither 534 1.45 rillig * fits in s8 nor u8. 535 1.30 rillig */ 536 1.27 rillig /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */ 537 1.27 rillig s8 = cond ? s8 : u8; 538 1.27 rillig /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */ 539 1.27 rillig u8 = cond ? s8 : u8; 540 1.27 rillig } 541 1.34 rillig 542 1.34 rillig void 543 1.45 rillig test_ic_con(void) 544 1.45 rillig { 545 1.45 rillig /* expect+1: warning: assignment of negative constant -1 to unsigned type 'unsigned char' [164] */ 546 1.45 rillig u8 = -1; 547 1.45 rillig u8 = 0; 548 1.45 rillig u8 = 255; 549 1.45 rillig /* expect+1: warning: constant truncated by assignment [165] */ 550 1.45 rillig u8 = 256; 551 1.45 rillig 552 1.45 rillig /* expect+1: warning: conversion of 'int' to 'signed char' is out of range [119] */ 553 1.45 rillig s8 = -129; 554 1.45 rillig s8 = -128; 555 1.45 rillig s8 = 127; 556 1.45 rillig /* expect+1: warning: conversion of 'int' to 'signed char' is out of range [119] */ 557 1.45 rillig s8 = 128; 558 1.45 rillig } 559 1.45 rillig 560 1.45 rillig void 561 1.45 rillig test_ic_cvt(void) 562 1.45 rillig { 563 1.45 rillig u16 = (u32 & 0x0000ff00); 564 1.45 rillig u16 = (u32_t)(u32 & 0x0000ff00); 565 1.45 rillig u16 = (u16_t)u32; 566 1.45 rillig u16 = (u8_t)(u32 & 0xffff) << 8; 567 1.50 rillig u16 = (int)3.0; 568 1.50 rillig 569 1.50 rillig u8 = (u8_t)(u64 & 0x0f); 570 1.50 rillig u8 = (u8_t)(u64 & 0x0f) << 4; 571 1.50 rillig /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */ 572 1.50 rillig u8 = (u8_t)(u64 & 0x0f) << 5; 573 1.45 rillig } 574 1.45 rillig 575 1.45 rillig unsigned char 576 1.45 rillig test_bit_fields(unsigned long long m) 577 1.45 rillig { 578 1.45 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:3' may lose accuracy [132] */ 579 1.45 rillig bits.u3 = bits.u32 & m; 580 1.45 rillig 581 1.45 rillig bits.u5 = bits.u3 & m; 582 1.45 rillig bits.u32 = bits.u5 & m; 583 1.45 rillig 584 1.45 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */ 585 1.45 rillig return bits.u32 & m; 586 1.45 rillig } 587 1.45 rillig 588 1.45 rillig void 589 1.36 rillig compare_bit_field_to_integer_constant(void) 590 1.34 rillig { 591 1.36 rillig static _Bool b; 592 1.36 rillig static struct { 593 1.36 rillig short s16:15; 594 1.36 rillig unsigned short u16:15; 595 1.36 rillig int s32:15; 596 1.36 rillig unsigned u32:15; 597 1.36 rillig long long s64:15; 598 1.36 rillig unsigned long long u64:15; 599 1.36 rillig } s; 600 1.34 rillig 601 1.35 rillig // Since decl.c 1.180 from 2021-05-02 and before tree.c 1.624 from 602 1.35 rillig // 2024-03-12, lint warned about a possible loss of accuracy [132] 603 1.36 rillig // when promoting an 'unsigned long long' bit-field to 'int'. 604 1.36 rillig b = s.s16 == 0; 605 1.36 rillig b = s.u16 == 0; 606 1.36 rillig b = s.s32 == 0; 607 1.36 rillig b = s.u32 == 0; 608 1.36 rillig b = s.s64 == 0; 609 1.36 rillig b = s.u64 == 0; 610 1.36 rillig b = !b; 611 1.34 rillig } 612 1.37 rillig 613 1.38 rillig /* 614 1.38 rillig * Before tree.c 1.626 from 2024-03-26, the usual arithmetic conversions for 615 1.38 rillig * bit-field types with the same base type but different widths simply took 616 1.38 rillig * the type of the left operand, leading to wrong warnings about loss of 617 1.38 rillig * accuracy when the right operand was wider than the left operand. 618 1.38 rillig */ 619 1.38 rillig void 620 1.37 rillig binary_operators_on_bit_fields(void) 621 1.37 rillig { 622 1.37 rillig struct { 623 1.38 rillig u64_t u15:15; 624 1.38 rillig u64_t u48:48; 625 1.38 rillig u64_t u64; 626 1.37 rillig } s = { 0, 0, 0 }; 627 1.37 rillig 628 1.37 rillig u64 = s.u15 | s.u48; 629 1.38 rillig u64 = s.u48 | s.u15; 630 1.37 rillig u64 = s.u15 | s.u48 | s.u64; 631 1.38 rillig u64 = s.u64 | s.u48 | s.u15; 632 1.38 rillig cond = (s.u15 | s.u48 | s.u64) != 0; 633 1.38 rillig cond = (s.u64 | s.u48 | s.u15) != 0; 634 1.39 rillig 635 1.40 rillig // Before tree.c from 1.638 from 2024-05-01, lint wrongly warned: 636 1.40 rillig // warning: conversion of 'int' to 'int:4' is out of range [119] 637 1.39 rillig s32 = 8 - bits.u3; 638 1.37 rillig } 639 1.41 rillig 640 1.41 rillig unsigned char 641 1.43 rillig combine_arithmetic_and_bit_operations(void) 642 1.41 rillig { 643 1.43 rillig return 0xc0 | (u32 & 0x07c0) / 64; 644 1.41 rillig } 645