OSDN Git Service

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