OSDN Git Service

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