xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_259.c (revision 0f4cfb3194727ca0b8e46faf51c9e2ed182e51ed)
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