OSDN Git Service

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