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