xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_132.c (revision aef5eb5f59cdfe8314f1b5f78ac04eb144e44010)
1 /*	$NetBSD: msg_132.c,v 1.24 2022/07/07 18:11:29 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 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
241 	return x;
242 }
243 
244 unsigned char
245 test_bit_fields(unsigned long long m)
246 {
247 	/* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned int:3' may lose accuracy [132] */
248 	bits.u3 = bits.u32 & m;
249 
250 	bits.u5 = bits.u3 & m;
251 	bits.u32 = bits.u5 & m;
252 
253 	/* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned char' may lose accuracy [132] */
254 	return bits.u32 & m;
255 }
256 
257 /*
258  * Traditional C has an extra rule that the right-hand operand of a bit shift
259  * operator is converted to 'int'.  Before tree.c 1.467 from 2022-07-02, this
260  * conversion was implemented as a CVT node, which means a cast, not an
261  * implicit conversion.  Changing the CVT to NOOP would have caused a wrong
262  * warning 'may lose accuracy' in language levels other than traditional C.
263  */
264 
265 u64_t
266 u64_shl(u64_t lhs, u64_t rhs)
267 {
268 	return lhs << rhs;
269 }
270 
271 u64_t
272 u64_shr(u64_t lhs, u64_t rhs)
273 {
274 	return lhs >> rhs;
275 }
276 
277 s64_t
278 s64_shl(s64_t lhs, s64_t rhs)
279 {
280 	return lhs << rhs;
281 }
282 
283 s64_t
284 s64_shr(s64_t lhs, s64_t rhs)
285 {
286 	return lhs >> rhs;
287 }
288 
289 void
290 test_ic_mod(void)
291 {
292 	/* The result is between 0 and 254. */
293 	u8 = u64 % u8;
294 
295 	/* The result is between 0 and 255. */
296 	u8 = u64 % 256;
297 
298 	/* The result is between 0 and 256. */
299 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
300 	u8 = u64 % 257;
301 
302 	/* The result is between 0 and 1000. */
303 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
304 	u8 = u64 % 1000;
305 	/* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:9' may lose accuracy [132] */
306 	bits.u9 = u64 % 1000;
307 	bits.u10 = u64 % 1000;
308 	u16 = u64 % 1000;
309 
310 	/*
311 	 * For signed division, if the result of 'a / b' is not representable
312 	 * exactly, the result of 'a % b' is defined such that
313 	 * '(a / b) * a + a % b == a'.
314 	 *
315 	 * If the result of 'a / b' is not representable exactly, the result
316 	 * of 'a % b' is not defined.  Due to this uncertainty, lint does not
317 	 * narrow down the range for signed modulo expressions.
318 	 *
319 	 * C90 6.3.5, C99 6.5.5.
320 	 */
321 
322 	/* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
323 	s8 = s16 % s8;
324 
325 	/*
326 	 * The result is always 0, it's a theoretical edge case though, so
327 	 * lint doesn't care to implement this.
328 	 */
329 	/* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
330 	s8 = s64 % 1;
331 }
332 
333 void
334 test_ic_bitand(void)
335 {
336 	/*
337 	 * ic_bitand assumes that integers are represented in 2's complement,
338 	 * and that the sign bit of signed integers behaves like a value bit.
339 	 * That way, the following expressions get their constraints computed
340 	 * correctly, regardless of whether ic_expr takes care of integer
341 	 * promotions or not.  Compare ic_mod, which ignores signed types.
342 	 */
343 
344 	u8 = u8 & u16;
345 
346 	/* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
347 	u8 = u16 & u32;
348 }
349