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