OSDN Git Service

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