1 /* $NetBSD: msg_132.c,v 1.25 2023/01/29 17:02:09 rillig Exp $ */ 2 # 3 "msg_132.c" 3 4 // Test for message: conversion from '%s' to '%s' may lose accuracy [132] 5 6 /* 7 * NetBSD's default lint flags only include a single -a, which only flags 8 * narrowing conversions from long. To get warnings for all narrowing 9 * conversions, -a needs to be given more than once. 10 * 11 * https://gnats.netbsd.org/14531 12 */ 13 14 /* lint1-extra-flags: -aa */ 15 16 typedef unsigned char u8_t; 17 typedef unsigned short u16_t; 18 typedef unsigned int u32_t; 19 typedef unsigned long long u64_t; 20 typedef signed char s8_t; 21 typedef signed short s16_t; 22 typedef signed int s32_t; 23 typedef signed long long s64_t; 24 25 26 u8_t u8; 27 u16_t u16; 28 u32_t u32; 29 u64_t u64; 30 31 s8_t s8; 32 s16_t s16; 33 s32_t s32; 34 s64_t s64; 35 36 struct bit_fields { 37 unsigned u1:1; 38 unsigned u2:2; 39 unsigned u3:3; 40 unsigned u4:4; 41 unsigned u5:5; 42 unsigned u6:6; 43 unsigned u7:7; 44 unsigned u8:8; 45 unsigned u9:9; 46 unsigned u10:10; 47 unsigned u11:11; 48 unsigned u12:12; 49 unsigned u32:32; 50 } bits; 51 52 53 void 54 unsigned_to_unsigned(void) 55 { 56 /* expect+1: warning: conversion from 'unsigned short' to 'unsigned char' may lose accuracy [132] */ 57 u8 = u16; 58 /* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */ 59 u8 = u32; 60 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */ 61 u8 = u64; 62 63 u16 = u8; 64 /* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */ 65 u16 = u32; 66 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned short' may lose accuracy [132] */ 67 u16 = u64; 68 69 u32 = u8; 70 u32 = u16; 71 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */ 72 u32 = u64; 73 74 u64 = u8; 75 u64 = u16; 76 u64 = u32; 77 } 78 79 void 80 unsigned_to_signed(void) 81 { 82 /* expect+1: warning: conversion from 'unsigned short' to 'signed char' may lose accuracy [132] */ 83 s8 = u16; 84 /* expect+1: warning: conversion from 'unsigned int' to 'signed char' may lose accuracy [132] */ 85 s8 = u32; 86 /* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */ 87 s8 = u64; 88 89 s16 = u8; 90 /* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */ 91 s16 = u32; 92 /* expect+1: warning: conversion from 'unsigned long long' to 'short' may lose accuracy [132] */ 93 s16 = u64; 94 95 s32 = u8; 96 s32 = u16; 97 /* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */ 98 s32 = u64; 99 100 s64 = u8; 101 s64 = u16; 102 s64 = u32; 103 } 104 105 void 106 signed_to_unsigned(void) 107 { 108 /* expect+1: warning: conversion from 'short' to 'unsigned char' may lose accuracy [132] */ 109 u8 = s16; 110 /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */ 111 u8 = s32; 112 /* expect+1: warning: conversion from 'long long' to 'unsigned char' may lose accuracy [132] */ 113 u8 = s64; 114 115 u16 = s8; 116 /* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */ 117 u16 = s32; 118 /* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */ 119 u16 = s64; 120 121 u32 = s8; 122 u32 = s16; 123 /* expect+1: warning: conversion from 'long long' to 'unsigned int' may lose accuracy [132] */ 124 u32 = s64; 125 126 u64 = s8; 127 u64 = s16; 128 u64 = s32; 129 } 130 131 void 132 signed_to_signed(void) 133 { 134 /* expect+1: warning: conversion from 'short' to 'signed char' may lose accuracy [132] */ 135 s8 = s16; 136 /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */ 137 s8 = s32; 138 /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */ 139 s8 = s64; 140 141 s16 = s8; 142 /* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */ 143 s16 = s32; 144 /* expect+1: warning: conversion from 'long long' to 'short' may lose accuracy [132] */ 145 s16 = s64; 146 147 s32 = s8; 148 s32 = s16; 149 /* expect+1: warning: conversion from 'long long' to 'int' may lose accuracy [132] */ 150 s32 = s64; 151 152 s64 = s8; 153 s64 = s16; 154 s64 = s32; 155 } 156 157 /* 158 * Before tree.c 1.268 from 2021-04-06, lint wrongly warned that conversion 159 * to _Bool might lose accuracy. C99 6.3.1.2 defines a special conversion 160 * rule from scalar to _Bool though by comparing the value to 0. 161 */ 162 _Bool 163 to_bool(long a, long b) 164 { 165 /* seen in fp_lib.h, function wideRightShiftWithSticky */ 166 return a | b; 167 } 168 169 /* ARGSUSED */ 170 const char * 171 cover_build_plus_minus(const char *arr, double idx) 172 { 173 /* expect+3: error: operands of '+' have incompatible types 'pointer' and 'double' [107] */ 174 /* expect+2: warning: function 'cover_build_plus_minus' expects to return value [214] */ 175 if (idx > 0.0) 176 return arr + idx; 177 return arr + (unsigned int)idx; 178 } 179 180 int 181 non_constant_expression(void) 182 { 183 /* 184 * Even though this variable definition looks like a constant, it 185 * does not fall within C's definition of an integer constant 186 * expression. Due to that, lint does not perform constant folding 187 * on the expression built from this variable and thus doesn't know 188 * that the conversion will always succeed. 189 */ 190 const int not_a_constant = 8; 191 /* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */ 192 return not_a_constant * 8ULL; 193 } 194 195 /* 196 * PR 36668 notices that lint wrongly complains about the possible loss. 197 * 198 * The expression 'u8_t << 8' is guaranteed to fit into an 'u16_t', and its 199 * lower 8 bits are guaranteed to be clear. 'u16_t | u8_t' is guaranteed to 200 * fit into 'u16_t'. 201 * 202 * Since tree.c 1.444 from 2022-05-26, lint tracks simple bitwise and 203 * arithmetic constraints across a single expression. 204 */ 205 static inline u16_t 206 be16dec(const void *buf) 207 { 208 const u8_t *p = buf; 209 210 /* 211 * Before tree.c 1.444 from 2022-05-26, lint complained that the 212 * conversion from 'int' to 'unsigned short' may lose accuracy. 213 */ 214 return ((u16_t)p[0]) << 8 | p[1]; 215 } 216 217 /* 218 * Since tree.c 1.434 from 2022-04-19, lint infers the possible values of 219 * expressions of the form 'integer & constant', see can_represent. 220 */ 221 static inline void 222 be32enc(void *buf, u32_t u) 223 { 224 u8_t *p = buf; 225 226 p[0] = u >> 24 & 0xff; 227 p[1] = u >> 16 & 0xff; 228 p[2] = u >> 8 & 0xff; 229 p[3] = u & 0xff; 230 } 231 232 u32_t 233 test_ic_shr(u64_t x) 234 { 235 if (x > 3) 236 return x >> 32; 237 if (x > 2) 238 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */ 239 return x >> 31; 240 241 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */ 242 u32 = u64 >> 31; 243 u32 = u64 >> 32; 244 u16 = u64 >> 48; 245 u8 = u64 >> 56; 246 u16 = u32 >> 16; 247 u8 = u32 >> 24; 248 u8 = u16 >> 8; 249 250 /* 251 * No matter whether the big integer is signed or unsigned, the 252 * result of '&' is guaranteed to be an unsigned value. 253 */ 254 u8 = (s64 & 0xf0) >> 4; 255 u8 = (s8 & 0xf0) >> 4; 256 257 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */ 258 return x; 259 } 260 261 unsigned char 262 test_bit_fields(unsigned long long m) 263 { 264 /* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned int:3' may lose accuracy [132] */ 265 bits.u3 = bits.u32 & m; 266 267 bits.u5 = bits.u3 & m; 268 bits.u32 = bits.u5 & m; 269 270 /* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned char' may lose accuracy [132] */ 271 return bits.u32 & m; 272 } 273 274 /* 275 * Traditional C has an extra rule that the right-hand operand of a bit shift 276 * operator is converted to 'int'. Before tree.c 1.467 from 2022-07-02, this 277 * conversion was implemented as a CVT node, which means a cast, not an 278 * implicit conversion. Changing the CVT to NOOP would have caused a wrong 279 * warning 'may lose accuracy' in language levels other than traditional C. 280 */ 281 282 u64_t 283 u64_shl(u64_t lhs, u64_t rhs) 284 { 285 return lhs << rhs; 286 } 287 288 u64_t 289 u64_shr(u64_t lhs, u64_t rhs) 290 { 291 return lhs >> rhs; 292 } 293 294 s64_t 295 s64_shl(s64_t lhs, s64_t rhs) 296 { 297 return lhs << rhs; 298 } 299 300 s64_t 301 s64_shr(s64_t lhs, s64_t rhs) 302 { 303 return lhs >> rhs; 304 } 305 306 void 307 test_ic_mod(void) 308 { 309 /* The result is between 0 and 254. */ 310 u8 = u64 % u8; 311 312 /* The result is between 0 and 255. */ 313 u8 = u64 % 256; 314 315 /* The result is between 0 and 256. */ 316 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */ 317 u8 = u64 % 257; 318 319 /* The result is between 0 and 1000. */ 320 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */ 321 u8 = u64 % 1000; 322 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:9' may lose accuracy [132] */ 323 bits.u9 = u64 % 1000; 324 bits.u10 = u64 % 1000; 325 u16 = u64 % 1000; 326 327 /* 328 * For signed division, if the result of 'a / b' is not representable 329 * exactly, the result of 'a % b' is defined such that 330 * '(a / b) * a + a % b == a'. 331 * 332 * If the result of 'a / b' is not representable exactly, the result 333 * of 'a % b' is not defined. Due to this uncertainty, lint does not 334 * narrow down the range for signed modulo expressions. 335 * 336 * C90 6.3.5, C99 6.5.5. 337 */ 338 339 /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */ 340 s8 = s16 % s8; 341 342 /* 343 * The result is always 0, it's a theoretical edge case though, so 344 * lint doesn't care to implement this. 345 */ 346 /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */ 347 s8 = s64 % 1; 348 } 349 350 void 351 test_ic_bitand(void) 352 { 353 /* 354 * ic_bitand assumes that integers are represented in 2's complement, 355 * and that the sign bit of signed integers behaves like a value bit. 356 * That way, the following expressions get their constraints computed 357 * correctly, regardless of whether ic_expr takes care of integer 358 * promotions or not. Compare ic_mod, which ignores signed types. 359 */ 360 361 u8 = u8 & u16; 362 363 /* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */ 364 u8 = u16 & u32; 365 } 366