msg_132.c revision 1.56 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