OSDN Git Service

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