OSDN Git Service

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