1 /* $NetBSD: chk.c,v 1.2 1995/07/03 21:24:42 cgd Exp $ */
4 * Copyright (c) 1994, 1995 Jochen Pohl
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * $NetBSD: chk.c,v 1.2 1995/07/03 21:24:42 cgd Exp $
34 * $DragonFly: src/usr.bin/xlint/lint2/chk.c,v 1.7 2004/07/07 12:24:01 asmodai Exp $
44 /* various type information */
48 static void chkund(hte_t
*);
49 static void chkdnu(hte_t
*);
50 static void chkdnud(hte_t
*);
51 static void chkmd(hte_t
*);
52 static void chkvtui(hte_t
*, sym_t
*, sym_t
*);
53 static void chkvtdi(hte_t
*, sym_t
*, sym_t
*);
54 static void chkfaui(hte_t
*, sym_t
*, sym_t
*);
55 static void chkau(hte_t
*, int, sym_t
*, sym_t
*, pos_t
*,
56 fcall_t
*, fcall_t
*, type_t
*, type_t
*);
57 static void chkrvu(hte_t
*, sym_t
*);
58 static void chkadecl(hte_t
*, sym_t
*, sym_t
*);
59 static void printflike(hte_t
*,fcall_t
*, int,
60 const char *, type_t
**);
61 static void scanflike(hte_t
*, fcall_t
*, int,
62 const char *, type_t
**);
63 static void badfmt(hte_t
*, fcall_t
*);
64 static void inconarg(hte_t
*, fcall_t
*, int);
65 static void tofewarg(hte_t
*, fcall_t
*);
66 static void tomanyarg(hte_t
*, fcall_t
*);
67 static int eqtype(type_t
*, type_t
*, int, int, int, int *);
68 static int eqargs(type_t
*, type_t
*, int *);
69 static int mnoarg(type_t
*, int *);
82 0, 0, 0, 0, 0, "signed" } },
85 0, 0, 0, 0, 0, "unsigned" } },
86 { CHAR
, { CHAR_BIT
, CHAR_BIT
,
88 1, 0, 0, 1, 1, "char" } },
89 { SCHAR
, { CHAR_BIT
, CHAR_BIT
,
91 1, 0, 0, 1, 1, "signed char" } },
92 { UCHAR
, { CHAR_BIT
, CHAR_BIT
,
94 1, 1, 0, 1, 1, "unsigned char" } },
95 { SHORT
, { sizeof (short) * CHAR_BIT
, 2 * CHAR_BIT
,
97 1, 0, 0, 1, 1, "short" } },
98 { USHORT
, { sizeof (u_short
) * CHAR_BIT
, 2 * CHAR_BIT
,
100 1, 1, 0, 1, 1, "unsigned short" } },
101 { INT
, { sizeof (int) * CHAR_BIT
, 3 * CHAR_BIT
,
103 1, 0, 0, 1, 1, "int" } },
104 { UINT
, { sizeof (u_int
) * CHAR_BIT
, 3 * CHAR_BIT
,
106 1, 1, 0, 1, 1, "unsigned int" } },
107 { LONG
, { sizeof (long) * CHAR_BIT
, 4 * CHAR_BIT
,
109 1, 0, 0, 1, 1, "long" } },
110 { ULONG
, { sizeof (u_long
) * CHAR_BIT
, 4 * CHAR_BIT
,
112 1, 1, 0, 1, 1, "unsigned long" } },
113 { QUAD
, { sizeof (quad_t
) * CHAR_BIT
, 8 * CHAR_BIT
,
115 1, 0, 0, 1, 1, "long long" } },
116 { UQUAD
, { sizeof (u_quad_t
) * CHAR_BIT
, 8 * CHAR_BIT
,
118 1, 1, 0, 1, 1, "unsigned long long" } },
119 { FLOAT
, { sizeof (float) * CHAR_BIT
, 4 * CHAR_BIT
,
121 0, 0, 1, 1, 1, "float" } },
122 { DOUBLE
, { sizeof (double) * CHAR_BIT
, 8 * CHAR_BIT
,
124 0, 0, 1, 1, 1, "double" } },
125 { LDOUBLE
, { sizeof (ldbl_t
) * CHAR_BIT
, 10 * CHAR_BIT
,
127 0, 0, 1, 1, 1, "long double" } },
130 0, 0, 0, 0, 0, "void" } },
133 0, 0, 0, 0, 0, "struct" } },
136 0, 0, 0, 0, 0, "union" } },
137 { ENUM
, { sizeof (int) * CHAR_BIT
, 3 * CHAR_BIT
,
139 1, 0, 0, 1, 1, "enum" } },
140 { PTR
, { sizeof (void *) * CHAR_BIT
, 4 * CHAR_BIT
,
142 0, 1, 0, 0, 1, "pointer" } },
145 0, 0, 0, 0, 0, "array" } },
148 0, 0, 0, 0, 0, "function" } },
151 for (i
= 0; i
< sizeof (ittab
) / sizeof (ittab
[0]); i
++)
152 STRUCT_ASSIGN(ttab
[ittab
[i
].it_tspec
], ittab
[i
].it_ttab
);
154 for (i
= 0; i
< NTSPEC
; i
++)
155 ttab
[i
].tt_psz
= ttab
[i
].tt_sz
;
161 * If there is a symbol named "main", mark it as used.
168 if ((hte
= hsearch("main", 0)) != NULL
)
173 * Performs all tests for a single name
178 sym_t
*sym
, *def
, *pdecl
, *decl
;
188 /* Get definition, prototype declaration and declaration */
189 def
= pdecl
= decl
= NULL
;
190 for (sym
= hte
->h_syms
; sym
!= NULL
; sym
= sym
->s_nxt
) {
191 if (def
== NULL
&& (sym
->s_def
== DEF
|| sym
->s_def
== TDEF
))
193 if (pdecl
== NULL
&& sym
->s_def
== DECL
&&
194 TP(sym
->s_type
)->t_tspec
== FUNC
&&
195 TP(sym
->s_type
)->t_proto
) {
198 if (decl
== NULL
&& sym
->s_def
== DECL
)
202 /* A prototype is better than an old style declaration. */
206 chkvtui(hte
, def
, decl
);
208 chkvtdi(hte
, def
, decl
);
210 chkfaui(hte
, def
, decl
);
214 chkadecl(hte
, def
, decl
);
218 * Print a warning if the name has been used, but not defined.
226 if (!hte
->h_used
|| hte
->h_def
)
229 if ((fcall
= hte
->h_calls
) != NULL
) {
230 /* %s used( %s ), but not defined */
231 msg(0, hte
->h_name
, mkpos(&fcall
->f_pos
));
232 } else if ((usym
= hte
->h_usyms
) != NULL
) {
233 /* %s used( %s ), but not defined */
234 msg(0, hte
->h_name
, mkpos(&usym
->u_pos
));
239 * Print a warning if the name has been defined, but never used.
246 if (!hte
->h_def
|| hte
->h_used
)
249 for (sym
= hte
->h_syms
; sym
!= NULL
; sym
= sym
->s_nxt
) {
250 if (sym
->s_def
== DEF
|| sym
->s_def
== TDEF
) {
251 /* %s defined( %s ), but never used */
252 msg(1, hte
->h_name
, mkpos(&sym
->s_pos
));
259 * Print a warning if the name has been declared, but is not used
267 if (hte
->h_syms
== NULL
|| hte
->h_used
|| hte
->h_def
)
270 if ((sym
= hte
->h_syms
) != NULL
) {
271 if (sym
->s_def
!= DECL
)
272 errx(1, "internal error: chkdnud() 1");
273 /* %s declared( %s ), but never used or defined */
274 msg(2, hte
->h_name
, mkpos(&sym
->s_pos
));
279 * Print a warning if there is more then one definition for
292 for (sym
= hte
->h_syms
; sym
!= NULL
; sym
= sym
->s_nxt
) {
294 * ANSI C allows tentative definitions of the same name in
295 * only one compilation unit.
297 if (sym
->s_def
!= DEF
&& (!sflag
|| sym
->s_def
!= TDEF
))
303 pos1
= xstrdup(mkpos(&def1
->s_pos
));
304 /* %s multiply defined\t%s :: %s */
305 msg(3, hte
->h_name
, pos1
, mkpos(&sym
->s_pos
));
311 * Print a warning if the return value assumed for a function call
312 * differs from the return value of the function definition or
313 * function declaration.
315 * If no definition/declaration can be found, the assumed return values
316 * are always int. So there is no need to compare with another function
317 * call as it's done for function arguments.
320 chkvtui(hte_t
*hte
, sym_t
*def
, sym_t
*decl
)
325 /* LINTED (automatic hides external declaration: warn) */
329 if (hte
->h_calls
== NULL
)
337 t1
= (tp1
= TP(def
->s_type
)->t_subt
)->t_tspec
;
338 for (call
= hte
->h_calls
; call
!= NULL
; call
= call
->f_nxt
) {
339 tp2
= TP(call
->f_type
)->t_subt
;
340 eq
= eqtype(tp1
, tp2
, 1, 0, 0, (warn
= 0, &warn
));
341 if (!call
->f_rused
) {
342 /* no return value used */
343 if ((t1
== STRUCT
|| t1
== UNION
) && !eq
) {
345 * If a function returns a struct or union it
346 * must be declared to return a struct or
347 * union, also if the return value is ignored.
348 * This is necessary because the caller must
349 * allocate stack space for the return value.
350 * If it does not, the return value would over-
352 * XXX Following massage may be confusing
353 * because it appears also if the return value
354 * was declared inconsistently. But this
355 * behaviour matches pcc based lint, so it is
358 pos1
= xstrdup(mkpos(&def
->s_pos
));
359 /* %s value must be decl. before use %s :: %s */
361 pos1
, mkpos(&call
->f_pos
));
366 if (!eq
|| (sflag
&& warn
)) {
367 pos1
= xstrdup(mkpos(&def
->s_pos
));
368 /* %s value used inconsistenty\t%s :: %s */
369 msg(4, hte
->h_name
, pos1
, mkpos(&call
->f_pos
));
376 * Print a warning if a definition/declaration does not match another
377 * definition/declaration of the same name. For functions, only the
378 * types of return values are tested.
381 chkvtdi(hte_t
*hte
, sym_t
*def
, sym_t
*decl
)
385 /* LINTED (automatic hides external declaration: warn) */
394 tp1
= TP(def
->s_type
);
395 for (sym
= hte
->h_syms
; sym
!= NULL
; sym
= sym
->s_nxt
) {
398 tp2
= TP(sym
->s_type
);
400 if (tp1
->t_tspec
== FUNC
&& tp2
->t_tspec
== FUNC
) {
401 eq
= eqtype(tp1
->t_subt
, tp2
->t_subt
, 1, 0, 0, &warn
);
403 eq
= eqtype(tp1
, tp2
, 0, 0, 0, &warn
);
405 if (!eq
|| (sflag
&& warn
)) {
406 pos1
= xstrdup(mkpos(&def
->s_pos
));
407 /* %s value declared inconsistently\t%s :: %s */
408 msg(5, hte
->h_name
, pos1
, mkpos(&sym
->s_pos
));
415 * Print a warning if a function is called with arguments which does
416 * not match the function definition, declaration or another call
417 * of the same function.
420 chkfaui(hte_t
*hte
, sym_t
*def
, sym_t
*decl
)
422 type_t
*tp1
, *tp2
, **ap1
, **ap2
;
424 fcall_t
*calls
, *call
, *call1
;
429 if ((calls
= hte
->h_calls
) == NULL
)
433 * If we find a function definition, we use this for comparision,
434 * otherwise the first prototype we can find. If there is no
435 * definition or prototype declaration, the first function call
441 if ((tp1
= TP(def
->s_type
))->t_tspec
!= FUNC
)
444 } else if (decl
!= NULL
&& TP(decl
->s_type
)->t_proto
) {
445 if ((tp1
= TP(decl
->s_type
))->t_tspec
!= FUNC
)
447 pos1p
= &decl
->s_pos
;
451 calls
= calls
->f_nxt
;
452 if ((tp1
= TP(call1
->f_type
))->t_tspec
!= FUNC
)
454 pos1p
= &call1
->f_pos
;
458 for (call
= calls
; call
!= NULL
; call
= call
->f_nxt
) {
459 if ((tp2
= TP(call
->f_type
))->t_tspec
!= FUNC
)
464 while (*ap1
!= NULL
&& *ap2
!= NULL
) {
465 if (def
!= NULL
&& def
->s_va
&& n
>= def
->s_nva
)
468 chkau(hte
, n
, def
, decl
, pos1p
, call1
, call
,
474 /* equal # of arguments */
475 } else if (def
!= NULL
&& def
->s_va
&& n
>= def
->s_nva
) {
477 * function definition with VARARGS; The # of
478 * arguments of the call must be at least as large
479 * as the parameter of VARARGS.
481 } else if (*ap2
!= NULL
&& tp1
->t_proto
&& tp1
->t_vararg
) {
483 * prototype with ... and function call with
484 * at least the same # of arguments as declared
488 pos1
= xstrdup(mkpos(pos1p
));
489 /* %s: variable # of args\t%s :: %s */
490 msg(7, hte
->h_name
, pos1
, mkpos(&call
->f_pos
));
495 /* perform SCANFLIKE/PRINTFLIKE tests */
496 if (def
== NULL
|| (!def
->s_prfl
&& !def
->s_scfl
))
498 as
= def
->s_prfl
? def
->s_nprfl
: def
->s_nscfl
;
499 for (ai
= call
->f_args
; ai
!= NULL
; ai
= ai
->a_nxt
) {
503 if (ai
== NULL
|| !ai
->a_fmt
)
506 printflike(hte
, call
, n
, ai
->a_fstrg
, ap2
);
508 scanflike(hte
, call
, n
, ai
->a_fstrg
, ap2
);
514 * Check a single argument in a function call.
516 * hte a pointer to the hash table entry of the function
517 * n the number of the argument (1..)
518 * def the function definition or NULL
519 * decl prototype declaration, old style declaration or NULL
520 * pos1p position of definition, declaration of first call
521 * call1 first call, if both def and decl are old style def/decl
523 * arg1 currently checked argument of def/decl/call1
524 * arg2 currently checked argument of call
528 chkau(hte_t
*hte
, int n
, sym_t
*def
, sym_t
*decl
, pos_t
*pos1p
,
529 fcall_t
*call1
, fcall_t
*call
, type_t
*arg1
, type_t
*arg2
)
531 /* LINTED (automatic hides external declaration: warn) */
532 int promote
, asgn
, warn
;
538 * If a function definition is available (def != NULL), we compair the
539 * function call (call) with the definition. Otherwise, if a function
540 * definition is available and it is not an old style definition
541 * (decl != NULL && TP(decl->s_type)->t_proto), we compair the call
542 * with this declaration. Otherwise we compair it with the first
543 * call we have found (call1).
546 /* arg1 must be promoted if it stems from an old style definition */
547 promote
= def
!= NULL
&& def
->s_osdef
;
550 * If we compair with a definition or declaration, we must perform
551 * the same checks for qualifiers in indirected types as in
554 asgn
= def
!= NULL
|| (decl
!= NULL
&& TP(decl
->s_type
)->t_proto
);
557 if (eqtype(arg1
, arg2
, 1, promote
, asgn
, &warn
) && (!sflag
|| !warn
))
561 * Other lint implementations print warnings as soon as the type
562 * of an argument does not match exactly the expected type. The
563 * result are lots of warnings which are really not neccessary.
564 * We print a warning only if
565 * (0) at least one type is not an interger type and types differ
566 * (1) hflag is set and types differ
567 * (2) types differ, except in signedness
568 * If the argument is an integer constant whose msb is not set,
569 * signedness is ignored (e.g. 0 matches both signed and unsigned
570 * int). This is with and without hflag.
571 * If the argument is an integer constant with value 0 and the
572 * expected argument is of type pointer and the width of the
573 * interger constant is the same as the width of the pointer,
574 * no warning is printed.
578 if (isityp(t1
) && isityp(t2
) && !arg1
->t_isenum
&& !arg2
->t_isenum
) {
581 * XXX Here is a problem: Althrough it is possible to
582 * pass an int where a char/short it expected, there
583 * may be loss in significant digits. We should first
584 * check for const arguments if they can be converted
585 * into the original parameter type.
589 } else if (t1
== CHAR
|| t1
== SCHAR
) {
591 } else if (t1
== UCHAR
) {
592 t1
= tflag
? UINT
: INT
;
593 } else if (t1
== SHORT
) {
595 } else if (t1
== USHORT
) {
597 t1
= INT_MAX
< USHRT_MAX
|| tflag
? UINT
: INT
;
601 if (styp(t1
) == styp(t2
)) {
604 * types differ only in signedness; get information
609 * treat a definition like a call with variable
612 ai1
= call1
!= NULL
? call1
->f_args
: NULL
;
615 * if two calls are compared, ai1 is set to the
616 * information for the n-th argument, if this was
617 * a constant, otherwise to NULL
619 for ( ; ai1
!= NULL
; ai1
= ai1
->a_nxt
) {
624 * ai is set to the information of the n-th arg
625 * of the (second) call, if this was a constant,
628 for (ai
= call
->f_args
; ai
!= NULL
; ai
= ai
->a_nxt
) {
633 if (ai1
== NULL
&& ai
== NULL
) {
634 /* no constant at all */
637 } else if (ai1
== NULL
|| ai
== NULL
) {
641 if (ai
->a_zero
|| ai
->a_pcon
)
642 /* same value in signed and unsigned */
644 /* value (not representation) differently */
647 * two constants, one signed, one unsigned;
648 * if the msb of one of the constants is set,
649 * the argument is used inconsistently.
651 if (!ai1
->a_ncon
&& !ai
->a_ncon
)
656 } else if (t1
== PTR
&& isityp(t2
) && psize(t1
) == psize(t2
)) {
657 for (ai
= call
->f_args
; ai
!= NULL
; ai
= ai
->a_nxt
) {
661 if (ai
!= NULL
&& ai
->a_zero
)
665 pos1
= xstrdup(mkpos(pos1p
));
666 /* %s, arg %d used inconsistently\t%s :: %s */
667 msg(6, hte
->h_name
, n
, pos1
, mkpos(&call
->f_pos
));
672 * Compare the types in the NULL-terminated array ap with the format
676 printflike(hte_t
*hte
, fcall_t
*call
, int n
, const char *fmt
, type_t
**ap
)
680 int fwidth
, prec
, left
, sign
, space
, alt
, zero
;
690 tomanyarg(hte
, call
);
698 fwidth
= prec
= left
= sign
= space
= alt
= zero
= 0;
707 } else if (fc
== '+') {
711 } else if (fc
== ' ') {
715 } else if (fc
== '#') {
719 } else if (fc
== '0') {
732 do { fc
= *fp
++; } while (isdigit(fc
)) ;
733 } else if (fc
== '*') {
736 if ((tp
= *ap
++) == NULL
) {
741 if ((t1
= tp
->t_tspec
) != INT
&& (hflag
|| t1
!= UINT
))
742 inconarg(hte
, call
, n
);
750 do { fc
= *fp
++; } while (isdigit(fc
));
751 } else if (fc
== '*') {
753 if ((tp
= *ap
++) == NULL
) {
758 if (tp
->t_tspec
!= INT
)
759 inconarg(hte
, call
, n
);
768 } else if (fc
== 'l') {
770 } else if (fc
== 'q') {
772 } else if (fc
== 'L') {
779 if (sz
!= NOTSPEC
|| left
|| sign
|| space
||
780 alt
|| zero
|| prec
|| fwidth
) {
792 if ((tp
= *ap
++) == NULL
) {
797 if ((t1
= tp
->t_tspec
) == PTR
)
798 t2
= tp
->t_subt
->t_tspec
;
800 if (fc
== 'd' || fc
== 'i') {
801 if (alt
|| sz
== LDOUBLE
) {
807 if (t1
!= LONG
&& (hflag
|| t1
!= ULONG
))
808 inconarg(hte
, call
, n
);
809 } else if (sz
== QUAD
) {
810 if (t1
!= QUAD
&& (hflag
|| t1
!= UQUAD
))
811 inconarg(hte
, call
, n
);
814 * SHORT is always promoted to INT, USHORT
817 if (t1
!= INT
&& (hflag
|| t1
!= UINT
))
818 inconarg(hte
, call
, n
);
820 } else if (fc
== 'o' || fc
== 'u' || fc
== 'x' || fc
== 'X') {
821 if ((alt
&& fc
== 'u') || sz
== LDOUBLE
)
825 if (t1
!= ULONG
&& (hflag
|| t1
!= LONG
))
826 inconarg(hte
, call
, n
);
827 } else if (sz
== QUAD
) {
828 if (t1
!= UQUAD
&& (hflag
|| t1
!= QUAD
))
829 inconarg(hte
, call
, n
);
830 } else if (sz
== SHORT
) {
831 /* USHORT was promoted to INT or UINT */
832 if (t1
!= UINT
&& t1
!= INT
)
833 inconarg(hte
, call
, n
);
835 if (t1
!= UINT
&& (hflag
|| t1
!= INT
))
836 inconarg(hte
, call
, n
);
838 } else if (fc
== 'D' || fc
== 'O' || fc
== 'U') {
839 if ((alt
&& fc
!= 'O') || sz
!= NOTSPEC
|| !tflag
)
847 } else if (fc
== 'f' || fc
== 'e' || fc
== 'E' ||
848 fc
== 'g' || fc
== 'G') {
851 if (sz
!= DOUBLE
&& sz
!= LDOUBLE
)
854 inconarg(hte
, call
, n
);
855 } else if (fc
== 'c') {
856 if (sz
!= NOTSPEC
|| alt
|| zero
)
859 inconarg(hte
, call
, n
);
860 } else if (fc
== 's') {
861 if (sz
!= NOTSPEC
|| alt
|| zero
)
864 (t2
!= CHAR
&& t2
!= UCHAR
&& t2
!= SCHAR
)) {
865 inconarg(hte
, call
, n
);
867 } else if (fc
== 'p') {
868 if (fwidth
|| prec
|| sz
!= NOTSPEC
|| alt
|| zero
)
870 if (t1
!= PTR
|| (hflag
&& t2
!= VOID
))
871 inconarg(hte
, call
, n
);
872 } else if (fc
== 'n') {
873 if (fwidth
|| prec
|| alt
|| zero
|| sz
== LDOUBLE
)
876 inconarg(hte
, call
, n
);
877 } else if (sz
== LONG
) {
878 if (t2
!= LONG
&& t2
!= ULONG
)
879 inconarg(hte
, call
, n
);
880 } else if (sz
== SHORT
) {
881 if (t2
!= SHORT
&& t2
!= USHORT
)
882 inconarg(hte
, call
, n
);
884 if (t2
!= INT
&& t2
!= UINT
)
885 inconarg(hte
, call
, n
);
897 * Compare the types in the NULL-terminated array ap with the format
901 scanflike(hte_t
*hte
, fcall_t
*call
, int n
, const char *fmt
, type_t
**ap
)
915 tomanyarg(hte
, call
);
934 do { fc
= *fp
++; } while (isdigit(fc
));
939 } else if (fc
== 'l') {
941 } else if (fc
== 'q') {
943 } else if (fc
== 'L') {
950 if (sz
!= NOTSPEC
|| noasgn
|| fwidth
)
957 if ((tp
= *ap
++) == NULL
) {
962 if ((t1
= tp
->t_tspec
) == PTR
)
963 t2
= tp
->t_subt
->t_tspec
;
966 if (fc
== 'd' || fc
== 'i' || fc
== 'n') {
969 if (sz
!= SHORT
&& sz
!= LONG
&& sz
!= QUAD
)
974 inconarg(hte
, call
, n
);
975 } else if (t2
!= styp(sz
)) {
976 inconarg(hte
, call
, n
);
977 } else if (hflag
&& t2
!= sz
) {
978 inconarg(hte
, call
, n
);
979 } else if (tp
->t_subt
->t_const
) {
980 inconarg(hte
, call
, n
);
983 } else if (fc
== 'o' || fc
== 'u' || fc
== 'x') {
988 } else if (sz
== LONG
) {
990 } else if (sz
== QUAD
) {
996 } else if (fc
== 'D') {
997 if (sz
!= NOTSPEC
|| !tflag
)
1001 } else if (fc
== 'O') {
1002 if (sz
!= NOTSPEC
|| !tflag
)
1006 } else if (fc
== 'X') {
1008 * XXX valid in ANSI C, but in NetBSD's libc imple-
1009 * mented as "lx". Thats why it should be avoided.
1011 if (sz
!= NOTSPEC
|| !tflag
)
1015 } else if (fc
== 'E') {
1017 * XXX valid in ANSI C, but in NetBSD's libc imple-
1018 * mented as "lf". Thats why it should be avoided.
1020 if (sz
!= NOTSPEC
|| !tflag
)
1024 } else if (fc
== 'F') {
1025 /* XXX only for backward compatibility */
1026 if (sz
!= NOTSPEC
|| !tflag
)
1030 } else if (fc
== 'G') {
1032 * XXX valid in ANSI C, but in NetBSD's libc not
1035 if (sz
!= NOTSPEC
&& sz
!= LONG
&& sz
!= LDOUBLE
)
1038 } else if (fc
== 'e' || fc
== 'f' || fc
== 'g') {
1040 if (sz
== NOTSPEC
) {
1042 } else if (sz
== LONG
) {
1044 } else if (sz
!= LDOUBLE
) {
1049 } else if (fc
== 's' || fc
== '[' || fc
== 'c') {
1053 if ((fc
= *fp
++) == '-') {
1065 inconarg(hte
, call
, n
);
1066 } else if (t2
!= CHAR
&& t2
!= UCHAR
&&
1068 inconarg(hte
, call
, n
);
1071 } else if (fc
== 'p') {
1075 if (t1
!= PTR
|| t2
!= PTR
) {
1076 inconarg(hte
, call
, n
);
1077 } else if (tp
->t_subt
->t_subt
->t_tspec
!=VOID
) {
1079 inconarg(hte
, call
, n
);
1092 badfmt(hte_t
*hte
, fcall_t
*call
)
1094 /* %s: malformed format string\t%s */
1095 msg(13, hte
->h_name
, mkpos(&call
->f_pos
));
1099 inconarg(hte_t
*hte
, fcall_t
*call
, int n
)
1101 /* %s, arg %d inconsistent with format\t%s(%d) */
1102 msg(14, hte
->h_name
, n
, mkpos(&call
->f_pos
));
1106 tofewarg(hte_t
*hte
, fcall_t
*call
)
1108 /* %s: too few args for format \t%s */
1109 msg(15, hte
->h_name
, mkpos(&call
->f_pos
));
1113 tomanyarg(hte_t
*hte
, fcall_t
*call
)
1115 /* %s: too many args for format \t%s */
1116 msg(16, hte
->h_name
, mkpos(&call
->f_pos
));
1121 * Print warnings for return values which are used, but not returned,
1122 * or return values which are always or sometimes ignored.
1125 chkrvu(hte_t
*hte
, sym_t
*def
)
1131 /* don't know wheter or not the functions returns a value */
1134 if (hte
->h_calls
== NULL
)
1138 /* function has return value */
1140 for (call
= hte
->h_calls
; call
!= NULL
; call
= call
->f_nxt
) {
1141 used
|= call
->f_rused
;
1142 ignored
|= !call
->f_rused
&& !call
->f_rdisc
;
1145 * XXX as soon as we are able to disable single warnings
1146 * the following dependencies from hflag should be removed.
1147 * but for now I do'nt want to be botherd by this warnings
1148 * which are almost always useless.
1150 if (!used
&& ignored
) {
1152 /* %s returns value which is always ignored */
1153 msg(8, hte
->h_name
);
1154 } else if (used
&& ignored
) {
1156 /* %s returns value which is sometimes ign. */
1157 msg(9, hte
->h_name
);
1160 /* function has no return value */
1161 for (call
= hte
->h_calls
; call
!= NULL
; call
= call
->f_nxt
) {
1163 /* %s value is used( %s ), but none ret. */
1164 msg(10, hte
->h_name
, mkpos(&call
->f_pos
));
1170 * Print warnings for inconsistent argument declarations.
1173 chkadecl(hte_t
*hte
, sym_t
*def
, sym_t
*decl
)
1175 /* LINTED (automatic hides external declaration: warn) */
1176 int osdef
, eq
, warn
, n
;
1178 type_t
**ap1
, **ap2
, *tp1
, *tp2
;
1184 osdef
= def
->s_osdef
;
1186 } else if (decl
!= NULL
&& TP(decl
->s_type
)->t_proto
) {
1191 if (TP(sym1
->s_type
)->t_tspec
!= FUNC
)
1195 * XXX Prototypes should also be compared with old style function
1199 for (sym
= hte
->h_syms
; sym
!= NULL
; sym
= sym
->s_nxt
) {
1200 if (sym
== sym1
|| !TP(sym
->s_type
)->t_proto
)
1202 ap1
= TP(sym1
->s_type
)->t_args
;
1203 ap2
= TP(sym
->s_type
)->t_args
;
1205 while (*ap1
!= NULL
&& *ap2
!= NULL
) {
1207 eq
= eqtype(*ap1
, *ap2
, 1, osdef
, 0, &warn
);
1209 pos1
= xstrdup(mkpos(&sym1
->s_pos
));
1210 pos2
= mkpos(&sym
->s_pos
);
1211 /* %s, arg %d declared inconsistently ... */
1212 msg(11, hte
->h_name
, n
+ 1, pos1
, pos2
);
1220 tp1
= TP(sym1
->s_type
);
1221 tp2
= TP(sym
->s_type
);
1222 if (tp1
->t_vararg
== tp2
->t_vararg
)
1224 if (tp2
->t_vararg
&&
1225 sym1
->s_va
&& sym1
->s_nva
== n
&& !sflag
) {
1229 /* %s: variable # of args declared\t%s :: %s */
1230 pos1
= xstrdup(mkpos(&sym1
->s_pos
));
1231 msg(12, hte
->h_name
, pos1
, mkpos(&sym
->s_pos
));
1238 * Check compatibility of two types. Returns 1 if types are compatible,
1241 * ignqual if set, ignore qualifiers of outhermost type; used for
1242 * function arguments
1243 * promote if set, promote left type before comparision; used for
1244 * comparisions of arguments with parameters of old style
1246 * asgn left indirected type must have at least the same qualifiers
1247 * like right indirected type (for assignments and function
1249 * *warn set to 1 if an old style declaration was compared with
1250 * an incompatible prototype declaration
1253 eqtype(type_t
*tp1
, type_t
*tp2
, int ignqual
, int promot
, int asgn
, int *warn
)
1261 while (tp1
!= NULL
&& tp2
!= NULL
) {
1267 } else if (t
== CHAR
|| t
== SCHAR
) {
1269 } else if (t
== UCHAR
) {
1270 t
= tflag
? UINT
: INT
;
1271 } else if (t
== SHORT
) {
1273 } else if (t
== USHORT
) {
1275 t
= INT_MAX
< USHRT_MAX
|| tflag
? UINT
: INT
;
1279 if (asgn
&& to
== PTR
) {
1280 if (indir
== 1 && (t
== VOID
|| tp2
->t_tspec
== VOID
))
1284 if (t
!= tp2
->t_tspec
) {
1286 * Give pointer to types which differ only in
1287 * signedness a chance if not sflag and not hflag.
1289 if (sflag
|| hflag
|| to
!= PTR
)
1291 if (styp(t
) != styp(tp2
->t_tspec
))
1295 if (tp1
->t_isenum
&& tp2
->t_isenum
) {
1296 if (tp1
->t_istag
&& tp2
->t_istag
) {
1297 return (tp1
->t_tag
== tp2
->t_tag
);
1298 } else if (tp1
->t_istynam
&& tp2
->t_istynam
) {
1299 return (tp1
->t_tynam
== tp2
->t_tynam
);
1306 * XXX Handle combinations of enum and int if eflag is set.
1307 * But note: enum and 0 should be allowed.
1310 if (asgn
&& indir
== 1) {
1311 if (!tp1
->t_const
&& tp2
->t_const
)
1313 if (!tp1
->t_volatile
&& tp2
->t_volatile
)
1315 } else if (!ignqual
&& !tflag
) {
1316 if (tp1
->t_const
!= tp2
->t_const
)
1318 if (tp1
->t_const
!= tp2
->t_const
)
1322 if (t
== STRUCT
|| t
== UNION
) {
1323 if (tp1
->t_istag
&& tp2
->t_istag
) {
1324 return (tp1
->t_tag
== tp2
->t_tag
);
1325 } else if (tp1
->t_istynam
&& tp2
->t_istynam
) {
1326 return (tp1
->t_tynam
== tp2
->t_tynam
);
1332 if (t
== ARRAY
&& tp1
->t_dim
!= tp2
->t_dim
) {
1333 if (tp1
->t_dim
!= 0 && tp2
->t_dim
!= 0)
1338 if (tp1
->t_proto
&& tp2
->t_proto
) {
1339 if (!eqargs(tp1
, tp2
, warn
))
1341 } else if (tp1
->t_proto
) {
1342 if (!mnoarg(tp1
, warn
))
1344 } else if (tp2
->t_proto
) {
1345 if (!mnoarg(tp2
, warn
))
1352 ignqual
= promot
= 0;
1358 return (tp1
== tp2
);
1362 * Compares arguments of two prototypes
1365 eqargs(type_t
*tp1
, type_t
*tp2
, int *warn
)
1369 if (tp1
->t_vararg
!= tp2
->t_vararg
)
1375 while (*a1
!= NULL
&& *a2
!= NULL
) {
1377 if (eqtype(*a1
, *a2
, 1, 0, 0, warn
) == 0)
1385 return (*a1
== *a2
);
1389 * mnoarg() (matches functions with no argument type information)
1390 * returns 1 if all parameters of a prototype are compatible with
1391 * and old style function declaration.
1392 * This is the case if following conditions are met:
1393 * 1. the prototype must have a fixed number of parameters
1394 * 2. no parameter is of type float
1395 * 3. no parameter is converted to another type if integer promotion
1399 mnoarg(type_t
*tp
, int *warn
)
1404 if (tp
->t_vararg
&& warn
!= NULL
)
1406 for (arg
= tp
->t_args
; *arg
!= NULL
; arg
++) {
1407 if ((t
= (*arg
)->t_tspec
) == FLOAT
)
1409 if (t
== CHAR
|| t
== SCHAR
|| t
== UCHAR
)
1411 if (t
== SHORT
|| t
== USHORT
)