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