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