OSDN Git Service

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