OSDN Git Service

* stmt.c (cost_table): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / c-format.c
1 /* Check calls to formatted I/O functions (-Wformat).
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3    Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "tree.h"
25 #include "flags.h"
26 #include "toplev.h"
27 #include "c-common.h"
28 #include "intl.h"
29 #include "diagnostic.h"
30
31 \f
32 /* Command line options and their associated flags.  */
33
34 /* Warn about format/argument anomalies in calls to formatted I/O functions
35    (*printf, *scanf, strftime, strfmon, etc.).  */
36
37 int warn_format;
38
39 /* Warn about Y2K problems with strftime formats.  */
40
41 int warn_format_y2k;
42
43 /* Warn about excess arguments to formats.  */
44
45 int warn_format_extra_args;
46
47 /* Warn about non-literal format arguments.  */
48
49 int warn_format_nonliteral;
50
51 /* Warn about possible security problems with calls to format functions.  */
52
53 int warn_format_security;
54
55 /* Set format warning options according to a -Wformat=n option.  */
56
57 void
58 set_Wformat (setting)
59      int setting;
60 {
61   warn_format = setting;
62   warn_format_y2k = setting;
63   warn_format_extra_args = setting;
64   if (setting != 1)
65     {
66       warn_format_nonliteral = setting;
67       warn_format_security = setting;
68     }
69 }
70
71 \f
72 /* Handle attributes associated with format checking.  */
73
74 /* This must be in the same order as format_types, with format_type_error
75    last.  */
76 enum format_type { printf_format_type, scanf_format_type,
77                    strftime_format_type, strfmon_format_type,
78                    format_type_error };
79
80 static enum format_type decode_format_type      PARAMS ((const char *));
81 static void record_function_format      PARAMS ((tree, tree, enum format_type,
82                                                  int, int));
83 static void record_international_format PARAMS ((tree, tree, int));
84
85 /* Handle the format attribute (with arguments ARGS) attached to the decl
86    DECL.  It is already verified that DECL is a decl and ARGS contains
87    exactly three arguments.  */
88
89 void
90 decl_handle_format_attribute (decl, args)
91      tree decl, args;
92 {
93   tree type = TREE_TYPE (decl);
94   tree format_type_id = TREE_VALUE (args);
95   tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
96   tree first_arg_num_expr
97     = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
98   unsigned HOST_WIDE_INT format_num, first_arg_num;
99   enum format_type format_type;
100   tree argument;
101   unsigned int arg_num;
102
103   if (TREE_CODE (decl) != FUNCTION_DECL)
104     {
105       error_with_decl (decl,
106                        "argument format specified for non-function `%s'");
107       return;
108     }
109
110   if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
111     {
112       error ("unrecognized format specifier");
113       return;
114     }
115   else
116     {
117       const char *p = IDENTIFIER_POINTER (format_type_id);
118
119       format_type = decode_format_type (p);
120
121       if (format_type == format_type_error)
122         {
123           warning ("`%s' is an unrecognized format function type", p);
124           return;
125         }
126     }
127
128   /* Strip any conversions from the string index and first arg number
129      and verify they are constants.  */
130   while (TREE_CODE (format_num_expr) == NOP_EXPR
131          || TREE_CODE (format_num_expr) == CONVERT_EXPR
132          || TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
133     format_num_expr = TREE_OPERAND (format_num_expr, 0);
134
135   while (TREE_CODE (first_arg_num_expr) == NOP_EXPR
136          || TREE_CODE (first_arg_num_expr) == CONVERT_EXPR
137          || TREE_CODE (first_arg_num_expr) == NON_LVALUE_EXPR)
138     first_arg_num_expr = TREE_OPERAND (first_arg_num_expr, 0);
139
140   if (TREE_CODE (format_num_expr) != INTEGER_CST
141       || TREE_INT_CST_HIGH (format_num_expr) != 0
142       || TREE_CODE (first_arg_num_expr) != INTEGER_CST
143       || TREE_INT_CST_HIGH (first_arg_num_expr) != 0)
144     {
145       error ("format string has invalid operand number");
146       return;
147     }
148
149   format_num = TREE_INT_CST_LOW (format_num_expr);
150   first_arg_num = TREE_INT_CST_LOW (first_arg_num_expr);
151   if (first_arg_num != 0 && first_arg_num <= format_num)
152     {
153       error ("format string arg follows the args to be formatted");
154       return;
155     }
156
157   /* If a parameter list is specified, verify that the format_num
158      argument is actually a string, in case the format attribute
159      is in error.  */
160   argument = TYPE_ARG_TYPES (type);
161   if (argument)
162     {
163       for (arg_num = 1; argument != 0 && arg_num != format_num;
164            ++arg_num, argument = TREE_CHAIN (argument))
165         ;
166
167       if (! argument
168           || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
169           || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
170               != char_type_node))
171         {
172           error ("format string arg not a string type");
173           return;
174         }
175
176       else if (first_arg_num != 0)
177         {
178           /* Verify that first_arg_num points to the last arg,
179              the ...  */
180           while (argument)
181             arg_num++, argument = TREE_CHAIN (argument);
182
183           if (arg_num != first_arg_num)
184             {
185               error ("args to be formatted is not '...'");
186               return;
187             }
188         }
189     }
190
191   if (format_type == strftime_format_type && first_arg_num != 0)
192     {
193       error ("strftime formats cannot format arguments");
194       return;
195     }
196
197   record_function_format (DECL_NAME (decl), DECL_ASSEMBLER_NAME (decl),
198                           format_type, format_num, first_arg_num);
199 }
200
201
202 /* Handle the format_arg attribute (with arguments ARGS) attached to
203    the decl DECL.  It is already verified that DECL is a decl and
204    ARGS contains exactly one argument.  */
205
206 void
207 decl_handle_format_arg_attribute (decl, args)
208      tree decl, args;
209 {
210   tree type = TREE_TYPE (decl);
211   tree format_num_expr = TREE_VALUE (args);
212   unsigned HOST_WIDE_INT format_num;
213   unsigned int arg_num;
214   tree argument;
215
216   if (TREE_CODE (decl) != FUNCTION_DECL)
217     {
218       error_with_decl (decl,
219                        "argument format specified for non-function `%s'");
220       return;
221     }
222
223   /* Strip any conversions from the first arg number and verify it
224      is a constant.  */
225   while (TREE_CODE (format_num_expr) == NOP_EXPR
226          || TREE_CODE (format_num_expr) == CONVERT_EXPR
227          || TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
228     format_num_expr = TREE_OPERAND (format_num_expr, 0);
229
230   if (TREE_CODE (format_num_expr) != INTEGER_CST
231       || TREE_INT_CST_HIGH (format_num_expr) != 0)
232     {
233       error ("format string has invalid operand number");
234       return;
235     }
236
237   format_num = TREE_INT_CST_LOW (format_num_expr);
238
239   /* If a parameter list is specified, verify that the format_num
240      argument is actually a string, in case the format attribute
241      is in error.  */
242   argument = TYPE_ARG_TYPES (type);
243   if (argument)
244     {
245       for (arg_num = 1; argument != 0 && arg_num != format_num;
246            ++arg_num, argument = TREE_CHAIN (argument))
247         ;
248
249       if (! argument
250           || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
251           || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
252               != char_type_node))
253         {
254           error ("format string arg not a string type");
255           return;
256         }
257     }
258
259   if (TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) != POINTER_TYPE
260       || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_TYPE (decl))))
261           != char_type_node))
262     {
263       error ("function does not return string type");
264       return;
265     }
266
267   record_international_format (DECL_NAME (decl), DECL_ASSEMBLER_NAME (decl),
268                                format_num);
269 }
270
271 typedef struct function_format_info
272 {
273   struct function_format_info *next;  /* next structure on the list */
274   tree name;                    /* identifier such as "printf" */
275   tree assembler_name;          /* optional mangled identifier (for C++) */
276   enum format_type format_type; /* type of format (printf, scanf, etc.) */
277   int format_num;               /* number of format argument */
278   int first_arg_num;            /* number of first arg (zero for varargs) */
279 } function_format_info;
280
281 static function_format_info *function_format_list = NULL;
282
283 typedef struct international_format_info
284 {
285   struct international_format_info *next;  /* next structure on the list */
286   tree name;                    /* identifier such as "gettext" */
287   tree assembler_name;          /* optional mangled identifier (for C++) */
288   int format_num;               /* number of format argument */
289 } international_format_info;
290
291 static international_format_info *international_format_list = NULL;
292
293 /* Initialize the table of functions to perform format checking on.
294    The ISO C functions are always checked (whether <stdio.h> is
295    included or not), since it is common to call printf without
296    including <stdio.h>.  There shouldn't be a problem with this,
297    since ISO C reserves these function names whether you include the
298    header file or not.  In any case, the checking is harmless.  With
299    -ffreestanding, these default attributes are disabled, and must be
300    specified manually if desired.
301
302    Also initialize the name of function that modify the format string for
303    internationalization purposes.  */
304
305 void
306 init_function_format_info ()
307 {
308   if (flag_hosted)
309     {
310       /* Functions from ISO/IEC 9899:1990.  */
311       record_function_format (get_identifier ("printf"), NULL_TREE,
312                               printf_format_type, 1, 2);
313       record_function_format (get_identifier ("__builtin_printf"), NULL_TREE,
314                               printf_format_type, 1, 2);
315       record_function_format (get_identifier ("fprintf"), NULL_TREE,
316                               printf_format_type, 2, 3);
317       record_function_format (get_identifier ("__builtin_fprintf"), NULL_TREE,
318                               printf_format_type, 2, 3);
319       record_function_format (get_identifier ("sprintf"), NULL_TREE,
320                               printf_format_type, 2, 3);
321       record_function_format (get_identifier ("scanf"), NULL_TREE,
322                               scanf_format_type, 1, 2);
323       record_function_format (get_identifier ("fscanf"), NULL_TREE,
324                               scanf_format_type, 2, 3);
325       record_function_format (get_identifier ("sscanf"), NULL_TREE,
326                               scanf_format_type, 2, 3);
327       record_function_format (get_identifier ("vprintf"), NULL_TREE,
328                               printf_format_type, 1, 0);
329       record_function_format (get_identifier ("vfprintf"), NULL_TREE,
330                               printf_format_type, 2, 0);
331       record_function_format (get_identifier ("vsprintf"), NULL_TREE,
332                               printf_format_type, 2, 0);
333       record_function_format (get_identifier ("strftime"), NULL_TREE,
334                               strftime_format_type, 3, 0);
335     }
336
337   if (flag_hosted && flag_isoc99)
338     {
339       /* ISO C99 adds the snprintf and vscanf family functions.  */
340       record_function_format (get_identifier ("snprintf"), NULL_TREE,
341                               printf_format_type, 3, 4);
342       record_function_format (get_identifier ("vsnprintf"), NULL_TREE,
343                               printf_format_type, 3, 0);
344       record_function_format (get_identifier ("vscanf"), NULL_TREE,
345                               scanf_format_type, 1, 0);
346       record_function_format (get_identifier ("vfscanf"), NULL_TREE,
347                               scanf_format_type, 2, 0);
348       record_function_format (get_identifier ("vsscanf"), NULL_TREE,
349                               scanf_format_type, 2, 0);
350     }
351
352   if (flag_hosted && flag_noniso_default_format_attributes)
353     {
354       /* Uniforum/GNU gettext functions, not in ISO C.  */
355       record_international_format (get_identifier ("gettext"), NULL_TREE, 1);
356       record_international_format (get_identifier ("dgettext"), NULL_TREE, 2);
357       record_international_format (get_identifier ("dcgettext"), NULL_TREE, 2);
358       /* X/Open strfmon function.  */
359       record_function_format (get_identifier ("strfmon"), NULL_TREE,
360                               strfmon_format_type, 3, 4);
361     }
362 }
363
364 /* Record information for argument format checking.  FUNCTION_IDENT is
365    the identifier node for the name of the function to check (its decl
366    need not exist yet).
367    FORMAT_TYPE specifies the type of format checking.  FORMAT_NUM is the number
368    of the argument which is the format control string (starting from 1).
369    FIRST_ARG_NUM is the number of the first actual argument to check
370    against the format string, or zero if no checking is not be done
371    (e.g. for varargs such as vfprintf).  */
372
373 static void
374 record_function_format (name, assembler_name, format_type,
375                         format_num, first_arg_num)
376       tree name;
377       tree assembler_name;
378       enum format_type format_type;
379       int format_num;
380       int first_arg_num;
381 {
382   function_format_info *info;
383
384   /* Re-use existing structure if it's there.  */
385
386   for (info = function_format_list; info; info = info->next)
387     {
388       if (info->name == name && info->assembler_name == assembler_name)
389         break;
390     }
391   if (! info)
392     {
393       info = (function_format_info *) xmalloc (sizeof (function_format_info));
394       info->next = function_format_list;
395       function_format_list = info;
396
397       info->name = name;
398       info->assembler_name = assembler_name;
399     }
400
401   info->format_type = format_type;
402   info->format_num = format_num;
403   info->first_arg_num = first_arg_num;
404 }
405
406 /* Record information for the names of function that modify the format
407    argument to format functions.  FUNCTION_IDENT is the identifier node for
408    the name of the function (its decl need not exist yet) and FORMAT_NUM is
409    the number of the argument which is the format control string (starting
410    from 1).  */
411
412 static void
413 record_international_format (name, assembler_name, format_num)
414       tree name;
415       tree assembler_name;
416       int format_num;
417 {
418   international_format_info *info;
419
420   /* Re-use existing structure if it's there.  */
421
422   for (info = international_format_list; info; info = info->next)
423     {
424       if (info->name == name && info->assembler_name == assembler_name)
425         break;
426     }
427
428   if (! info)
429     {
430       info
431         = (international_format_info *)
432           xmalloc (sizeof (international_format_info));
433       info->next = international_format_list;
434       international_format_list = info;
435
436       info->name = name;
437       info->assembler_name = assembler_name;
438     }
439
440   info->format_num = format_num;
441 }
442
443
444
445 \f
446 /* Check a call to a format function against a parameter list.  */
447
448 /* The meaningfully distinct length modifiers for format checking recognised
449    by GCC.  */
450 enum format_lengths
451 {
452   FMT_LEN_none,
453   FMT_LEN_hh,
454   FMT_LEN_h,
455   FMT_LEN_l,
456   FMT_LEN_ll,
457   FMT_LEN_L,
458   FMT_LEN_z,
459   FMT_LEN_t,
460   FMT_LEN_j,
461   FMT_LEN_MAX
462 };
463
464
465 /* The standard versions in which various format features appeared.  */
466 enum format_std_version
467 {
468   STD_C89,
469   STD_C94,
470   STD_C9L, /* C99, but treat as C89 if -Wno-long-long.  */
471   STD_C99,
472   STD_EXT
473 };
474
475 /* The C standard version C++ is treated as equivalent to
476    or inheriting from, for the purpose of format features supported.  */
477 #define CPLUSPLUS_STD_VER       STD_C89
478 /* The C standard version we are checking formats against when pedantic.  */
479 #define C_STD_VER               (c_language == clk_cplusplus              \
480                                  ? CPLUSPLUS_STD_VER                      \
481                                  : (flag_isoc99                           \
482                                     ? STD_C99                             \
483                                     : (flag_isoc94 ? STD_C94 : STD_C89)))
484 /* The name to give to the standard version we are warning about when
485    pedantic.  FEATURE_VER is the version in which the feature warned out
486    appeared, which is higher than C_STD_VER.  */
487 #define C_STD_NAME(FEATURE_VER) (c_language == clk_cplusplus    \
488                                  ? "ISO C++"                    \
489                                  : ((FEATURE_VER) == STD_EXT    \
490                                     ? "ISO C"                   \
491                                     : "ISO C89"))
492 /* Adjust a C standard version, which may be STD_C9L, to account for
493    -Wno-long-long.  Returns other standard versions unchanged.  */
494 #define ADJ_STD(VER)            ((int)((VER) == STD_C9L                       \
495                                        ? (warn_long_long ? STD_C99 : STD_C89) \
496                                        : (VER)))
497
498 /* Flags that may apply to a particular kind of format checked by GCC.  */
499 enum
500 {
501   /* This format converts arguments of types determined by the
502      format string.  */
503   FMT_FLAG_ARG_CONVERT = 1,
504   /* The scanf allocation 'a' kludge applies to this format kind.  */
505   FMT_FLAG_SCANF_A_KLUDGE = 2,
506   /* A % during parsing a specifier is allowed to be a modified % rather
507      that indicating the format is broken and we are out-of-sync.  */
508   FMT_FLAG_FANCY_PERCENT_OK = 4,
509   /* With $ operand numbers, it is OK to reference the same argument more
510      than once.  */
511   FMT_FLAG_DOLLAR_MULTIPLE = 8,
512   /* This format type uses $ operand numbers (strfmon doesn't).  */
513   FMT_FLAG_USE_DOLLAR = 16,
514   /* Zero width is bad in this type of format (scanf).  */
515   FMT_FLAG_ZERO_WIDTH_BAD = 32,
516   /* Empty precision specification is OK in this type of format (printf).  */
517   FMT_FLAG_EMPTY_PREC_OK = 64
518   /* Not included here: details of whether width or precision may occur
519      (controlled by width_char and precision_char); details of whether
520      '*' can be used for these (width_type and precision_type); details
521      of whether length modifiers can occur (length_char_specs).  */
522 };
523
524
525 /* Structure describing a length modifier supported in format checking, and
526    possibly a doubled version such as "hh".  */
527 typedef struct
528 {
529   /* Name of the single-character length modifier.  */
530   const char *name;
531   /* Index into a format_char_info.types array.  */
532   enum format_lengths index;
533   /* Standard version this length appears in.  */
534   enum format_std_version std;
535   /* Same, if the modifier can be repeated, or NULL if it can't.  */
536   const char *double_name;
537   enum format_lengths double_index;
538   enum format_std_version double_std;
539 } format_length_info;
540
541
542 /* Structure desribing the combination of a conversion specifier
543    (or a set of specifiers which act identically) and a length modifier.  */
544 typedef struct
545 {
546   /* The standard version this combination of length and type appeared in.
547      This is only relevant if greater than those for length and type
548      individually; otherwise it is ignored.  */
549   enum format_std_version std;
550   /* The name to use for the type, if different from that generated internally
551      (e.g., "signed size_t").  */
552   const char *name;
553   /* The type itself.  */
554   tree *type;
555 } format_type_detail;
556
557
558 /* Macros to fill out tables of these.  */
559 #define BADLEN  { 0, NULL, NULL }
560 #define NOLENGTHS       { BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }
561
562
563 /* Structure desribing a format conversion specifier (or a set of specifiers
564    which act identically), and the length modifiers used with it.  */
565 typedef struct
566 {
567   const char *format_chars;
568   int pointer_count;
569   enum format_std_version std;
570   /* Types accepted for each length modifier.  */
571   format_type_detail types[FMT_LEN_MAX];
572   /* List of other modifier characters allowed with these specifiers.
573      This lists flags, and additionally "w" for width, "p" for precision
574      (right precision, for strfmon), "#" for left precision (strfmon),
575      "a" for scanf "a" allocation extension (not applicable in C99 mode),
576      "*" for scanf suppression, and "E" and "O" for those strftime
577      modifiers.  */
578   const char *flag_chars;
579   /* List of additional flags describing these conversion specifiers.
580      "c" for generic character pointers being allowed, "2" for strftime
581      two digit year formats, "3" for strftime formats giving two digit
582      years in some locales, "4" for "2" which becomes "3" with an "E" modifier,
583      "o" if use of strftime "O" is a GNU extension beyond C99,
584      "W" if the argument is a pointer which is dereferenced and written into,
585      "R" if the argument is a pointer which is dereferenced and read from,
586      "i" for printf integer formats where the '0' flag is ignored with
587      precision, and "[" for the starting character of a scanf scanset.  */
588   const char *flags2;
589 } format_char_info;
590
591
592 /* Structure describing a flag accepted by some kind of format.  */
593 typedef struct
594 {
595   /* The flag character in question (0 for end of array).  */
596   int flag_char;
597   /* Zero if this entry describes the flag character in general, or a
598      non-zero character that may be found in flags2 if it describes the
599      flag when used with certain formats only.  If the latter, only
600      the first such entry found that applies to the current conversion
601      specifier is used; the values of `name' and `long_name' it supplies
602      will be used, if non-NULL and the standard version is higher than
603      the unpredicated one, for any pedantic warning.  For example, 'o'
604      for strftime formats (meaning 'O' is an extension over C99).  */
605   int predicate;
606   /* Nonzero if the next character after this flag in the format should
607      be skipped ('=' in strfmon), zero otherwise.  */
608   int skip_next_char;
609   /* The name to use for this flag in diagnostic messages.  For example,
610      N_("`0' flag"), N_("field width").  */
611   const char *name;
612   /* Long name for this flag in diagnostic messages; currently only used for
613      "ISO C does not support ...".  For example, N_("the `I' printf flag").  */
614   const char *long_name;
615   /* The standard version in which it appeared.  */
616   enum format_std_version std;
617 } format_flag_spec;
618
619
620 /* Structure describing a combination of flags that is bad for some kind
621    of format.  */
622 typedef struct
623 {
624   /* The first flag character in question (0 for end of array).  */
625   int flag_char1;
626   /* The second flag character.  */
627   int flag_char2;
628   /* Non-zero if the message should say that the first flag is ignored with
629      the second, zero if the combination should simply be objected to.  */
630   int ignored;
631   /* Zero if this entry applies whenever this flag combination occurs,
632      a non-zero character from flags2 if it only applies in some
633      circumstances (e.g. 'i' for printf formats ignoring 0 with precision).  */
634   int predicate;
635 } format_flag_pair;
636
637
638 /* Structure describing a particular kind of format processed by GCC.  */
639 typedef struct
640 {
641   /* The name of this kind of format, for use in diagnostics.  Also
642      the name of the attribute (without preceding and following __).  */
643   const char *name;
644   /* Specifications of the length modifiers accepted; possibly NULL.  */
645   const format_length_info *length_char_specs;
646   /* Details of the conversion specification characters accepted.  */
647   const format_char_info *conversion_specs;
648   /* String listing the flag characters that are accepted.  */
649   const char *flag_chars;
650   /* String listing modifier characters (strftime) accepted.  May be NULL.  */
651   const char *modifier_chars;
652   /* Details of the flag characters, including pseudo-flags.  */
653   const format_flag_spec *flag_specs;
654   /* Details of bad combinations of flags.  */
655   const format_flag_pair *bad_flag_pairs;
656   /* Flags applicable to this kind of format.  */
657   int flags;
658   /* Flag character to treat a width as, or 0 if width not used.  */
659   int width_char;
660   /* Flag character to treat a left precision (strfmon) as,
661      or 0 if left precision not used.  */
662   int left_precision_char;
663   /* Flag character to treat a precision (for strfmon, right precision) as,
664      or 0 if precision not used.  */
665   int precision_char;
666   /* If a flag character has the effect of suppressing the conversion of
667      an argument ('*' in scanf), that flag character, otherwise 0.  */
668   int suppression_char;
669   /* Flag character to treat a length modifier as (ignored if length
670      modifiers not used).  Need not be placed in flag_chars for conversion
671      specifiers, but is used to check for bad combinations such as length
672      modifier with assignment suppression in scanf.  */
673   int length_code_char;
674   /* Pointer to type of argument expected if '*' is used for a width,
675      or NULL if '*' not used for widths.  */
676   tree *width_type;
677   /* Pointer to type of argument expected if '*' is used for a precision,
678      or NULL if '*' not used for precisions.  */
679   tree *precision_type;
680 } format_kind_info;
681
682
683 /* Structure describing details of a type expected in format checking,
684    and the type to check against it.  */
685 typedef struct format_wanted_type
686 {
687   /* The type wanted.  */
688   tree wanted_type;
689   /* The name of this type to use in diagnostics.  */
690   const char *wanted_type_name;
691   /* The level of indirection through pointers at which this type occurs.  */
692   int pointer_count;
693   /* Whether, when pointer_count is 1, to allow any character type when
694      pedantic, rather than just the character or void type specified.  */
695   int char_lenient_flag;
696   /* Whether the argument, dereferenced once, is written into and so the
697      argument must not be a pointer to a const-qualified type.  */
698   int writing_in_flag;
699   /* Whether the argument, dereferenced once, is read from and so
700      must not be a NULL pointer.  */
701   int reading_from_flag;
702   /* If warnings should be of the form "field precision is not type int",
703      the name to use (in this case "field precision"), otherwise NULL,
704      for "%s format, %s arg" type messages.  If (in an extension), this
705      is a pointer type, wanted_type_name should be set to include the
706      terminating '*' characters of the type name to give a correct
707      message.  */
708   const char *name;
709   /* The actual parameter to check against the wanted type.  */
710   tree param;
711   /* The argument number of that parameter.  */
712   int arg_num;
713   /* The next type to check for this format conversion, or NULL if none.  */
714   struct format_wanted_type *next;
715 } format_wanted_type;
716
717
718 static const format_length_info printf_length_specs[] =
719 {
720   { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
721   { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
722   { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
723   { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
724   { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
725   { "Z", FMT_LEN_z, STD_EXT, NULL, 0, 0 },
726   { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
727   { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
728   { NULL, 0, 0, NULL, 0, 0 }
729 };
730
731
732 /* This differs from printf_length_specs only in that "Z" is not accepted.  */
733 static const format_length_info scanf_length_specs[] =
734 {
735   { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
736   { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
737   { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
738   { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
739   { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
740   { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
741   { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
742   { NULL, 0, 0, NULL, 0, 0 }
743 };
744
745
746 /* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings
747    make no sense for a format type not part of any C standard version.  */
748 static const format_length_info strfmon_length_specs[] =
749 {
750   /* A GNU extension.  */
751   { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
752   { NULL, 0, 0, NULL, 0, 0 }
753 };
754
755 static const format_flag_spec printf_flag_specs[] =
756 {
757   { ' ',  0, 0, N_("` ' flag"),        N_("the ` ' printf flag"),              STD_C89 },
758   { '+',  0, 0, N_("`+' flag"),        N_("the `+' printf flag"),              STD_C89 },
759   { '#',  0, 0, N_("`#' flag"),        N_("the `#' printf flag"),              STD_C89 },
760   { '0',  0, 0, N_("`0' flag"),        N_("the `0' printf flag"),              STD_C89 },
761   { '-',  0, 0, N_("`-' flag"),        N_("the `-' printf flag"),              STD_C89 },
762   { '\'', 0, 0, N_("`'' flag"),        N_("the `'' printf flag"),              STD_EXT },
763   { 'I',  0, 0, N_("`I' flag"),        N_("the `I' printf flag"),              STD_EXT },
764   { 'w',  0, 0, N_("field width"),     N_("field width in printf format"),     STD_C89 },
765   { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
766   { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
767   { 0, 0, 0, NULL, NULL, 0 }
768 };
769
770
771 static const format_flag_pair printf_flag_pairs[] =
772 {
773   { ' ', '+', 1, 0   },
774   { '0', '-', 1, 0   },
775   { '0', 'p', 1, 'i' },
776   { 0, 0, 0, 0 }
777 };
778
779
780 static const format_flag_spec scanf_flag_specs[] =
781 {
782   { '*',  0, 0, N_("assignment suppression"), N_("assignment suppression"),          STD_C89 },
783   { 'a',  0, 0, N_("`a' flag"),               N_("the `a' scanf flag"),              STD_EXT },
784   { 'w',  0, 0, N_("field width"),            N_("field width in scanf format"),     STD_C89 },
785   { 'L',  0, 0, N_("length modifier"),        N_("length modifier in scanf format"), STD_C89 },
786   { '\'', 0, 0, N_("`'' flag"),               N_("the `'' scanf flag"),              STD_EXT },
787   { 'I',  0, 0, N_("`I' flag"),               N_("the `I' scanf flag"),              STD_EXT },
788   { 0, 0, 0, NULL, NULL, 0 }
789 };
790
791
792 static const format_flag_pair scanf_flag_pairs[] =
793 {
794   { '*', 'L', 0, 0 },
795   { 0, 0, 0, 0 }
796 };
797
798
799 static const format_flag_spec strftime_flag_specs[] =
800 {
801   { '_', 0,   0, N_("`_' flag"),     N_("the `_' strftime flag"),          STD_EXT },
802   { '-', 0,   0, N_("`-' flag"),     N_("the `-' strftime flag"),          STD_EXT },
803   { '0', 0,   0, N_("`0' flag"),     N_("the `0' strftime flag"),          STD_EXT },
804   { '^', 0,   0, N_("`^' flag"),     N_("the `^' strftime flag"),          STD_EXT },
805   { '#', 0,   0, N_("`#' flag"),     N_("the `#' strftime flag"),          STD_EXT },
806   { 'w', 0,   0, N_("field width"),  N_("field width in strftime format"), STD_EXT },
807   { 'E', 0,   0, N_("`E' modifier"), N_("the `E' strftime modifier"),      STD_C99 },
808   { 'O', 0,   0, N_("`O' modifier"), N_("the `O' strftime modifier"),      STD_C99 },
809   { 'O', 'o', 0, NULL,               N_("the `O' modifier"),               STD_EXT },
810   { 0, 0, 0, NULL, NULL, 0 }
811 };
812
813
814 static const format_flag_pair strftime_flag_pairs[] =
815 {
816   { 'E', 'O', 0, 0 },
817   { '_', '-', 0, 0 },
818   { '_', '0', 0, 0 },
819   { '-', '0', 0, 0 },
820   { '^', '#', 0, 0 },
821   { 0, 0, 0, 0 }
822 };
823
824
825 static const format_flag_spec strfmon_flag_specs[] =
826 {
827   { '=',  0, 1, N_("fill character"),  N_("fill character in strfmon format"),  STD_C89 },
828   { '^',  0, 0, N_("`^' flag"),        N_("the `^' strfmon flag"),              STD_C89 },
829   { '+',  0, 0, N_("`+' flag"),        N_("the `+' strfmon flag"),              STD_C89 },
830   { '(',  0, 0, N_("`(' flag"),        N_("the `(' strfmon flag"),              STD_C89 },
831   { '!',  0, 0, N_("`!' flag"),        N_("the `!' strfmon flag"),              STD_C89 },
832   { '-',  0, 0, N_("`-' flag"),        N_("the `-' strfmon flag"),              STD_C89 },
833   { 'w',  0, 0, N_("field width"),     N_("field width in strfmon format"),     STD_C89 },
834   { '#',  0, 0, N_("left precision"),  N_("left precision in strfmon format"),  STD_C89 },
835   { 'p',  0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
836   { 'L',  0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 },
837   { 0, 0, 0, NULL, NULL, 0 }
838 };
839
840 static const format_flag_pair strfmon_flag_pairs[] =
841 {
842   { '+', '(', 0, 0 },
843   { 0, 0, 0, 0 }
844 };
845
846
847 #define T_I     &integer_type_node
848 #define T89_I   { STD_C89, NULL, T_I }
849 #define T99_I   { STD_C99, NULL, T_I }
850 #define T_L     &long_integer_type_node
851 #define T89_L   { STD_C89, NULL, T_L }
852 #define T_LL    &long_long_integer_type_node
853 #define T9L_LL  { STD_C9L, NULL, T_LL }
854 #define TEX_LL  { STD_EXT, NULL, T_LL }
855 #define T_S     &short_integer_type_node
856 #define T89_S   { STD_C89, NULL, T_S }
857 #define T_UI    &unsigned_type_node
858 #define T89_UI  { STD_C89, NULL, T_UI }
859 #define T99_UI  { STD_C99, NULL, T_UI }
860 #define T_UL    &long_unsigned_type_node
861 #define T89_UL  { STD_C89, NULL, T_UL }
862 #define T_ULL   &long_long_unsigned_type_node
863 #define T9L_ULL { STD_C9L, NULL, T_ULL }
864 #define TEX_ULL { STD_EXT, NULL, T_ULL }
865 #define T_US    &short_unsigned_type_node
866 #define T89_US  { STD_C89, NULL, T_US }
867 #define T_F     &float_type_node
868 #define T89_F   { STD_C89, NULL, T_F }
869 #define T99_F   { STD_C99, NULL, T_F }
870 #define T_D     &double_type_node
871 #define T89_D   { STD_C89, NULL, T_D }
872 #define T99_D   { STD_C99, NULL, T_D }
873 #define T_LD    &long_double_type_node
874 #define T89_LD  { STD_C89, NULL, T_LD }
875 #define T99_LD  { STD_C99, NULL, T_LD }
876 #define T_C     &char_type_node
877 #define T89_C   { STD_C89, NULL, T_C }
878 #define T_SC    &signed_char_type_node
879 #define T99_SC  { STD_C99, NULL, T_SC }
880 #define T_UC    &unsigned_char_type_node
881 #define T99_UC  { STD_C99, NULL, T_UC }
882 #define T_V     &void_type_node
883 #define T89_V   { STD_C89, NULL, T_V }
884 #define T_W     &wchar_type_node
885 #define T94_W   { STD_C94, "wchar_t", T_W }
886 #define TEX_W   { STD_EXT, "wchar_t", T_W }
887 #define T_WI    &wint_type_node
888 #define T94_WI  { STD_C94, "wint_t", T_WI }
889 #define TEX_WI  { STD_EXT, "wint_t", T_WI }
890 #define T_ST    &c_size_type_node
891 #define T99_ST  { STD_C99, "size_t", T_ST }
892 #define T_SST   &signed_size_type_node
893 #define T99_SST { STD_C99, "signed size_t", T_SST }
894 #define T_PD    &ptrdiff_type_node
895 #define T99_PD  { STD_C99, "ptrdiff_t", T_PD }
896 #define T_UPD   &unsigned_ptrdiff_type_node
897 #define T99_UPD { STD_C99, "unsigned ptrdiff_t", T_UPD }
898 #define T_IM    &intmax_type_node
899 #define T99_IM  { STD_C99, "intmax_t", T_IM }
900 #define T_UIM   &uintmax_type_node
901 #define T99_UIM { STD_C99, "uintmax_t", T_UIM }
902
903 static const format_char_info print_char_table[] =
904 {
905   /* C89 conversion specifiers.  */
906   { "di",  0, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  TEX_LL,  T99_SST, T99_PD,  T99_IM  }, "-wp0 +'I", "i"  },
907   { "oxX", 0, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "-wp0#",    "i"  },
908   { "u",   0, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "-wp0'I",   "i"  },
909   { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#'", ""   },
910   { "eE",  0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#",  ""   },
911   { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T94_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",       ""   },
912   { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",      "cR" },
913   { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",       "c"  },
914   { "n",   1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM  }, "",         "W"  },
915   /* C99 conversion specifiers.  */
916   { "F",   0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#'", ""   },
917   { "aA",  0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#",  ""   },
918   /* X/Open conversion specifiers.  */
919   { "C",   0, STD_EXT, { TEX_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",       ""   },
920   { "S",   1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",      "R"  },
921   /* GNU conversion specifiers.  */
922   { "m",   0, STD_EXT, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",      ""   },
923   { NULL,  0, 0, NOLENGTHS, NULL, NULL }
924 };
925
926 static const format_char_info scan_char_table[] =
927 {
928   /* C89 conversion specifiers.  */
929   { "di",    1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  TEX_LL,  T99_SST, T99_PD,  T99_IM  }, "*w'I", "W"   },
930   { "u",     1, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "*w'I", "W"   },
931   { "oxX",   1, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "*w",   "W"   },
932   { "efgEG", 1, STD_C89, { T89_F,   BADLEN,  BADLEN,  T89_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W"   },
933   { "c",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "cW"  },
934   { "s",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW"  },
935   { "[",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW[" },
936   { "p",     2, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W"   },
937   { "n",     1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM  }, "",     "W"   },
938   /* C99 conversion specifiers.  */
939   { "FaA",   1, STD_C99, { T99_F,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W"   },
940   /* X/Open conversion specifiers.  */
941   { "C",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W"   },
942   { "S",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "W"   },
943   { NULL, 0, 0, NOLENGTHS, NULL, NULL }
944 };
945
946 static const format_char_info time_char_table[] =
947 {
948   /* C89 conversion specifiers.  */
949   { "ABZab",            0, STD_C89, NOLENGTHS, "^#",     ""   },
950   { "cx",               0, STD_C89, NOLENGTHS, "E",      "3"  },
951   { "HIMSUWdmw",        0, STD_C89, NOLENGTHS, "-_0Ow",  ""   },
952   { "j",                0, STD_C89, NOLENGTHS, "-_0Ow",  "o"  },
953   { "p",                0, STD_C89, NOLENGTHS, "#",      ""   },
954   { "X",                0, STD_C89, NOLENGTHS, "E",      ""   },
955   { "y",                0, STD_C89, NOLENGTHS, "EO-_0w", "4"  },
956   { "Y",                0, STD_C89, NOLENGTHS, "-_0EOw", "o"  },
957   { "%",                0, STD_C89, NOLENGTHS, "",       ""   },
958   /* C99 conversion specifiers.  */
959   { "C",                0, STD_C99, NOLENGTHS, "-_0EOw", "o"  },
960   { "D",                0, STD_C99, NOLENGTHS, "",       "2"  },
961   { "eVu",              0, STD_C99, NOLENGTHS, "-_0Ow",  ""   },
962   { "FRTnrt",           0, STD_C99, NOLENGTHS, "",       ""   },
963   { "g",                0, STD_C99, NOLENGTHS, "O-_0w",  "2o" },
964   { "G",                0, STD_C99, NOLENGTHS, "-_0Ow",  "o"  },
965   { "h",                0, STD_C99, NOLENGTHS, "^#",     ""   },
966   { "z",                0, STD_C99, NOLENGTHS, "O",      "o"  },
967   /* GNU conversion specifiers.  */
968   { "kls",              0, STD_EXT, NOLENGTHS, "-_0Ow",  ""   },
969   { "P",                0, STD_EXT, NOLENGTHS, "",       ""   },
970   { NULL,               0, 0, NOLENGTHS, NULL, NULL }
971 };
972
973 static const format_char_info monetary_char_table[] =
974 {
975   { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "" },
976   { NULL, 0, 0, NOLENGTHS, NULL, NULL }
977 };
978
979
980 /* This must be in the same order as enum format_type.  */
981 static const format_kind_info format_types[] =
982 {
983   { "printf",   printf_length_specs,  print_char_table, " +#0-'I", NULL, 
984     printf_flag_specs, printf_flag_pairs,
985     FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
986     'w', 0, 'p', 0, 'L',
987     &integer_type_node, &integer_type_node
988   },
989   { "scanf",    scanf_length_specs,   scan_char_table,  "*'I", NULL, 
990     scanf_flag_specs, scanf_flag_pairs,
991     FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD,
992     'w', 0, 0, '*', 'L',
993     NULL, NULL
994   },
995   { "strftime", NULL,                 time_char_table,  "_-0^#", "EO",
996     strftime_flag_specs, strftime_flag_pairs,
997     FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0,
998     NULL, NULL
999   },
1000   { "strfmon",  strfmon_length_specs, monetary_char_table, "=^+(!-", NULL, 
1001     strfmon_flag_specs, strfmon_flag_pairs,
1002     FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L',
1003     NULL, NULL
1004   }
1005 };
1006
1007
1008 /* Structure detailing the results of checking a format function call
1009    where the format expression may be a conditional expression with
1010    many leaves resulting from nested conditional expressions.  */
1011 typedef struct
1012 {
1013   /* Number of leaves of the format argument that could not be checked
1014      as they were not string literals.  */
1015   int number_non_literal;
1016   /* Number of leaves of the format argument that were null pointers or
1017      string literals, but had extra format arguments.  */
1018   int number_extra_args;
1019   /* Number of leaves of the format argument that were null pointers or
1020      string literals, but had extra format arguments and used $ operand
1021      numbers.  */
1022   int number_dollar_extra_args;
1023   /* Number of leaves of the format argument that were wide string
1024      literals.  */
1025   int number_wide;
1026   /* Number of leaves of the format argument that were empty strings.  */
1027   int number_empty;
1028   /* Number of leaves of the format argument that were unterminated
1029      strings.  */
1030   int number_unterminated;
1031   /* Number of leaves of the format argument that were not counted above.  */
1032   int number_other;
1033 } format_check_results;
1034
1035 static void check_format_info   PARAMS ((int *, function_format_info *, tree));
1036 static void check_format_info_recurse PARAMS ((int *, format_check_results *,
1037                                                function_format_info *, tree,
1038                                                tree, int));
1039 static void check_format_info_main PARAMS ((int *, format_check_results *,
1040                                             function_format_info *,
1041                                             const char *, int, tree, int));
1042 static void status_warning PARAMS ((int *, const char *, ...))
1043      ATTRIBUTE_PRINTF_2;
1044
1045 static void init_dollar_format_checking         PARAMS ((int, tree));
1046 static int maybe_read_dollar_number             PARAMS ((int *, const char **, int,
1047                                                          tree, tree *,
1048                                                          const format_kind_info *));
1049 static void finish_dollar_format_checking       PARAMS ((int *, format_check_results *));
1050
1051 static const format_flag_spec *get_flag_spec    PARAMS ((const format_flag_spec *,
1052                                                          int, const char *));
1053
1054 static void check_format_types  PARAMS ((int *, format_wanted_type *));
1055
1056 /* Decode a format type from a string, returning the type, or
1057    format_type_error if not valid, in which case the caller should print an
1058    error message.  */
1059 static enum format_type
1060 decode_format_type (s)
1061      const char *s;
1062 {
1063   int i;
1064   int slen;
1065   slen = strlen (s);
1066   for (i = 0; i < (int) format_type_error; i++)
1067     {
1068       int alen;
1069       if (!strcmp (s, format_types[i].name))
1070         break;
1071       alen = strlen (format_types[i].name);
1072       if (slen == alen + 4 && s[0] == '_' && s[1] == '_'
1073           && s[slen - 1] == '_' && s[slen - 2] == '_'
1074           && !strncmp (s + 2, format_types[i].name, alen))
1075         break;
1076     }
1077   return ((enum format_type) i);
1078 }
1079
1080 \f
1081 /* Check the argument list of a call to printf, scanf, etc.
1082    NAME is the function identifier.
1083    ASSEMBLER_NAME is the function's assembler identifier.
1084    (Either NAME or ASSEMBLER_NAME, but not both, may be NULL_TREE.)
1085    PARAMS is the list of argument values.  Also, if -Wmissing-format-attribute,
1086    warn for calls to vprintf or vscanf in functions with no such format
1087    attribute themselves.  */
1088
1089 void
1090 check_function_format (status, name, assembler_name, params)
1091      int *status;
1092      tree name;
1093      tree assembler_name;
1094      tree params;
1095 {
1096   function_format_info *info;
1097
1098   /* See if this function is a format function.  */
1099   for (info = function_format_list; info; info = info->next)
1100     {
1101       if (info->assembler_name
1102           ? (info->assembler_name == assembler_name)
1103           : (info->name == name))
1104         {
1105           /* Yup; check it.  */
1106           check_format_info (status, info, params);
1107           if (warn_missing_format_attribute && info->first_arg_num == 0
1108               && (format_types[info->format_type].flags & FMT_FLAG_ARG_CONVERT))
1109             {
1110               function_format_info *info2;
1111               for (info2 = function_format_list; info2; info2 = info2->next)
1112                 if ((info2->assembler_name
1113                      ? (info2->assembler_name == DECL_ASSEMBLER_NAME (current_function_decl))
1114                      : (info2->name == DECL_NAME (current_function_decl)))
1115                     && info2->format_type == info->format_type)
1116                   break;
1117               if (info2 == NULL)
1118                 {
1119                   /* Check if the current function has a parameter to which
1120                      the format attribute could be attached; if not, it
1121                      can't be a candidate for a format attribute, despite
1122                      the vprintf-like or vscanf-like call.  */
1123                   tree args;
1124                   for (args = DECL_ARGUMENTS (current_function_decl);
1125                        args != 0;
1126                        args = TREE_CHAIN (args))
1127                     {
1128                       if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
1129                           && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
1130                               == char_type_node))
1131                         break;
1132                     }
1133                   if (args != 0)
1134                     warning ("function might be possible candidate for `%s' format attribute",
1135                              format_types[info->format_type].name);
1136                 }
1137             }
1138           break;
1139         }
1140     }
1141 }
1142
1143 /* This function replaces `warning' inside the printf format checking
1144    functions.  If the `status' parameter is non-NULL, then it is
1145    dereferenced and set to 1 whenever a warning is caught.  Otherwise
1146    it warns as usual by replicating the innards of the warning
1147    function from diagnostic.c.  */
1148 static void
1149 status_warning VPARAMS ((int *status, const char *msgid, ...))
1150 {
1151 #ifndef ANSI_PROTOTYPES
1152   int *status;
1153   const char *msgid;
1154 #endif
1155   va_list ap;
1156   diagnostic_context dc;
1157
1158   VA_START (ap, msgid);
1159
1160 #ifndef ANSI_PROTOTYPES
1161   status = va_arg (ap, int *);
1162   msgid = va_arg (ap, const char *);
1163 #endif
1164
1165   if (status)
1166     *status = 1;
1167   else
1168     {
1169       /* This duplicates the warning function behavior.  */
1170       set_diagnostic_context
1171         (&dc, msgid, &ap, input_filename, lineno, /* warn = */ 1);
1172       report_diagnostic (&dc);
1173     }
1174
1175   va_end (ap);
1176 }
1177
1178 /* Variables used by the checking of $ operand number formats.  */
1179 static char *dollar_arguments_used = NULL;
1180 static int dollar_arguments_alloc = 0;
1181 static int dollar_arguments_count;
1182 static int dollar_first_arg_num;
1183 static int dollar_max_arg_used;
1184 static int dollar_format_warned;
1185
1186 /* Initialize the checking for a format string that may contain $
1187    parameter number specifications; we will need to keep track of whether
1188    each parameter has been used.  FIRST_ARG_NUM is the number of the first
1189    argument that is a parameter to the format, or 0 for a vprintf-style
1190    function; PARAMS is the list of arguments starting at this argument.  */
1191
1192 static void
1193 init_dollar_format_checking (first_arg_num, params)
1194      int first_arg_num;
1195      tree params;
1196 {
1197   dollar_first_arg_num = first_arg_num;
1198   dollar_arguments_count = 0;
1199   dollar_max_arg_used = 0;
1200   dollar_format_warned = 0;
1201   if (first_arg_num > 0)
1202     {
1203       while (params)
1204         {
1205           dollar_arguments_count++;
1206           params = TREE_CHAIN (params);
1207         }
1208     }
1209   if (dollar_arguments_alloc < dollar_arguments_count)
1210     {
1211       if (dollar_arguments_used)
1212         free (dollar_arguments_used);
1213       dollar_arguments_alloc = dollar_arguments_count;
1214       dollar_arguments_used = xmalloc (dollar_arguments_alloc);
1215     }
1216   if (dollar_arguments_alloc)
1217     memset (dollar_arguments_used, 0, dollar_arguments_alloc);
1218 }
1219
1220
1221 /* Look for a decimal number followed by a $ in *FORMAT.  If DOLLAR_NEEDED
1222    is set, it is an error if one is not found; otherwise, it is OK.  If
1223    such a number is found, check whether it is within range and mark that
1224    numbered operand as being used for later checking.  Returns the operand
1225    number if found and within range, zero if no such number was found and
1226    this is OK, or -1 on error.  PARAMS points to the first operand of the
1227    format; PARAM_PTR is made to point to the parameter referred to.  If
1228    a $ format is found, *FORMAT is updated to point just after it.  */
1229
1230 static int
1231 maybe_read_dollar_number (status, format, dollar_needed, params, param_ptr,
1232                           fki)
1233      int *status;
1234      const char **format;
1235      int dollar_needed;
1236      tree params;
1237      tree *param_ptr;
1238      const format_kind_info *fki;
1239 {
1240   int argnum;
1241   int overflow_flag;
1242   const char *fcp = *format;
1243   if (*fcp < '0' || *fcp > '9')
1244     {
1245       if (dollar_needed)
1246         {
1247           status_warning (status, "missing $ operand number in format");
1248           return -1;
1249         }
1250       else
1251         return 0;
1252     }
1253   argnum = 0;
1254   overflow_flag = 0;
1255   while (*fcp >= '0' && *fcp <= '9')
1256     {
1257       int nargnum;
1258       nargnum = 10 * argnum + (*fcp - '0');
1259       if (nargnum < 0 || nargnum / 10 != argnum)
1260         overflow_flag = 1;
1261       argnum = nargnum;
1262       fcp++;
1263     }
1264   if (*fcp != '$')
1265     {
1266       if (dollar_needed)
1267         {
1268           status_warning (status, "missing $ operand number in format");
1269           return -1;
1270         }
1271       else
1272         return 0;
1273     }
1274   *format = fcp + 1;
1275   if (pedantic && !dollar_format_warned)
1276     {
1277       status_warning (status,
1278                       "%s does not support %%n$ operand number formats",
1279                       C_STD_NAME (STD_EXT));
1280       dollar_format_warned = 1;
1281     }
1282   if (overflow_flag || argnum == 0
1283       || (dollar_first_arg_num && argnum > dollar_arguments_count))
1284     {
1285       status_warning (status, "operand number out of range in format");
1286       return -1;
1287     }
1288   if (argnum > dollar_max_arg_used)
1289     dollar_max_arg_used = argnum;
1290   /* For vprintf-style functions we may need to allocate more memory to
1291      track which arguments are used.  */
1292   while (dollar_arguments_alloc < dollar_max_arg_used)
1293     {
1294       int nalloc;
1295       nalloc = 2 * dollar_arguments_alloc + 16;
1296       dollar_arguments_used = xrealloc (dollar_arguments_used, nalloc);
1297       memset (dollar_arguments_used + dollar_arguments_alloc, 0,
1298               nalloc - dollar_arguments_alloc);
1299       dollar_arguments_alloc = nalloc;
1300     }
1301   if (!(fki->flags & FMT_FLAG_DOLLAR_MULTIPLE)
1302       && dollar_arguments_used[argnum - 1] == 1)
1303     {
1304       dollar_arguments_used[argnum - 1] = 2;
1305       status_warning (status,
1306                       "format argument %d used more than once in %s format",
1307                       argnum, fki->name);
1308     }
1309   else
1310     dollar_arguments_used[argnum - 1] = 1;
1311   if (dollar_first_arg_num)
1312     {
1313       int i;
1314       *param_ptr = params;
1315       for (i = 1; i < argnum && *param_ptr != 0; i++)
1316         *param_ptr = TREE_CHAIN (*param_ptr);
1317
1318       if (*param_ptr == 0)
1319         {
1320           /* This case shouldn't be caught here.  */
1321           abort ();
1322         }
1323     }
1324   else
1325     *param_ptr = 0;
1326   return argnum;
1327 }
1328
1329
1330 /* Finish the checking for a format string that used $ operand number formats
1331    instead of non-$ formats.  We check for unused operands before used ones
1332    (a serious error, since the implementation of the format function
1333    can't know what types to pass to va_arg to find the later arguments).
1334    and for unused operands at the end of the format (if we know how many
1335    arguments the format had, so not for vprintf).  If there were operand
1336    numbers out of range on a non-vprintf-style format, we won't have reached
1337    here.  */
1338
1339 static void
1340 finish_dollar_format_checking (status, res)
1341      int *status;
1342      format_check_results *res;
1343 {
1344   int i;
1345   for (i = 0; i < dollar_max_arg_used; i++)
1346     {
1347       if (!dollar_arguments_used[i])
1348         status_warning (status, "format argument %d unused before used argument %d in $-style format",
1349                  i + 1, dollar_max_arg_used);
1350     }
1351   if (dollar_first_arg_num && dollar_max_arg_used < dollar_arguments_count)
1352     {
1353       res->number_other--;
1354       res->number_dollar_extra_args++;
1355     }
1356 }
1357
1358
1359 /* Retrieve the specification for a format flag.  SPEC contains the
1360    specifications for format flags for the applicable kind of format.
1361    FLAG is the flag in question.  If PREDICATES is NULL, the basic
1362    spec for that flag must be retrieved and this function aborts if
1363    it cannot be found.  If PREDICATES is not NULL, it is a string listing
1364    possible predicates for the spec entry; if an entry predicated on any
1365    of these is found, it is returned, otherwise NULL is returned.  */
1366
1367 static const format_flag_spec *
1368 get_flag_spec (spec, flag, predicates)
1369      const format_flag_spec *spec;
1370      int flag;
1371      const char *predicates;
1372 {
1373   int i;
1374   for (i = 0; spec[i].flag_char != 0; i++)
1375     {
1376       if (spec[i].flag_char != flag)
1377         continue;
1378       if (predicates != NULL)
1379         {
1380           if (spec[i].predicate != 0
1381               && strchr (predicates, spec[i].predicate) != 0)
1382             return &spec[i];
1383         }
1384       else if (spec[i].predicate == 0)
1385         return &spec[i];
1386     }
1387   if (predicates == NULL)
1388     abort ();
1389   else
1390     return NULL;
1391 }
1392
1393
1394 /* Check the argument list of a call to printf, scanf, etc.
1395    INFO points to the function_format_info structure.
1396    PARAMS is the list of argument values.  */
1397
1398 static void
1399 check_format_info (status, info, params)
1400      int *status;
1401      function_format_info *info;
1402      tree params;
1403 {
1404   int arg_num;
1405   tree format_tree;
1406   format_check_results res;
1407   /* Skip to format argument.  If the argument isn't available, there's
1408      no work for us to do; prototype checking will catch the problem.  */
1409   for (arg_num = 1; ; ++arg_num)
1410     {
1411       if (params == 0)
1412         return;
1413       if (arg_num == info->format_num)
1414         break;
1415       params = TREE_CHAIN (params);
1416     }
1417   format_tree = TREE_VALUE (params);
1418   params = TREE_CHAIN (params);
1419   if (format_tree == 0)
1420     return;
1421
1422   res.number_non_literal = 0;
1423   res.number_extra_args = 0;
1424   res.number_dollar_extra_args = 0;
1425   res.number_wide = 0;
1426   res.number_empty = 0;
1427   res.number_unterminated = 0;
1428   res.number_other = 0;
1429
1430   check_format_info_recurse (status, &res, info, format_tree, params, arg_num);
1431
1432   if (res.number_non_literal > 0)
1433     {
1434       /* Functions taking a va_list normally pass a non-literal format
1435          string.  These functions typically are declared with
1436          first_arg_num == 0, so avoid warning in those cases.  */
1437       if (!(format_types[info->format_type].flags & FMT_FLAG_ARG_CONVERT))
1438         {
1439           /* For strftime-like formats, warn for not checking the format
1440              string; but there are no arguments to check.  */
1441           if (warn_format_nonliteral)
1442             status_warning (status, "format not a string literal, format string not checked");
1443         }
1444       else if (info->first_arg_num != 0)
1445         {
1446           /* If there are no arguments for the format at all, we may have
1447              printf (foo) which is likely to be a security hole.  */
1448           while (arg_num + 1 < info->first_arg_num)
1449             {
1450               if (params == 0)
1451                 break;
1452               params = TREE_CHAIN (params);
1453               ++arg_num;
1454             }
1455           if (params == 0 && (warn_format_nonliteral || warn_format_security))
1456             status_warning (status, "format not a string literal and no format arguments");
1457           else if (warn_format_nonliteral)
1458             status_warning (status, "format not a string literal, argument types not checked");
1459         }
1460     }
1461
1462   /* If there were extra arguments to the format, normally warn.  However,
1463      the standard does say extra arguments are ignored, so in the specific
1464      case where we have multiple leaves (conditional expressions or
1465      ngettext) allow extra arguments if at least one leaf didn't have extra
1466      arguments, but was otherwise OK (either non-literal or checked OK).
1467      If the format is an empty string, this should be counted similarly to the
1468      case of extra format arguments.  */
1469   if (res.number_extra_args > 0 && res.number_non_literal == 0
1470       && res.number_other == 0 && warn_format_extra_args)
1471     status_warning (status, "too many arguments for format");
1472   if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
1473       && res.number_other == 0 && warn_format_extra_args)
1474     status_warning (status, "unused arguments in $-style format");
1475   if (res.number_empty > 0 && res.number_non_literal == 0
1476       && res.number_other == 0)
1477     status_warning (status, "zero-length format string");
1478
1479   if (res.number_wide > 0)
1480     status_warning (status, "format is a wide character string");
1481
1482   if (res.number_unterminated > 0)
1483     status_warning (status, "unterminated format string");
1484 }
1485
1486
1487 /* Recursively check a call to a format function.  FORMAT_TREE is the
1488    format parameter, which may be a conditional expression in which
1489    both halves should be checked.  ARG_NUM is the number of the
1490    format argument; PARAMS points just after it in the argument list.  */
1491
1492 static void
1493 check_format_info_recurse (status, res, info, format_tree, params, arg_num)
1494      int *status;
1495      format_check_results *res;
1496      function_format_info *info;
1497      tree format_tree;
1498      tree params;
1499      int arg_num;
1500 {
1501   int format_length;
1502   const char *format_chars;
1503   tree array_size = 0;
1504   tree array_init;
1505
1506   if (TREE_CODE (format_tree) == NOP_EXPR)
1507     {
1508       /* Strip coercion.  */
1509       check_format_info_recurse (status, res, info,
1510                                  TREE_OPERAND (format_tree, 0), params,
1511                                  arg_num);
1512       return;
1513     }
1514
1515   if (TREE_CODE (format_tree) == CALL_EXPR
1516       && TREE_CODE (TREE_OPERAND (format_tree, 0)) == ADDR_EXPR
1517       && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (format_tree, 0), 0))
1518           == FUNCTION_DECL))
1519     {
1520       tree function = TREE_OPERAND (TREE_OPERAND (format_tree, 0), 0);
1521
1522       /* See if this is a call to a known internationalization function
1523          that modifies the format arg.  */
1524       international_format_info *iinfo;
1525
1526       for (iinfo = international_format_list; iinfo; iinfo = iinfo->next)
1527         if (iinfo->assembler_name
1528             ? (iinfo->assembler_name == DECL_ASSEMBLER_NAME (function))
1529             : (iinfo->name == DECL_NAME (function)))
1530           {
1531             tree inner_args;
1532             int i;
1533
1534             for (inner_args = TREE_OPERAND (format_tree, 1), i = 1;
1535                  inner_args != 0;
1536                  inner_args = TREE_CHAIN (inner_args), i++)
1537               if (i == iinfo->format_num)
1538                 {
1539                   /* FIXME: with Marc Espie's __attribute__((nonnull))
1540                      patch in GCC, we will have chained attributes,
1541                      and be able to handle functions like ngettext
1542                      with multiple format_arg attributes properly.  */
1543                   check_format_info_recurse (status, res, info,
1544                                              TREE_VALUE (inner_args), params,
1545                                              arg_num);
1546                   return;
1547                 }
1548           }
1549     }
1550
1551   if (TREE_CODE (format_tree) == COND_EXPR)
1552     {
1553       /* Check both halves of the conditional expression.  */
1554       check_format_info_recurse (status, res, info,
1555                                  TREE_OPERAND (format_tree, 1), params,
1556                                  arg_num);
1557       check_format_info_recurse (status, res, info,
1558                                  TREE_OPERAND (format_tree, 2), params,
1559                                  arg_num);
1560       return;
1561     }
1562
1563   if (integer_zerop (format_tree))
1564     {
1565       /* FIXME: this warning should go away once Marc Espie's
1566          __attribute__((nonnull)) patch is in.  Instead, checking for
1567          nonnull attributes should probably change this function to act
1568          specially if info == NULL and add a res->number_null entry for
1569          that case, or maybe add a function pointer to be called at
1570          the end instead of hardcoding check_format_info_main.  */
1571       status_warning (status, "null format string");
1572
1573       /* Skip to first argument to check, so we can see if this format
1574          has any arguments (it shouldn't).  */
1575       while (arg_num + 1 < info->first_arg_num)
1576         {
1577           if (params == 0)
1578             return;
1579           params = TREE_CHAIN (params);
1580           ++arg_num;
1581         }
1582
1583       if (params == 0)
1584         res->number_other++;
1585       else
1586         res->number_extra_args++;
1587
1588       return;
1589     }
1590
1591   if (TREE_CODE (format_tree) != ADDR_EXPR)
1592     {
1593       res->number_non_literal++;
1594       return;
1595     }
1596   format_tree = TREE_OPERAND (format_tree, 0);
1597   if (TREE_CODE (format_tree) == VAR_DECL
1598       && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
1599       && (array_init = decl_constant_value (format_tree)) != format_tree
1600       && TREE_CODE (array_init) == STRING_CST)
1601     {
1602       /* Extract the string constant initializer.  Note that this may include
1603          a trailing NUL character that is not in the array (e.g.
1604          const char a[3] = "foo";).  */
1605       array_size = DECL_SIZE_UNIT (format_tree);
1606       format_tree = array_init;
1607     }
1608   if (TREE_CODE (format_tree) != STRING_CST)
1609     {
1610       res->number_non_literal++;
1611       return;
1612     }
1613   if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
1614     {
1615       res->number_wide++;
1616       return;
1617     }
1618   format_chars = TREE_STRING_POINTER (format_tree);
1619   format_length = TREE_STRING_LENGTH (format_tree);
1620   if (array_size != 0)
1621     {
1622       /* Variable length arrays can't be initialized.  */
1623       if (TREE_CODE (array_size) != INTEGER_CST)
1624         abort ();
1625       if (host_integerp (array_size, 0))
1626         {
1627           HOST_WIDE_INT array_size_value = TREE_INT_CST_LOW (array_size);
1628           if (array_size_value > 0
1629               && array_size_value == (int) array_size_value
1630               && format_length > array_size_value)
1631             format_length = array_size_value;
1632         }
1633     }
1634   if (format_length < 1)
1635     {
1636       res->number_unterminated++;
1637       return;
1638     }
1639   if (format_length == 1)
1640     {
1641       res->number_empty++;
1642       return;
1643     }
1644   if (format_chars[--format_length] != 0)
1645     {
1646       res->number_unterminated++;
1647       return;
1648     }
1649
1650   /* Skip to first argument to check.  */
1651   while (arg_num + 1 < info->first_arg_num)
1652     {
1653       if (params == 0)
1654         return;
1655       params = TREE_CHAIN (params);
1656       ++arg_num;
1657     }
1658   /* Provisionally increment res->number_other; check_format_info_main
1659      will decrement it if it finds there are extra arguments, but this way
1660      need not adjust it for every return.  */
1661   res->number_other++;
1662   check_format_info_main (status, res, info, format_chars, format_length,
1663                           params, arg_num);
1664 }
1665
1666
1667 /* Do the main part of checking a call to a format function.  FORMAT_CHARS
1668    is the NUL-terminated format string (which at this point may contain
1669    internal NUL characters); FORMAT_LENGTH is its length (excluding the
1670    terminating NUL character).  ARG_NUM is one less than the number of
1671    the first format argument to check; PARAMS points to that format
1672    argument in the list of arguments.  */
1673
1674 static void
1675 check_format_info_main (status, res, info, format_chars, format_length,
1676                         params, arg_num)
1677      int *status;
1678      format_check_results *res;
1679      function_format_info *info;
1680      const char *format_chars;
1681      int format_length;
1682      tree params;
1683      int arg_num;
1684 {
1685   const char *orig_format_chars = format_chars;
1686   tree first_fillin_param = params;
1687
1688   const format_kind_info *fki = &format_types[info->format_type];
1689   const format_flag_spec *flag_specs = fki->flag_specs;
1690   const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs;
1691
1692   /* -1 if no conversions taking an operand have been found; 0 if one has
1693      and it didn't use $; 1 if $ formats are in use.  */
1694   int has_operand_number = -1;
1695
1696   init_dollar_format_checking (info->first_arg_num, first_fillin_param);
1697
1698   while (1)
1699     {
1700       int i;
1701       int suppressed = FALSE;
1702       const char *length_chars = NULL;
1703       enum format_lengths length_chars_val = FMT_LEN_none;
1704       enum format_std_version length_chars_std = STD_C89;
1705       int format_char;
1706       tree cur_param;
1707       tree wanted_type;
1708       int main_arg_num = 0;
1709       tree main_arg_params = 0;
1710       enum format_std_version wanted_type_std;
1711       const char *wanted_type_name;
1712       format_wanted_type width_wanted_type;
1713       format_wanted_type precision_wanted_type;
1714       format_wanted_type main_wanted_type;
1715       format_wanted_type *first_wanted_type = NULL;
1716       format_wanted_type *last_wanted_type = NULL;
1717       const format_length_info *fli = NULL;
1718       const format_char_info *fci = NULL;
1719       char flag_chars[256];
1720       int aflag = 0;
1721       if (*format_chars == 0)
1722         {
1723           if (format_chars - orig_format_chars != format_length)
1724             status_warning (status, "embedded `\\0' in format");
1725           if (info->first_arg_num != 0 && params != 0
1726               && has_operand_number <= 0)
1727             {
1728               res->number_other--;
1729               res->number_extra_args++;
1730             }
1731           if (has_operand_number > 0)
1732             finish_dollar_format_checking (status, res);
1733           return;
1734         }
1735       if (*format_chars++ != '%')
1736         continue;
1737       if (*format_chars == 0)
1738         {
1739           status_warning (status, "spurious trailing `%%' in format");
1740           continue;
1741         }
1742       if (*format_chars == '%')
1743         {
1744           ++format_chars;
1745           continue;
1746         }
1747       flag_chars[0] = 0;
1748
1749       if ((fki->flags & FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
1750         {
1751           /* Possibly read a $ operand number at the start of the format.
1752              If one was previously used, one is required here.  If one
1753              is not used here, we can't immediately conclude this is a
1754              format without them, since it could be printf %m or scanf %*.  */
1755           int opnum;
1756           opnum = maybe_read_dollar_number (status, &format_chars, 0,
1757                                             first_fillin_param,
1758                                             &main_arg_params, fki);
1759           if (opnum == -1)
1760             return;
1761           else if (opnum > 0)
1762             {
1763               has_operand_number = 1;
1764               main_arg_num = opnum + info->first_arg_num - 1;
1765             }
1766         }
1767
1768       /* Read any format flags, but do not yet validate them beyond removing
1769          duplicates, since in general validation depends on the rest of
1770          the format.  */
1771       while (*format_chars != 0
1772              && strchr (fki->flag_chars, *format_chars) != 0)
1773         {
1774           const format_flag_spec *s = get_flag_spec (flag_specs,
1775                                                      *format_chars, NULL);
1776           if (strchr (flag_chars, *format_chars) != 0)
1777             {
1778               status_warning (status, "repeated %s in format", _(s->name));
1779             }
1780           else
1781             {
1782               i = strlen (flag_chars);
1783               flag_chars[i++] = *format_chars;
1784               flag_chars[i] = 0;
1785             }
1786           if (s->skip_next_char)
1787             {
1788               ++format_chars;
1789               if (*format_chars == 0)
1790                 {
1791                   status_warning (status, "missing fill character at end of strfmon format");
1792                   return;
1793                 }
1794             }
1795           ++format_chars;
1796         }
1797
1798       /* Read any format width, possibly * or *m$.  */
1799       if (fki->width_char != 0)
1800         {
1801           if (fki->width_type != NULL && *format_chars == '*')
1802             {
1803               i = strlen (flag_chars);
1804               flag_chars[i++] = fki->width_char;
1805               flag_chars[i] = 0;
1806               /* "...a field width...may be indicated by an asterisk.
1807                  In this case, an int argument supplies the field width..."  */
1808               ++format_chars;
1809               if (params == 0)
1810                 {
1811                   status_warning (status, "too few arguments for format");
1812                   return;
1813                 }
1814               if (has_operand_number != 0)
1815                 {
1816                   int opnum;
1817                   opnum = maybe_read_dollar_number (status, &format_chars,
1818                                                     has_operand_number == 1,
1819                                                     first_fillin_param,
1820                                                     &params, fki);
1821                   if (opnum == -1)
1822                     return;
1823                   else if (opnum > 0)
1824                     {
1825                       has_operand_number = 1;
1826                       arg_num = opnum + info->first_arg_num - 1;
1827                     }
1828                   else
1829                     has_operand_number = 0;
1830                 }
1831               if (info->first_arg_num != 0)
1832                 {
1833                   cur_param = TREE_VALUE (params);
1834                   if (has_operand_number <= 0)
1835                     {
1836                       params = TREE_CHAIN (params);
1837                       ++arg_num;
1838                     }
1839                   width_wanted_type.wanted_type = *fki->width_type;
1840                   width_wanted_type.wanted_type_name = NULL;
1841                   width_wanted_type.pointer_count = 0;
1842                   width_wanted_type.char_lenient_flag = 0;
1843                   width_wanted_type.writing_in_flag = 0;
1844                   width_wanted_type.reading_from_flag = 0;
1845                   width_wanted_type.name = _("field width");
1846                   width_wanted_type.param = cur_param;
1847                   width_wanted_type.arg_num = arg_num;
1848                   width_wanted_type.next = NULL;
1849                   if (last_wanted_type != 0)
1850                     last_wanted_type->next = &width_wanted_type;
1851                   if (first_wanted_type == 0)
1852                     first_wanted_type = &width_wanted_type;
1853                   last_wanted_type = &width_wanted_type;
1854                 }
1855             }
1856           else
1857             {
1858               /* Possibly read a numeric width.  If the width is zero,
1859                  we complain if appropriate.  */
1860               int non_zero_width_char = FALSE;
1861               int found_width = FALSE;
1862               while (ISDIGIT (*format_chars))
1863                 {
1864                   found_width = TRUE;
1865                   if (*format_chars != '0')
1866                     non_zero_width_char = TRUE;
1867                   ++format_chars;
1868                 }
1869               if (found_width && !non_zero_width_char &&
1870                   (fki->flags & FMT_FLAG_ZERO_WIDTH_BAD))
1871                 status_warning (status, "zero width in %s format",
1872                                 fki->name);
1873               if (found_width)
1874                 {
1875                   i = strlen (flag_chars);
1876                   flag_chars[i++] = fki->width_char;
1877                   flag_chars[i] = 0;
1878                 }
1879             }
1880         }
1881
1882       /* Read any format left precision (must be a number, not *).  */
1883       if (fki->left_precision_char != 0 && *format_chars == '#')
1884         {
1885           ++format_chars;
1886           i = strlen (flag_chars);
1887           flag_chars[i++] = fki->left_precision_char;
1888           flag_chars[i] = 0;
1889           if (!ISDIGIT (*format_chars))
1890             status_warning (status, "empty left precision in %s format",
1891                             fki->name);
1892           while (ISDIGIT (*format_chars))
1893             ++format_chars;
1894         }
1895
1896       /* Read any format precision, possibly * or *m$.  */
1897       if (fki->precision_char != 0 && *format_chars == '.')
1898         {
1899           ++format_chars;
1900           i = strlen (flag_chars);
1901           flag_chars[i++] = fki->precision_char;
1902           flag_chars[i] = 0;
1903           if (fki->precision_type != NULL && *format_chars == '*')
1904             {
1905               /* "...a...precision...may be indicated by an asterisk.
1906                  In this case, an int argument supplies the...precision."  */
1907               ++format_chars;
1908               if (has_operand_number != 0)
1909                 {
1910                   int opnum;
1911                   opnum = maybe_read_dollar_number (status, &format_chars,
1912                                                     has_operand_number == 1,
1913                                                     first_fillin_param,
1914                                                     &params, fki);
1915                   if (opnum == -1)
1916                     return;
1917                   else if (opnum > 0)
1918                     {
1919                       has_operand_number = 1;
1920                       arg_num = opnum + info->first_arg_num - 1;
1921                     }
1922                   else
1923                     has_operand_number = 0;
1924                 }
1925               if (info->first_arg_num != 0)
1926                 {
1927                   if (params == 0)
1928                     {
1929                       status_warning (status, "too few arguments for format");
1930                       return;
1931                     }
1932                   cur_param = TREE_VALUE (params);
1933                   if (has_operand_number <= 0)
1934                     {
1935                       params = TREE_CHAIN (params);
1936                       ++arg_num;
1937                     }
1938                   precision_wanted_type.wanted_type = *fki->precision_type;
1939                   precision_wanted_type.wanted_type_name = NULL;
1940                   precision_wanted_type.pointer_count = 0;
1941                   precision_wanted_type.char_lenient_flag = 0;
1942                   precision_wanted_type.writing_in_flag = 0;
1943                   precision_wanted_type.reading_from_flag = 0;
1944                   precision_wanted_type.name = _("field precision");
1945                   precision_wanted_type.param = cur_param;
1946                   precision_wanted_type.arg_num = arg_num;
1947                   precision_wanted_type.next = NULL;
1948                   if (last_wanted_type != 0)
1949                     last_wanted_type->next = &precision_wanted_type;
1950                   if (first_wanted_type == 0)
1951                     first_wanted_type = &precision_wanted_type;
1952                   last_wanted_type = &precision_wanted_type;
1953                 }
1954             }
1955           else
1956             {
1957               if (!(fki->flags & FMT_FLAG_EMPTY_PREC_OK)
1958                   && !ISDIGIT (*format_chars))
1959                 status_warning (status, "empty precision in %s format",
1960                                 fki->name);
1961               while (ISDIGIT (*format_chars))
1962                 ++format_chars;
1963             }
1964         }
1965
1966       /* Read any length modifier, if this kind of format has them.  */
1967       fli = fki->length_char_specs;
1968       length_chars = NULL;
1969       length_chars_val = FMT_LEN_none;
1970       length_chars_std = STD_C89;
1971       if (fli)
1972         {
1973           while (fli->name != 0 && fli->name[0] != *format_chars)
1974             fli++;
1975           if (fli->name != 0)
1976             {
1977               format_chars++;
1978               if (fli->double_name != 0 && fli->name[0] == *format_chars)
1979                 {
1980                   format_chars++;
1981                   length_chars = fli->double_name;
1982                   length_chars_val = fli->double_index;
1983                   length_chars_std = fli->double_std;
1984                 }
1985               else
1986                 {
1987                   length_chars = fli->name;
1988                   length_chars_val = fli->index;
1989                   length_chars_std = fli->std;
1990                 }
1991               i = strlen (flag_chars);
1992               flag_chars[i++] = fki->length_code_char;
1993               flag_chars[i] = 0;
1994             }
1995           if (pedantic)
1996             {
1997               /* Warn if the length modifier is non-standard.  */
1998               if (ADJ_STD (length_chars_std) > C_STD_VER)
1999                 status_warning (status, "%s does not support the `%s' %s length modifier",
2000                                 C_STD_NAME (length_chars_std), length_chars,
2001                                 fki->name);
2002             }
2003         }
2004
2005       /* Read any modifier (strftime E/O).  */
2006       if (fki->modifier_chars != NULL)
2007         {
2008           while (*format_chars != 0
2009                  && strchr (fki->modifier_chars, *format_chars) != 0)
2010             {
2011               if (strchr (flag_chars, *format_chars) != 0)
2012                 {
2013                   const format_flag_spec *s = get_flag_spec (flag_specs,
2014                                                              *format_chars, NULL);
2015                   status_warning (status, "repeated %s in format", _(s->name));
2016                 }
2017               else
2018                 {
2019                   i = strlen (flag_chars);
2020                   flag_chars[i++] = *format_chars;
2021                   flag_chars[i] = 0;
2022                 }
2023               ++format_chars;
2024             }
2025         }
2026
2027       /* Handle the scanf allocation kludge.  */
2028       if (fki->flags & FMT_FLAG_SCANF_A_KLUDGE)
2029         {
2030           if (*format_chars == 'a' && !flag_isoc99)
2031             {
2032               if (format_chars[1] == 's' || format_chars[1] == 'S'
2033                   || format_chars[1] == '[')
2034                 {
2035                   /* `a' is used as a flag.  */
2036                   i = strlen (flag_chars);
2037                   flag_chars[i++] = 'a';
2038                   flag_chars[i] = 0;
2039                   format_chars++;
2040                 }
2041             }
2042         }
2043
2044       format_char = *format_chars;
2045       if (format_char == 0
2046           || (!(fki->flags & FMT_FLAG_FANCY_PERCENT_OK) && format_char == '%'))
2047         {
2048           status_warning (status, "conversion lacks type at end of format");
2049           continue;
2050         }
2051       format_chars++;
2052       fci = fki->conversion_specs;
2053       while (fci->format_chars != 0
2054              && strchr (fci->format_chars, format_char) == 0)
2055           ++fci;
2056       if (fci->format_chars == 0)
2057         {
2058           if (ISGRAPH(format_char))
2059             status_warning (status, "unknown conversion type character `%c' in format",
2060                      format_char);
2061           else
2062             status_warning (status, "unknown conversion type character 0x%x in format",
2063                      format_char);
2064           continue;
2065         }
2066       if (pedantic)
2067         {
2068           if (ADJ_STD (fci->std) > C_STD_VER)
2069             status_warning (status, "%s does not support the `%%%c' %s format",
2070                             C_STD_NAME (fci->std), format_char, fki->name);
2071         }
2072
2073       /* Validate the individual flags used, removing any that are invalid.  */
2074       {
2075         int d = 0;
2076         for (i = 0; flag_chars[i] != 0; i++)
2077           {
2078             const format_flag_spec *s = get_flag_spec (flag_specs,
2079                                                        flag_chars[i], NULL);
2080             flag_chars[i - d] = flag_chars[i];
2081             if (flag_chars[i] == fki->length_code_char)
2082               continue;
2083             if (strchr (fci->flag_chars, flag_chars[i]) == 0)
2084               {
2085                 status_warning (status, "%s used with `%%%c' %s format",
2086                                 _(s->name), format_char, fki->name);
2087                 d++;
2088                 continue;
2089               }
2090             if (pedantic)
2091               {
2092                 const format_flag_spec *t;
2093                 if (ADJ_STD (s->std) > C_STD_VER)
2094                   status_warning (status, "%s does not support %s",
2095                                   C_STD_NAME (s->std), _(s->long_name));
2096                 t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
2097                 if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
2098                   {
2099                     const char *long_name = (t->long_name != NULL
2100                                              ? t->long_name
2101                                              : s->long_name);
2102                     if (ADJ_STD (t->std) > C_STD_VER)
2103                       status_warning (status, "%s does not support %s with the `%%%c' %s format",
2104                                       C_STD_NAME (t->std), _(long_name),
2105                                       format_char, fki->name);
2106                   }
2107               }
2108           }
2109         flag_chars[i - d] = 0;
2110       }
2111
2112       if ((fki->flags & FMT_FLAG_SCANF_A_KLUDGE)
2113           && strchr (flag_chars, 'a') != 0)
2114         aflag = 1;
2115
2116       if (fki->suppression_char
2117           && strchr (flag_chars, fki->suppression_char) != 0)
2118         suppressed = 1;
2119
2120       /* Validate the pairs of flags used.  */
2121       for (i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
2122         {
2123           const format_flag_spec *s, *t;
2124           if (strchr (flag_chars, bad_flag_pairs[i].flag_char1) == 0)
2125             continue;
2126           if (strchr (flag_chars, bad_flag_pairs[i].flag_char2) == 0)
2127             continue;
2128           if (bad_flag_pairs[i].predicate != 0
2129               && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
2130             continue;
2131           s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
2132           t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
2133           if (bad_flag_pairs[i].ignored)
2134             {
2135               if (bad_flag_pairs[i].predicate != 0)
2136                 status_warning (status, "%s ignored with %s and `%%%c' %s format",
2137                                 _(s->name), _(t->name), format_char,
2138                                 fki->name);
2139               else
2140                 status_warning (status, "%s ignored with %s in %s format",
2141                                 _(s->name), _(t->name), fki->name);
2142             }
2143           else
2144             {
2145               if (bad_flag_pairs[i].predicate != 0)
2146                 status_warning (status, "use of %s and %s together with `%%%c' %s format",
2147                                 _(s->name), _(t->name), format_char,
2148                                 fki->name);
2149               else
2150                 status_warning (status, "use of %s and %s together in %s format",
2151                                 _(s->name), _(t->name), fki->name);
2152             }
2153         }
2154
2155       /* Give Y2K warnings.  */
2156       if (warn_format_y2k)
2157         {
2158           int y2k_level = 0;
2159           if (strchr (fci->flags2, '4') != 0)
2160             if (strchr (flag_chars, 'E') != 0)
2161               y2k_level = 3;
2162             else
2163               y2k_level = 2;
2164           else if (strchr (fci->flags2, '3') != 0)
2165             y2k_level = 3;
2166           else if (strchr (fci->flags2, '2') != 0)
2167             y2k_level = 2;
2168           if (y2k_level == 3)
2169             status_warning (status, "`%%%c' yields only last 2 digits of year in some locales",
2170                             format_char);
2171           else if (y2k_level == 2)
2172             status_warning (status, "`%%%c' yields only last 2 digits of year", format_char);
2173         }
2174
2175       if (strchr (fci->flags2, '[') != 0)
2176         {
2177           /* Skip over scan set, in case it happens to have '%' in it.  */
2178           if (*format_chars == '^')
2179             ++format_chars;
2180           /* Find closing bracket; if one is hit immediately, then
2181              it's part of the scan set rather than a terminator.  */
2182           if (*format_chars == ']')
2183             ++format_chars;
2184           while (*format_chars && *format_chars != ']')
2185             ++format_chars;
2186           if (*format_chars != ']')
2187             /* The end of the format string was reached.  */
2188             status_warning (status, "no closing `]' for `%%[' format");
2189         }
2190
2191       wanted_type = 0;
2192       wanted_type_name = 0;
2193       if (fki->flags & FMT_FLAG_ARG_CONVERT)
2194         {
2195           wanted_type = (fci->types[length_chars_val].type
2196                          ? *fci->types[length_chars_val].type : 0);
2197           wanted_type_name = fci->types[length_chars_val].name;
2198           wanted_type_std = fci->types[length_chars_val].std;
2199           if (wanted_type == 0)
2200             {
2201               status_warning (status, "use of `%s' length modifier with `%c' type character",
2202                               length_chars, format_char);
2203               /* Heuristic: skip one argument when an invalid length/type
2204                  combination is encountered.  */
2205               arg_num++;
2206               if (params == 0)
2207                 {
2208                   status_warning (status, "too few arguments for format");
2209                   return;
2210                 }
2211               params = TREE_CHAIN (params);
2212               continue;
2213             }
2214           else if (pedantic
2215                    /* Warn if non-standard, provided it is more non-standard
2216                       than the length and type characters that may already
2217                       have been warned for.  */
2218                    && ADJ_STD (wanted_type_std) > ADJ_STD (length_chars_std)
2219                    && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
2220             {
2221               if (ADJ_STD (wanted_type_std) > C_STD_VER)
2222                 status_warning (status, "%s does not support the `%%%s%c' %s format",
2223                                 C_STD_NAME (wanted_type_std), length_chars,
2224                                 format_char, fki->name);
2225             }
2226         }
2227
2228       /* Finally. . .check type of argument against desired type!  */
2229       if (info->first_arg_num == 0)
2230         continue;
2231       if ((fci->pointer_count == 0 && wanted_type == void_type_node)
2232           || suppressed)
2233         {
2234           if (main_arg_num != 0)
2235             {
2236               if (suppressed)
2237                 status_warning (status, "operand number specified with suppressed assignment");
2238               else
2239                 status_warning (status, "operand number specified for format taking no argument");
2240             }
2241         }
2242       else
2243         {
2244           if (main_arg_num != 0)
2245             {
2246               arg_num = main_arg_num;
2247               params = main_arg_params;
2248             }
2249           else
2250             {
2251               ++arg_num;
2252               if (has_operand_number > 0)
2253                 {
2254                   status_warning (status, "missing $ operand number in format");
2255                   return;
2256                 }
2257               else
2258                 has_operand_number = 0;
2259               if (params == 0)
2260                 {
2261                   status_warning (status, "too few arguments for format");
2262                   return;
2263                 }
2264             }
2265           cur_param = TREE_VALUE (params);
2266           params = TREE_CHAIN (params);
2267           main_wanted_type.wanted_type = wanted_type;
2268           main_wanted_type.wanted_type_name = wanted_type_name;
2269           main_wanted_type.pointer_count = fci->pointer_count + aflag;
2270           main_wanted_type.char_lenient_flag = 0;
2271           if (strchr (fci->flags2, 'c') != 0)
2272             main_wanted_type.char_lenient_flag = 1;
2273           main_wanted_type.writing_in_flag = 0;
2274           main_wanted_type.reading_from_flag = 0;
2275           if (aflag)
2276             main_wanted_type.writing_in_flag = 1;
2277           else
2278             {
2279               if (strchr (fci->flags2, 'W') != 0)
2280                 main_wanted_type.writing_in_flag = 1;
2281               if (strchr (fci->flags2, 'R') != 0)
2282                 main_wanted_type.reading_from_flag = 1;
2283             }
2284           main_wanted_type.name = NULL;
2285           main_wanted_type.param = cur_param;
2286           main_wanted_type.arg_num = arg_num;
2287           main_wanted_type.next = NULL;
2288           if (last_wanted_type != 0)
2289             last_wanted_type->next = &main_wanted_type;
2290           if (first_wanted_type == 0)
2291             first_wanted_type = &main_wanted_type;
2292           last_wanted_type = &main_wanted_type;
2293         }
2294
2295       if (first_wanted_type != 0)
2296         check_format_types (status, first_wanted_type);
2297
2298     }
2299 }
2300
2301
2302 /* Check the argument types from a single format conversion (possibly
2303    including width and precision arguments).  */
2304 static void
2305 check_format_types (status, types)
2306      int *status;
2307      format_wanted_type *types;
2308 {
2309   for (; types != 0; types = types->next)
2310     {
2311       tree cur_param;
2312       tree cur_type;
2313       tree orig_cur_type;
2314       tree wanted_type;
2315       tree promoted_type;
2316       int arg_num;
2317       int i;
2318       int char_type_flag;
2319       cur_param = types->param;
2320       cur_type = TREE_TYPE (cur_param);
2321       if (cur_type == error_mark_node)
2322         continue;
2323       char_type_flag = 0;
2324       wanted_type = types->wanted_type;
2325       arg_num = types->arg_num;
2326
2327       /* The following should not occur here.  */
2328       if (wanted_type == 0)
2329         abort ();
2330       if (wanted_type == void_type_node && types->pointer_count == 0)
2331         abort ();
2332
2333       if (types->pointer_count == 0)
2334         {
2335           promoted_type = simple_type_promotes_to (wanted_type);
2336           if (promoted_type != NULL_TREE)
2337             wanted_type = promoted_type;
2338         }
2339
2340       STRIP_NOPS (cur_param);
2341
2342       /* Check the types of any additional pointer arguments
2343          that precede the "real" argument.  */
2344       for (i = 0; i < types->pointer_count; ++i)
2345         {
2346           if (TREE_CODE (cur_type) == POINTER_TYPE)
2347             {
2348               cur_type = TREE_TYPE (cur_type);
2349               if (cur_type == error_mark_node)
2350                 break;
2351
2352               /* Check for writing through a NULL pointer.  */
2353               if (types->writing_in_flag
2354                   && i == 0
2355                   && cur_param != 0
2356                   && integer_zerop (cur_param))
2357                 status_warning (status,
2358                                 "writing through null pointer (arg %d)",
2359                                 arg_num);
2360
2361               /* Check for reading through a NULL pointer.  */
2362               if (types->reading_from_flag
2363                   && i == 0
2364                   && cur_param != 0
2365                   && integer_zerop (cur_param))
2366                 status_warning (status,
2367                                 "reading through null pointer (arg %d)",
2368                                 arg_num);
2369
2370               if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
2371                 cur_param = TREE_OPERAND (cur_param, 0);
2372               else
2373                 cur_param = 0;
2374
2375               /* See if this is an attempt to write into a const type with
2376                  scanf or with printf "%n".  Note: the writing in happens
2377                  at the first indirection only, if for example
2378                  void * const * is passed to scanf %p; passing
2379                  const void ** is simply passing an incompatible type.  */
2380               if (types->writing_in_flag
2381                   && i == 0
2382                   && (TYPE_READONLY (cur_type)
2383                       || (cur_param != 0
2384                           && (TREE_CODE_CLASS (TREE_CODE (cur_param)) == 'c'
2385                               || (DECL_P (cur_param)
2386                                   && TREE_READONLY (cur_param))))))
2387                 status_warning (status, "writing into constant object (arg %d)", arg_num);
2388
2389               /* If there are extra type qualifiers beyond the first
2390                  indirection, then this makes the types technically
2391                  incompatible.  */
2392               if (i > 0
2393                   && pedantic
2394                   && (TYPE_READONLY (cur_type)
2395                       || TYPE_VOLATILE (cur_type)
2396                       || TYPE_RESTRICT (cur_type)))
2397                 status_warning (status, "extra type qualifiers in format argument (arg %d)",
2398                          arg_num);
2399
2400             }
2401           else
2402             {
2403               if (types->pointer_count == 1)
2404                 status_warning (status, "format argument is not a pointer (arg %d)", arg_num);
2405               else
2406                 status_warning (status, "format argument is not a pointer to a pointer (arg %d)", arg_num);
2407               break;
2408             }
2409         }
2410
2411       if (i < types->pointer_count)
2412         continue;
2413
2414       orig_cur_type = cur_type;
2415       cur_type = TYPE_MAIN_VARIANT (cur_type);
2416
2417       /* Check whether the argument type is a character type.  This leniency
2418          only applies to certain formats, flagged with 'c'.
2419       */
2420       if (types->char_lenient_flag)
2421         char_type_flag = (cur_type == char_type_node
2422                           || cur_type == signed_char_type_node
2423                           || cur_type == unsigned_char_type_node);
2424
2425       /* Check the type of the "real" argument, if there's a type we want.  */
2426       if (wanted_type == cur_type)
2427         continue;
2428       /* If we want `void *', allow any pointer type.
2429          (Anything else would already have got a warning.)
2430          With -pedantic, only allow pointers to void and to character
2431          types.  */
2432       if (wanted_type == void_type_node
2433           && (!pedantic || (i == 1 && char_type_flag)))
2434         continue;
2435       /* Don't warn about differences merely in signedness, unless
2436          -pedantic.  With -pedantic, warn if the type is a pointer
2437          target and not a character type, and for character types at
2438          a second level of indirection.  */
2439       if (TREE_CODE (wanted_type) == INTEGER_TYPE
2440           && TREE_CODE (cur_type) == INTEGER_TYPE
2441           && (! pedantic || i == 0 || (i == 1 && char_type_flag))
2442           && (TREE_UNSIGNED (wanted_type)
2443               ? wanted_type == unsigned_type (cur_type)
2444               : wanted_type == signed_type (cur_type)))
2445         continue;
2446       /* Likewise, "signed char", "unsigned char" and "char" are
2447          equivalent but the above test won't consider them equivalent.  */
2448       if (wanted_type == char_type_node
2449           && (! pedantic || i < 2)
2450           && char_type_flag)
2451         continue;
2452       /* Now we have a type mismatch.  */
2453       {
2454         register const char *this;
2455         register const char *that;
2456
2457         this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type)));
2458         that = 0;
2459         if (TYPE_NAME (orig_cur_type) != 0
2460             && TREE_CODE (orig_cur_type) != INTEGER_TYPE
2461             && !(TREE_CODE (orig_cur_type) == POINTER_TYPE
2462                  && TREE_CODE (TREE_TYPE (orig_cur_type)) == INTEGER_TYPE))
2463           {
2464             if (TREE_CODE (TYPE_NAME (orig_cur_type)) == TYPE_DECL
2465                 && DECL_NAME (TYPE_NAME (orig_cur_type)) != 0)
2466               that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (orig_cur_type)));
2467             else
2468               that = IDENTIFIER_POINTER (TYPE_NAME (orig_cur_type));
2469           }
2470
2471         /* A nameless type can't possibly match what the format wants.
2472            So there will be a warning for it.
2473            Make up a string to describe vaguely what it is.  */
2474         if (that == 0)
2475           {
2476             if (TREE_CODE (orig_cur_type) == POINTER_TYPE)
2477               that = "pointer";
2478             else
2479               that = "different type";
2480           }
2481
2482         /* Make the warning better in case of mismatch of int vs long.  */
2483         if (TREE_CODE (orig_cur_type) == INTEGER_TYPE
2484             && TREE_CODE (wanted_type) == INTEGER_TYPE
2485             && TYPE_PRECISION (orig_cur_type) == TYPE_PRECISION (wanted_type)
2486             && TYPE_NAME (orig_cur_type) != 0
2487             && TREE_CODE (TYPE_NAME (orig_cur_type)) == TYPE_DECL)
2488           that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (orig_cur_type)));
2489
2490         if (strcmp (this, that) != 0)
2491           {
2492             /* There may be a better name for the format, e.g. size_t,
2493                but we should allow for programs with a perverse typedef
2494                making size_t something other than what the compiler
2495                thinks.  */
2496             if (types->wanted_type_name != 0
2497                 && strcmp (types->wanted_type_name, that) != 0)
2498               this = types->wanted_type_name;
2499             if (types->name != 0)
2500               status_warning (status, "%s is not type %s (arg %d)", types->name, this,
2501                        arg_num);
2502             else
2503               status_warning (status, "%s format, %s arg (arg %d)", this, that, arg_num);
2504           }
2505       }
2506     }
2507 }