msg_132.c revision 1.22 1 1.22 rillig /* $NetBSD: msg_132.c,v 1.22 2022/07/06 21:59:06 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.12 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
241 1.12 rillig return x;
242 1.12 rillig }
243 1.14 rillig
244 1.14 rillig unsigned char
245 1.22 rillig test_bit_fields(unsigned long long m)
246 1.14 rillig {
247 1.21 rillig /* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned int:3' may lose accuracy [132] */
248 1.22 rillig bits.u3 = bits.u32 & m;
249 1.14 rillig
250 1.22 rillig bits.u5 = bits.u3 & m;
251 1.22 rillig bits.u32 = bits.u5 & m;
252 1.14 rillig
253 1.21 rillig /* expect+1: warning: conversion from 'unsigned long long:32' to 'unsigned char' may lose accuracy [132] */
254 1.22 rillig return bits.u32 & m;
255 1.14 rillig }
256 1.20 rillig
257 1.22 rillig /*
258 1.22 rillig * Traditional C has an extra rule that the right-hand operand of a bit shift
259 1.22 rillig * operator is converted to 'int'. Before tree.c 1.467 from 2022-07-02, this
260 1.22 rillig * conversion was implemented as a CVT node, which means a cast, not an
261 1.22 rillig * implicit conversion. Changing the CVT to NOOP would have caused a wrong
262 1.22 rillig * warning 'may lose accuracy' in language levels other than traditional C.
263 1.22 rillig */
264 1.22 rillig
265 1.20 rillig u64_t
266 1.20 rillig u64_shl(u64_t lhs, u64_t rhs)
267 1.20 rillig {
268 1.20 rillig return lhs << rhs;
269 1.20 rillig }
270 1.20 rillig
271 1.20 rillig u64_t
272 1.20 rillig u64_shr(u64_t lhs, u64_t rhs)
273 1.20 rillig {
274 1.20 rillig return lhs >> rhs;
275 1.20 rillig }
276 1.20 rillig
277 1.20 rillig s64_t
278 1.20 rillig s64_shl(s64_t lhs, s64_t rhs)
279 1.20 rillig {
280 1.20 rillig return lhs << rhs;
281 1.20 rillig }
282 1.20 rillig
283 1.20 rillig s64_t
284 1.20 rillig s64_shr(s64_t lhs, s64_t rhs)
285 1.20 rillig {
286 1.20 rillig return lhs >> rhs;
287 1.20 rillig }
288 1.22 rillig
289 1.22 rillig void
290 1.22 rillig test_ic_mod(void)
291 1.22 rillig {
292 1.22 rillig /* The result is between 0 and 254. */
293 1.22 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
294 1.22 rillig u8 = u64 % u8;
295 1.22 rillig
296 1.22 rillig /* The result is between 0 and 1000. */
297 1.22 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
298 1.22 rillig u8 = u64 % 1000;
299 1.22 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned short' may lose accuracy [132] */
300 1.22 rillig u16 = u64 % 1000;
301 1.22 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:9' may lose accuracy [132] */
302 1.22 rillig bits.u9 = u64 % 1000;
303 1.22 rillig /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int:10' may lose accuracy [132] */
304 1.22 rillig bits.u10 = u64 % 1000;
305 1.22 rillig
306 1.22 rillig /*
307 1.22 rillig * For signed division, if the result of 'a / b' is not representable
308 1.22 rillig * exactly, the result of 'a % b' is defined such that
309 1.22 rillig * '(a / b) * a + a % b == a'.
310 1.22 rillig *
311 1.22 rillig * If the result of 'a / b' is not representable exactly, the result
312 1.22 rillig * of 'a % b' is not defined.
313 1.22 rillig *
314 1.22 rillig * C90 6.3.5, C99 6.5.5.
315 1.22 rillig */
316 1.22 rillig }
317