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