OSDN Git Service

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