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