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