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