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