msg_132.c revision 1.38 1 1.38 rillig /* $NetBSD: msg_132.c,v 1.38 2024/03/25 23:39:14 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.26 rillig /* lint1-extra-flags: -X 351 */
7 1.26 rillig
8 1.3 rillig /*
9 1.3 rillig * NetBSD's default lint flags only include a single -a, which only flags
10 1.3 rillig * narrowing conversions from long. To get warnings for all narrowing
11 1.9 rillig * conversions, -a needs to be given more than once.
12 1.3 rillig *
13 1.3 rillig * https://gnats.netbsd.org/14531
14 1.3 rillig */
15 1.3 rillig
16 1.3 rillig /* lint1-extra-flags: -aa */
17 1.3 rillig
18 1.20 rillig typedef unsigned char u8_t;
19 1.20 rillig typedef unsigned short u16_t;
20 1.20 rillig typedef unsigned int u32_t;
21 1.20 rillig typedef unsigned long long u64_t;
22 1.20 rillig typedef signed char s8_t;
23 1.20 rillig typedef signed short s16_t;
24 1.20 rillig typedef signed int s32_t;
25 1.20 rillig typedef signed long long s64_t;
26 1.20 rillig
27 1.27 rillig _Bool cond;
28 1.27 rillig char ch;
29 1.22 rillig
30 1.20 rillig u8_t u8;
31 1.20 rillig u16_t u16;
32 1.20 rillig u32_t u32;
33 1.20 rillig u64_t u64;
34 1.20 rillig
35 1.20 rillig s8_t s8;
36 1.20 rillig s16_t s16;
37 1.20 rillig s32_t s32;
38 1.20 rillig s64_t s64;
39 1.3 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.10 rillig static inline u16_t
210 1.10 rillig be16dec(const void *buf)
211 1.10 rillig {
212 1.10 rillig const u8_t *p = buf;
213 1.10 rillig
214 1.11 rillig /*
215 1.11 rillig * Before tree.c 1.444 from 2022-05-26, lint complained that the
216 1.11 rillig * conversion from 'int' to 'unsigned short' may lose accuracy.
217 1.11 rillig */
218 1.10 rillig return ((u16_t)p[0]) << 8 | p[1];
219 1.10 rillig }
220 1.10 rillig
221 1.10 rillig /*
222 1.10 rillig * Since tree.c 1.434 from 2022-04-19, lint infers the possible values of
223 1.10 rillig * expressions of the form 'integer & constant', see can_represent.
224 1.10 rillig */
225 1.10 rillig static inline void
226 1.10 rillig be32enc(void *buf, u32_t u)
227 1.10 rillig {
228 1.10 rillig u8_t *p = buf;
229 1.10 rillig
230 1.10 rillig p[0] = u >> 24 & 0xff;
231 1.10 rillig p[1] = u >> 16 & 0xff;
232 1.10 rillig p[2] = u >> 8 & 0xff;
233 1.10 rillig p[3] = u & 0xff;
234 1.10 rillig }
235 1.12 rillig
236 1.12 rillig u32_t
237 1.12 rillig test_ic_shr(u64_t x)
238 1.12 rillig {
239 1.12 rillig if (x > 3)
240 1.12 rillig return x >> 32;
241 1.12 rillig if (x > 2)
242 1.12 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
243 1.12 rillig return x >> 31;
244 1.25 rillig
245 1.25 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
246 1.25 rillig u32 = u64 >> 31;
247 1.25 rillig u32 = u64 >> 32;
248 1.25 rillig u16 = u64 >> 48;
249 1.25 rillig u8 = u64 >> 56;
250 1.25 rillig u16 = u32 >> 16;
251 1.25 rillig u8 = u32 >> 24;
252 1.25 rillig u8 = u16 >> 8;
253 1.25 rillig
254 1.25 rillig /*
255 1.25 rillig * No matter whether the big integer is signed or unsigned, the
256 1.25 rillig * result of '&' is guaranteed to be an unsigned value.
257 1.25 rillig */
258 1.25 rillig u8 = (s64 & 0xf0) >> 4;
259 1.25 rillig u8 = (s8 & 0xf0) >> 4;
260 1.25 rillig
261 1.12 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
262 1.12 rillig return x;
263 1.12 rillig }
264 1.14 rillig
265 1.14 rillig unsigned char
266 1.22 rillig test_bit_fields(unsigned long long m)
267 1.14 rillig {
268 1.21 rillig /* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned int:3' may lose accuracy [132] */
269 1.22 rillig bits.u3 = bits.u32 & m;
270 1.14 rillig
271 1.22 rillig bits.u5 = bits.u3 & m;
272 1.22 rillig bits.u32 = bits.u5 & m;
273 1.14 rillig
274 1.21 rillig /* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned char' may lose accuracy [132] */
275 1.22 rillig return bits.u32 & m;
276 1.14 rillig }
277 1.20 rillig
278 1.22 rillig /*
279 1.22 rillig * Traditional C has an extra rule that the right-hand operand of a bit shift
280 1.22 rillig * operator is converted to 'int'. Before tree.c 1.467 from 2022-07-02, this
281 1.22 rillig * conversion was implemented as a CVT node, which means a cast, not an
282 1.22 rillig * implicit conversion. Changing the CVT to NOOP would have caused a wrong
283 1.22 rillig * warning 'may lose accuracy' in language levels other than traditional C.
284 1.22 rillig */
285 1.22 rillig
286 1.20 rillig u64_t
287 1.20 rillig u64_shl(u64_t lhs, u64_t rhs)
288 1.20 rillig {
289 1.20 rillig return lhs << rhs;
290 1.20 rillig }
291 1.20 rillig
292 1.20 rillig u64_t
293 1.20 rillig u64_shr(u64_t lhs, u64_t rhs)
294 1.20 rillig {
295 1.20 rillig return lhs >> rhs;
296 1.20 rillig }
297 1.20 rillig
298 1.20 rillig s64_t
299 1.20 rillig s64_shl(s64_t lhs, s64_t rhs)
300 1.20 rillig {
301 1.20 rillig return lhs << rhs;
302 1.20 rillig }
303 1.20 rillig
304 1.20 rillig s64_t
305 1.20 rillig s64_shr(s64_t lhs, s64_t rhs)
306 1.20 rillig {
307 1.20 rillig return lhs >> rhs;
308 1.20 rillig }
309 1.22 rillig
310 1.22 rillig void
311 1.22 rillig test_ic_mod(void)
312 1.22 rillig {
313 1.22 rillig /* The result is between 0 and 254. */
314 1.23 rillig u8 = u64 % u8;
315 1.23 rillig
316 1.23 rillig /* The result is between 0 and 255. */
317 1.23 rillig u8 = u64 % 256;
318 1.23 rillig
319 1.23 rillig /* The result is between 0 and 256. */
320 1.22 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
321 1.23 rillig u8 = u64 % 257;
322 1.22 rillig
323 1.22 rillig /* The result is between 0 and 1000. */
324 1.22 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
325 1.22 rillig u8 = u64 % 1000;
326 1.22 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:9' may lose accuracy [132] */
327 1.22 rillig bits.u9 = u64 % 1000;
328 1.22 rillig bits.u10 = u64 % 1000;
329 1.23 rillig u16 = u64 % 1000;
330 1.22 rillig
331 1.22 rillig /*
332 1.22 rillig * For signed division, if the result of 'a / b' is not representable
333 1.22 rillig * exactly, the result of 'a % b' is defined such that
334 1.22 rillig * '(a / b) * a + a % b == a'.
335 1.22 rillig *
336 1.22 rillig * If the result of 'a / b' is not representable exactly, the result
337 1.23 rillig * of 'a % b' is not defined. Due to this uncertainty, lint does not
338 1.23 rillig * narrow down the range for signed modulo expressions.
339 1.22 rillig *
340 1.22 rillig * C90 6.3.5, C99 6.5.5.
341 1.22 rillig */
342 1.23 rillig
343 1.23 rillig /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
344 1.23 rillig s8 = s16 % s8;
345 1.23 rillig
346 1.23 rillig /*
347 1.23 rillig * The result is always 0, it's a theoretical edge case though, so
348 1.23 rillig * lint doesn't care to implement this.
349 1.23 rillig */
350 1.23 rillig /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
351 1.23 rillig s8 = s64 % 1;
352 1.22 rillig }
353 1.24 rillig
354 1.24 rillig void
355 1.24 rillig test_ic_bitand(void)
356 1.24 rillig {
357 1.24 rillig /*
358 1.24 rillig * ic_bitand assumes that integers are represented in 2's complement,
359 1.24 rillig * and that the sign bit of signed integers behaves like a value bit.
360 1.24 rillig * That way, the following expressions get their constraints computed
361 1.24 rillig * correctly, regardless of whether ic_expr takes care of integer
362 1.24 rillig * promotions or not. Compare ic_mod, which ignores signed types.
363 1.24 rillig */
364 1.24 rillig
365 1.24 rillig u8 = u8 & u16;
366 1.24 rillig
367 1.24 rillig /* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
368 1.24 rillig u8 = u16 & u32;
369 1.24 rillig }
370 1.27 rillig
371 1.27 rillig void
372 1.28 rillig test_ic_cvt(void)
373 1.28 rillig {
374 1.28 rillig u16 = (u32 & 0x0000ff00);
375 1.28 rillig u16 = (u32_t)(u32 & 0x0000ff00);
376 1.28 rillig }
377 1.28 rillig
378 1.28 rillig void
379 1.27 rillig test_ic_conditional(char c1, char c2)
380 1.27 rillig {
381 1.27 rillig /* Both operands are representable as char. */
382 1.27 rillig ch = cond ? '?' : ':';
383 1.27 rillig
384 1.27 rillig /*
385 1.27 rillig * Both operands are representable as char. Clang-Tidy 17 wrongly
386 1.27 rillig * warns about a narrowing conversion from 'int' to signed type
387 1.27 rillig * 'char'.
388 1.27 rillig */
389 1.27 rillig ch = cond ? c1 : c2;
390 1.27 rillig
391 1.30 rillig /*
392 1.30 rillig * Mixing s8 and u8 results in a number from -128 to 255, which does
393 1.30 rillig * not necessarily fit into s8.
394 1.30 rillig */
395 1.27 rillig /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
396 1.27 rillig s8 = cond ? s8 : u8;
397 1.27 rillig
398 1.30 rillig /*
399 1.30 rillig * Mixing s8 and u8 results in a number from -128 to 255, which does
400 1.30 rillig * not necessarily fit into u8.
401 1.30 rillig */
402 1.27 rillig /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
403 1.27 rillig u8 = cond ? s8 : u8;
404 1.27 rillig }
405 1.34 rillig
406 1.34 rillig void
407 1.36 rillig compare_bit_field_to_integer_constant(void)
408 1.34 rillig {
409 1.36 rillig static _Bool b;
410 1.36 rillig static struct {
411 1.36 rillig short s16:15;
412 1.36 rillig unsigned short u16:15;
413 1.36 rillig int s32:15;
414 1.36 rillig unsigned u32:15;
415 1.36 rillig long long s64:15;
416 1.36 rillig unsigned long long u64:15;
417 1.36 rillig } s;
418 1.34 rillig
419 1.35 rillig // Since decl.c 1.180 from 2021-05-02 and before tree.c 1.624 from
420 1.35 rillig // 2024-03-12, lint warned about a possible loss of accuracy [132]
421 1.36 rillig // when promoting an 'unsigned long long' bit-field to 'int'.
422 1.36 rillig b = s.s16 == 0;
423 1.36 rillig b = s.u16 == 0;
424 1.36 rillig b = s.s32 == 0;
425 1.36 rillig b = s.u32 == 0;
426 1.36 rillig b = s.s64 == 0;
427 1.36 rillig b = s.u64 == 0;
428 1.36 rillig b = !b;
429 1.34 rillig }
430 1.37 rillig
431 1.38 rillig /*
432 1.38 rillig * Before tree.c 1.626 from 2024-03-26, the usual arithmetic conversions for
433 1.38 rillig * bit-field types with the same base type but different widths simply took
434 1.38 rillig * the type of the left operand, leading to wrong warnings about loss of
435 1.38 rillig * accuracy when the right operand was wider than the left operand.
436 1.38 rillig */
437 1.38 rillig void
438 1.37 rillig binary_operators_on_bit_fields(void)
439 1.37 rillig {
440 1.37 rillig struct {
441 1.38 rillig u64_t u15:15;
442 1.38 rillig u64_t u48:48;
443 1.38 rillig u64_t u64;
444 1.37 rillig } s = { 0, 0, 0 };
445 1.37 rillig
446 1.37 rillig u64 = s.u15 | s.u48;
447 1.38 rillig u64 = s.u48 | s.u15;
448 1.37 rillig u64 = s.u15 | s.u48 | s.u64;
449 1.38 rillig u64 = s.u64 | s.u48 | s.u15;
450 1.38 rillig cond = (s.u15 | s.u48 | s.u64) != 0;
451 1.38 rillig cond = (s.u64 | s.u48 | s.u15) != 0;
452 1.37 rillig }
453