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