OSDN Git Service

* doc/install.texi (Prerequisites): Update documentation of
[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 ("%qs 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   { 'q',  0, 0, N_("`q' flag"),        N_("the `q' diagnostic flag"),          STD_C89 },
619   { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
620   { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
621   { 0, 0, 0, NULL, NULL, 0 }
622 };
623
624 #define gcc_cdiag_flag_specs gcc_diag_flag_specs
625
626 static const format_flag_spec gcc_cxxdiag_flag_specs[] =
627 {
628   { '+',  0, 0, N_("`+' flag"),        N_("the `+' printf flag"),              STD_C89 },
629   { '#',  0, 0, N_("`#' flag"),        N_("the `#' printf flag"),              STD_C89 },
630   { 'q',  0, 0, N_("`q' flag"),        N_("the `q' diagnostic flag"),          STD_C89 },
631   { 'p',  0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
632   { 'L',  0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
633   { 0, 0, 0, NULL, NULL, 0 }
634 };
635
636 static const format_flag_spec scanf_flag_specs[] =
637 {
638   { '*',  0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
639   { 'a',  0, 0, N_("`a' flag"),               N_("the `a' scanf flag"),                       STD_EXT },
640   { 'w',  0, 0, N_("field width"),            N_("field width in scanf format"),              STD_C89 },
641   { 'L',  0, 0, N_("length modifier"),        N_("length modifier in scanf format"),          STD_C89 },
642   { '\'', 0, 0, N_("`'' flag"),               N_("the `'' scanf flag"),                       STD_EXT },
643   { 'I',  0, 0, N_("`I' flag"),               N_("the `I' scanf flag"),                       STD_EXT },
644   { 0, 0, 0, NULL, NULL, 0 }
645 };
646
647
648 static const format_flag_pair scanf_flag_pairs[] =
649 {
650   { '*', 'L', 0, 0 },
651   { 0, 0, 0, 0 }
652 };
653
654
655 static const format_flag_spec strftime_flag_specs[] =
656 {
657   { '_', 0,   0, N_("`_' flag"),     N_("the `_' strftime flag"),          STD_EXT },
658   { '-', 0,   0, N_("`-' flag"),     N_("the `-' strftime flag"),          STD_EXT },
659   { '0', 0,   0, N_("`0' flag"),     N_("the `0' strftime flag"),          STD_EXT },
660   { '^', 0,   0, N_("`^' flag"),     N_("the `^' strftime flag"),          STD_EXT },
661   { '#', 0,   0, N_("`#' flag"),     N_("the `#' strftime flag"),          STD_EXT },
662   { 'w', 0,   0, N_("field width"),  N_("field width in strftime format"), STD_EXT },
663   { 'E', 0,   0, N_("`E' modifier"), N_("the `E' strftime modifier"),      STD_C99 },
664   { 'O', 0,   0, N_("`O' modifier"), N_("the `O' strftime modifier"),      STD_C99 },
665   { 'O', 'o', 0, NULL,               N_("the `O' modifier"),               STD_EXT },
666   { 0, 0, 0, NULL, NULL, 0 }
667 };
668
669
670 static const format_flag_pair strftime_flag_pairs[] =
671 {
672   { 'E', 'O', 0, 0 },
673   { '_', '-', 0, 0 },
674   { '_', '0', 0, 0 },
675   { '-', '0', 0, 0 },
676   { '^', '#', 0, 0 },
677   { 0, 0, 0, 0 }
678 };
679
680
681 static const format_flag_spec strfmon_flag_specs[] =
682 {
683   { '=',  0, 1, N_("fill character"),  N_("fill character in strfmon format"),  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   { '!',  0, 0, N_("`!' flag"),        N_("the `!' strfmon flag"),              STD_C89 },
688   { '-',  0, 0, N_("`-' flag"),        N_("the `-' strfmon flag"),              STD_C89 },
689   { 'w',  0, 0, N_("field width"),     N_("field width in strfmon format"),     STD_C89 },
690   { '#',  0, 0, N_("left precision"),  N_("left precision in strfmon format"),  STD_C89 },
691   { 'p',  0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
692   { 'L',  0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 },
693   { 0, 0, 0, NULL, NULL, 0 }
694 };
695
696 static const format_flag_pair strfmon_flag_pairs[] =
697 {
698   { '+', '(', 0, 0 },
699   { 0, 0, 0, 0 }
700 };
701
702
703 #define T_I     &integer_type_node
704 #define T89_I   { STD_C89, NULL, T_I }
705 #define T_L     &long_integer_type_node
706 #define T89_L   { STD_C89, NULL, T_L }
707 #define T_LL    &long_long_integer_type_node
708 #define T9L_LL  { STD_C9L, NULL, T_LL }
709 #define TEX_LL  { STD_EXT, NULL, T_LL }
710 #define T_S     &short_integer_type_node
711 #define T89_S   { STD_C89, NULL, T_S }
712 #define T_UI    &unsigned_type_node
713 #define T89_UI  { STD_C89, NULL, T_UI }
714 #define T_UL    &long_unsigned_type_node
715 #define T89_UL  { STD_C89, NULL, T_UL }
716 #define T_ULL   &long_long_unsigned_type_node
717 #define T9L_ULL { STD_C9L, NULL, T_ULL }
718 #define TEX_ULL { STD_EXT, NULL, T_ULL }
719 #define T_US    &short_unsigned_type_node
720 #define T89_US  { STD_C89, NULL, T_US }
721 #define T_F     &float_type_node
722 #define T89_F   { STD_C89, NULL, T_F }
723 #define T99_F   { STD_C99, NULL, T_F }
724 #define T_D     &double_type_node
725 #define T89_D   { STD_C89, NULL, T_D }
726 #define T99_D   { STD_C99, NULL, T_D }
727 #define T_LD    &long_double_type_node
728 #define T89_LD  { STD_C89, NULL, T_LD }
729 #define T99_LD  { STD_C99, NULL, T_LD }
730 #define T_C     &char_type_node
731 #define T89_C   { STD_C89, NULL, T_C }
732 #define T_SC    &signed_char_type_node
733 #define T99_SC  { STD_C99, NULL, T_SC }
734 #define T_UC    &unsigned_char_type_node
735 #define T99_UC  { STD_C99, NULL, T_UC }
736 #define T_V     &void_type_node
737 #define T89_V   { STD_C89, NULL, T_V }
738 #define T_W     &wchar_type_node
739 #define T94_W   { STD_C94, "wchar_t", T_W }
740 #define TEX_W   { STD_EXT, "wchar_t", T_W }
741 #define T_WI    &wint_type_node
742 #define T94_WI  { STD_C94, "wint_t", T_WI }
743 #define TEX_WI  { STD_EXT, "wint_t", T_WI }
744 #define T_ST    &size_type_node
745 #define T99_ST  { STD_C99, "size_t", T_ST }
746 #define T_SST   &signed_size_type_node
747 #define T99_SST { STD_C99, "signed size_t", T_SST }
748 #define T_PD    &ptrdiff_type_node
749 #define T99_PD  { STD_C99, "ptrdiff_t", T_PD }
750 #define T_UPD   &unsigned_ptrdiff_type_node
751 #define T99_UPD { STD_C99, "unsigned ptrdiff_t", T_UPD }
752 #define T_IM    &intmax_type_node
753 #define T99_IM  { STD_C99, "intmax_t", T_IM }
754 #define T_UIM   &uintmax_type_node
755 #define T99_UIM { STD_C99, "uintmax_t", T_UIM }
756
757 static const format_char_info print_char_table[] =
758 {
759   /* C89 conversion specifiers.  */
760   { "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"  },
761   { "oxX", 0, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "-wp0#",     "i"  },
762   { "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"  },
763   { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#'I", ""   },
764   { "eE",  0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#I",  ""   },
765   { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T94_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",        ""   },
766   { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",       "cR" },
767   { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",        "c"  },
768   { "n",   1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM  }, "",          "W"  },
769   /* C99 conversion specifiers.  */
770   { "F",   0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#'I", ""   },
771   { "aA",  0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +#",   ""   },
772   /* X/Open conversion specifiers.  */
773   { "C",   0, STD_EXT, { TEX_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",        ""   },
774   { "S",   1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",       "R"  },
775   /* GNU conversion specifiers.  */
776   { "m",   0, STD_EXT, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",       ""   },
777   { NULL,  0, 0, NOLENGTHS, NULL, NULL }
778 };
779
780 static const format_char_info asm_fprintf_char_table[] =
781 {
782   /* C89 conversion specifiers.  */
783   { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0 +",  "i" },
784   { "oxX", 0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0#",   "i" },
785   { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp0",    "i" },
786   { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-w",       "" },
787   { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "-wp",    "cR" },
788
789   /* asm_fprintf conversion specifiers.  */
790   { "O",   0, STD_C89, NOARGUMENTS, "",      ""   },
791   { "R",   0, STD_C89, NOARGUMENTS, "",      ""   },
792   { "I",   0, STD_C89, NOARGUMENTS, "",      ""   },
793   { "L",   0, STD_C89, NOARGUMENTS, "",      ""   },
794   { "U",   0, STD_C89, NOARGUMENTS, "",      ""   },
795   { "r",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",  "" },
796   { "@",   0, STD_C89, NOARGUMENTS, "",      ""   },
797   { NULL,  0, 0, NOLENGTHS, NULL, NULL }
798 };
799
800 static const format_char_info gcc_diag_char_table[] =
801 {
802   /* C89 conversion specifiers.  */
803   { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
804   { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
805   { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
806   { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
807   { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "pq", "cR" },
808   { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "c"  },
809
810   /* Custom conversion specifiers.  */
811
812   /* %H will require "location_t" at runtime.  */
813   { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
814
815   /* These will require a "tree" at runtime.  */
816   { "J", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",    ""   },
817
818   { "<>'", 0, STD_C89, NOARGUMENTS, "",      ""   },
819   { "m",   0, STD_C89, NOARGUMENTS, "q",     ""   },
820   { NULL,  0, 0, NOLENGTHS, NULL, NULL }
821 };
822
823 static const format_char_info gcc_cdiag_char_table[] =
824 {
825   /* C89 conversion specifiers.  */
826   { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
827   { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
828   { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
829   { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
830   { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "pq", "cR" },
831   { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "c"  },
832
833   /* Custom conversion specifiers.  */
834
835   /* %H will require "location_t" at runtime.  */
836   { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
837
838   /* These will require a "tree" at runtime.  */
839   { "DEFJT", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q", ""   },
840
841   { "<>'", 0, STD_C89, NOARGUMENTS, "",      ""   },
842   { "m",   0, STD_C89, NOARGUMENTS, "q",     ""   },
843   { NULL,  0, 0, NOLENGTHS, NULL, NULL }
844 };
845
846 static const format_char_info gcc_cxxdiag_char_table[] =
847 {
848   /* C89 conversion specifiers.  */
849   { "di",  0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T89_L,   T9L_LL,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
850   { "ox",  0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
851   { "u",   0, STD_C89, { T89_UI,  BADLEN,  BADLEN,  T89_UL,  T9L_ULL, BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
852   { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
853   { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "pq", "cR" },
854   { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "c"  },
855
856   /* Custom conversion specifiers.  */
857
858   /* %H will require "location_t" at runtime.  */
859   { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
860
861   /* These will require a "tree" at runtime.  */
862   { "ADEFJTV",0,STD_C89,{ T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+#",   ""   },
863
864   /* These accept either an `int' or an `enum tree_code' (which is handled as an `int'.)  */
865   { "CLOPQ",0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  ""   },
866
867   { "<>'", 0, STD_C89, NOARGUMENTS, "",      ""   },
868   { "m",   0, STD_C89, NOARGUMENTS, "q",     ""   },
869   { NULL,  0, 0, NOLENGTHS, NULL, NULL }
870 };
871
872 static const format_char_info scan_char_table[] =
873 {
874   /* C89 conversion specifiers.  */
875   { "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"   },
876   { "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"   },
877   { "oxX",   1, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_ULL, T99_ST,  T99_UPD, T99_UIM }, "*w",   "W"   },
878   { "efgEG", 1, STD_C89, { T89_F,   BADLEN,  BADLEN,  T89_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W"   },
879   { "c",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "cW"  },
880   { "s",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW"  },
881   { "[",     1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "cW[" },
882   { "p",     2, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W"   },
883   { "n",     1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM  }, "",     "W"   },
884   /* C99 conversion specifiers.  */
885   { "FaA",   1, STD_C99, { T99_F,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN  }, "*w'",  "W"   },
886   /* X/Open conversion specifiers.  */
887   { "C",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*w",   "W"   },
888   { "S",     1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "*aw",  "W"   },
889   { NULL, 0, 0, NOLENGTHS, NULL, NULL }
890 };
891
892 static const format_char_info time_char_table[] =
893 {
894   /* C89 conversion specifiers.  */
895   { "ABZab",            0, STD_C89, NOLENGTHS, "^#",     ""   },
896   { "cx",               0, STD_C89, NOLENGTHS, "E",      "3"  },
897   { "HIMSUWdmw",        0, STD_C89, NOLENGTHS, "-_0Ow",  ""   },
898   { "j",                0, STD_C89, NOLENGTHS, "-_0Ow",  "o"  },
899   { "p",                0, STD_C89, NOLENGTHS, "#",      ""   },
900   { "X",                0, STD_C89, NOLENGTHS, "E",      ""   },
901   { "y",                0, STD_C89, NOLENGTHS, "EO-_0w", "4"  },
902   { "Y",                0, STD_C89, NOLENGTHS, "-_0EOw", "o"  },
903   { "%",                0, STD_C89, NOLENGTHS, "",       ""   },
904   /* C99 conversion specifiers.  */
905   { "C",                0, STD_C99, NOLENGTHS, "-_0EOw", "o"  },
906   { "D",                0, STD_C99, NOLENGTHS, "",       "2"  },
907   { "eVu",              0, STD_C99, NOLENGTHS, "-_0Ow",  ""   },
908   { "FRTnrt",           0, STD_C99, NOLENGTHS, "",       ""   },
909   { "g",                0, STD_C99, NOLENGTHS, "O-_0w",  "2o" },
910   { "G",                0, STD_C99, NOLENGTHS, "-_0Ow",  "o"  },
911   { "h",                0, STD_C99, NOLENGTHS, "^#",     ""   },
912   { "z",                0, STD_C99, NOLENGTHS, "O",      "o"  },
913   /* GNU conversion specifiers.  */
914   { "kls",              0, STD_EXT, NOLENGTHS, "-_0Ow",  ""   },
915   { "P",                0, STD_EXT, NOLENGTHS, "",       ""   },
916   { NULL,               0, 0, NOLENGTHS, NULL, NULL }
917 };
918
919 static const format_char_info monetary_char_table[] =
920 {
921   { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "" },
922   { NULL, 0, 0, NOLENGTHS, NULL, NULL }
923 };
924
925
926 /* This must be in the same order as enum format_type.  */
927 static const format_kind_info format_types_orig[] =
928 {
929   { "printf",   printf_length_specs,  print_char_table, " +#0-'I", NULL, 
930     printf_flag_specs, printf_flag_pairs,
931     FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
932     'w', 0, 'p', 0, 'L',
933     &integer_type_node, &integer_type_node
934   },
935   { "asm_fprintf",   asm_fprintf_length_specs,  asm_fprintf_char_table, " +#0-", NULL, 
936     asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
937     FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
938     'w', 0, 'p', 0, 'L',
939     NULL, NULL
940   },
941   { "gcc_diag",   gcc_diag_length_specs,  gcc_diag_char_table, "q", NULL, 
942     gcc_diag_flag_specs, gcc_diag_flag_pairs,
943     FMT_FLAG_ARG_CONVERT,
944     0, 0, 'p', 0, 'L',
945     NULL, &integer_type_node
946   },
947   { "gcc_cdiag",   gcc_cdiag_length_specs,  gcc_cdiag_char_table, "q", NULL, 
948     gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
949     FMT_FLAG_ARG_CONVERT,
950     0, 0, 'p', 0, 'L',
951     NULL, &integer_type_node
952   },
953   { "gcc_cxxdiag",   gcc_cxxdiag_length_specs,  gcc_cxxdiag_char_table, "q+#", NULL, 
954     gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
955     FMT_FLAG_ARG_CONVERT,
956     0, 0, 'p', 0, 'L',
957     NULL, &integer_type_node
958   },
959   { "scanf",    scanf_length_specs,   scan_char_table,  "*'I", NULL, 
960     scanf_flag_specs, scanf_flag_pairs,
961     FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
962     'w', 0, 0, '*', 'L',
963     NULL, NULL
964   },
965   { "strftime", NULL,                 time_char_table,  "_-0^#", "EO",
966     strftime_flag_specs, strftime_flag_pairs,
967     FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0,
968     NULL, NULL
969   },
970   { "strfmon",  strfmon_length_specs, monetary_char_table, "=^+(!-", NULL, 
971     strfmon_flag_specs, strfmon_flag_pairs,
972     FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L',
973     NULL, NULL
974   }
975 };
976
977 /* This layer of indirection allows GCC to reassign format_types with
978    new data if necessary, while still allowing the original data to be
979    const.  */
980 static const format_kind_info *format_types = format_types_orig;
981 /* We can modify this one.  */
982 static format_kind_info *dynamic_format_types;
983
984 /* Structure detailing the results of checking a format function call
985    where the format expression may be a conditional expression with
986    many leaves resulting from nested conditional expressions.  */
987 typedef struct
988 {
989   /* Number of leaves of the format argument that could not be checked
990      as they were not string literals.  */
991   int number_non_literal;
992   /* Number of leaves of the format argument that were null pointers or
993      string literals, but had extra format arguments.  */
994   int number_extra_args;
995   /* Number of leaves of the format argument that were null pointers or
996      string literals, but had extra format arguments and used $ operand
997      numbers.  */
998   int number_dollar_extra_args;
999   /* Number of leaves of the format argument that were wide string
1000      literals.  */
1001   int number_wide;
1002   /* Number of leaves of the format argument that were empty strings.  */
1003   int number_empty;
1004   /* Number of leaves of the format argument that were unterminated
1005      strings.  */
1006   int number_unterminated;
1007   /* Number of leaves of the format argument that were not counted above.  */
1008   int number_other;
1009 } format_check_results;
1010
1011 typedef struct
1012 {
1013   format_check_results *res;
1014   function_format_info *info;
1015   tree params;
1016   int *status;
1017 } format_check_context;
1018
1019 static void check_format_info (int *, function_format_info *, tree);
1020 static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
1021 static void check_format_info_main (int *, format_check_results *,
1022                                     function_format_info *,
1023                                     const char *, int, tree,
1024                                     unsigned HOST_WIDE_INT);
1025 static void status_warning (int *, const char *, ...)
1026      ATTRIBUTE_GCC_DIAG(2, 3);
1027
1028 static void init_dollar_format_checking (int, tree);
1029 static int maybe_read_dollar_number (int *, const char **, int,
1030                                      tree, tree *, const format_kind_info *);
1031 static bool avoid_dollar_number (int *, const char *);
1032 static void finish_dollar_format_checking (int *, format_check_results *, int);
1033
1034 static const format_flag_spec *get_flag_spec (const format_flag_spec *,
1035                                               int, const char *);
1036
1037 static void check_format_types (int *, format_wanted_type *);
1038
1039 /* Decode a format type from a string, returning the type, or
1040    format_type_error if not valid, in which case the caller should print an
1041    error message.  */
1042 static enum format_type
1043 decode_format_type (const char *s)
1044 {
1045   int i;
1046   int slen;
1047   slen = strlen (s);
1048   for (i = 0; i < (int) format_type_error; i++)
1049     {
1050       int alen;
1051       if (!strcmp (s, format_types[i].name))
1052         break;
1053       alen = strlen (format_types[i].name);
1054       if (slen == alen + 4 && s[0] == '_' && s[1] == '_'
1055           && s[slen - 1] == '_' && s[slen - 2] == '_'
1056           && !strncmp (s + 2, format_types[i].name, alen))
1057         break;
1058     }
1059   return ((enum format_type) i);
1060 }
1061
1062 \f
1063 /* Check the argument list of a call to printf, scanf, etc.
1064    ATTRS are the attributes on the function type.
1065    PARAMS is the list of argument values.  Also, if -Wmissing-format-attribute,
1066    warn for calls to vprintf or vscanf in functions with no such format
1067    attribute themselves.  */
1068
1069 void
1070 check_function_format (int *status, tree attrs, tree params)
1071 {
1072   tree a;
1073
1074   /* See if this function has any format attributes.  */
1075   for (a = attrs; a; a = TREE_CHAIN (a))
1076     {
1077       if (is_attribute_p ("format", TREE_PURPOSE (a)))
1078         {
1079           /* Yup; check it.  */
1080           function_format_info info;
1081           decode_format_attr (TREE_VALUE (a), &info, 1);
1082           check_format_info (status, &info, params);
1083           if (warn_missing_format_attribute && info.first_arg_num == 0
1084               && (format_types[info.format_type].flags
1085                   & (int) FMT_FLAG_ARG_CONVERT))
1086             {
1087               tree c;
1088               for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
1089                    c;
1090                    c = TREE_CHAIN (c))
1091                 if (is_attribute_p ("format", TREE_PURPOSE (c))
1092                     && (decode_format_type (IDENTIFIER_POINTER
1093                                             (TREE_VALUE (TREE_VALUE (c))))
1094                         == info.format_type))
1095                   break;
1096               if (c == NULL_TREE)
1097                 {
1098                   /* Check if the current function has a parameter to which
1099                      the format attribute could be attached; if not, it
1100                      can't be a candidate for a format attribute, despite
1101                      the vprintf-like or vscanf-like call.  */
1102                   tree args;
1103                   for (args = DECL_ARGUMENTS (current_function_decl);
1104                        args != 0;
1105                        args = TREE_CHAIN (args))
1106                     {
1107                       if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
1108                           && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
1109                               == char_type_node))
1110                         break;
1111                     }
1112                   if (args != 0)
1113                     warning ("function might be possible candidate for %qs format attribute",
1114                              format_types[info.format_type].name);
1115                 }
1116             }
1117         }
1118     }
1119 }
1120
1121 /* This function replaces `warning' inside the printf format checking
1122    functions.  If the `status' parameter is non-NULL, then it is
1123    dereferenced and set to 1 whenever a warning is caught.  Otherwise
1124    it warns as usual by replicating the innards of the warning
1125    function from diagnostic.c.  */
1126 static void
1127 status_warning (int *status, const char *msgid, ...)
1128 {
1129   diagnostic_info diagnostic ;
1130   va_list ap;
1131   
1132   va_start (ap, msgid);
1133
1134   if (status)
1135     *status = 1;
1136   else
1137     {
1138       /* This duplicates the warning function behavior.  */
1139       diagnostic_set_info (&diagnostic, _(msgid), &ap,
1140                            input_location, DK_WARNING);
1141       report_diagnostic (&diagnostic);
1142     }
1143
1144   va_end (ap);
1145 }
1146
1147 /* Variables used by the checking of $ operand number formats.  */
1148 static char *dollar_arguments_used = NULL;
1149 static char *dollar_arguments_pointer_p = NULL;
1150 static int dollar_arguments_alloc = 0;
1151 static int dollar_arguments_count;
1152 static int dollar_first_arg_num;
1153 static int dollar_max_arg_used;
1154 static int dollar_format_warned;
1155
1156 /* Initialize the checking for a format string that may contain $
1157    parameter number specifications; we will need to keep track of whether
1158    each parameter has been used.  FIRST_ARG_NUM is the number of the first
1159    argument that is a parameter to the format, or 0 for a vprintf-style
1160    function; PARAMS is the list of arguments starting at this argument.  */
1161
1162 static void
1163 init_dollar_format_checking (int first_arg_num, tree params)
1164 {
1165   tree oparams = params;
1166
1167   dollar_first_arg_num = first_arg_num;
1168   dollar_arguments_count = 0;
1169   dollar_max_arg_used = 0;
1170   dollar_format_warned = 0;
1171   if (first_arg_num > 0)
1172     {
1173       while (params)
1174         {
1175           dollar_arguments_count++;
1176           params = TREE_CHAIN (params);
1177         }
1178     }
1179   if (dollar_arguments_alloc < dollar_arguments_count)
1180     {
1181       if (dollar_arguments_used)
1182         free (dollar_arguments_used);
1183       if (dollar_arguments_pointer_p)
1184         free (dollar_arguments_pointer_p);
1185       dollar_arguments_alloc = dollar_arguments_count;
1186       dollar_arguments_used = xmalloc (dollar_arguments_alloc);
1187       dollar_arguments_pointer_p = xmalloc (dollar_arguments_alloc);
1188     }
1189   if (dollar_arguments_alloc)
1190     {
1191       memset (dollar_arguments_used, 0, dollar_arguments_alloc);
1192       if (first_arg_num > 0)
1193         {
1194           int i = 0;
1195           params = oparams;
1196           while (params)
1197             {
1198               dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params)))
1199                                                == POINTER_TYPE);
1200               params = TREE_CHAIN (params);
1201               i++;
1202             }
1203         }
1204     }
1205 }
1206
1207
1208 /* Look for a decimal number followed by a $ in *FORMAT.  If DOLLAR_NEEDED
1209    is set, it is an error if one is not found; otherwise, it is OK.  If
1210    such a number is found, check whether it is within range and mark that
1211    numbered operand as being used for later checking.  Returns the operand
1212    number if found and within range, zero if no such number was found and
1213    this is OK, or -1 on error.  PARAMS points to the first operand of the
1214    format; PARAM_PTR is made to point to the parameter referred to.  If
1215    a $ format is found, *FORMAT is updated to point just after it.  */
1216
1217 static int
1218 maybe_read_dollar_number (int *status, const char **format,
1219                           int dollar_needed, tree params, tree *param_ptr,
1220                           const format_kind_info *fki)
1221 {
1222   int argnum;
1223   int overflow_flag;
1224   const char *fcp = *format;
1225   if (! ISDIGIT (*fcp))
1226     {
1227       if (dollar_needed)
1228         {
1229           status_warning (status, "missing $ operand number in format");
1230           return -1;
1231         }
1232       else
1233         return 0;
1234     }
1235   argnum = 0;
1236   overflow_flag = 0;
1237   while (ISDIGIT (*fcp))
1238     {
1239       int nargnum;
1240       nargnum = 10 * argnum + (*fcp - '0');
1241       if (nargnum < 0 || nargnum / 10 != argnum)
1242         overflow_flag = 1;
1243       argnum = nargnum;
1244       fcp++;
1245     }
1246   if (*fcp != '$')
1247     {
1248       if (dollar_needed)
1249         {
1250           status_warning (status, "missing $ operand number in format");
1251           return -1;
1252         }
1253       else
1254         return 0;
1255     }
1256   *format = fcp + 1;
1257   if (pedantic && !dollar_format_warned)
1258     {
1259       status_warning (status,
1260                       "%s does not support %%n$ operand number formats",
1261                       C_STD_NAME (STD_EXT));
1262       dollar_format_warned = 1;
1263     }
1264   if (overflow_flag || argnum == 0
1265       || (dollar_first_arg_num && argnum > dollar_arguments_count))
1266     {
1267       status_warning (status, "operand number out of range in format");
1268       return -1;
1269     }
1270   if (argnum > dollar_max_arg_used)
1271     dollar_max_arg_used = argnum;
1272   /* For vprintf-style functions we may need to allocate more memory to
1273      track which arguments are used.  */
1274   while (dollar_arguments_alloc < dollar_max_arg_used)
1275     {
1276       int nalloc;
1277       nalloc = 2 * dollar_arguments_alloc + 16;
1278       dollar_arguments_used = xrealloc (dollar_arguments_used, nalloc);
1279       dollar_arguments_pointer_p = xrealloc (dollar_arguments_pointer_p,
1280                                              nalloc);
1281       memset (dollar_arguments_used + dollar_arguments_alloc, 0,
1282               nalloc - dollar_arguments_alloc);
1283       dollar_arguments_alloc = nalloc;
1284     }
1285   if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE)
1286       && dollar_arguments_used[argnum - 1] == 1)
1287     {
1288       dollar_arguments_used[argnum - 1] = 2;
1289       status_warning (status,
1290                       "format argument %d used more than once in %s format",
1291                       argnum, fki->name);
1292     }
1293   else
1294     dollar_arguments_used[argnum - 1] = 1;
1295   if (dollar_first_arg_num)
1296     {
1297       int i;
1298       *param_ptr = params;
1299       for (i = 1; i < argnum && *param_ptr != 0; i++)
1300         *param_ptr = TREE_CHAIN (*param_ptr);
1301
1302       if (*param_ptr == 0)
1303         {
1304           /* This case shouldn't be caught here.  */
1305           abort ();
1306         }
1307     }
1308   else
1309     *param_ptr = 0;
1310   return argnum;
1311 }
1312
1313 /* Ensure that FORMAT does not start with a decimal number followed by
1314    a $; give a diagnostic and return true if it does, false otherwise.  */
1315
1316 static bool
1317 avoid_dollar_number (int *status, const char *format)
1318 {
1319   if (!ISDIGIT (*format))
1320     return false;
1321   while (ISDIGIT (*format))
1322     format++;
1323   if (*format == '$')
1324     {
1325       status_warning (status,
1326                       "$ operand number used after format"
1327                       " without operand number");
1328       return true;
1329     }
1330   return false;
1331 }
1332
1333
1334 /* Finish the checking for a format string that used $ operand number formats
1335    instead of non-$ formats.  We check for unused operands before used ones
1336    (a serious error, since the implementation of the format function
1337    can't know what types to pass to va_arg to find the later arguments).
1338    and for unused operands at the end of the format (if we know how many
1339    arguments the format had, so not for vprintf).  If there were operand
1340    numbers out of range on a non-vprintf-style format, we won't have reached
1341    here.  If POINTER_GAP_OK, unused arguments are OK if all arguments are
1342    pointers.  */
1343
1344 static void
1345 finish_dollar_format_checking (int *status, format_check_results *res, int pointer_gap_ok)
1346 {
1347   int i;
1348   bool found_pointer_gap = false;
1349   for (i = 0; i < dollar_max_arg_used; i++)
1350     {
1351       if (!dollar_arguments_used[i])
1352         {
1353           if (pointer_gap_ok && (dollar_first_arg_num == 0
1354                                  || dollar_arguments_pointer_p[i]))
1355             found_pointer_gap = true;
1356           else
1357             status_warning (status, "format argument %d unused before used argument %d in $-style format",
1358                             i + 1, dollar_max_arg_used);
1359         }
1360     }
1361   if (found_pointer_gap
1362       || (dollar_first_arg_num
1363           && dollar_max_arg_used < dollar_arguments_count))
1364     {
1365       res->number_other--;
1366       res->number_dollar_extra_args++;
1367     }
1368 }
1369
1370
1371 /* Retrieve the specification for a format flag.  SPEC contains the
1372    specifications for format flags for the applicable kind of format.
1373    FLAG is the flag in question.  If PREDICATES is NULL, the basic
1374    spec for that flag must be retrieved and this function aborts if
1375    it cannot be found.  If PREDICATES is not NULL, it is a string listing
1376    possible predicates for the spec entry; if an entry predicated on any
1377    of these is found, it is returned, otherwise NULL is returned.  */
1378
1379 static const format_flag_spec *
1380 get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
1381 {
1382   int i;
1383   for (i = 0; spec[i].flag_char != 0; i++)
1384     {
1385       if (spec[i].flag_char != flag)
1386         continue;
1387       if (predicates != NULL)
1388         {
1389           if (spec[i].predicate != 0
1390               && strchr (predicates, spec[i].predicate) != 0)
1391             return &spec[i];
1392         }
1393       else if (spec[i].predicate == 0)
1394         return &spec[i];
1395     }
1396   if (predicates == NULL)
1397     abort ();
1398   else
1399     return NULL;
1400 }
1401
1402
1403 /* Check the argument list of a call to printf, scanf, etc.
1404    INFO points to the function_format_info structure.
1405    PARAMS is the list of argument values.  */
1406
1407 static void
1408 check_format_info (int *status, function_format_info *info, tree params)
1409 {
1410   format_check_context format_ctx;
1411   unsigned HOST_WIDE_INT arg_num;
1412   tree format_tree;
1413   format_check_results res;
1414   /* Skip to format argument.  If the argument isn't available, there's
1415      no work for us to do; prototype checking will catch the problem.  */
1416   for (arg_num = 1; ; ++arg_num)
1417     {
1418       if (params == 0)
1419         return;
1420       if (arg_num == info->format_num)
1421         break;
1422       params = TREE_CHAIN (params);
1423     }
1424   format_tree = TREE_VALUE (params);
1425   params = TREE_CHAIN (params);
1426   if (format_tree == 0)
1427     return;
1428
1429   res.number_non_literal = 0;
1430   res.number_extra_args = 0;
1431   res.number_dollar_extra_args = 0;
1432   res.number_wide = 0;
1433   res.number_empty = 0;
1434   res.number_unterminated = 0;
1435   res.number_other = 0;
1436
1437   format_ctx.res = &res;
1438   format_ctx.info = info;
1439   format_ctx.params = params;
1440   format_ctx.status = status;
1441
1442   check_function_arguments_recurse (check_format_arg, &format_ctx,
1443                                     format_tree, arg_num);
1444
1445   if (res.number_non_literal > 0)
1446     {
1447       /* Functions taking a va_list normally pass a non-literal format
1448          string.  These functions typically are declared with
1449          first_arg_num == 0, so avoid warning in those cases.  */
1450       if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT))
1451         {
1452           /* For strftime-like formats, warn for not checking the format
1453              string; but there are no arguments to check.  */
1454           if (warn_format_nonliteral)
1455             status_warning (status, "format not a string literal, format string not checked");
1456         }
1457       else if (info->first_arg_num != 0)
1458         {
1459           /* If there are no arguments for the format at all, we may have
1460              printf (foo) which is likely to be a security hole.  */
1461           while (arg_num + 1 < info->first_arg_num)
1462             {
1463               if (params == 0)
1464                 break;
1465               params = TREE_CHAIN (params);
1466               ++arg_num;
1467             }
1468           if (params == 0 && (warn_format_nonliteral || warn_format_security))
1469             status_warning (status, "format not a string literal and no format arguments");
1470           else if (warn_format_nonliteral)
1471             status_warning (status, "format not a string literal, argument types not checked");
1472         }
1473     }
1474
1475   /* If there were extra arguments to the format, normally warn.  However,
1476      the standard does say extra arguments are ignored, so in the specific
1477      case where we have multiple leaves (conditional expressions or
1478      ngettext) allow extra arguments if at least one leaf didn't have extra
1479      arguments, but was otherwise OK (either non-literal or checked OK).
1480      If the format is an empty string, this should be counted similarly to the
1481      case of extra format arguments.  */
1482   if (res.number_extra_args > 0 && res.number_non_literal == 0
1483       && res.number_other == 0 && warn_format_extra_args)
1484     status_warning (status, "too many arguments for format");
1485   if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
1486       && res.number_other == 0 && warn_format_extra_args)
1487     status_warning (status, "unused arguments in $-style format");
1488   if (res.number_empty > 0 && res.number_non_literal == 0
1489       && res.number_other == 0 && warn_format_zero_length)
1490     status_warning (status, "zero-length %s format string",
1491                     format_types[info->format_type].name);
1492
1493   if (res.number_wide > 0)
1494     status_warning (status, "format is a wide character string");
1495
1496   if (res.number_unterminated > 0)
1497     status_warning (status, "unterminated format string");
1498 }
1499
1500 /* Callback from check_function_arguments_recurse to check a
1501    format string.  FORMAT_TREE is the format parameter.  ARG_NUM
1502    is the number of the format argument.  CTX points to a
1503    format_check_context.  */
1504
1505 static void
1506 check_format_arg (void *ctx, tree format_tree,
1507                   unsigned HOST_WIDE_INT arg_num)
1508 {
1509   format_check_context *format_ctx = ctx;
1510   format_check_results *res = format_ctx->res;
1511   function_format_info *info = format_ctx->info;
1512   tree params = format_ctx->params;
1513   int *status = format_ctx->status;
1514
1515   int format_length;
1516   HOST_WIDE_INT offset;
1517   const char *format_chars;
1518   tree array_size = 0;
1519   tree array_init;
1520
1521   if (integer_zerop (format_tree))
1522     {
1523       /* Skip to first argument to check, so we can see if this format
1524          has any arguments (it shouldn't).  */
1525       while (arg_num + 1 < info->first_arg_num)
1526         {
1527           if (params == 0)
1528             return;
1529           params = TREE_CHAIN (params);
1530           ++arg_num;
1531         }
1532
1533       if (params == 0)
1534         res->number_other++;
1535       else
1536         res->number_extra_args++;
1537
1538       return;
1539     }
1540
1541   offset = 0;
1542   if (TREE_CODE (format_tree) == PLUS_EXPR)
1543     {
1544       tree arg0, arg1;
1545
1546       arg0 = TREE_OPERAND (format_tree, 0);
1547       arg1 = TREE_OPERAND (format_tree, 1);
1548       STRIP_NOPS (arg0);
1549       STRIP_NOPS (arg1);
1550       if (TREE_CODE (arg1) == INTEGER_CST)
1551         format_tree = arg0;
1552       else if (TREE_CODE (arg0) == INTEGER_CST)
1553         {
1554           format_tree = arg1;
1555           arg1 = arg0;
1556         }
1557       else
1558         {
1559           res->number_non_literal++;
1560           return;
1561         }
1562       if (!host_integerp (arg1, 0)
1563           || (offset = tree_low_cst (arg1, 0)) < 0)
1564         {
1565           res->number_non_literal++;
1566           return;
1567         }
1568     }
1569   if (TREE_CODE (format_tree) != ADDR_EXPR)
1570     {
1571       res->number_non_literal++;
1572       return;
1573     }
1574   format_tree = TREE_OPERAND (format_tree, 0);
1575   if (TREE_CODE (format_tree) == VAR_DECL
1576       && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
1577       && (array_init = decl_constant_value (format_tree)) != format_tree
1578       && TREE_CODE (array_init) == STRING_CST)
1579     {
1580       /* Extract the string constant initializer.  Note that this may include
1581          a trailing NUL character that is not in the array (e.g.
1582          const char a[3] = "foo";).  */
1583       array_size = DECL_SIZE_UNIT (format_tree);
1584       format_tree = array_init;
1585     }
1586   if (TREE_CODE (format_tree) != STRING_CST)
1587     {
1588       res->number_non_literal++;
1589       return;
1590     }
1591   if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
1592     {
1593       res->number_wide++;
1594       return;
1595     }
1596   format_chars = TREE_STRING_POINTER (format_tree);
1597   format_length = TREE_STRING_LENGTH (format_tree);
1598   if (array_size != 0)
1599     {
1600       /* Variable length arrays can't be initialized.  */
1601       if (TREE_CODE (array_size) != INTEGER_CST)
1602         abort ();
1603       if (host_integerp (array_size, 0))
1604         {
1605           HOST_WIDE_INT array_size_value = TREE_INT_CST_LOW (array_size);
1606           if (array_size_value > 0
1607               && array_size_value == (int) array_size_value
1608               && format_length > array_size_value)
1609             format_length = array_size_value;
1610         }
1611     }
1612   if (offset)
1613     {
1614       if (offset >= format_length)
1615         {
1616           res->number_non_literal++;
1617           return;
1618         }
1619       format_chars += offset;
1620       format_length -= offset;
1621     }
1622   if (format_length < 1)
1623     {
1624       res->number_unterminated++;
1625       return;
1626     }
1627   if (format_length == 1)
1628     {
1629       res->number_empty++;
1630       return;
1631     }
1632   if (format_chars[--format_length] != 0)
1633     {
1634       res->number_unterminated++;
1635       return;
1636     }
1637
1638   /* Skip to first argument to check.  */
1639   while (arg_num + 1 < info->first_arg_num)
1640     {
1641       if (params == 0)
1642         return;
1643       params = TREE_CHAIN (params);
1644       ++arg_num;
1645     }
1646   /* Provisionally increment res->number_other; check_format_info_main
1647      will decrement it if it finds there are extra arguments, but this way
1648      need not adjust it for every return.  */
1649   res->number_other++;
1650   check_format_info_main (status, res, info, format_chars, format_length,
1651                           params, arg_num);
1652 }
1653
1654
1655 /* Do the main part of checking a call to a format function.  FORMAT_CHARS
1656    is the NUL-terminated format string (which at this point may contain
1657    internal NUL characters); FORMAT_LENGTH is its length (excluding the
1658    terminating NUL character).  ARG_NUM is one less than the number of
1659    the first format argument to check; PARAMS points to that format
1660    argument in the list of arguments.  */
1661
1662 static void
1663 check_format_info_main (int *status, format_check_results *res,
1664                         function_format_info *info, const char *format_chars,
1665                         int format_length, tree params,
1666                         unsigned HOST_WIDE_INT arg_num)
1667 {
1668   const char *orig_format_chars = format_chars;
1669   tree first_fillin_param = params;
1670
1671   const format_kind_info *fki = &format_types[info->format_type];
1672   const format_flag_spec *flag_specs = fki->flag_specs;
1673   const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs;
1674
1675   /* -1 if no conversions taking an operand have been found; 0 if one has
1676      and it didn't use $; 1 if $ formats are in use.  */
1677   int has_operand_number = -1;
1678
1679   init_dollar_format_checking (info->first_arg_num, first_fillin_param);
1680
1681   while (1)
1682     {
1683       int i;
1684       int suppressed = FALSE;
1685       const char *length_chars = NULL;
1686       enum format_lengths length_chars_val = FMT_LEN_none;
1687       enum format_std_version length_chars_std = STD_C89;
1688       int format_char;
1689       tree cur_param;
1690       tree wanted_type;
1691       int main_arg_num = 0;
1692       tree main_arg_params = 0;
1693       enum format_std_version wanted_type_std;
1694       const char *wanted_type_name;
1695       format_wanted_type width_wanted_type;
1696       format_wanted_type precision_wanted_type;
1697       format_wanted_type main_wanted_type;
1698       format_wanted_type *first_wanted_type = NULL;
1699       format_wanted_type *last_wanted_type = NULL;
1700       const format_length_info *fli = NULL;
1701       const format_char_info *fci = NULL;
1702       char flag_chars[256];
1703       int aflag = 0;
1704       if (*format_chars == 0)
1705         {
1706           if (format_chars - orig_format_chars != format_length)
1707             status_warning (status, "embedded %<\\0%> in format");
1708           if (info->first_arg_num != 0 && params != 0
1709               && has_operand_number <= 0)
1710             {
1711               res->number_other--;
1712               res->number_extra_args++;
1713             }
1714           if (has_operand_number > 0)
1715             finish_dollar_format_checking (status, res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
1716           return;
1717         }
1718       if (*format_chars++ != '%')
1719         continue;
1720       if (*format_chars == 0)
1721         {
1722           status_warning (status, "spurious trailing %<%%%> in format");
1723           continue;
1724         }
1725       if (*format_chars == '%')
1726         {
1727           ++format_chars;
1728           continue;
1729         }
1730       flag_chars[0] = 0;
1731
1732       if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
1733         {
1734           /* Possibly read a $ operand number at the start of the format.
1735              If one was previously used, one is required here.  If one
1736              is not used here, we can't immediately conclude this is a
1737              format without them, since it could be printf %m or scanf %*.  */
1738           int opnum;
1739           opnum = maybe_read_dollar_number (status, &format_chars, 0,
1740                                             first_fillin_param,
1741                                             &main_arg_params, fki);
1742           if (opnum == -1)
1743             return;
1744           else if (opnum > 0)
1745             {
1746               has_operand_number = 1;
1747               main_arg_num = opnum + info->first_arg_num - 1;
1748             }
1749         }
1750       else if (fki->flags & FMT_FLAG_USE_DOLLAR)
1751         {
1752           if (avoid_dollar_number (status, format_chars))
1753             return;
1754         }
1755
1756       /* Read any format flags, but do not yet validate them beyond removing
1757          duplicates, since in general validation depends on the rest of
1758          the format.  */
1759       while (*format_chars != 0
1760              && strchr (fki->flag_chars, *format_chars) != 0)
1761         {
1762           const format_flag_spec *s = get_flag_spec (flag_specs,
1763                                                      *format_chars, NULL);
1764           if (strchr (flag_chars, *format_chars) != 0)
1765             {
1766               status_warning (status, "repeated %s in format", _(s->name));
1767             }
1768           else
1769             {
1770               i = strlen (flag_chars);
1771               flag_chars[i++] = *format_chars;
1772               flag_chars[i] = 0;
1773             }
1774           if (s->skip_next_char)
1775             {
1776               ++format_chars;
1777               if (*format_chars == 0)
1778                 {
1779                   status_warning (status, "missing fill character at end of strfmon format");
1780                   return;
1781                 }
1782             }
1783           ++format_chars;
1784         }
1785
1786       /* Read any format width, possibly * or *m$.  */
1787       if (fki->width_char != 0)
1788         {
1789           if (fki->width_type != NULL && *format_chars == '*')
1790             {
1791               i = strlen (flag_chars);
1792               flag_chars[i++] = fki->width_char;
1793               flag_chars[i] = 0;
1794               /* "...a field width...may be indicated by an asterisk.
1795                  In this case, an int argument supplies the field width..."  */
1796               ++format_chars;
1797               if (has_operand_number != 0)
1798                 {
1799                   int opnum;
1800                   opnum = maybe_read_dollar_number (status, &format_chars,
1801                                                     has_operand_number == 1,
1802                                                     first_fillin_param,
1803                                                     &params, fki);
1804                   if (opnum == -1)
1805                     return;
1806                   else if (opnum > 0)
1807                     {
1808                       has_operand_number = 1;
1809                       arg_num = opnum + info->first_arg_num - 1;
1810                     }
1811                   else
1812                     has_operand_number = 0;
1813                 }
1814               else
1815                 {
1816                   if (avoid_dollar_number (status, format_chars))
1817                     return;
1818                 }
1819               if (info->first_arg_num != 0)
1820                 {
1821                   if (params == 0)
1822                     {
1823                       status_warning (status, "too few arguments for format");
1824                       return;
1825                     }
1826                   cur_param = TREE_VALUE (params);
1827                   if (has_operand_number <= 0)
1828                     {
1829                       params = TREE_CHAIN (params);
1830                       ++arg_num;
1831                     }
1832                   width_wanted_type.wanted_type = *fki->width_type;
1833                   width_wanted_type.wanted_type_name = NULL;
1834                   width_wanted_type.pointer_count = 0;
1835                   width_wanted_type.char_lenient_flag = 0;
1836                   width_wanted_type.writing_in_flag = 0;
1837                   width_wanted_type.reading_from_flag = 0;
1838                   width_wanted_type.name = _("field width");
1839                   width_wanted_type.param = cur_param;
1840                   width_wanted_type.arg_num = arg_num;
1841                   width_wanted_type.next = NULL;
1842                   if (last_wanted_type != 0)
1843                     last_wanted_type->next = &width_wanted_type;
1844                   if (first_wanted_type == 0)
1845                     first_wanted_type = &width_wanted_type;
1846                   last_wanted_type = &width_wanted_type;
1847                 }
1848             }
1849           else
1850             {
1851               /* Possibly read a numeric width.  If the width is zero,
1852                  we complain if appropriate.  */
1853               int non_zero_width_char = FALSE;
1854               int found_width = FALSE;
1855               while (ISDIGIT (*format_chars))
1856                 {
1857                   found_width = TRUE;
1858                   if (*format_chars != '0')
1859                     non_zero_width_char = TRUE;
1860                   ++format_chars;
1861                 }
1862               if (found_width && !non_zero_width_char &&
1863                   (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
1864                 status_warning (status, "zero width in %s format",
1865                                 fki->name);
1866               if (found_width)
1867                 {
1868                   i = strlen (flag_chars);
1869                   flag_chars[i++] = fki->width_char;
1870                   flag_chars[i] = 0;
1871                 }
1872             }
1873         }
1874
1875       /* Read any format left precision (must be a number, not *).  */
1876       if (fki->left_precision_char != 0 && *format_chars == '#')
1877         {
1878           ++format_chars;
1879           i = strlen (flag_chars);
1880           flag_chars[i++] = fki->left_precision_char;
1881           flag_chars[i] = 0;
1882           if (!ISDIGIT (*format_chars))
1883             status_warning (status, "empty left precision in %s format",
1884                             fki->name);
1885           while (ISDIGIT (*format_chars))
1886             ++format_chars;
1887         }
1888
1889       /* Read any format precision, possibly * or *m$.  */
1890       if (fki->precision_char != 0 && *format_chars == '.')
1891         {
1892           ++format_chars;
1893           i = strlen (flag_chars);
1894           flag_chars[i++] = fki->precision_char;
1895           flag_chars[i] = 0;
1896           if (fki->precision_type != NULL && *format_chars == '*')
1897             {
1898               /* "...a...precision...may be indicated by an asterisk.
1899                  In this case, an int argument supplies the...precision."  */
1900               ++format_chars;
1901               if (has_operand_number != 0)
1902                 {
1903                   int opnum;
1904                   opnum = maybe_read_dollar_number (status, &format_chars,
1905                                                     has_operand_number == 1,
1906                                                     first_fillin_param,
1907                                                     &params, fki);
1908                   if (opnum == -1)
1909                     return;
1910                   else if (opnum > 0)
1911                     {
1912                       has_operand_number = 1;
1913                       arg_num = opnum + info->first_arg_num - 1;
1914                     }
1915                   else
1916                     has_operand_number = 0;
1917                 }
1918               else
1919                 {
1920                   if (avoid_dollar_number (status, format_chars))
1921                     return;
1922                 }
1923               if (info->first_arg_num != 0)
1924                 {
1925                   if (params == 0)
1926                     {
1927                       status_warning (status, "too few arguments for format");
1928                       return;
1929                     }
1930                   cur_param = TREE_VALUE (params);
1931                   if (has_operand_number <= 0)
1932                     {
1933                       params = TREE_CHAIN (params);
1934                       ++arg_num;
1935                     }
1936                   precision_wanted_type.wanted_type = *fki->precision_type;
1937                   precision_wanted_type.wanted_type_name = NULL;
1938                   precision_wanted_type.pointer_count = 0;
1939                   precision_wanted_type.char_lenient_flag = 0;
1940                   precision_wanted_type.writing_in_flag = 0;
1941                   precision_wanted_type.reading_from_flag = 0;
1942                   precision_wanted_type.name = _("field precision");
1943                   precision_wanted_type.param = cur_param;
1944                   precision_wanted_type.arg_num = arg_num;
1945                   precision_wanted_type.next = NULL;
1946                   if (last_wanted_type != 0)
1947                     last_wanted_type->next = &precision_wanted_type;
1948                   if (first_wanted_type == 0)
1949                     first_wanted_type = &precision_wanted_type;
1950                   last_wanted_type = &precision_wanted_type;
1951                 }
1952             }
1953           else
1954             {
1955               if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
1956                   && !ISDIGIT (*format_chars))
1957                 status_warning (status, "empty precision in %s format",
1958                                 fki->name);
1959               while (ISDIGIT (*format_chars))
1960                 ++format_chars;
1961             }
1962         }
1963
1964       /* Read any length modifier, if this kind of format has them.  */
1965       fli = fki->length_char_specs;
1966       length_chars = NULL;
1967       length_chars_val = FMT_LEN_none;
1968       length_chars_std = STD_C89;
1969       if (fli)
1970         {
1971           while (fli->name != 0 && fli->name[0] != *format_chars)
1972             fli++;
1973           if (fli->name != 0)
1974             {
1975               format_chars++;
1976               if (fli->double_name != 0 && fli->name[0] == *format_chars)
1977                 {
1978                   format_chars++;
1979                   length_chars = fli->double_name;
1980                   length_chars_val = fli->double_index;
1981                   length_chars_std = fli->double_std;
1982                 }
1983               else
1984                 {
1985                   length_chars = fli->name;
1986                   length_chars_val = fli->index;
1987                   length_chars_std = fli->std;
1988                 }
1989               i = strlen (flag_chars);
1990               flag_chars[i++] = fki->length_code_char;
1991               flag_chars[i] = 0;
1992             }
1993           if (pedantic)
1994             {
1995               /* Warn if the length modifier is non-standard.  */
1996               if (ADJ_STD (length_chars_std) > C_STD_VER)
1997                 status_warning (status, "%s does not support the %qs %s length modifier",
1998                                 C_STD_NAME (length_chars_std), length_chars,
1999                                 fki->name);
2000             }
2001         }
2002
2003       /* Read any modifier (strftime E/O).  */
2004       if (fki->modifier_chars != NULL)
2005         {
2006           while (*format_chars != 0
2007                  && strchr (fki->modifier_chars, *format_chars) != 0)
2008             {
2009               if (strchr (flag_chars, *format_chars) != 0)
2010                 {
2011                   const format_flag_spec *s = get_flag_spec (flag_specs,
2012                                                              *format_chars, NULL);
2013                   status_warning (status, "repeated %s in format", _(s->name));
2014                 }
2015               else
2016                 {
2017                   i = strlen (flag_chars);
2018                   flag_chars[i++] = *format_chars;
2019                   flag_chars[i] = 0;
2020                 }
2021               ++format_chars;
2022             }
2023         }
2024
2025       /* Handle the scanf allocation kludge.  */
2026       if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
2027         {
2028           if (*format_chars == 'a' && !flag_isoc99)
2029             {
2030               if (format_chars[1] == 's' || format_chars[1] == 'S'
2031                   || format_chars[1] == '[')
2032                 {
2033                   /* `a' is used as a flag.  */
2034                   i = strlen (flag_chars);
2035                   flag_chars[i++] = 'a';
2036                   flag_chars[i] = 0;
2037                   format_chars++;
2038                 }
2039             }
2040         }
2041
2042       format_char = *format_chars;
2043       if (format_char == 0
2044           || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
2045               && format_char == '%'))
2046         {
2047           status_warning (status, "conversion lacks type at end of format");
2048           continue;
2049         }
2050       format_chars++;
2051       fci = fki->conversion_specs;
2052       while (fci->format_chars != 0
2053              && strchr (fci->format_chars, format_char) == 0)
2054           ++fci;
2055       if (fci->format_chars == 0)
2056         {
2057           if (ISGRAPH(format_char))
2058             status_warning (status, "unknown conversion type character %qc in format",
2059                      format_char);
2060           else
2061             status_warning (status, "unknown conversion type character 0x%x in format",
2062                      format_char);
2063           continue;
2064         }
2065       if (pedantic)
2066         {
2067           if (ADJ_STD (fci->std) > C_STD_VER)
2068             status_warning (status, "%s does not support the %<%%%c%> %s format",
2069                             C_STD_NAME (fci->std), format_char, fki->name);
2070         }
2071
2072       /* Validate the individual flags used, removing any that are invalid.  */
2073       {
2074         int d = 0;
2075         for (i = 0; flag_chars[i] != 0; i++)
2076           {
2077             const format_flag_spec *s = get_flag_spec (flag_specs,
2078                                                        flag_chars[i], NULL);
2079             flag_chars[i - d] = flag_chars[i];
2080             if (flag_chars[i] == fki->length_code_char)
2081               continue;
2082             if (strchr (fci->flag_chars, flag_chars[i]) == 0)
2083               {
2084                 status_warning (status, "%s used with %<%%%c%> %s format",
2085                                 _(s->name), format_char, fki->name);
2086                 d++;
2087                 continue;
2088               }
2089             if (pedantic)
2090               {
2091                 const format_flag_spec *t;
2092                 if (ADJ_STD (s->std) > C_STD_VER)
2093                   status_warning (status, "%s does not support %s",
2094                                   C_STD_NAME (s->std), _(s->long_name));
2095                 t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
2096                 if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
2097                   {
2098                     const char *long_name = (t->long_name != NULL
2099                                              ? t->long_name
2100                                              : s->long_name);
2101                     if (ADJ_STD (t->std) > C_STD_VER)
2102                       status_warning (status, "%s does not support %s with the %<%%%c%> %s format",
2103                                       C_STD_NAME (t->std), _(long_name),
2104                                       format_char, fki->name);
2105                   }
2106               }
2107           }
2108         flag_chars[i - d] = 0;
2109       }
2110
2111       if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
2112           && strchr (flag_chars, 'a') != 0)
2113         aflag = 1;
2114
2115       if (fki->suppression_char
2116           && strchr (flag_chars, fki->suppression_char) != 0)
2117         suppressed = 1;
2118
2119       /* Validate the pairs of flags used.  */
2120       for (i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
2121         {
2122           const format_flag_spec *s, *t;
2123           if (strchr (flag_chars, bad_flag_pairs[i].flag_char1) == 0)
2124             continue;
2125           if (strchr (flag_chars, bad_flag_pairs[i].flag_char2) == 0)
2126             continue;
2127           if (bad_flag_pairs[i].predicate != 0
2128               && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
2129             continue;
2130           s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
2131           t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
2132           if (bad_flag_pairs[i].ignored)
2133             {
2134               if (bad_flag_pairs[i].predicate != 0)
2135                 status_warning (status, "%s ignored with %s and %<%%%c%> %s format",
2136                                 _(s->name), _(t->name), format_char,
2137                                 fki->name);
2138               else
2139                 status_warning (status, "%s ignored with %s in %s format",
2140                                 _(s->name), _(t->name), fki->name);
2141             }
2142           else
2143             {
2144               if (bad_flag_pairs[i].predicate != 0)
2145                 status_warning (status, "use of %s and %s together with %<%%%c%> %s format",
2146                                 _(s->name), _(t->name), format_char,
2147                                 fki->name);
2148               else
2149                 status_warning (status, "use of %s and %s together in %s format",
2150                                 _(s->name), _(t->name), fki->name);
2151             }
2152         }
2153
2154       /* Give Y2K warnings.  */
2155       if (warn_format_y2k)
2156         {
2157           int y2k_level = 0;
2158           if (strchr (fci->flags2, '4') != 0)
2159             if (strchr (flag_chars, 'E') != 0)
2160               y2k_level = 3;
2161             else
2162               y2k_level = 2;
2163           else if (strchr (fci->flags2, '3') != 0)
2164             y2k_level = 3;
2165           else if (strchr (fci->flags2, '2') != 0)
2166             y2k_level = 2;
2167           if (y2k_level == 3)
2168             status_warning (status, "%<%%%c%> yields only last 2 digits of year in some locales",
2169                             format_char);
2170           else if (y2k_level == 2)
2171             status_warning (status, "%<%%%c%> yields only last 2 digits of year", format_char);
2172         }
2173
2174       if (strchr (fci->flags2, '[') != 0)
2175         {
2176           /* Skip over scan set, in case it happens to have '%' in it.  */
2177           if (*format_chars == '^')
2178             ++format_chars;
2179           /* Find closing bracket; if one is hit immediately, then
2180              it's part of the scan set rather than a terminator.  */
2181           if (*format_chars == ']')
2182             ++format_chars;
2183           while (*format_chars && *format_chars != ']')
2184             ++format_chars;
2185           if (*format_chars != ']')
2186             /* The end of the format string was reached.  */
2187             status_warning (status, "no closing %<]%> for %<%%[%> format");
2188         }
2189
2190       wanted_type = 0;
2191       wanted_type_name = 0;
2192       if (fki->flags & (int) FMT_FLAG_ARG_CONVERT)
2193         {
2194           wanted_type = (fci->types[length_chars_val].type
2195                          ? *fci->types[length_chars_val].type : 0);
2196           wanted_type_name = fci->types[length_chars_val].name;
2197           wanted_type_std = fci->types[length_chars_val].std;
2198           if (wanted_type == 0)
2199             {
2200               status_warning (status, "use of %qs length modifier with %qc type character",
2201                               length_chars, format_char);
2202               /* Heuristic: skip one argument when an invalid length/type
2203                  combination is encountered.  */
2204               arg_num++;
2205               if (params == 0)
2206                 {
2207                   status_warning (status, "too few arguments for format");
2208                   return;
2209                 }
2210               params = TREE_CHAIN (params);
2211               continue;
2212             }
2213           else if (pedantic
2214                    /* Warn if non-standard, provided it is more non-standard
2215                       than the length and type characters that may already
2216                       have been warned for.  */
2217                    && ADJ_STD (wanted_type_std) > ADJ_STD (length_chars_std)
2218                    && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
2219             {
2220               if (ADJ_STD (wanted_type_std) > C_STD_VER)
2221                 status_warning (status, "%s does not support the %<%%%s%c%> %s format",
2222                                 C_STD_NAME (wanted_type_std), length_chars,
2223                                 format_char, fki->name);
2224             }
2225         }
2226
2227       /* Finally. . .check type of argument against desired type!  */
2228       if (info->first_arg_num == 0)
2229         continue;
2230       if ((fci->pointer_count == 0 && wanted_type == void_type_node)
2231           || suppressed)
2232         {
2233           if (main_arg_num != 0)
2234             {
2235               if (suppressed)
2236                 status_warning (status, "operand number specified with suppressed assignment");
2237               else
2238                 status_warning (status, "operand number specified for format taking no argument");
2239             }
2240         }
2241       else
2242         {
2243           if (main_arg_num != 0)
2244             {
2245               arg_num = main_arg_num;
2246               params = main_arg_params;
2247             }
2248           else
2249             {
2250               ++arg_num;
2251               if (has_operand_number > 0)
2252                 {
2253                   status_warning (status, "missing $ operand number in format");
2254                   return;
2255                 }
2256               else
2257                 has_operand_number = 0;
2258               if (params == 0)
2259                 {
2260                   status_warning (status, "too few arguments for format");
2261                   return;
2262                 }
2263             }
2264           cur_param = TREE_VALUE (params);
2265           params = TREE_CHAIN (params);
2266           main_wanted_type.wanted_type = wanted_type;
2267           main_wanted_type.wanted_type_name = wanted_type_name;
2268           main_wanted_type.pointer_count = fci->pointer_count + aflag;
2269           main_wanted_type.char_lenient_flag = 0;
2270           if (strchr (fci->flags2, 'c') != 0)
2271             main_wanted_type.char_lenient_flag = 1;
2272           main_wanted_type.writing_in_flag = 0;
2273           main_wanted_type.reading_from_flag = 0;
2274           if (aflag)
2275             main_wanted_type.writing_in_flag = 1;
2276           else
2277             {
2278               if (strchr (fci->flags2, 'W') != 0)
2279                 main_wanted_type.writing_in_flag = 1;
2280               if (strchr (fci->flags2, 'R') != 0)
2281                 main_wanted_type.reading_from_flag = 1;
2282             }
2283           main_wanted_type.name = NULL;
2284           main_wanted_type.param = cur_param;
2285           main_wanted_type.arg_num = arg_num;
2286           main_wanted_type.next = NULL;
2287           if (last_wanted_type != 0)
2288             last_wanted_type->next = &main_wanted_type;
2289           if (first_wanted_type == 0)
2290             first_wanted_type = &main_wanted_type;
2291           last_wanted_type = &main_wanted_type;
2292         }
2293
2294       if (first_wanted_type != 0)
2295         check_format_types (status, first_wanted_type);
2296
2297     }
2298 }
2299
2300
2301 /* Check the argument types from a single format conversion (possibly
2302    including width and precision arguments).  */
2303 static void
2304 check_format_types (int *status, format_wanted_type *types)
2305 {
2306   for (; types != 0; types = types->next)
2307     {
2308       tree cur_param;
2309       tree cur_type;
2310       tree orig_cur_type;
2311       tree wanted_type;
2312       int arg_num;
2313       int i;
2314       int char_type_flag;
2315       cur_param = types->param;
2316       cur_type = TREE_TYPE (cur_param);
2317       if (cur_type == error_mark_node)
2318         continue;
2319       char_type_flag = 0;
2320       wanted_type = types->wanted_type;
2321       arg_num = types->arg_num;
2322
2323       /* The following should not occur here.  */
2324       if (wanted_type == 0)
2325         abort ();
2326       if (wanted_type == void_type_node && types->pointer_count == 0)
2327         abort ();
2328
2329       if (types->pointer_count == 0)
2330         wanted_type = lang_hooks.types.type_promotes_to (wanted_type);
2331
2332       STRIP_NOPS (cur_param);
2333
2334       /* Check the types of any additional pointer arguments
2335          that precede the "real" argument.  */
2336       for (i = 0; i < types->pointer_count; ++i)
2337         {
2338           if (TREE_CODE (cur_type) == POINTER_TYPE)
2339             {
2340               cur_type = TREE_TYPE (cur_type);
2341               if (cur_type == error_mark_node)
2342                 break;
2343
2344               /* Check for writing through a NULL pointer.  */
2345               if (types->writing_in_flag
2346                   && i == 0
2347                   && cur_param != 0
2348                   && integer_zerop (cur_param))
2349                 status_warning (status,
2350                                 "writing through null pointer (arg %d)",
2351                                 arg_num);
2352
2353               /* Check for reading through a NULL pointer.  */
2354               if (types->reading_from_flag
2355                   && i == 0
2356                   && cur_param != 0
2357                   && integer_zerop (cur_param))
2358                 status_warning (status,
2359                                 "reading through null pointer (arg %d)",
2360                                 arg_num);
2361
2362               if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
2363                 cur_param = TREE_OPERAND (cur_param, 0);
2364               else
2365                 cur_param = 0;
2366
2367               /* See if this is an attempt to write into a const type with
2368                  scanf or with printf "%n".  Note: the writing in happens
2369                  at the first indirection only, if for example
2370                  void * const * is passed to scanf %p; passing
2371                  const void ** is simply passing an incompatible type.  */
2372               if (types->writing_in_flag
2373                   && i == 0
2374                   && (TYPE_READONLY (cur_type)
2375                       || (cur_param != 0
2376                           && (TREE_CODE_CLASS (TREE_CODE (cur_param)) == 'c'
2377                               || (DECL_P (cur_param)
2378                                   && TREE_READONLY (cur_param))))))
2379                 status_warning (status, "writing into constant object (arg %d)", arg_num);
2380
2381               /* If there are extra type qualifiers beyond the first
2382                  indirection, then this makes the types technically
2383                  incompatible.  */
2384               if (i > 0
2385                   && pedantic
2386                   && (TYPE_READONLY (cur_type)
2387                       || TYPE_VOLATILE (cur_type)
2388                       || TYPE_RESTRICT (cur_type)))
2389                 status_warning (status, "extra type qualifiers in format argument (arg %d)",
2390                          arg_num);
2391
2392             }
2393           else
2394             {
2395               if (types->pointer_count == 1)
2396                 status_warning (status, "format argument is not a pointer (arg %d)", arg_num);
2397               else
2398                 status_warning (status, "format argument is not a pointer to a pointer (arg %d)", arg_num);
2399               break;
2400             }
2401         }
2402
2403       if (i < types->pointer_count)
2404         continue;
2405
2406       orig_cur_type = cur_type;
2407       cur_type = TYPE_MAIN_VARIANT (cur_type);
2408
2409       /* Check whether the argument type is a character type.  This leniency
2410          only applies to certain formats, flagged with 'c'.
2411       */
2412       if (types->char_lenient_flag)
2413         char_type_flag = (cur_type == char_type_node
2414                           || cur_type == signed_char_type_node
2415                           || cur_type == unsigned_char_type_node);
2416
2417       /* Check the type of the "real" argument, if there's a type we want.  */
2418       if (wanted_type == cur_type)
2419         continue;
2420       /* If we want `void *', allow any pointer type.
2421          (Anything else would already have got a warning.)
2422          With -pedantic, only allow pointers to void and to character
2423          types.  */
2424       if (wanted_type == void_type_node
2425           && (!pedantic || (i == 1 && char_type_flag)))
2426         continue;
2427       /* Don't warn about differences merely in signedness, unless
2428          -pedantic.  With -pedantic, warn if the type is a pointer
2429          target and not a character type, and for character types at
2430          a second level of indirection.  */
2431       if (TREE_CODE (wanted_type) == INTEGER_TYPE
2432           && TREE_CODE (cur_type) == INTEGER_TYPE
2433           && (! pedantic || i == 0 || (i == 1 && char_type_flag))
2434           && (TYPE_UNSIGNED (wanted_type)
2435               ? wanted_type == c_common_unsigned_type (cur_type)
2436               : wanted_type == c_common_signed_type (cur_type)))
2437         continue;
2438       /* Likewise, "signed char", "unsigned char" and "char" are
2439          equivalent but the above test won't consider them equivalent.  */
2440       if (wanted_type == char_type_node
2441           && (! pedantic || i < 2)
2442           && char_type_flag)
2443         continue;
2444       /* Now we have a type mismatch.  */
2445       {
2446         const char *this;
2447         const char *that;
2448         tree tmp;
2449
2450         tmp = TYPE_NAME (wanted_type);
2451         if (TREE_CODE (tmp) == TYPE_DECL)
2452           tmp = DECL_NAME (tmp);
2453         this = IDENTIFIER_POINTER (tmp);
2454
2455         that = 0;
2456         if (TYPE_NAME (orig_cur_type) != 0
2457             && TREE_CODE (orig_cur_type) != INTEGER_TYPE
2458             && !(TREE_CODE (orig_cur_type) == POINTER_TYPE
2459                  && TREE_CODE (TREE_TYPE (orig_cur_type)) == INTEGER_TYPE))
2460           {
2461             tmp = TYPE_NAME (orig_cur_type);
2462             if (TREE_CODE (tmp) == TYPE_DECL)
2463               tmp = DECL_NAME (tmp);
2464             if (tmp)
2465               that = IDENTIFIER_POINTER (tmp);
2466           }
2467
2468         /* A nameless type can't possibly match what the format wants.
2469            So there will be a warning for it.
2470            Make up a string to describe vaguely what it is.  */
2471         if (that == 0)
2472           {
2473             if (TREE_CODE (orig_cur_type) == POINTER_TYPE)
2474               that = _("pointer");
2475             else
2476               that = _("different type");
2477           }
2478
2479         /* Make the warning better in case of mismatch of int vs long.  */
2480         if (TREE_CODE (orig_cur_type) == INTEGER_TYPE
2481             && TREE_CODE (wanted_type) == INTEGER_TYPE
2482             && TYPE_PRECISION (orig_cur_type) == TYPE_PRECISION (wanted_type)
2483             && TYPE_NAME (orig_cur_type) != 0
2484             && TREE_CODE (TYPE_NAME (orig_cur_type)) == TYPE_DECL)
2485           that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (orig_cur_type)));
2486
2487         if (strcmp (this, that) != 0)
2488           {
2489             /* There may be a better name for the format, e.g. size_t,
2490                but we should allow for programs with a perverse typedef
2491                making size_t something other than what the compiler
2492                thinks.  */
2493             if (types->wanted_type_name != 0
2494                 && strcmp (types->wanted_type_name, that) != 0)
2495               this = types->wanted_type_name;
2496             if (types->name != 0)
2497               status_warning (status, "%s is not type %s (arg %d)", types->name, this,
2498                        arg_num);
2499             else
2500               status_warning (status, "%s format, %s arg (arg %d)", this, that, arg_num);
2501           }
2502       }
2503     }
2504 }
2505
2506 /* Given a format_char_info array FCI, and a character C, this function
2507    returns the index into the conversion_specs where that specifier's
2508    data is located.  If the character isn't found it aborts.  */
2509 static unsigned int
2510 find_char_info_specifier_index (const format_char_info *fci, int c)
2511 {
2512   unsigned int i = 0;
2513   
2514   while (fci->format_chars)
2515     {
2516       if (strchr (fci->format_chars, c))
2517         return i;
2518       i++; fci++;
2519     }
2520   
2521   /* We shouldn't be looking for a non-existent specifier.  */
2522   abort ();
2523 }
2524
2525 /* Given a format_length_info array FLI, and a character C, this
2526    function returns the index into the conversion_specs where that
2527    modifier's data is located.  If the character isn't found it
2528    aborts.  */
2529 static unsigned int
2530 find_length_info_modifier_index (const format_length_info *fli, int c)
2531 {
2532   unsigned int i = 0;
2533   
2534   while (fli->name)
2535     {
2536       if (strchr (fli->name, c))
2537         return i;
2538       i++; fli++;
2539     }
2540   
2541   /* We shouldn't be looking for a non-existent modifier.  */
2542   abort ();
2543 }
2544
2545 /* Determine the type of HOST_WIDE_INT in the code being compiled for
2546    use in GCC's __asm_fprintf__ custom format attribute.  You must
2547    have set dynamic_format_types before calling this function.  */
2548 static void
2549 init_dynamic_asm_fprintf_info (void)
2550 {
2551   static tree hwi;
2552       
2553   if (!hwi)
2554     {
2555       format_length_info *new_asm_fprintf_length_specs;
2556       unsigned int i;
2557           
2558       /* Find the underlying type for HOST_WIDE_INT.  For the %w
2559          length modifier to work, one must have issued: "typedef
2560          HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2561          prior to using that modifier.  */
2562       if (!(hwi = maybe_get_identifier ("__gcc_host_wide_int__"))
2563           || !(hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi))))
2564         abort ();
2565
2566       /* Create a new (writable) copy of asm_fprintf_length_specs.  */
2567       new_asm_fprintf_length_specs = xmemdup (asm_fprintf_length_specs,
2568                                               sizeof (asm_fprintf_length_specs),
2569                                               sizeof (asm_fprintf_length_specs));
2570
2571       /* HOST_WIDE_INT must be one of 'long' or 'long long'.  */
2572       i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
2573       if (hwi == long_integer_type_node)
2574         new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
2575       else if (hwi == long_long_integer_type_node)
2576         new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
2577       else
2578         abort ();
2579
2580       /* Assign the new data for use.  */
2581       dynamic_format_types[asm_fprintf_format_type].length_char_specs =
2582         new_asm_fprintf_length_specs;
2583     }
2584 }
2585
2586 /* Determine the types of "tree" and "location_t" in the code being
2587    compiled for use in GCC's diagnostic custom format attributes.  You
2588    must have set dynamic_format_types before calling this function.  */
2589 static void
2590 init_dynamic_diag_info (void)
2591 {
2592   static tree t, loc, hwi;
2593       
2594   if (!loc || !t || !hwi)
2595     {
2596       static format_char_info *diag_fci, *cdiag_fci, *cxxdiag_fci;
2597       static format_length_info *diag_ls;
2598       unsigned int i;
2599
2600       /* For the GCC-diagnostics custom format specifiers to work, one
2601          must have declared `tree' and/or `location_t' prior to using
2602          those attributes.  If we haven't seen these declarations then
2603          you shouldn't use the specifiers requiring these types.
2604          However we don't force a hard ICE because we may see only one
2605          or the other type.  */
2606       if ((loc = maybe_get_identifier ("location_t")))
2607         loc = TREE_TYPE (identifier_global_value (loc));
2608
2609       /* We need to grab the underlying `union tree_node' so peek into
2610          an extra type level.  */
2611       if ((t = maybe_get_identifier ("tree")))
2612         t = TREE_TYPE (TREE_TYPE (identifier_global_value (t)));
2613     
2614       /* Find the underlying type for HOST_WIDE_INT.  For the %w
2615          length modifier to work, one must have issued: "typedef
2616          HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2617          prior to using that modifier.  */
2618       if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
2619         hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi));
2620       
2621       /* Assign the new data for use.  */
2622
2623       /* All the GCC diag formats use the same length specs.  */
2624       if (! diag_ls)
2625         dynamic_format_types[gcc_diag_format_type].length_char_specs =
2626           dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
2627           dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
2628           diag_ls = xmemdup (gcc_diag_length_specs,
2629                              sizeof (gcc_diag_length_specs),
2630                              sizeof (gcc_diag_length_specs)); 
2631       if (hwi)
2632         {
2633           /* HOST_WIDE_INT must be one of 'long' or 'long long'.  */
2634           i = find_length_info_modifier_index (diag_ls, 'w');
2635           if (hwi == long_integer_type_node)
2636             diag_ls[i].index = FMT_LEN_l;
2637           else if (hwi == long_long_integer_type_node)
2638             diag_ls[i].index = FMT_LEN_ll;
2639           else
2640             abort ();
2641         }
2642
2643       /* Handle the __gcc_diag__ format specifics.  */
2644       if (! diag_fci)
2645         dynamic_format_types[gcc_diag_format_type].conversion_specs =
2646           diag_fci = xmemdup (gcc_diag_char_table,
2647                               sizeof(gcc_diag_char_table),
2648                               sizeof(gcc_diag_char_table));
2649       if (loc)
2650         {
2651           i = find_char_info_specifier_index (diag_fci, 'H');
2652           diag_fci[i].types[0].type = &loc;
2653           diag_fci[i].pointer_count = 1;
2654         }
2655       if (t)
2656         {
2657           i = find_char_info_specifier_index (diag_fci, 'J');
2658           diag_fci[i].types[0].type = &t;
2659           diag_fci[i].pointer_count = 1;
2660         }
2661
2662       /* Handle the __gcc_cdiag__ format specifics.  */
2663       if (! cdiag_fci)
2664         dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
2665           cdiag_fci = xmemdup (gcc_cdiag_char_table,
2666                                sizeof(gcc_cdiag_char_table),
2667                                sizeof(gcc_cdiag_char_table));
2668       if (loc)
2669         {
2670           i = find_char_info_specifier_index (cdiag_fci, 'H');
2671           cdiag_fci[i].types[0].type = &loc;
2672           cdiag_fci[i].pointer_count = 1;
2673         }
2674       if (t)
2675         {
2676           /* All specifiers taking a tree share the same struct.  */
2677           i = find_char_info_specifier_index (cdiag_fci, 'D');
2678           cdiag_fci[i].types[0].type = &t;
2679           cdiag_fci[i].pointer_count = 1;
2680           i = find_char_info_specifier_index (cdiag_fci, 'J');
2681           cdiag_fci[i].types[0].type = &t;
2682           cdiag_fci[i].pointer_count = 1;
2683         }
2684
2685       /* Handle the __gcc_cxxdiag__ format specifics.  */
2686       if (! cxxdiag_fci)
2687         dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
2688           cxxdiag_fci = xmemdup (gcc_cxxdiag_char_table,
2689                                  sizeof(gcc_cxxdiag_char_table),
2690                                  sizeof(gcc_cxxdiag_char_table));
2691       if (loc)
2692         {
2693           i = find_char_info_specifier_index (cxxdiag_fci, 'H');
2694           cxxdiag_fci[i].types[0].type = &loc;
2695           cxxdiag_fci[i].pointer_count = 1;
2696         }
2697       if (t)
2698         {
2699           /* All specifiers taking a tree share the same struct.  */
2700           i = find_char_info_specifier_index (cxxdiag_fci, 'D');
2701           cxxdiag_fci[i].types[0].type = &t;
2702           cxxdiag_fci[i].pointer_count = 1;
2703           i = find_char_info_specifier_index (cxxdiag_fci, 'J');
2704           cxxdiag_fci[i].types[0].type = &t;
2705           cxxdiag_fci[i].pointer_count = 1;
2706         }
2707     }
2708 }
2709
2710 /* Handle a "format" attribute; arguments as in
2711    struct attribute_spec.handler.  */
2712 tree
2713 handle_format_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
2714                          int flags, bool *no_add_attrs)
2715 {
2716   tree type = *node;
2717   function_format_info info;
2718   tree argument;
2719
2720   if (!decode_format_attr (args, &info, 0))
2721     {
2722       *no_add_attrs = true;
2723       return NULL_TREE;
2724     }
2725
2726   argument = TYPE_ARG_TYPES (type);
2727   if (argument)
2728     {
2729       if (!check_format_string (argument, info.format_num, flags,
2730                                 no_add_attrs))
2731         return NULL_TREE;
2732
2733       if (info.first_arg_num != 0)
2734         {
2735           unsigned HOST_WIDE_INT arg_num = 1;
2736
2737           /* Verify that first_arg_num points to the last arg,
2738              the ...  */
2739           while (argument)
2740             arg_num++, argument = TREE_CHAIN (argument);
2741
2742           if (arg_num != info.first_arg_num)
2743             {
2744               if (!(flags & (int) ATTR_FLAG_BUILT_IN))
2745                 error ("args to be formatted is not '...'");
2746               *no_add_attrs = true;
2747               return NULL_TREE;
2748             }
2749         }
2750     }
2751
2752   if (info.format_type == strftime_format_type && info.first_arg_num != 0)
2753     {
2754       error ("strftime formats cannot format arguments");
2755       *no_add_attrs = true;
2756       return NULL_TREE;
2757     }
2758
2759   /* If this is a custom GCC-internal format type, we have to
2760      initialize certain bits a runtime.  */
2761   if (info.format_type == asm_fprintf_format_type
2762       || info.format_type == gcc_diag_format_type
2763       || info.format_type == gcc_cdiag_format_type
2764       || info.format_type == gcc_cxxdiag_format_type)
2765     {
2766       /* Our first time through, we have to make sure that our
2767          format_type data is allocated dynamically and is modifiable.  */
2768       if (!dynamic_format_types)
2769         format_types = dynamic_format_types =
2770           xmemdup (format_types_orig, sizeof (format_types_orig),
2771                    sizeof (format_types_orig));
2772
2773       /* If this is format __asm_fprintf__, we have to initialize
2774          GCC's notion of HOST_WIDE_INT for checking %wd.  */
2775       if (info.format_type == asm_fprintf_format_type)
2776         init_dynamic_asm_fprintf_info();
2777       /* If this is one of the diagnostic attributes, then we have to
2778          initialize `location_t' and `tree' at runtime.  */
2779       else if (info.format_type == gcc_diag_format_type
2780                || info.format_type == gcc_cdiag_format_type
2781                || info.format_type == gcc_cxxdiag_format_type)
2782         init_dynamic_diag_info();
2783       else
2784         abort();
2785     }
2786
2787   return NULL_TREE;
2788 }