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