1 /*        $NetBSD: msg_259_c90.c,v 1.6 2023/07/09 10:42:07 rillig Exp $         */
2 # 3 "msg_259_c90.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: -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 /* No 'long long' since it requires C99. */
35 
36 void
change_in_type_width(char c,int i,long l)37 change_in_type_width(char c, int i, long l)
38 {
39           plain_char(c);
40           signed_int(c);
41           /* No warning 259 on LP64, only on ILP32 */
42           signed_long(c);
43 
44           plain_char(i);                /* XXX: why no warning? */
45           signed_int(i);
46           /* No warning 259 on LP64, only on ILP32 */
47           signed_long(i);
48 
49           plain_char(l);                /* XXX: why no warning? */
50           /* expect+1: ... from 'long' to 'int' due to prototype [259] */
51           signed_int(l);
52           signed_long(l);
53 }
54 
55 /*
56  * Converting a signed integer type to its corresponding unsigned integer
57  * type (C99 6.2.5p6) is usually not a problem since the actual values of the
58  * expressions are usually not anywhere near the maximum signed value.  From
59  * a technical standpoint, it is correct to warn here since even small
60  * negative numbers may result in very large positive numbers.
61  *
62  * A common case where it occurs is when the difference of two pointers is
63  * converted to size_t.  The type ptrdiff_t is defined to be signed, but in
64  * many practical cases, the expression is '(end - start)', which makes the
65  * resulting value necessarily positive.
66  */
67 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 sl,unsigned long ul)68 small_integer_types(char c, signed char sc, unsigned char uc,
69                         signed short ss, unsigned short us,
70                         signed int si, unsigned int ui,
71                         signed long sl, unsigned long ul)
72 {
73           plain_char(c);
74           plain_char(sc);
75           plain_char(uc);
76           plain_char(ss);
77           plain_char(us);
78           plain_char(si);
79           plain_char(ui);
80           plain_char(sl);
81           plain_char(ul);
82 
83           signed_char(c);
84           signed_char(sc);
85           signed_char(uc);
86           signed_char(ss);
87           signed_char(us);
88           signed_char(si);
89           signed_char(ui);
90           signed_char(sl);
91           signed_char(ul);
92 
93           unsigned_char(c);
94           unsigned_char(sc);
95           unsigned_char(uc);
96           unsigned_char(ss);
97           unsigned_char(us);
98           unsigned_char(si);
99           unsigned_char(ui);
100           unsigned_char(sl);
101           unsigned_char(ul);
102 
103           signed_short(c);
104           signed_short(sc);
105           signed_short(uc);
106           signed_short(ss);
107           signed_short(us);
108           signed_short(si);
109           signed_short(ui);
110           signed_short(sl);
111           signed_short(ul);
112 
113           unsigned_short(c);
114           unsigned_short(sc);
115           unsigned_short(uc);
116           unsigned_short(ss);
117           unsigned_short(us);
118           unsigned_short(si);
119           unsigned_short(ui);
120           unsigned_short(sl);
121           unsigned_short(ul);
122 }
123 
124 /*
125  * This function tests, among others, the conversion from a signed integer
126  * type to its corresponding unsigned integer type.  Warning 259 is not
127  * about lossy integer conversions but about ABI calling conventions.
128  *
129  * A common case where a conversion from a signed integer type to its
130  * corresponding unsigned integer type occurs is when the difference of two
131  * pointers is converted to size_t.  The type ptrdiff_t is defined to be
132  * signed, but in many practical cases, the expression is '(end - start)',
133  * which makes the resulting value necessarily positive.
134  */
135 void
signed_to_unsigned(int si,long sl)136 signed_to_unsigned(int si, long sl)
137 {
138           /* expect+1: warning: argument 1 is converted from 'int' to 'unsigned int' due to prototype [259] */
139           unsigned_int(si);
140 
141           /* expect+1: warning: argument 1 is converted from 'long' to 'unsigned int' due to prototype [259] */
142           unsigned_int(sl);
143 
144           /*
145            * No warning here.  Even though 'unsigned long' is 64 bits wide, it
146            * cannot represent negative 32-bit values.  This lossy conversion is
147            * covered by message 297 instead, which requires nonstandard flags.
148            */
149           unsigned_long(si);
150 
151           /* expect+1: warning: argument 1 is converted from 'long' to 'unsigned long' due to prototype [259] */
152           unsigned_long(sl);
153 }
154 
155 void
unsigned_to_signed(unsigned int ui,unsigned long ul)156 unsigned_to_signed(unsigned int ui, unsigned long ul)
157 {
158           /* expect+1: warning: argument 1 is converted from 'unsigned int' to 'int' due to prototype [259] */
159           signed_int(ui);
160           /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'int' due to prototype [259] */
161           signed_int(ul);
162           signed_long(ui);
163           /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'long' due to prototype [259] */
164           signed_long(ul);
165 }
166 
167 void
signed_to_signed(signed int si,signed long sl)168 signed_to_signed(signed int si, signed long sl)
169 {
170           signed_int(si);
171           /* expect+1: warning: argument 1 is converted from 'long' to 'int' due to prototype [259] */
172           signed_int(sl);
173           signed_long(si);
174           signed_long(sl);
175 }
176 
177 void
unsigned_to_unsigned(unsigned int ui,unsigned long ul)178 unsigned_to_unsigned(unsigned int ui, unsigned long ul)
179 {
180           unsigned_int(ui);
181           /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned int' due to prototype [259] */
182           unsigned_int(ul);
183           unsigned_long(ui);
184           unsigned_long(ul);
185 }
186 
187 void
pass_sizeof_as_smaller_type(void)188 pass_sizeof_as_smaller_type(void)
189 {
190           /*
191            * Even though the expression has type size_t, it has a constant
192            * value that fits effortless into an 'unsigned int', it's so small
193            * that it would even fit into a 3-bit bit-field, so lint's warning
194            * may seem wrong here.
195            *
196            * This warning 259 is not about lossy integer conversion though but
197            * instead covers calling conventions that may differ between integer
198            * types of different sizes, and from that point of view, the
199            * constant, even though its value would fit in an unsigned int, is
200            * still passed as size_t.
201            */
202           /* expect+1: warning: argument 1 is converted from 'unsigned long' to 'unsigned int' due to prototype [259] */
203           unsigned_int(sizeof(int));
204 }
205