OSDN Git Service

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