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