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