OSDN Git Service

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