OSDN Git Service

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