1 /* $NetBSD: msg_259.c,v 1.25 2024/06/09 10:27:39 rillig Exp $ */
2 # 3 "msg_259.c"
3
4 // Test for message: argument %d is converted from '%s' to '%s' due to prototype [259]
5
6 /*
7 * This warning detects function calls that are translated in very different
8 * translation environments, one where prototypes are omitted, and one where
9 * prototypes are active. It is possible to make such code interoperable,
10 * but that requires that each argument is converted to its proper type by
11 * the caller of the function.
12 *
13 * When lint is run with the '-s' flag, it no longer warns about code with
14 * incompatibilities between traditional C and C90, therefore this test omits
15 * all of the options '-t', '-s', '-S' and '-Ac11'.
16 *
17 * See also msg_297, which is about lossy integer conversions, but that
18 * requires the flags -a -p -P, which are not enabled in the default NetBSD
19 * build.
20 */
21
22 /* lint1-only-if: lp64 */
23 /* lint1-flags: -g -h -w -X 351 */
24
25 void plain_char(char);
26 void signed_char(signed char);
27 void unsigned_char(unsigned char);
28 void signed_short(signed short);
29 void unsigned_short(unsigned short);
30 void signed_int(int);
31 void unsigned_int(unsigned int);
32 void signed_long(long);
33 void unsigned_long(unsigned long);
34 void signed_long_long(long long);
35 void unsigned_long_long(unsigned long long);
36 void take_float(float);
37
38 void
change_in_type_width(char c,int i,long l)39 change_in_type_width(char c, int i, long l)
40 {
41 plain_char(c);
42 signed_int(c);
43 /* No warning 259 on LP64, only on ILP32 */
44 signed_long(c);
45
46 plain_char(i); /* XXX: why no warning? */
47 signed_int(i);
48 /* No warning 259 on LP64, only on ILP32 */
49 signed_long(i);
50
51 plain_char(l); /* XXX: why no warning? */
52 /* expect+1: ... from 'long' to 'int' due to prototype [259] */
53 signed_int(l);
54 signed_long(l);
55 }
56
57 /*
58 * Converting a signed integer type to its corresponding unsigned integer
59 * type (C99 6.2.5p6) is usually not a problem since the actual values of the
60 * expressions are usually not anywhere near the maximum signed value. From
61 * a technical standpoint, it is correct to warn here since even small
62 * negative numbers may result in very large positive numbers.
63 *
64 * A common case where it occurs is when the difference of two pointers is
65 * converted to size_t. The type ptrdiff_t is defined to be signed, but in
66 * many practical cases, the expression is '(end - start)', which makes the
67 * resulting value necessarily positive.
68 */
69 void
small_integer_types(char c,signed char sc,unsigned char uc,signed short ss,unsigned short us,signed int si,unsigned int ui,signed long long sll,unsigned long long ull)70 small_integer_types(char c, signed char sc, unsigned char uc,
71 signed short ss, unsigned short us,
72 signed int si, unsigned int ui,
73 signed long long sll, unsigned long long ull)
74 {
75 plain_char(c);
76 plain_char(sc);
77 plain_char(uc);
78 plain_char(ss);
79 plain_char(us);
80 plain_char(si);
81 plain_char(ui);
82 plain_char(sll);
83 plain_char(ull);
84
85 signed_char(c);
86 signed_char(sc);
87 signed_char(uc);
88 signed_char(ss);
89 signed_char(us);
90 signed_char(si);
91 signed_char(ui);
92 signed_char(sll);
93 signed_char(ull);
94
95 unsigned_char(c);
96 unsigned_char(sc);
97 unsigned_char(uc);
98 unsigned_char(ss);
99 unsigned_char(us);
100 unsigned_char(si);
101 unsigned_char(ui);
102 unsigned_char(sll);
103 unsigned_char(ull);
104
105 signed_short(c);
106 signed_short(sc);
107 signed_short(uc);
108 signed_short(ss);
109 signed_short(us);
110 signed_short(si);
111 signed_short(ui);
112 signed_short(sll);
113 signed_short(ull);
114
115 unsigned_short(c);
116 unsigned_short(sc);
117 unsigned_short(uc);
118 unsigned_short(ss);
119 unsigned_short(us);
120 unsigned_short(si);
121 unsigned_short(ui);
122 unsigned_short(sll);
123 unsigned_short(ull);
124 }
125
126 /*
127 * This function tests, among others, the conversion from a signed integer
128 * type to its corresponding unsigned integer type. Warning 259 is not
129 * about lossy integer conversions but about ABI calling conventions.
130 *
131 * A common case where a conversion from a signed integer type to its
132 * corresponding unsigned integer type occurs is when the difference of two
133 * pointers is converted to size_t. The type ptrdiff_t is defined to be
134 * signed, but in many practical cases, the expression is '(end - start)',
135 * which makes the resulting value necessarily positive.
136 */
137 void
signed_to_unsigned(int si,long sl,long long sll)138 signed_to_unsigned(int si, long sl, long long sll)
139 {
140 /* expect+1: warning: argument 1 is converted from 'int' to 'unsigned int' due to prototype [259] */
141 unsigned_int(si);
142
143 /* expect+1: warning: argument 1 is converted from 'long' to 'unsigned int' due to prototype [259] */
144 unsigned_int(sl);
145
146 /* expect+1: warning: argument 1 is converted from 'long long' to 'unsigned int' due to prototype [259] */
147 unsigned_int(sll);
148
149 /*
150 * No warning here. Even though 'unsigned long' is 64 bits wide, it
151 * cannot represent negative 32-bit values. This lossy conversion is
152 * covered by message 297 instead, which requires nonstandard flags.
153 */
154 unsigned_long(si);
155
156 /* expect+1: warning: argument 1 is converted from 'long' to 'unsigned long' due to prototype [259] */
157 unsigned_long(sl);
158 /* expect+1: warning: argument 1 is converted from 'long long' to 'unsigned long' due to prototype [259] */
159 unsigned_long(sll);
160
161 /*
162 * No warning here. Even though 'unsigned long long' is 64 bits
163 * wide, it cannot represent negative 32-bit values. This lossy
164 * conversion is covered by message 297 instead, which requires
165 * nonstandard flags.
166 */
167 unsigned_long_long(si);
168
169 /* expect+1: warning: argument 1 is converted from 'long' to 'unsigned long long' due to prototype [259] */
170 unsigned_long_long(sl);
171
172 /* expect+1: warning: argument 1 is converted from 'long long' to 'unsigned long long' due to prototype [259] */
173 unsigned_long_long(sll);
174 }
175
176 void
unsigned_to_signed(unsigned int ui,unsigned long ul,unsigned long long ull)177 unsigned_to_signed(unsigned int ui, unsigned long ul, unsigned long long ull)
178 {
179 /* expect+1: warning: argument 1 is converted from 'unsigned int' to 'int' due to prototype [259] */
180 signed_int(ui);
181 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'int' due to prototype [259] */
182 signed_int(ul);
183 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'int' due to prototype [259] */
184 signed_int(ull);
185 signed_long(ui);
186 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'long' due to prototype [259] */
187 signed_long(ul);
188 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'long' due to prototype [259] */
189 signed_long(ull);
190 signed_long_long(ui);
191 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'long long' due to prototype [259] */
192 signed_long_long(ul);
193 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'long long' due to prototype [259] */
194 signed_long_long(ull);
195 }
196
197 void
signed_to_signed(signed int si,signed long sl,signed long long sll)198 signed_to_signed(signed int si, signed long sl, signed long long sll)
199 {
200 signed_int(si);
201 /* expect+1: warning: argument 1 is converted from 'long' to 'int' due to prototype [259] */
202 signed_int(sl);
203 /* expect+1: warning: argument 1 is converted from 'long long' to 'int' due to prototype [259] */
204 signed_int(sll);
205 signed_long(si);
206 signed_long(sl);
207 /* expect+1: warning: argument 1 is converted from 'long long' to 'long' due to prototype [259] */
208 signed_long(sll);
209 signed_long_long(si);
210 /* expect+1: warning: argument 1 is converted from 'long' to 'long long' due to prototype [259] */
211 signed_long_long(sl);
212 signed_long_long(sll);
213 }
214
215 void
unsigned_to_unsigned(unsigned int ui,unsigned long ul,unsigned long long ull)216 unsigned_to_unsigned(unsigned int ui, unsigned long ul, unsigned long long ull)
217 {
218 unsigned_int(ui);
219 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned int' due to prototype [259] */
220 unsigned_int(ul);
221 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'unsigned int' due to prototype [259] */
222 unsigned_int(ull);
223 unsigned_long(ui);
224 unsigned_long(ul);
225 /* expect+1: warning: argument 1 is converted from 'unsigned long long' to 'unsigned long' due to prototype [259] */
226 unsigned_long(ull);
227 unsigned_long_long(ui);
228 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned long long' due to prototype [259] */
229 unsigned_long_long(ul);
230 unsigned_long_long(ull);
231 }
232
233 void
constants(void)234 constants(void)
235 {
236 /* expect+2: warning: argument 1 is converted from 'long long' to 'unsigned int' due to prototype [259] */
237 /* expect+1: warning: conversion of 'long long' to 'unsigned int' is out of range, arg #1 [295] */
238 unsigned_int(0x7fffffffffffffffLL);
239 /* expect+2: warning: argument 1 is converted from 'double' to 'unsigned int' due to prototype [259] */
240 /* expect+1: warning: lossy conversion of 2.1 to 'unsigned int', arg #1 [380] */
241 unsigned_int(2.1);
242 }
243
244 void
to_float(double dbl)245 to_float(double dbl)
246 {
247 /* expect+1: warning: argument 1 is converted from 'double' to 'float' due to prototype [259] */
248 take_float(dbl);
249 }
250
251 void
pass_sizeof_as_smaller_type(void)252 pass_sizeof_as_smaller_type(void)
253 {
254 /*
255 * Even though the expression has type size_t, it has a constant
256 * value that fits effortless into an 'unsigned int', it's so small
257 * that it would even fit into a 3-bit bit-field, so lint's warning
258 * may seem wrong here.
259 *
260 * This warning 259 is not about lossy integer conversion though but
261 * instead covers calling conventions that may differ between integer
262 * types of different sizes, and from that point of view, the
263 * constant, even though its value would fit in an unsigned int, is
264 * still passed as size_t.
265 */
266 /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned int' due to prototype [259] */
267 unsigned_int(sizeof(int));
268 }
269