msg_132.c revision 1.20 1 /* $NetBSD: msg_132.c,v 1.20 2022/07/02 09:48:18 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 u8_t u8;
26 u16_t u16;
27 u32_t u32;
28 u64_t u64;
29
30 s8_t s8;
31 s16_t s16;
32 s32_t s32;
33 s64_t s64;
34
35 void
36 unsigned_to_unsigned(void)
37 {
38 /* expect+1: warning: conversion from 'unsigned short' to 'unsigned char' may lose accuracy [132] */
39 u8 = u16;
40 /* expect+1: warning: conversion from 'unsigned int' to 'unsigned char' may lose accuracy [132] */
41 u8 = u32;
42 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
43 u8 = u64;
44
45 u16 = u8;
46 /* expect+1: warning: conversion from 'unsigned int' to 'unsigned short' may lose accuracy [132] */
47 u16 = u32;
48 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned short' may lose accuracy [132] */
49 u16 = u64;
50
51 u32 = u8;
52 u32 = u16;
53 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
54 u32 = u64;
55
56 u64 = u8;
57 u64 = u16;
58 u64 = u32;
59 }
60
61 void
62 unsigned_to_signed(void)
63 {
64 /* expect+1: warning: conversion from 'unsigned short' to 'signed char' may lose accuracy [132] */
65 s8 = u16;
66 /* expect+1: warning: conversion from 'unsigned int' to 'signed char' may lose accuracy [132] */
67 s8 = u32;
68 /* expect+1: warning: conversion from 'unsigned long long' to 'signed char' may lose accuracy [132] */
69 s8 = u64;
70
71 s16 = u8;
72 /* expect+1: warning: conversion from 'unsigned int' to 'short' may lose accuracy [132] */
73 s16 = u32;
74 /* expect+1: warning: conversion from 'unsigned long long' to 'short' may lose accuracy [132] */
75 s16 = u64;
76
77 s32 = u8;
78 s32 = u16;
79 /* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
80 s32 = u64;
81
82 s64 = u8;
83 s64 = u16;
84 s64 = u32;
85 }
86
87 void
88 signed_to_unsigned(void)
89 {
90 /* expect+1: warning: conversion from 'short' to 'unsigned char' may lose accuracy [132] */
91 u8 = s16;
92 /* expect+1: warning: conversion from 'int' to 'unsigned char' may lose accuracy [132] */
93 u8 = s32;
94 /* expect+1: warning: conversion from 'long long' to 'unsigned char' may lose accuracy [132] */
95 u8 = s64;
96
97 u16 = s8;
98 /* expect+1: warning: conversion from 'int' to 'unsigned short' may lose accuracy [132] */
99 u16 = s32;
100 /* expect+1: warning: conversion from 'long long' to 'unsigned short' may lose accuracy [132] */
101 u16 = s64;
102
103 u32 = s8;
104 u32 = s16;
105 /* expect+1: warning: conversion from 'long long' to 'unsigned int' may lose accuracy [132] */
106 u32 = s64;
107
108 u64 = s8;
109 u64 = s16;
110 u64 = s32;
111 }
112
113 void
114 signed_to_signed(void)
115 {
116 /* expect+1: warning: conversion from 'short' to 'signed char' may lose accuracy [132] */
117 s8 = s16;
118 /* expect+1: warning: conversion from 'int' to 'signed char' may lose accuracy [132] */
119 s8 = s32;
120 /* expect+1: warning: conversion from 'long long' to 'signed char' may lose accuracy [132] */
121 s8 = s64;
122
123 s16 = s8;
124 /* expect+1: warning: conversion from 'int' to 'short' may lose accuracy [132] */
125 s16 = s32;
126 /* expect+1: warning: conversion from 'long long' to 'short' may lose accuracy [132] */
127 s16 = s64;
128
129 s32 = s8;
130 s32 = s16;
131 /* expect+1: warning: conversion from 'long long' to 'int' may lose accuracy [132] */
132 s32 = s64;
133
134 s64 = s8;
135 s64 = s16;
136 s64 = s32;
137 }
138
139 /*
140 * Before tree.c 1.268 from 2021-04-06, lint wrongly warned that conversion
141 * to _Bool might lose accuracy. C99 6.3.1.2 defines a special conversion
142 * rule from scalar to _Bool though by comparing the value to 0.
143 */
144 _Bool
145 to_bool(long a, long b)
146 {
147 /* seen in fp_lib.h, function wideRightShiftWithSticky */
148 return a | b;
149 }
150
151 /* ARGSUSED */
152 const char *
153 cover_build_plus_minus(const char *arr, double idx)
154 {
155 /* expect+3: error: operands of '+' have incompatible types 'pointer' and 'double' [107] */
156 /* expect+2: warning: function 'cover_build_plus_minus' expects to return value [214] */
157 if (idx > 0.0)
158 return arr + idx;
159 return arr + (unsigned int)idx;
160 }
161
162 int
163 non_constant_expression(void)
164 {
165 /*
166 * Even though this variable definition looks like a constant, it
167 * does not fall within C's definition of an integer constant
168 * expression. Due to that, lint does not perform constant folding
169 * on the expression built from this variable and thus doesn't know
170 * that the conversion will always succeed.
171 */
172 const int not_a_constant = 8;
173 /* expect+1: warning: conversion from 'unsigned long long' to 'int' may lose accuracy [132] */
174 return not_a_constant * 8ULL;
175 }
176
177 /*
178 * PR 36668 notices that lint wrongly complains about the possible loss.
179 *
180 * The expression 'u8_t << 8' is guaranteed to fit into an 'u16_t', and its
181 * lower 8 bits are guaranteed to be clear. 'u16_t | u8_t' is guaranteed to
182 * fit into 'u16_t'.
183 *
184 * Since tree.c 1.444 from 2022-05-26, lint tracks simple bitwise and
185 * arithmetic constraints across a single expression.
186 */
187 static inline u16_t
188 be16dec(const void *buf)
189 {
190 const u8_t *p = buf;
191
192 /*
193 * Before tree.c 1.444 from 2022-05-26, lint complained that the
194 * conversion from 'int' to 'unsigned short' may lose accuracy.
195 */
196 return ((u16_t)p[0]) << 8 | p[1];
197 }
198
199 /*
200 * Since tree.c 1.434 from 2022-04-19, lint infers the possible values of
201 * expressions of the form 'integer & constant', see can_represent.
202 */
203 static inline void
204 be32enc(void *buf, u32_t u)
205 {
206 u8_t *p = buf;
207
208 p[0] = u >> 24 & 0xff;
209 p[1] = u >> 16 & 0xff;
210 p[2] = u >> 8 & 0xff;
211 p[3] = u & 0xff;
212 }
213
214 u32_t
215 test_ic_shr(u64_t x)
216 {
217 if (x > 3)
218 return x >> 32;
219 if (x > 2)
220 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
221 return x >> 31;
222 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
223 return x;
224 }
225
226
227 struct bit_fields {
228 unsigned bits_32: 32;
229 unsigned bits_5: 5;
230 unsigned bits_3: 3;
231 };
232
233 unsigned char
234 test_bit_fields(struct bit_fields s, unsigned long long m)
235 {
236 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned int' may lose accuracy [132] */
237 s.bits_3 = s.bits_32 & m;
238
239 s.bits_5 = s.bits_3 & m;
240 s.bits_32 = s.bits_5 & m;
241
242 /* expect+1: warning: conversion from 'unsigned long long' to 'unsigned char' may lose accuracy [132] */
243 return s.bits_32 & m;
244 }
245
246 u64_t
247 u64_shl(u64_t lhs, u64_t rhs)
248 {
249 return lhs << rhs;
250 }
251
252 u64_t
253 u64_shr(u64_t lhs, u64_t rhs)
254 {
255 return lhs >> rhs;
256 }
257
258 s64_t
259 s64_shl(s64_t lhs, s64_t rhs)
260 {
261 return lhs << rhs;
262 }
263
264 s64_t
265 s64_shr(s64_t lhs, s64_t rhs)
266 {
267 return lhs >> rhs;
268 }
269