chk.c revision 1.72 1 1.72 rillig /* $NetBSD: chk.c,v 1.72 2025/05/24 07:38:59 rillig Exp $ */
2 1.2 cgd
3 1.1 cgd /*
4 1.3 cgd * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 1.1 cgd * Copyright (c) 1994, 1995 Jochen Pohl
6 1.1 cgd * All Rights Reserved.
7 1.1 cgd *
8 1.1 cgd * Redistribution and use in source and binary forms, with or without
9 1.1 cgd * modification, are permitted provided that the following conditions
10 1.1 cgd * are met:
11 1.1 cgd * 1. Redistributions of source code must retain the above copyright
12 1.1 cgd * notice, this list of conditions and the following disclaimer.
13 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 cgd * notice, this list of conditions and the following disclaimer in the
15 1.1 cgd * documentation and/or other materials provided with the distribution.
16 1.1 cgd * 3. All advertising materials mentioning features or use of this software
17 1.1 cgd * must display the following acknowledgement:
18 1.60 rillig * This product includes software developed by Jochen Pohl for
19 1.1 cgd * The NetBSD Project.
20 1.1 cgd * 4. The name of the author may not be used to endorse or promote products
21 1.1 cgd * derived from this software without specific prior written permission.
22 1.1 cgd *
23 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 1.1 cgd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 1.1 cgd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.1 cgd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 1.1 cgd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 1.1 cgd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 1.1 cgd * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 1.1 cgd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 1.1 cgd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 1.1 cgd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.1 cgd */
34 1.1 cgd
35 1.17 jmc #if HAVE_NBTOOL_CONFIG_H
36 1.17 jmc #include "nbtool_config.h"
37 1.17 jmc #endif
38 1.17 jmc
39 1.5 christos #include <sys/cdefs.h>
40 1.48 rillig #if defined(__RCSID)
41 1.72 rillig __RCSID("$NetBSD: chk.c,v 1.72 2025/05/24 07:38:59 rillig Exp $");
42 1.1 cgd #endif
43 1.1 cgd
44 1.1 cgd #include <ctype.h>
45 1.1 cgd #include <limits.h>
46 1.15 tv #include <stdlib.h>
47 1.25 rillig #include <string.h>
48 1.1 cgd
49 1.1 cgd #include "lint2.h"
50 1.1 cgd
51 1.65 rillig static void check_used_not_defined(const hte_t *);
52 1.65 rillig static void check_defined_not_used(const hte_t *);
53 1.65 rillig static void check_declared_not_used_or_defined(const hte_t *);
54 1.65 rillig static void check_multiple_definitions(const hte_t *);
55 1.72 rillig static void chkvtui(const hte_t *, const sym_t *, const sym_t *);
56 1.72 rillig static void chkvtdi(const hte_t *, const sym_t *, const sym_t *);
57 1.72 rillig static void chkfaui(const hte_t *, const sym_t *, const sym_t *);
58 1.72 rillig static void chkau(const hte_t *, int, const sym_t *, const sym_t *,
59 1.72 rillig const pos_t *, const fcall_t *, const fcall_t *,
60 1.72 rillig const type_t *, const type_t *);
61 1.72 rillig static void check_return_values(const hte_t *, const sym_t *);
62 1.72 rillig static void check_argument_declarations(const hte_t *,
63 1.72 rillig const sym_t *, const sym_t *);
64 1.72 rillig static void printflike(const hte_t *, const fcall_t *,
65 1.72 rillig int, const char *, const type_t **);
66 1.72 rillig static void scanflike(const hte_t *, const fcall_t *,
67 1.72 rillig int, const char *, const type_t **);
68 1.72 rillig static void bad_format_string(const hte_t *, const fcall_t *);
69 1.72 rillig static void inconsistent_arguments(const hte_t *, const fcall_t *, int);
70 1.72 rillig static void too_few_arguments(const hte_t *, const fcall_t *);
71 1.72 rillig static void too_many_arguments(const hte_t *, const fcall_t *);
72 1.72 rillig static bool types_compatible(const type_t *, const type_t *,
73 1.72 rillig bool, bool, bool, bool *);
74 1.72 rillig static bool prototypes_compatible(const type_t *, const type_t *, bool *);
75 1.72 rillig static bool matches_no_arg_function(const type_t *, bool *);
76 1.1 cgd
77 1.1 cgd
78 1.1 cgd /*
79 1.1 cgd * If there is a symbol named "main", mark it as used.
80 1.1 cgd */
81 1.1 cgd void
82 1.53 rillig mark_main_as_used(void)
83 1.1 cgd {
84 1.55 rillig hte_t *hte;
85 1.1 cgd
86 1.58 rillig if ((hte = htab_search("main", false)) != NULL)
87 1.34 rillig hte->h_used = true;
88 1.1 cgd }
89 1.1 cgd
90 1.1 cgd /*
91 1.1 cgd * Performs all tests for a single name
92 1.1 cgd */
93 1.1 cgd void
94 1.53 rillig check_name(const hte_t *hte)
95 1.1 cgd {
96 1.55 rillig sym_t *sym, *def, *pdecl, *decl;
97 1.1 cgd
98 1.57 rillig if (!uflag) {
99 1.53 rillig check_used_not_defined(hte);
100 1.53 rillig check_defined_not_used(hte);
101 1.1 cgd if (xflag)
102 1.53 rillig check_declared_not_used_or_defined(hte);
103 1.1 cgd }
104 1.53 rillig check_multiple_definitions(hte);
105 1.1 cgd
106 1.1 cgd /* Get definition, prototype declaration and declaration */
107 1.1 cgd def = pdecl = decl = NULL;
108 1.28 rillig for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
109 1.1 cgd if (def == NULL && (sym->s_def == DEF || sym->s_def == TDEF))
110 1.1 cgd def = sym;
111 1.1 cgd if (pdecl == NULL && sym->s_def == DECL &&
112 1.1 cgd TP(sym->s_type)->t_tspec == FUNC &&
113 1.1 cgd TP(sym->s_type)->t_proto) {
114 1.1 cgd pdecl = sym;
115 1.1 cgd }
116 1.1 cgd if (decl == NULL && sym->s_def == DECL)
117 1.1 cgd decl = sym;
118 1.1 cgd }
119 1.1 cgd
120 1.52 rillig /* A prototype is better than an old-style declaration. */
121 1.1 cgd if (pdecl != NULL)
122 1.1 cgd decl = pdecl;
123 1.1 cgd
124 1.1 cgd chkvtui(hte, def, decl);
125 1.1 cgd
126 1.1 cgd chkvtdi(hte, def, decl);
127 1.1 cgd
128 1.1 cgd chkfaui(hte, def, decl);
129 1.1 cgd
130 1.53 rillig check_return_values(hte, def);
131 1.1 cgd
132 1.53 rillig check_argument_declarations(hte, def, decl);
133 1.1 cgd }
134 1.1 cgd
135 1.1 cgd /*
136 1.1 cgd * Print a warning if the name has been used, but not defined.
137 1.1 cgd */
138 1.1 cgd static void
139 1.53 rillig check_used_not_defined(const hte_t *hte)
140 1.1 cgd {
141 1.55 rillig fcall_t *fcall;
142 1.55 rillig usym_t *usym;
143 1.1 cgd
144 1.1 cgd if (!hte->h_used || hte->h_def)
145 1.1 cgd return;
146 1.1 cgd
147 1.1 cgd if ((fcall = hte->h_calls) != NULL) {
148 1.68 rillig /* %s is used in %s but never defined */
149 1.1 cgd msg(0, hte->h_name, mkpos(&fcall->f_pos));
150 1.1 cgd } else if ((usym = hte->h_usyms) != NULL) {
151 1.68 rillig /* %s is used in %s but never defined */
152 1.1 cgd msg(0, hte->h_name, mkpos(&usym->u_pos));
153 1.1 cgd }
154 1.1 cgd }
155 1.1 cgd
156 1.1 cgd /*
157 1.1 cgd * Print a warning if the name has been defined, but never used.
158 1.1 cgd */
159 1.1 cgd static void
160 1.53 rillig check_defined_not_used(const hte_t *hte)
161 1.1 cgd {
162 1.55 rillig sym_t *sym;
163 1.1 cgd
164 1.1 cgd if (!hte->h_def || hte->h_used)
165 1.1 cgd return;
166 1.1 cgd
167 1.28 rillig for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
168 1.1 cgd if (sym->s_def == DEF || sym->s_def == TDEF) {
169 1.68 rillig /* %s is defined in %s but never used */
170 1.1 cgd msg(1, hte->h_name, mkpos(&sym->s_pos));
171 1.1 cgd break;
172 1.1 cgd }
173 1.1 cgd }
174 1.1 cgd }
175 1.1 cgd
176 1.1 cgd /*
177 1.4 cgd * Print a warning if the variable has been declared, but is not used
178 1.1 cgd * or defined.
179 1.1 cgd */
180 1.1 cgd static void
181 1.53 rillig check_declared_not_used_or_defined(const hte_t *hte)
182 1.1 cgd {
183 1.55 rillig sym_t *sym;
184 1.1 cgd
185 1.1 cgd if (hte->h_syms == NULL || hte->h_used || hte->h_def)
186 1.1 cgd return;
187 1.4 cgd
188 1.4 cgd sym = hte->h_syms;
189 1.4 cgd if (TP(sym->s_type)->t_tspec == FUNC)
190 1.4 cgd return;
191 1.4 cgd
192 1.4 cgd if (sym->s_def != DECL)
193 1.53 rillig errx(1, "internal error: check_declared_not_used_or_defined");
194 1.68 rillig /* %s is declared in %s but never used or defined */
195 1.4 cgd msg(2, hte->h_name, mkpos(&sym->s_pos));
196 1.1 cgd }
197 1.1 cgd
198 1.1 cgd /*
199 1.12 wiz * Print a warning if there is more than one definition for
200 1.1 cgd * this name.
201 1.1 cgd */
202 1.1 cgd static void
203 1.53 rillig check_multiple_definitions(const hte_t *hte)
204 1.1 cgd {
205 1.55 rillig sym_t *sym, *def1;
206 1.1 cgd
207 1.1 cgd if (!hte->h_def)
208 1.1 cgd return;
209 1.1 cgd
210 1.1 cgd def1 = NULL;
211 1.28 rillig for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
212 1.1 cgd /*
213 1.64 rillig * C90 allows tentative definitions of the same name in only
214 1.64 rillig * one compilation unit.
215 1.1 cgd */
216 1.1 cgd if (sym->s_def != DEF && (!sflag || sym->s_def != TDEF))
217 1.1 cgd continue;
218 1.23 christos if (sym->s_inline)
219 1.23 christos continue;
220 1.1 cgd if (def1 == NULL) {
221 1.1 cgd def1 = sym;
222 1.1 cgd continue;
223 1.1 cgd }
224 1.68 rillig /* %s has multiple definitions in %s and %s */
225 1.59 rillig msg(3, hte->h_name, mkpos(&def1->s_pos), mkpos(&sym->s_pos));
226 1.1 cgd }
227 1.1 cgd }
228 1.1 cgd
229 1.1 cgd /*
230 1.1 cgd * Print a warning if the return value assumed for a function call
231 1.1 cgd * differs from the return value of the function definition or
232 1.1 cgd * function declaration.
233 1.1 cgd *
234 1.1 cgd * If no definition/declaration can be found, the assumed return values
235 1.1 cgd * are always int. So there is no need to compare with another function
236 1.1 cgd * call as it's done for function arguments.
237 1.1 cgd */
238 1.1 cgd static void
239 1.72 rillig chkvtui(const hte_t *hte, const sym_t *def, const sym_t *decl)
240 1.1 cgd {
241 1.55 rillig fcall_t *call;
242 1.55 rillig type_t *tp1, *tp2;
243 1.55 rillig bool dowarn, eq;
244 1.55 rillig tspec_t t1;
245 1.1 cgd
246 1.1 cgd if (hte->h_calls == NULL)
247 1.1 cgd return;
248 1.1 cgd
249 1.1 cgd if (def == NULL)
250 1.1 cgd def = decl;
251 1.1 cgd if (def == NULL)
252 1.1 cgd return;
253 1.1 cgd
254 1.1 cgd t1 = (tp1 = TP(def->s_type)->t_subt)->t_tspec;
255 1.29 rillig for (call = hte->h_calls; call != NULL; call = call->f_next) {
256 1.1 cgd tp2 = TP(call->f_type)->t_subt;
257 1.51 rillig eq = types_compatible(tp1, tp2,
258 1.34 rillig true, false, false, (dowarn = false, &dowarn));
259 1.1 cgd if (!call->f_rused) {
260 1.1 cgd /* no return value used */
261 1.1 cgd if ((t1 == STRUCT || t1 == UNION) && !eq) {
262 1.1 cgd /*
263 1.68 rillig * If a function returns a struct or union, it
264 1.1 cgd * must be declared to return a struct or
265 1.68 rillig * union, even if the return value is ignored.
266 1.1 cgd * This is necessary because the caller must
267 1.1 cgd * allocate stack space for the return value.
268 1.49 rillig * If it does not, the return value would
269 1.49 rillig * overwrite other data.
270 1.49 rillig *
271 1.68 rillig * XXX: The following message may be confusing
272 1.68 rillig * because it occurs also if the return value
273 1.1 cgd * was declared inconsistently. But this
274 1.49 rillig * behavior matches pcc-based lint, so it is
275 1.1 cgd * accepted for now.
276 1.1 cgd */
277 1.68 rillig /* %s's return type in %s must be decl... */
278 1.1 cgd msg(17, hte->h_name,
279 1.59 rillig mkpos(&def->s_pos), mkpos(&call->f_pos));
280 1.1 cgd }
281 1.1 cgd continue;
282 1.1 cgd }
283 1.20 lukem if (!eq || (sflag && dowarn)) {
284 1.68 rillig /* %s has its return value used inconsistently ... */
285 1.59 rillig msg(4, hte->h_name,
286 1.59 rillig mkpos(&def->s_pos), mkpos(&call->f_pos));
287 1.1 cgd }
288 1.1 cgd }
289 1.1 cgd }
290 1.1 cgd
291 1.1 cgd /*
292 1.1 cgd * Print a warning if a definition/declaration does not match another
293 1.1 cgd * definition/declaration of the same name. For functions, only the
294 1.1 cgd * types of return values are tested.
295 1.1 cgd */
296 1.1 cgd static void
297 1.72 rillig chkvtdi(const hte_t *hte, const sym_t *def, const sym_t *decl)
298 1.1 cgd {
299 1.1 cgd if (def == NULL)
300 1.1 cgd def = decl;
301 1.1 cgd if (def == NULL)
302 1.1 cgd return;
303 1.1 cgd
304 1.72 rillig const type_t *tp1 = TP(def->s_type);
305 1.71 rillig for (sym_t *sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
306 1.1 cgd if (sym == def)
307 1.1 cgd continue;
308 1.72 rillig const type_t *tp2 = TP(sym->s_type);
309 1.71 rillig bool dowarn = false;
310 1.71 rillig bool is_func = tp1->t_tspec == FUNC && tp2->t_tspec == FUNC;
311 1.72 rillig const type_t *xt1 = is_func ? tp1->t_subt : tp1;
312 1.72 rillig const type_t *xt2 = is_func ? tp2->t_subt : tp2;
313 1.71 rillig bool eq = types_compatible(xt1, xt2,
314 1.71 rillig is_func, false, false, &dowarn);
315 1.20 lukem if (!eq || (sflag && dowarn)) {
316 1.71 rillig /* %s %s '%s' at %s, versus '%s' at %s */
317 1.71 rillig msg(5, hte->h_name,
318 1.71 rillig is_func ? "returns" : "has type",
319 1.71 rillig type_name(xt1), mkpos(&def->s_pos),
320 1.68 rillig type_name(xt2), mkpos(&sym->s_pos));
321 1.1 cgd }
322 1.1 cgd }
323 1.1 cgd }
324 1.1 cgd
325 1.68 rillig static int
326 1.72 rillig total_args(int n, const type_t **tpp)
327 1.68 rillig {
328 1.68 rillig for (; *tpp != NULL; tpp++)
329 1.68 rillig n++;
330 1.68 rillig return n;
331 1.68 rillig }
332 1.68 rillig
333 1.1 cgd /*
334 1.1 cgd * Print a warning if a function is called with arguments which does
335 1.1 cgd * not match the function definition, declaration or another call
336 1.1 cgd * of the same function.
337 1.1 cgd */
338 1.1 cgd static void
339 1.72 rillig chkfaui(const hte_t *hte, const sym_t *def, const sym_t *decl)
340 1.1 cgd {
341 1.72 rillig const type_t *tp1, *tp2, **ap1, **ap2;
342 1.72 rillig const pos_t *pos1p = NULL;
343 1.55 rillig fcall_t *calls, *call, *call1;
344 1.55 rillig int n, as;
345 1.1 cgd arginf_t *ai;
346 1.1 cgd
347 1.1 cgd if ((calls = hte->h_calls) == NULL)
348 1.1 cgd return;
349 1.1 cgd
350 1.1 cgd /*
351 1.7 mycroft * If we find a function definition, we use this for comparison,
352 1.64 rillig * otherwise the first prototype we can find. If there is no definition
353 1.64 rillig * or prototype declaration, the first function call is used.
354 1.1 cgd */
355 1.1 cgd tp1 = NULL;
356 1.1 cgd call1 = NULL;
357 1.1 cgd if (def != NULL) {
358 1.1 cgd if ((tp1 = TP(def->s_type))->t_tspec != FUNC)
359 1.1 cgd return;
360 1.1 cgd pos1p = &def->s_pos;
361 1.1 cgd } else if (decl != NULL && TP(decl->s_type)->t_proto) {
362 1.1 cgd if ((tp1 = TP(decl->s_type))->t_tspec != FUNC)
363 1.1 cgd return;
364 1.1 cgd pos1p = &decl->s_pos;
365 1.1 cgd }
366 1.1 cgd if (tp1 == NULL) {
367 1.1 cgd call1 = calls;
368 1.29 rillig calls = calls->f_next;
369 1.1 cgd if ((tp1 = TP(call1->f_type))->t_tspec != FUNC)
370 1.1 cgd return;
371 1.1 cgd pos1p = &call1->f_pos;
372 1.1 cgd }
373 1.1 cgd
374 1.1 cgd n = 1;
375 1.29 rillig for (call = calls; call != NULL; call = call->f_next) {
376 1.1 cgd if ((tp2 = TP(call->f_type))->t_tspec != FUNC)
377 1.1 cgd continue;
378 1.1 cgd ap1 = tp1->t_args;
379 1.1 cgd ap2 = tp2->t_args;
380 1.1 cgd n = 0;
381 1.1 cgd while (*ap1 != NULL && *ap2 != NULL) {
382 1.45 rillig if (def != NULL && def->s_check_only_first_args &&
383 1.45 rillig n >= def->s_check_num_args)
384 1.1 cgd break;
385 1.1 cgd n++;
386 1.1 cgd chkau(hte, n, def, decl, pos1p, call1, call,
387 1.63 rillig *ap1, *ap2);
388 1.1 cgd ap1++;
389 1.1 cgd ap2++;
390 1.1 cgd }
391 1.1 cgd if (*ap1 == *ap2) {
392 1.1 cgd /* equal # of arguments */
393 1.45 rillig } else if (def != NULL && def->s_check_only_first_args &&
394 1.63 rillig n >= def->s_check_num_args) {
395 1.1 cgd /*
396 1.64 rillig * function definition with VARARGS; The # of arguments
397 1.64 rillig * of the call must be at least as large as the
398 1.64 rillig * parameter of VARARGS.
399 1.1 cgd */
400 1.1 cgd } else if (*ap2 != NULL && tp1->t_proto && tp1->t_vararg) {
401 1.1 cgd /*
402 1.64 rillig * prototype with ... and function call with at least
403 1.64 rillig * the same # of arguments as declared in the
404 1.64 rillig * prototype.
405 1.1 cgd */
406 1.1 cgd } else {
407 1.68 rillig /* %s has %d parameters in %s, versus %d ... */
408 1.68 rillig msg(7, hte->h_name, total_args(n, ap1), mkpos(pos1p),
409 1.68 rillig total_args(n, ap2), mkpos(&call->f_pos));
410 1.1 cgd continue;
411 1.1 cgd }
412 1.1 cgd
413 1.1 cgd /* perform SCANFLIKE/PRINTFLIKE tests */
414 1.45 rillig if (def == NULL || (!def->s_printflike && !def->s_scanflike))
415 1.1 cgd continue;
416 1.45 rillig as = def->s_printflike
417 1.45 rillig ? def->s_printflike_arg
418 1.45 rillig : def->s_scanflike_arg;
419 1.29 rillig for (ai = call->f_args; ai != NULL; ai = ai->a_next) {
420 1.1 cgd if (ai->a_num == as)
421 1.1 cgd break;
422 1.1 cgd }
423 1.1 cgd if (ai == NULL || !ai->a_fmt)
424 1.1 cgd continue;
425 1.45 rillig if (def->s_printflike) {
426 1.1 cgd printflike(hte, call, n, ai->a_fstrg, ap2);
427 1.1 cgd } else {
428 1.1 cgd scanflike(hte, call, n, ai->a_fstrg, ap2);
429 1.1 cgd }
430 1.1 cgd }
431 1.1 cgd }
432 1.1 cgd
433 1.1 cgd /*
434 1.1 cgd * Check a single argument in a function call.
435 1.1 cgd *
436 1.69 rillig * hte a pointer to the hash table entry of the function
437 1.69 rillig * n the number of the argument (1..)
438 1.69 rillig * def the function definition or NULL
439 1.69 rillig * decl prototype declaration, old-style declaration or NULL
440 1.69 rillig * pos1p position of definition, declaration of first call
441 1.69 rillig * call1 first call, if both def and decl are old-style def/decl
442 1.69 rillig * call checked call
443 1.69 rillig * arg1 currently checked argument of def/decl/call1
444 1.69 rillig * arg2 currently checked argument of call
445 1.1 cgd */
446 1.1 cgd static void
447 1.72 rillig chkau(const hte_t *hte,
448 1.72 rillig int n, const sym_t *def, const sym_t *decl,
449 1.72 rillig const pos_t *pos1p, const fcall_t *call1, const fcall_t *call,
450 1.72 rillig const type_t *arg1, const type_t *arg2)
451 1.1 cgd {
452 1.55 rillig bool promote, asgn, dowarn;
453 1.55 rillig tspec_t t1, t2;
454 1.1 cgd arginf_t *ai, *ai1;
455 1.1 cgd
456 1.1 cgd /*
457 1.32 rillig * If a function definition is available (def != NULL), we compare the
458 1.1 cgd * function call (call) with the definition. Otherwise, if a function
459 1.64 rillig * definition is available and it is not an old-style definition (decl
460 1.64 rillig * != NULL && TP(decl->s_type)->t_proto), we compare the call with this
461 1.64 rillig * declaration. Otherwise we compare it with the first call we have
462 1.64 rillig * found (call1).
463 1.1 cgd */
464 1.1 cgd
465 1.52 rillig /* arg1 must be promoted if it stems from an old-style definition */
466 1.45 rillig promote = def != NULL && def->s_old_style_function;
467 1.1 cgd
468 1.1 cgd /*
469 1.64 rillig * If we compare with a definition or declaration, we must perform the
470 1.64 rillig * same checks for qualifiers in indirected types as in assignments.
471 1.1 cgd */
472 1.1 cgd asgn = def != NULL || (decl != NULL && TP(decl->s_type)->t_proto);
473 1.1 cgd
474 1.34 rillig dowarn = false;
475 1.51 rillig if (types_compatible(arg1, arg2, true, promote, asgn, &dowarn) &&
476 1.34 rillig (!sflag || !dowarn))
477 1.1 cgd return;
478 1.1 cgd
479 1.64 rillig /*-
480 1.64 rillig * Other lint implementations print warnings as soon as the type of an
481 1.64 rillig * argument does not match exactly the expected type. The result are
482 1.64 rillig * lots of warnings which are really not necessary.
483 1.1 cgd * We print a warning only if
484 1.69 rillig * (0) at least one type is not an integer type and types differ
485 1.69 rillig * (1) hflag is set and types differ
486 1.69 rillig * (2) types differ, except in signedness
487 1.64 rillig *
488 1.1 cgd * If the argument is an integer constant whose msb is not set,
489 1.64 rillig * signedness is ignored (e.g. 0 matches both signed and unsigned int).
490 1.64 rillig * This is with and without hflag.
491 1.64 rillig *
492 1.64 rillig * If the argument is an integer constant with value 0 and the expected
493 1.64 rillig * argument is of type pointer and the width of the integer constant is
494 1.64 rillig * the same as the width of the pointer, no warning is printed.
495 1.1 cgd */
496 1.1 cgd t1 = arg1->t_tspec;
497 1.1 cgd t2 = arg2->t_tspec;
498 1.33 rillig if (is_integer(t1) && is_integer(t2) &&
499 1.38 rillig !arg1->t_is_enum && !arg2->t_is_enum) {
500 1.1 cgd if (promote) {
501 1.1 cgd /*
502 1.32 rillig * XXX Here is a problem: Although it is possible to
503 1.1 cgd * pass an int where a char/short it expected, there
504 1.1 cgd * may be loss in significant digits. We should first
505 1.1 cgd * check for const arguments if they can be converted
506 1.1 cgd * into the original parameter type.
507 1.1 cgd */
508 1.1 cgd if (t1 == FLOAT) {
509 1.1 cgd t1 = DOUBLE;
510 1.1 cgd } else if (t1 == CHAR || t1 == SCHAR) {
511 1.1 cgd t1 = INT;
512 1.1 cgd } else if (t1 == UCHAR) {
513 1.1 cgd t1 = tflag ? UINT : INT;
514 1.1 cgd } else if (t1 == SHORT) {
515 1.1 cgd t1 = INT;
516 1.1 cgd } else if (t1 == USHORT) {
517 1.1 cgd t1 = INT_MAX < USHRT_MAX || tflag ? UINT : INT;
518 1.1 cgd }
519 1.1 cgd }
520 1.1 cgd
521 1.30 rillig if (signed_type(t1) == signed_type(t2)) {
522 1.1 cgd
523 1.1 cgd /*
524 1.1 cgd * types differ only in signedness; get information
525 1.1 cgd * about arguments
526 1.1 cgd */
527 1.1 cgd
528 1.1 cgd /*
529 1.1 cgd * treat a definition like a call with variable
530 1.1 cgd * arguments
531 1.1 cgd */
532 1.1 cgd ai1 = call1 != NULL ? call1->f_args : NULL;
533 1.1 cgd
534 1.1 cgd /*
535 1.1 cgd * if two calls are compared, ai1 is set to the
536 1.64 rillig * information for the n-th argument, if this was a
537 1.64 rillig * constant, otherwise to NULL
538 1.1 cgd */
539 1.29 rillig for ( ; ai1 != NULL; ai1 = ai1->a_next) {
540 1.1 cgd if (ai1->a_num == n)
541 1.1 cgd break;
542 1.1 cgd }
543 1.1 cgd /*
544 1.64 rillig * ai is set to the information of the n-th arg of the
545 1.64 rillig * (second) call, if this was a constant, otherwise to
546 1.64 rillig * NULL
547 1.1 cgd */
548 1.29 rillig for (ai = call->f_args; ai != NULL; ai = ai->a_next) {
549 1.1 cgd if (ai->a_num == n)
550 1.1 cgd break;
551 1.1 cgd }
552 1.1 cgd
553 1.1 cgd if (ai1 == NULL && ai == NULL) {
554 1.1 cgd /* no constant at all */
555 1.1 cgd if (!hflag)
556 1.1 cgd return;
557 1.1 cgd } else if (ai1 == NULL || ai == NULL) {
558 1.1 cgd /* one constant */
559 1.1 cgd if (ai == NULL)
560 1.1 cgd ai = ai1;
561 1.1 cgd if (ai->a_zero || ai->a_pcon)
562 1.1 cgd /* same value in signed and unsigned */
563 1.1 cgd return;
564 1.1 cgd /* value (not representation) differently */
565 1.1 cgd } else {
566 1.1 cgd /*
567 1.64 rillig * two constants, one signed, one unsigned; if
568 1.64 rillig * the msb of one of the constants is set, the
569 1.64 rillig * argument is used inconsistently.
570 1.1 cgd */
571 1.1 cgd if (!ai1->a_ncon && !ai->a_ncon)
572 1.1 cgd return;
573 1.1 cgd }
574 1.1 cgd }
575 1.1 cgd
576 1.33 rillig } else if (t1 == PTR && is_integer(t2)) {
577 1.29 rillig for (ai = call->f_args; ai != NULL; ai = ai->a_next) {
578 1.1 cgd if (ai->a_num == n)
579 1.1 cgd break;
580 1.1 cgd }
581 1.3 cgd /*
582 1.3 cgd * Vendor implementations of lint (e.g. HP-UX, Digital UNIX)
583 1.64 rillig * don't care about the size of the integer argument, only
584 1.64 rillig * whether or not it is zero. We do the same.
585 1.3 cgd */
586 1.1 cgd if (ai != NULL && ai->a_zero)
587 1.1 cgd return;
588 1.1 cgd }
589 1.1 cgd
590 1.68 rillig /* %s has argument %d with type '%s' at %s, versus '%s' at %s */
591 1.68 rillig msg(6, hte->h_name, n, type_name(arg1), mkpos(pos1p),
592 1.68 rillig type_name(arg2), mkpos(&call->f_pos));
593 1.1 cgd }
594 1.1 cgd
595 1.1 cgd /*
596 1.1 cgd * Compare the types in the NULL-terminated array ap with the format
597 1.1 cgd * string fmt.
598 1.1 cgd */
599 1.1 cgd static void
600 1.72 rillig printflike(const hte_t *hte, const fcall_t *call,
601 1.72 rillig int n, const char *fmt, const type_t **ap)
602 1.1 cgd {
603 1.55 rillig const char *fp;
604 1.55 rillig char fc;
605 1.55 rillig bool fwidth, prec, left, sign, space, alt, zero;
606 1.55 rillig tspec_t sz, t1, t2 = NO_TSPEC;
607 1.72 rillig const type_t *tp;
608 1.1 cgd
609 1.1 cgd fp = fmt;
610 1.1 cgd fc = *fp++;
611 1.1 cgd
612 1.36 rillig for (;;) {
613 1.1 cgd if (fc == '\0') {
614 1.1 cgd if (*ap != NULL)
615 1.53 rillig too_many_arguments(hte, call);
616 1.1 cgd break;
617 1.1 cgd }
618 1.1 cgd if (fc != '%') {
619 1.53 rillig bad_format_string(hte, call);
620 1.1 cgd break;
621 1.1 cgd }
622 1.1 cgd fc = *fp++;
623 1.34 rillig fwidth = prec = left = sign = space = alt = zero = false;
624 1.54 rillig sz = NO_TSPEC;
625 1.1 cgd
626 1.1 cgd /* Flags */
627 1.36 rillig for (;;) {
628 1.1 cgd if (fc == '-') {
629 1.1 cgd if (left)
630 1.1 cgd break;
631 1.34 rillig left = true;
632 1.1 cgd } else if (fc == '+') {
633 1.1 cgd if (sign)
634 1.1 cgd break;
635 1.34 rillig sign = true;
636 1.1 cgd } else if (fc == ' ') {
637 1.1 cgd if (space)
638 1.1 cgd break;
639 1.34 rillig space = true;
640 1.1 cgd } else if (fc == '#') {
641 1.1 cgd if (alt)
642 1.1 cgd break;
643 1.34 rillig alt = true;
644 1.1 cgd } else if (fc == '0') {
645 1.1 cgd if (zero)
646 1.1 cgd break;
647 1.34 rillig zero = true;
648 1.1 cgd } else {
649 1.1 cgd break;
650 1.1 cgd }
651 1.1 cgd fc = *fp++;
652 1.1 cgd }
653 1.1 cgd
654 1.1 cgd /* field width */
655 1.67 rillig if (ch_isdigit(fc)) {
656 1.34 rillig fwidth = true;
657 1.67 rillig do { fc = *fp++; } while (ch_isdigit(fc));
658 1.1 cgd } else if (fc == '*') {
659 1.34 rillig fwidth = true;
660 1.1 cgd fc = *fp++;
661 1.1 cgd if ((tp = *ap++) == NULL) {
662 1.53 rillig too_few_arguments(hte, call);
663 1.1 cgd break;
664 1.1 cgd }
665 1.1 cgd n++;
666 1.1 cgd if ((t1 = tp->t_tspec) != INT && (hflag || t1 != UINT))
667 1.53 rillig inconsistent_arguments(hte, call, n);
668 1.1 cgd }
669 1.1 cgd
670 1.1 cgd /* precision */
671 1.1 cgd if (fc == '.') {
672 1.1 cgd fc = *fp++;
673 1.34 rillig prec = true;
674 1.67 rillig if (ch_isdigit(fc)) {
675 1.66 rillig do {
676 1.66 rillig fc = *fp++;
677 1.67 rillig } while (ch_isdigit(fc));
678 1.1 cgd } else if (fc == '*') {
679 1.1 cgd fc = *fp++;
680 1.1 cgd if ((tp = *ap++) == NULL) {
681 1.53 rillig too_few_arguments(hte, call);
682 1.1 cgd break;
683 1.1 cgd }
684 1.1 cgd n++;
685 1.1 cgd if (tp->t_tspec != INT)
686 1.53 rillig inconsistent_arguments(hte, call, n);
687 1.1 cgd } else {
688 1.53 rillig bad_format_string(hte, call);
689 1.1 cgd break;
690 1.1 cgd }
691 1.1 cgd }
692 1.1 cgd
693 1.1 cgd if (fc == 'h') {
694 1.1 cgd sz = SHORT;
695 1.1 cgd } else if (fc == 'l') {
696 1.1 cgd sz = LONG;
697 1.1 cgd } else if (fc == 'q') {
698 1.56 rillig sz = LLONG;
699 1.1 cgd } else if (fc == 'L') {
700 1.1 cgd sz = LDOUBLE;
701 1.1 cgd }
702 1.54 rillig if (sz != NO_TSPEC)
703 1.1 cgd fc = *fp++;
704 1.1 cgd
705 1.1 cgd if (fc == '%') {
706 1.54 rillig if (sz != NO_TSPEC || left || sign || space ||
707 1.1 cgd alt || zero || prec || fwidth) {
708 1.53 rillig bad_format_string(hte, call);
709 1.1 cgd }
710 1.1 cgd fc = *fp++;
711 1.1 cgd continue;
712 1.1 cgd }
713 1.1 cgd
714 1.1 cgd if (fc == '\0') {
715 1.53 rillig bad_format_string(hte, call);
716 1.1 cgd break;
717 1.1 cgd }
718 1.1 cgd
719 1.1 cgd if ((tp = *ap++) == NULL) {
720 1.53 rillig too_few_arguments(hte, call);
721 1.1 cgd break;
722 1.1 cgd }
723 1.1 cgd n++;
724 1.1 cgd if ((t1 = tp->t_tspec) == PTR)
725 1.1 cgd t2 = tp->t_subt->t_tspec;
726 1.1 cgd
727 1.1 cgd if (fc == 'd' || fc == 'i') {
728 1.1 cgd if (alt || sz == LDOUBLE) {
729 1.53 rillig bad_format_string(hte, call);
730 1.1 cgd break;
731 1.1 cgd }
732 1.1 cgd int_conv:
733 1.1 cgd if (sz == LONG) {
734 1.1 cgd if (t1 != LONG && (hflag || t1 != ULONG))
735 1.53 rillig inconsistent_arguments(hte, call, n);
736 1.56 rillig } else if (sz == LLONG) {
737 1.56 rillig if (t1 != LLONG && (hflag || t1 != ULLONG))
738 1.53 rillig inconsistent_arguments(hte, call, n);
739 1.1 cgd } else {
740 1.1 cgd /*
741 1.64 rillig * SHORT is always promoted to INT, USHORT to
742 1.64 rillig * INT or UINT.
743 1.1 cgd */
744 1.1 cgd if (t1 != INT && (hflag || t1 != UINT))
745 1.53 rillig inconsistent_arguments(hte, call, n);
746 1.1 cgd }
747 1.1 cgd } else if (fc == 'o' || fc == 'u' || fc == 'x' || fc == 'X') {
748 1.1 cgd if ((alt && fc == 'u') || sz == LDOUBLE)
749 1.53 rillig bad_format_string(hte, call);
750 1.1 cgd uint_conv:
751 1.1 cgd if (sz == LONG) {
752 1.1 cgd if (t1 != ULONG && (hflag || t1 != LONG))
753 1.53 rillig inconsistent_arguments(hte, call, n);
754 1.56 rillig } else if (sz == LLONG) {
755 1.56 rillig if (t1 != ULLONG && (hflag || t1 != LLONG))
756 1.53 rillig inconsistent_arguments(hte, call, n);
757 1.1 cgd } else if (sz == SHORT) {
758 1.1 cgd /* USHORT was promoted to INT or UINT */
759 1.1 cgd if (t1 != UINT && t1 != INT)
760 1.53 rillig inconsistent_arguments(hte, call, n);
761 1.1 cgd } else {
762 1.1 cgd if (t1 != UINT && (hflag || t1 != INT))
763 1.53 rillig inconsistent_arguments(hte, call, n);
764 1.1 cgd }
765 1.1 cgd } else if (fc == 'D' || fc == 'O' || fc == 'U') {
766 1.54 rillig if ((alt && fc != 'O') || sz != NO_TSPEC || !tflag)
767 1.53 rillig bad_format_string(hte, call);
768 1.1 cgd sz = LONG;
769 1.1 cgd if (fc == 'D') {
770 1.1 cgd goto int_conv;
771 1.1 cgd } else {
772 1.1 cgd goto uint_conv;
773 1.1 cgd }
774 1.1 cgd } else if (fc == 'f' || fc == 'e' || fc == 'E' ||
775 1.63 rillig fc == 'g' || fc == 'G') {
776 1.54 rillig if (sz == NO_TSPEC)
777 1.1 cgd sz = DOUBLE;
778 1.1 cgd if (sz != DOUBLE && sz != LDOUBLE)
779 1.53 rillig bad_format_string(hte, call);
780 1.1 cgd if (t1 != sz)
781 1.53 rillig inconsistent_arguments(hte, call, n);
782 1.1 cgd } else if (fc == 'c') {
783 1.54 rillig if (sz != NO_TSPEC || alt || zero)
784 1.53 rillig bad_format_string(hte, call);
785 1.1 cgd if (t1 != INT)
786 1.53 rillig inconsistent_arguments(hte, call, n);
787 1.1 cgd } else if (fc == 's') {
788 1.54 rillig if (sz != NO_TSPEC || alt || zero)
789 1.53 rillig bad_format_string(hte, call);
790 1.1 cgd if (t1 != PTR ||
791 1.1 cgd (t2 != CHAR && t2 != UCHAR && t2 != SCHAR)) {
792 1.53 rillig inconsistent_arguments(hte, call, n);
793 1.1 cgd }
794 1.1 cgd } else if (fc == 'p') {
795 1.54 rillig if (fwidth || prec || sz != NO_TSPEC || alt || zero)
796 1.53 rillig bad_format_string(hte, call);
797 1.1 cgd if (t1 != PTR || (hflag && t2 != VOID))
798 1.53 rillig inconsistent_arguments(hte, call, n);
799 1.1 cgd } else if (fc == 'n') {
800 1.1 cgd if (fwidth || prec || alt || zero || sz == LDOUBLE)
801 1.53 rillig bad_format_string(hte, call);
802 1.1 cgd if (t1 != PTR) {
803 1.53 rillig inconsistent_arguments(hte, call, n);
804 1.1 cgd } else if (sz == LONG) {
805 1.1 cgd if (t2 != LONG && t2 != ULONG)
806 1.53 rillig inconsistent_arguments(hte, call, n);
807 1.1 cgd } else if (sz == SHORT) {
808 1.1 cgd if (t2 != SHORT && t2 != USHORT)
809 1.53 rillig inconsistent_arguments(hte, call, n);
810 1.1 cgd } else {
811 1.1 cgd if (t2 != INT && t2 != UINT)
812 1.53 rillig inconsistent_arguments(hte, call, n);
813 1.1 cgd }
814 1.1 cgd } else {
815 1.53 rillig bad_format_string(hte, call);
816 1.1 cgd break;
817 1.1 cgd }
818 1.1 cgd
819 1.1 cgd fc = *fp++;
820 1.1 cgd }
821 1.1 cgd }
822 1.1 cgd
823 1.1 cgd /*
824 1.1 cgd * Compare the types in the NULL-terminated array ap with the format
825 1.1 cgd * string fmt.
826 1.1 cgd */
827 1.1 cgd static void
828 1.72 rillig scanflike(const hte_t *hte, const fcall_t *call,
829 1.72 rillig int n, const char *fmt, const type_t **ap)
830 1.1 cgd {
831 1.55 rillig const char *fp;
832 1.55 rillig char fc;
833 1.55 rillig bool noasgn, fwidth;
834 1.55 rillig tspec_t sz, t1 = NO_TSPEC, t2 = NO_TSPEC;
835 1.72 rillig const type_t *tp = NULL;
836 1.1 cgd
837 1.1 cgd fp = fmt;
838 1.1 cgd fc = *fp++;
839 1.1 cgd
840 1.36 rillig for (;;) {
841 1.1 cgd if (fc == '\0') {
842 1.1 cgd if (*ap != NULL)
843 1.53 rillig too_many_arguments(hte, call);
844 1.1 cgd break;
845 1.1 cgd }
846 1.1 cgd if (fc != '%') {
847 1.53 rillig bad_format_string(hte, call);
848 1.1 cgd break;
849 1.1 cgd }
850 1.1 cgd fc = *fp++;
851 1.1 cgd
852 1.34 rillig noasgn = fwidth = false;
853 1.54 rillig sz = NO_TSPEC;
854 1.1 cgd
855 1.1 cgd if (fc == '*') {
856 1.34 rillig noasgn = true;
857 1.1 cgd fc = *fp++;
858 1.1 cgd }
859 1.10 lukem
860 1.67 rillig if (ch_isdigit(fc)) {
861 1.34 rillig fwidth = true;
862 1.67 rillig do { fc = *fp++; } while (ch_isdigit(fc));
863 1.1 cgd }
864 1.1 cgd
865 1.1 cgd if (fc == 'h') {
866 1.1 cgd sz = SHORT;
867 1.1 cgd } else if (fc == 'l') {
868 1.1 cgd sz = LONG;
869 1.1 cgd } else if (fc == 'q') {
870 1.56 rillig sz = LLONG;
871 1.1 cgd } else if (fc == 'L') {
872 1.1 cgd sz = LDOUBLE;
873 1.1 cgd }
874 1.54 rillig if (sz != NO_TSPEC)
875 1.1 cgd fc = *fp++;
876 1.1 cgd
877 1.1 cgd if (fc == '%') {
878 1.54 rillig if (sz != NO_TSPEC || noasgn || fwidth)
879 1.53 rillig bad_format_string(hte, call);
880 1.1 cgd fc = *fp++;
881 1.1 cgd continue;
882 1.1 cgd }
883 1.1 cgd
884 1.1 cgd if (!noasgn) {
885 1.1 cgd if ((tp = *ap++) == NULL) {
886 1.53 rillig too_few_arguments(hte, call);
887 1.1 cgd break;
888 1.1 cgd }
889 1.1 cgd n++;
890 1.1 cgd if ((t1 = tp->t_tspec) == PTR)
891 1.1 cgd t2 = tp->t_subt->t_tspec;
892 1.1 cgd }
893 1.1 cgd
894 1.1 cgd if (fc == 'd' || fc == 'i' || fc == 'n') {
895 1.1 cgd if (sz == LDOUBLE)
896 1.53 rillig bad_format_string(hte, call);
897 1.56 rillig if (sz != SHORT && sz != LONG && sz != LLONG)
898 1.1 cgd sz = INT;
899 1.1 cgd conv:
900 1.1 cgd if (!noasgn) {
901 1.1 cgd if (t1 != PTR) {
902 1.53 rillig inconsistent_arguments(hte, call, n);
903 1.30 rillig } else if (t2 != signed_type(sz)) {
904 1.53 rillig inconsistent_arguments(hte, call, n);
905 1.1 cgd } else if (hflag && t2 != sz) {
906 1.53 rillig inconsistent_arguments(hte, call, n);
907 1.1 cgd } else if (tp->t_subt->t_const) {
908 1.53 rillig inconsistent_arguments(hte, call, n);
909 1.1 cgd }
910 1.1 cgd }
911 1.1 cgd } else if (fc == 'o' || fc == 'u' || fc == 'x') {
912 1.1 cgd if (sz == LDOUBLE)
913 1.53 rillig bad_format_string(hte, call);
914 1.1 cgd if (sz == SHORT) {
915 1.1 cgd sz = USHORT;
916 1.1 cgd } else if (sz == LONG) {
917 1.1 cgd sz = ULONG;
918 1.56 rillig } else if (sz == LLONG) {
919 1.56 rillig sz = ULLONG;
920 1.1 cgd } else {
921 1.1 cgd sz = UINT;
922 1.1 cgd }
923 1.1 cgd goto conv;
924 1.1 cgd } else if (fc == 'D') {
925 1.54 rillig if (sz != NO_TSPEC || !tflag)
926 1.53 rillig bad_format_string(hte, call);
927 1.1 cgd sz = LONG;
928 1.1 cgd goto conv;
929 1.1 cgd } else if (fc == 'O') {
930 1.54 rillig if (sz != NO_TSPEC || !tflag)
931 1.53 rillig bad_format_string(hte, call);
932 1.1 cgd sz = ULONG;
933 1.1 cgd goto conv;
934 1.1 cgd } else if (fc == 'X') {
935 1.1 cgd /*
936 1.64 rillig * XXX valid in C90, but in NetBSD's libc implemented
937 1.64 rillig * as "lx". That's why it should be avoided.
938 1.1 cgd */
939 1.54 rillig if (sz != NO_TSPEC || !tflag)
940 1.53 rillig bad_format_string(hte, call);
941 1.1 cgd sz = ULONG;
942 1.1 cgd goto conv;
943 1.1 cgd } else if (fc == 'E') {
944 1.1 cgd /*
945 1.64 rillig * XXX valid in C90, but in NetBSD's libc implemented
946 1.64 rillig * as "lf". That's why it should be avoided.
947 1.1 cgd */
948 1.54 rillig if (sz != NO_TSPEC || !tflag)
949 1.53 rillig bad_format_string(hte, call);
950 1.1 cgd sz = DOUBLE;
951 1.1 cgd goto conv;
952 1.1 cgd } else if (fc == 'F') {
953 1.1 cgd /* XXX only for backward compatibility */
954 1.54 rillig if (sz != NO_TSPEC || !tflag)
955 1.53 rillig bad_format_string(hte, call);
956 1.1 cgd sz = DOUBLE;
957 1.1 cgd goto conv;
958 1.1 cgd } else if (fc == 'G') {
959 1.1 cgd /*
960 1.61 rillig * XXX valid in C90, but in NetBSD's libc not
961 1.1 cgd * implemented
962 1.1 cgd */
963 1.54 rillig if (sz != NO_TSPEC && sz != LONG && sz != LDOUBLE)
964 1.53 rillig bad_format_string(hte, call);
965 1.1 cgd goto fconv;
966 1.1 cgd } else if (fc == 'e' || fc == 'f' || fc == 'g') {
967 1.1 cgd fconv:
968 1.54 rillig if (sz == NO_TSPEC) {
969 1.1 cgd sz = FLOAT;
970 1.1 cgd } else if (sz == LONG) {
971 1.1 cgd sz = DOUBLE;
972 1.1 cgd } else if (sz != LDOUBLE) {
973 1.53 rillig bad_format_string(hte, call);
974 1.1 cgd sz = FLOAT;
975 1.1 cgd }
976 1.1 cgd goto conv;
977 1.1 cgd } else if (fc == 's' || fc == '[' || fc == 'c') {
978 1.54 rillig if (sz != NO_TSPEC)
979 1.53 rillig bad_format_string(hte, call);
980 1.1 cgd if (fc == '[') {
981 1.1 cgd if ((fc = *fp++) == '-') {
982 1.53 rillig bad_format_string(hte, call);
983 1.1 cgd fc = *fp++;
984 1.1 cgd }
985 1.1 cgd if (fc != ']') {
986 1.53 rillig bad_format_string(hte, call);
987 1.1 cgd if (fc == '\0')
988 1.1 cgd break;
989 1.1 cgd }
990 1.1 cgd }
991 1.1 cgd if (!noasgn) {
992 1.1 cgd if (t1 != PTR) {
993 1.53 rillig inconsistent_arguments(hte, call, n);
994 1.1 cgd } else if (t2 != CHAR && t2 != UCHAR &&
995 1.63 rillig t2 != SCHAR) {
996 1.53 rillig inconsistent_arguments(hte, call, n);
997 1.1 cgd }
998 1.1 cgd }
999 1.1 cgd } else if (fc == 'p') {
1000 1.54 rillig if (sz != NO_TSPEC)
1001 1.53 rillig bad_format_string(hte, call);
1002 1.1 cgd if (!noasgn) {
1003 1.1 cgd if (t1 != PTR || t2 != PTR) {
1004 1.53 rillig inconsistent_arguments(hte, call, n);
1005 1.1 cgd } else if (tp->t_subt->t_subt->t_tspec!=VOID) {
1006 1.1 cgd if (hflag)
1007 1.53 rillig inconsistent_arguments(hte, call, n);
1008 1.1 cgd }
1009 1.1 cgd }
1010 1.1 cgd } else {
1011 1.53 rillig bad_format_string(hte, call);
1012 1.1 cgd break;
1013 1.1 cgd }
1014 1.1 cgd
1015 1.1 cgd fc = *fp++;
1016 1.1 cgd }
1017 1.1 cgd }
1018 1.1 cgd
1019 1.1 cgd static void
1020 1.72 rillig bad_format_string(const hte_t *hte, const fcall_t *call)
1021 1.1 cgd {
1022 1.10 lukem
1023 1.68 rillig /* %s is called with a malformed format string in %s */
1024 1.1 cgd msg(13, hte->h_name, mkpos(&call->f_pos));
1025 1.1 cgd }
1026 1.1 cgd
1027 1.1 cgd static void
1028 1.72 rillig inconsistent_arguments(const hte_t *hte, const fcall_t *call, int n)
1029 1.1 cgd {
1030 1.10 lukem
1031 1.68 rillig /* %s is called in %s with argument %d being incompatible with ... */
1032 1.68 rillig msg(14, hte->h_name, mkpos(&call->f_pos), n);
1033 1.1 cgd }
1034 1.1 cgd
1035 1.1 cgd static void
1036 1.72 rillig too_few_arguments(const hte_t *hte, const fcall_t *call)
1037 1.1 cgd {
1038 1.10 lukem
1039 1.68 rillig /* %s is called in %s with too few arguments for format string */
1040 1.1 cgd msg(15, hte->h_name, mkpos(&call->f_pos));
1041 1.1 cgd }
1042 1.1 cgd
1043 1.1 cgd static void
1044 1.72 rillig too_many_arguments(const hte_t *hte, const fcall_t *call)
1045 1.1 cgd {
1046 1.10 lukem
1047 1.68 rillig /* %s is called in %s with too many arguments for format string */
1048 1.1 cgd msg(16, hte->h_name, mkpos(&call->f_pos));
1049 1.1 cgd }
1050 1.1 cgd
1051 1.21 christos /*
1052 1.21 christos * List of functions where we usually don't care about their result.
1053 1.21 christos * NB: Must be sorted.
1054 1.21 christos */
1055 1.21 christos static const char ignorelist[][8] = {
1056 1.21 christos "memcpy",
1057 1.21 christos "memmove",
1058 1.21 christos "memset",
1059 1.21 christos "printf",
1060 1.21 christos "strcat",
1061 1.21 christos "strcpy",
1062 1.21 christos "vprintf",
1063 1.21 christos };
1064 1.1 cgd
1065 1.1 cgd /*
1066 1.53 rillig * Print warnings for return values which are used but not returned,
1067 1.1 cgd * or return values which are always or sometimes ignored.
1068 1.1 cgd */
1069 1.1 cgd static void
1070 1.72 rillig check_return_values(const hte_t *hte, const sym_t *def)
1071 1.1 cgd {
1072 1.55 rillig fcall_t *call;
1073 1.55 rillig bool used, ignored;
1074 1.1 cgd
1075 1.1 cgd if (def == NULL)
1076 1.22 mbalmer /* don't know whether or not the functions returns a value */
1077 1.1 cgd return;
1078 1.1 cgd
1079 1.1 cgd if (hte->h_calls == NULL)
1080 1.1 cgd return;
1081 1.1 cgd
1082 1.45 rillig if (def->s_function_has_return_value) {
1083 1.21 christos /*
1084 1.64 rillig * XXX as soon as we are able to disable single warnings, the
1085 1.64 rillig * following dependencies from hflag should be removed. But for
1086 1.64 rillig * now I don't want to be bothered by these warnings which are
1087 1.64 rillig * almost always useless.
1088 1.21 christos */
1089 1.43 rillig if (!hflag)
1090 1.21 christos return;
1091 1.43 rillig if (hflag && bsearch(hte->h_name, ignorelist,
1092 1.47 rillig sizeof(ignorelist) / sizeof(ignorelist[0]),
1093 1.47 rillig sizeof(ignorelist[0]),
1094 1.21 christos (int (*)(const void *, const void *))strcmp) != NULL)
1095 1.21 christos return;
1096 1.21 christos
1097 1.1 cgd /* function has return value */
1098 1.34 rillig used = ignored = false;
1099 1.29 rillig for (call = hte->h_calls; call != NULL; call = call->f_next) {
1100 1.8 mycroft used |= call->f_rused || call->f_rdisc;
1101 1.1 cgd ignored |= !call->f_rused && !call->f_rdisc;
1102 1.1 cgd }
1103 1.1 cgd if (!used && ignored) {
1104 1.68 rillig /* %s returns a value that is always ignored */
1105 1.21 christos msg(8, hte->h_name);
1106 1.1 cgd } else if (used && ignored) {
1107 1.68 rillig /* %s returns a value that is sometimes ignored */
1108 1.21 christos msg(9, hte->h_name);
1109 1.1 cgd }
1110 1.1 cgd } else {
1111 1.1 cgd /* function has no return value */
1112 1.29 rillig for (call = hte->h_calls; call != NULL; call = call->f_next) {
1113 1.1 cgd if (call->f_rused)
1114 1.68 rillig /* %s has its return value used in %s but doesn't return one */
1115 1.1 cgd msg(10, hte->h_name, mkpos(&call->f_pos));
1116 1.1 cgd }
1117 1.1 cgd }
1118 1.1 cgd }
1119 1.1 cgd
1120 1.1 cgd /*
1121 1.1 cgd * Print warnings for inconsistent argument declarations.
1122 1.1 cgd */
1123 1.1 cgd static void
1124 1.72 rillig check_argument_declarations(const hte_t *hte,
1125 1.72 rillig const sym_t *def, const sym_t *decl)
1126 1.1 cgd {
1127 1.55 rillig bool osdef, eq, dowarn;
1128 1.55 rillig int n;
1129 1.72 rillig const sym_t *sym1, *sym;
1130 1.72 rillig const type_t **ap1, **ap2, *tp1, *tp2;
1131 1.1 cgd
1132 1.34 rillig osdef = false;
1133 1.1 cgd if (def != NULL) {
1134 1.45 rillig osdef = def->s_old_style_function;
1135 1.1 cgd sym1 = def;
1136 1.1 cgd } else if (decl != NULL && TP(decl->s_type)->t_proto) {
1137 1.1 cgd sym1 = decl;
1138 1.1 cgd } else {
1139 1.1 cgd return;
1140 1.1 cgd }
1141 1.1 cgd if (TP(sym1->s_type)->t_tspec != FUNC)
1142 1.1 cgd return;
1143 1.1 cgd
1144 1.1 cgd /*
1145 1.52 rillig * XXX Prototypes should also be compared with old-style function
1146 1.1 cgd * declarations.
1147 1.1 cgd */
1148 1.1 cgd
1149 1.28 rillig for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) {
1150 1.1 cgd if (sym == sym1 || !TP(sym->s_type)->t_proto)
1151 1.1 cgd continue;
1152 1.1 cgd ap1 = TP(sym1->s_type)->t_args;
1153 1.1 cgd ap2 = TP(sym->s_type)->t_args;
1154 1.1 cgd n = 0;
1155 1.1 cgd while (*ap1 != NULL && *ap2 != NULL) {
1156 1.72 rillig const type_t *xt1, *xt2;
1157 1.34 rillig dowarn = false;
1158 1.51 rillig eq = types_compatible(xt1 = *ap1, xt2 = *ap2,
1159 1.35 rillig true, osdef, false, &dowarn);
1160 1.20 lukem if (!eq || dowarn) {
1161 1.68 rillig /* %s has parameter %d declared as '%s' ... */
1162 1.19 christos msg(11, hte->h_name, n + 1,
1163 1.68 rillig type_name(xt1), mkpos(&sym1->s_pos),
1164 1.68 rillig type_name(xt2), mkpos(&sym->s_pos));
1165 1.1 cgd }
1166 1.1 cgd n++;
1167 1.1 cgd ap1++;
1168 1.1 cgd ap2++;
1169 1.1 cgd }
1170 1.1 cgd if (*ap1 == *ap2) {
1171 1.1 cgd tp1 = TP(sym1->s_type);
1172 1.1 cgd tp2 = TP(sym->s_type);
1173 1.1 cgd if (tp1->t_vararg == tp2->t_vararg)
1174 1.1 cgd continue;
1175 1.45 rillig if (tp2->t_vararg && sym1->s_check_only_first_args &&
1176 1.45 rillig sym1->s_check_num_args == n && !sflag) {
1177 1.1 cgd continue;
1178 1.1 cgd }
1179 1.1 cgd }
1180 1.68 rillig /* %s has %d parameters in %s, versus %d in %s */
1181 1.68 rillig msg(12, hte->h_name,
1182 1.68 rillig total_args(n, ap1), mkpos(&sym1->s_pos),
1183 1.68 rillig total_args(n, ap2), mkpos(&sym->s_pos));
1184 1.1 cgd }
1185 1.1 cgd }
1186 1.1 cgd
1187 1.1 cgd
1188 1.1 cgd /*
1189 1.37 rillig * Check compatibility of two types. Returns whether types are compatible.
1190 1.1 cgd *
1191 1.37 rillig * ignqual if set, ignore qualifiers of outermost type; used for
1192 1.1 cgd * function arguments
1193 1.7 mycroft * promote if set, promote left type before comparison; used for
1194 1.52 rillig * comparisons of arguments with parameters of old-style
1195 1.1 cgd * definitions
1196 1.1 cgd * asgn left indirected type must have at least the same qualifiers
1197 1.1 cgd * like right indirected type (for assignments and function
1198 1.1 cgd * arguments)
1199 1.52 rillig * *dowarn set to true if an old-style declaration was compared with
1200 1.1 cgd * an incompatible prototype declaration
1201 1.1 cgd */
1202 1.34 rillig static bool
1203 1.72 rillig types_compatible(const type_t *tp1, const type_t *tp2,
1204 1.51 rillig bool ignqual, bool promot, bool asgn, bool *dowarn)
1205 1.1 cgd {
1206 1.55 rillig tspec_t t, to;
1207 1.55 rillig int indir;
1208 1.1 cgd
1209 1.54 rillig to = NO_TSPEC;
1210 1.1 cgd indir = 0;
1211 1.1 cgd
1212 1.1 cgd while (tp1 != NULL && tp2 != NULL) {
1213 1.1 cgd
1214 1.1 cgd t = tp1->t_tspec;
1215 1.1 cgd if (promot) {
1216 1.1 cgd if (t == FLOAT) {
1217 1.1 cgd t = DOUBLE;
1218 1.1 cgd } else if (t == CHAR || t == SCHAR) {
1219 1.1 cgd t = INT;
1220 1.1 cgd } else if (t == UCHAR) {
1221 1.1 cgd t = tflag ? UINT : INT;
1222 1.1 cgd } else if (t == SHORT) {
1223 1.1 cgd t = INT;
1224 1.1 cgd } else if (t == USHORT) {
1225 1.1 cgd t = INT_MAX < USHRT_MAX || tflag ? UINT : INT;
1226 1.1 cgd }
1227 1.1 cgd }
1228 1.1 cgd
1229 1.1 cgd if (asgn && to == PTR) {
1230 1.1 cgd if (indir == 1 && (t == VOID || tp2->t_tspec == VOID))
1231 1.35 rillig return true;
1232 1.1 cgd }
1233 1.10 lukem
1234 1.1 cgd if (t != tp2->t_tspec) {
1235 1.1 cgd /*
1236 1.1 cgd * Give pointer to types which differ only in
1237 1.1 cgd * signedness a chance if not sflag and not hflag.
1238 1.1 cgd */
1239 1.1 cgd if (sflag || hflag || to != PTR)
1240 1.35 rillig return false;
1241 1.30 rillig if (signed_type(t) != signed_type(tp2->t_tspec))
1242 1.35 rillig return false;
1243 1.1 cgd }
1244 1.1 cgd
1245 1.38 rillig if (tp1->t_is_enum && tp2->t_is_enum) {
1246 1.1 cgd if (tp1->t_istag && tp2->t_istag) {
1247 1.27 rillig return tp1->t_tag == tp2->t_tag;
1248 1.1 cgd } else if (tp1->t_istynam && tp2->t_istynam) {
1249 1.27 rillig return tp1->t_tynam == tp2->t_tynam;
1250 1.3 cgd } else if (tp1->t_isuniqpos && tp2->t_isuniqpos) {
1251 1.3 cgd return (tp1->t_uniqpos.p_line ==
1252 1.3 cgd tp2->t_uniqpos.p_line &&
1253 1.3 cgd tp1->t_uniqpos.p_file ==
1254 1.3 cgd tp2->t_uniqpos.p_file &&
1255 1.3 cgd tp1->t_uniqpos.p_uniq ==
1256 1.3 cgd tp2->t_uniqpos.p_uniq);
1257 1.1 cgd } else {
1258 1.35 rillig return false;
1259 1.1 cgd }
1260 1.1 cgd }
1261 1.1 cgd
1262 1.1 cgd /*
1263 1.64 rillig * XXX Handle combinations of enum and int if eflag is set. But
1264 1.64 rillig * note: enum and 0 should be allowed.
1265 1.1 cgd */
1266 1.1 cgd
1267 1.1 cgd if (asgn && indir == 1) {
1268 1.1 cgd if (!tp1->t_const && tp2->t_const)
1269 1.35 rillig return false;
1270 1.1 cgd if (!tp1->t_volatile && tp2->t_volatile)
1271 1.35 rillig return false;
1272 1.1 cgd } else if (!ignqual && !tflag) {
1273 1.1 cgd if (tp1->t_const != tp2->t_const)
1274 1.35 rillig return false;
1275 1.1 cgd if (tp1->t_const != tp2->t_const)
1276 1.35 rillig return false;
1277 1.1 cgd }
1278 1.1 cgd
1279 1.1 cgd if (t == STRUCT || t == UNION) {
1280 1.1 cgd if (tp1->t_istag && tp2->t_istag) {
1281 1.27 rillig return tp1->t_tag == tp2->t_tag;
1282 1.1 cgd } else if (tp1->t_istynam && tp2->t_istynam) {
1283 1.27 rillig return tp1->t_tynam == tp2->t_tynam;
1284 1.3 cgd } else if (tp1->t_isuniqpos && tp2->t_isuniqpos) {
1285 1.3 cgd return (tp1->t_uniqpos.p_line ==
1286 1.3 cgd tp2->t_uniqpos.p_line &&
1287 1.3 cgd tp1->t_uniqpos.p_file ==
1288 1.3 cgd tp2->t_uniqpos.p_file &&
1289 1.3 cgd tp1->t_uniqpos.p_uniq ==
1290 1.3 cgd tp2->t_uniqpos.p_uniq);
1291 1.1 cgd } else {
1292 1.35 rillig return false;
1293 1.1 cgd }
1294 1.1 cgd }
1295 1.1 cgd
1296 1.1 cgd if (t == ARRAY && tp1->t_dim != tp2->t_dim) {
1297 1.1 cgd if (tp1->t_dim != 0 && tp2->t_dim != 0)
1298 1.35 rillig return false;
1299 1.1 cgd }
1300 1.1 cgd
1301 1.1 cgd if (t == FUNC) {
1302 1.1 cgd if (tp1->t_proto && tp2->t_proto) {
1303 1.51 rillig if (!prototypes_compatible(tp1, tp2, dowarn))
1304 1.35 rillig return false;
1305 1.1 cgd } else if (tp1->t_proto) {
1306 1.50 rillig if (!matches_no_arg_function(tp1, dowarn))
1307 1.35 rillig return false;
1308 1.1 cgd } else if (tp2->t_proto) {
1309 1.50 rillig if (!matches_no_arg_function(tp2, dowarn))
1310 1.35 rillig return false;
1311 1.1 cgd }
1312 1.1 cgd }
1313 1.1 cgd
1314 1.1 cgd tp1 = tp1->t_subt;
1315 1.1 cgd tp2 = tp2->t_subt;
1316 1.34 rillig ignqual = promot = false;
1317 1.1 cgd to = t;
1318 1.1 cgd indir++;
1319 1.1 cgd }
1320 1.1 cgd
1321 1.27 rillig return tp1 == tp2;
1322 1.1 cgd }
1323 1.1 cgd
1324 1.1 cgd /*
1325 1.1 cgd * Compares arguments of two prototypes
1326 1.1 cgd */
1327 1.34 rillig static bool
1328 1.72 rillig prototypes_compatible(const type_t *tp1, const type_t *tp2, bool *dowarn)
1329 1.1 cgd {
1330 1.1 cgd
1331 1.1 cgd if (tp1->t_vararg != tp2->t_vararg)
1332 1.35 rillig return false;
1333 1.1 cgd
1334 1.72 rillig const type_t **a1 = tp1->t_args;
1335 1.72 rillig const type_t **a2 = tp2->t_args;
1336 1.1 cgd
1337 1.72 rillig for (; *a1 != NULL && *a2 != NULL; a1++, a2++)
1338 1.51 rillig if (!types_compatible(*a1, *a2, true, false, false, dowarn))
1339 1.35 rillig return false;
1340 1.27 rillig return *a1 == *a2;
1341 1.1 cgd }
1342 1.1 cgd
1343 1.1 cgd /*
1344 1.50 rillig * Returns whether all parameters of a prototype are compatible with an
1345 1.50 rillig * old-style function declaration.
1346 1.50 rillig *
1347 1.50 rillig * This is the case if the following conditions are met:
1348 1.1 cgd * 1. the prototype must have a fixed number of parameters
1349 1.1 cgd * 2. no parameter is of type float
1350 1.1 cgd * 3. no parameter is converted to another type if integer promotion
1351 1.1 cgd * is applied on it
1352 1.1 cgd */
1353 1.34 rillig static bool
1354 1.72 rillig matches_no_arg_function(const type_t *tp, bool *dowarn)
1355 1.1 cgd {
1356 1.20 lukem if (tp->t_vararg && dowarn != NULL)
1357 1.34 rillig *dowarn = true;
1358 1.72 rillig for (const type_t **arg = tp->t_args; *arg != NULL; arg++) {
1359 1.72 rillig tspec_t t = (*arg)->t_tspec;
1360 1.72 rillig if (t == FLOAT)
1361 1.34 rillig return false;
1362 1.1 cgd if (t == CHAR || t == SCHAR || t == UCHAR)
1363 1.34 rillig return false;
1364 1.1 cgd if (t == SHORT || t == USHORT)
1365 1.34 rillig return false;
1366 1.1 cgd }
1367 1.34 rillig return true;
1368 1.1 cgd }
1369