dma: bump man page date
[dragonfly.git] / contrib / gcc-4.4 / gcc / c-format.c
blob54c8cd05a0f33d370e6ce26abcac81659c4f3f99
1 /* Check calls to formatted I/O functions (-Wformat).
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
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.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "c-common.h"
28 #include "toplev.h"
29 #include "intl.h"
30 #include "diagnostic.h"
31 #include "langhooks.h"
32 #include "c-format.h"
33 #include "alloc-pool.h"
35 /* Set format warning options according to a -Wformat=n option. */
37 void
38 set_Wformat (int setting)
40 warn_format = setting;
41 warn_format_extra_args = setting;
42 warn_format_zero_length = setting;
43 warn_format_contains_nul = setting;
44 if (setting != 1)
46 warn_format_nonliteral = setting;
47 warn_format_security = setting;
48 warn_format_y2k = setting;
50 /* Make sure not to disable -Wnonnull if -Wformat=0 is specified. */
51 if (setting)
52 warn_nonnull = setting;
56 /* Handle attributes associated with format checking. */
58 /* This must be in the same order as format_types, except for
59 format_type_error. Target-specific format types do not have
60 matching enum values. */
61 enum format_type { printf_format_type, asm_fprintf_format_type,
62 gcc_diag_format_type, gcc_tdiag_format_type,
63 gcc_cdiag_format_type,
64 gcc_cxxdiag_format_type, gcc_gfc_format_type,
65 format_type_error = -1};
67 typedef struct function_format_info
69 int format_type; /* type of format (printf, scanf, etc.) */
70 unsigned HOST_WIDE_INT format_num; /* number of format argument */
71 unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */
72 } function_format_info;
74 static bool decode_format_attr (tree, function_format_info *, int);
75 static int decode_format_type (const char *);
77 static bool check_format_string (tree argument,
78 unsigned HOST_WIDE_INT format_num,
79 int flags, bool *no_add_attrs);
80 static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value,
81 int validated_p);
82 static const char *convert_format_name_to_system_name (const char *attr_name);
83 static bool cmp_attribs (const char *tattr_name, const char *attr_name);
85 /* Handle a "format_arg" attribute; arguments as in
86 struct attribute_spec.handler. */
87 tree
88 handle_format_arg_attribute (tree *node, tree ARG_UNUSED (name),
89 tree args, int flags, bool *no_add_attrs)
91 tree type = *node;
92 tree format_num_expr = TREE_VALUE (args);
93 unsigned HOST_WIDE_INT format_num = 0;
94 tree argument;
96 if (!get_constant (format_num_expr, &format_num, 0))
98 error ("format string has invalid operand number");
99 *no_add_attrs = true;
100 return NULL_TREE;
103 argument = TYPE_ARG_TYPES (type);
104 if (argument)
106 if (!check_format_string (argument, format_num, flags, no_add_attrs))
107 return NULL_TREE;
110 if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
111 || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
112 != char_type_node))
114 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
115 error ("function does not return string type");
116 *no_add_attrs = true;
117 return NULL_TREE;
120 return NULL_TREE;
123 /* Verify that the format_num argument is actually a string, in case
124 the format attribute is in error. */
125 static bool
126 check_format_string (tree argument, unsigned HOST_WIDE_INT format_num,
127 int flags, bool *no_add_attrs)
129 unsigned HOST_WIDE_INT i;
131 for (i = 1; i != format_num; i++)
133 if (argument == 0)
134 break;
135 argument = TREE_CHAIN (argument);
138 if (!argument
139 || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
140 || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
141 != char_type_node))
143 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
144 error ("format string argument not a string type");
145 *no_add_attrs = true;
146 return false;
149 return true;
152 /* Verify EXPR is a constant, and store its value.
153 If validated_p is true there should be no errors.
154 Returns true on success, false otherwise. */
155 static bool
156 get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
158 if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0)
160 gcc_assert (!validated_p);
161 return false;
164 *value = TREE_INT_CST_LOW (expr);
166 return true;
169 /* Decode the arguments to a "format" attribute into a
170 function_format_info structure. It is already known that the list
171 is of the right length. If VALIDATED_P is true, then these
172 attributes have already been validated and must not be erroneous;
173 if false, it will give an error message. Returns true if the
174 attributes are successfully decoded, false otherwise. */
176 static bool
177 decode_format_attr (tree args, function_format_info *info, int validated_p)
179 tree format_type_id = TREE_VALUE (args);
180 tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
181 tree first_arg_num_expr
182 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
184 if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
186 gcc_assert (!validated_p);
187 error ("unrecognized format specifier");
188 return false;
190 else
192 const char *p = IDENTIFIER_POINTER (format_type_id);
194 p = convert_format_name_to_system_name (p);
196 info->format_type = decode_format_type (p);
198 if (info->format_type == format_type_error)
200 gcc_assert (!validated_p);
201 warning (OPT_Wformat, "%qE is an unrecognized format function type",
202 format_type_id);
203 return false;
207 if (!get_constant (format_num_expr, &info->format_num, validated_p))
209 error ("format string has invalid operand number");
210 return false;
213 if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
215 error ("%<...%> has invalid operand number");
216 return false;
219 if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
221 gcc_assert (!validated_p);
222 error ("format string argument follows the args to be formatted");
223 return false;
226 return true;
229 /* Check a call to a format function against a parameter list. */
231 /* The C standard version C++ is treated as equivalent to
232 or inheriting from, for the purpose of format features supported. */
233 #define CPLUSPLUS_STD_VER STD_C94
234 /* The C standard version we are checking formats against when pedantic. */
235 #define C_STD_VER ((int) (c_dialect_cxx () \
236 ? CPLUSPLUS_STD_VER \
237 : (flag_isoc99 \
238 ? STD_C99 \
239 : (flag_isoc94 ? STD_C94 : STD_C89))))
240 /* The name to give to the standard version we are warning about when
241 pedantic. FEATURE_VER is the version in which the feature warned out
242 appeared, which is higher than C_STD_VER. */
243 #define C_STD_NAME(FEATURE_VER) (c_dialect_cxx () \
244 ? "ISO C++" \
245 : ((FEATURE_VER) == STD_EXT \
246 ? "ISO C" \
247 : "ISO C90"))
248 /* Adjust a C standard version, which may be STD_C9L, to account for
249 -Wno-long-long. Returns other standard versions unchanged. */
250 #define ADJ_STD(VER) ((int) ((VER) == STD_C9L \
251 ? (warn_long_long ? STD_C99 : STD_C89) \
252 : (VER)))
254 /* Structure describing details of a type expected in format checking,
255 and the type to check against it. */
256 typedef struct format_wanted_type
258 /* The type wanted. */
259 tree wanted_type;
260 /* The name of this type to use in diagnostics. */
261 const char *wanted_type_name;
262 /* The level of indirection through pointers at which this type occurs. */
263 int pointer_count;
264 /* Whether, when pointer_count is 1, to allow any character type when
265 pedantic, rather than just the character or void type specified. */
266 int char_lenient_flag;
267 /* Whether the argument, dereferenced once, is written into and so the
268 argument must not be a pointer to a const-qualified type. */
269 int writing_in_flag;
270 /* Whether the argument, dereferenced once, is read from and so
271 must not be a NULL pointer. */
272 int reading_from_flag;
273 /* If warnings should be of the form "field precision should have
274 type 'int'", the name to use (in this case "field precision"),
275 otherwise NULL, for "format expects type 'long'" type
276 messages. */
277 const char *name;
278 /* The actual parameter to check against the wanted type. */
279 tree param;
280 /* The argument number of that parameter. */
281 int arg_num;
282 /* The next type to check for this format conversion, or NULL if none. */
283 struct format_wanted_type *next;
284 } format_wanted_type;
286 /* Convenience macro for format_length_info meaning unused. */
287 #define NO_FMT NULL, FMT_LEN_none, STD_C89
289 static const format_length_info printf_length_specs[] =
291 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
292 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
293 { "q", FMT_LEN_ll, STD_EXT, NO_FMT },
294 { "L", FMT_LEN_L, STD_C89, NO_FMT },
295 { "z", FMT_LEN_z, STD_C99, NO_FMT },
296 { "Z", FMT_LEN_z, STD_EXT, NO_FMT },
297 { "t", FMT_LEN_t, STD_C99, NO_FMT },
298 { "j", FMT_LEN_j, STD_C99, NO_FMT },
299 { "H", FMT_LEN_H, STD_EXT, NO_FMT },
300 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT },
301 { NO_FMT, NO_FMT }
304 /* Length specifiers valid for asm_fprintf. */
305 static const format_length_info asm_fprintf_length_specs[] =
307 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
308 { "w", FMT_LEN_none, STD_C89, NO_FMT },
309 { NO_FMT, NO_FMT }
312 /* Length specifiers valid for GCC diagnostics. */
313 static const format_length_info gcc_diag_length_specs[] =
315 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
316 { "w", FMT_LEN_none, STD_C89, NO_FMT },
317 { NO_FMT, NO_FMT }
320 /* The custom diagnostics all accept the same length specifiers. */
321 #define gcc_tdiag_length_specs gcc_diag_length_specs
322 #define gcc_cdiag_length_specs gcc_diag_length_specs
323 #define gcc_cxxdiag_length_specs gcc_diag_length_specs
325 /* This differs from printf_length_specs only in that "Z" is not accepted. */
326 static const format_length_info scanf_length_specs[] =
328 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
329 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
330 { "q", FMT_LEN_ll, STD_EXT, NO_FMT },
331 { "L", FMT_LEN_L, STD_C89, NO_FMT },
332 { "z", FMT_LEN_z, STD_C99, NO_FMT },
333 { "t", FMT_LEN_t, STD_C99, NO_FMT },
334 { "j", FMT_LEN_j, STD_C99, NO_FMT },
335 { "H", FMT_LEN_H, STD_EXT, NO_FMT },
336 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT },
337 { NO_FMT, NO_FMT }
341 /* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings
342 make no sense for a format type not part of any C standard version. */
343 static const format_length_info strfmon_length_specs[] =
345 /* A GNU extension. */
346 { "L", FMT_LEN_L, STD_C89, NO_FMT },
347 { NO_FMT, NO_FMT }
351 /* For now, the Fortran front-end routines only use l as length modifier. */
352 static const format_length_info gcc_gfc_length_specs[] =
354 { "l", FMT_LEN_l, STD_C89, NO_FMT },
355 { NO_FMT, NO_FMT }
359 static const format_flag_spec printf_flag_specs[] =
361 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
362 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
363 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
364 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
365 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
366 { '\'', 0, 0, N_("''' flag"), N_("the ''' printf flag"), STD_EXT },
367 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' printf flag"), STD_EXT },
368 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
369 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
370 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
371 { 0, 0, 0, NULL, NULL, STD_C89 }
375 static const format_flag_pair printf_flag_pairs[] =
377 { ' ', '+', 1, 0 },
378 { '0', '-', 1, 0 },
379 { '0', 'p', 1, 'i' },
380 { 0, 0, 0, 0 }
383 static const format_flag_spec asm_fprintf_flag_specs[] =
385 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
386 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
387 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
388 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
389 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
390 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
391 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
392 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
393 { 0, 0, 0, NULL, NULL, STD_C89 }
396 static const format_flag_pair asm_fprintf_flag_pairs[] =
398 { ' ', '+', 1, 0 },
399 { '0', '-', 1, 0 },
400 { '0', 'p', 1, 'i' },
401 { 0, 0, 0, 0 }
404 static const format_flag_pair gcc_diag_flag_pairs[] =
406 { 0, 0, 0, 0 }
409 #define gcc_tdiag_flag_pairs gcc_diag_flag_pairs
410 #define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
411 #define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
413 static const format_flag_pair gcc_gfc_flag_pairs[] =
415 { 0, 0, 0, 0 }
418 static const format_flag_spec gcc_diag_flag_specs[] =
420 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
421 { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 },
422 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
423 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
424 { 0, 0, 0, NULL, NULL, STD_C89 }
427 #define gcc_tdiag_flag_specs gcc_diag_flag_specs
428 #define gcc_cdiag_flag_specs gcc_diag_flag_specs
430 static const format_flag_spec gcc_cxxdiag_flag_specs[] =
432 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
433 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
434 { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 },
435 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
436 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
437 { 0, 0, 0, NULL, NULL, STD_C89 }
440 static const format_flag_spec scanf_flag_specs[] =
442 { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
443 { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
444 { 'm', 0, 0, N_("'m' flag"), N_("the 'm' scanf flag"), STD_EXT },
445 { 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
446 { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
447 { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT },
448 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT },
449 { 0, 0, 0, NULL, NULL, STD_C89 }
453 static const format_flag_pair scanf_flag_pairs[] =
455 { '*', 'L', 0, 0 },
456 { 'a', 'm', 0, 0 },
457 { 0, 0, 0, 0 }
461 static const format_flag_spec strftime_flag_specs[] =
463 { '_', 0, 0, N_("'_' flag"), N_("the '_' strftime flag"), STD_EXT },
464 { '-', 0, 0, N_("'-' flag"), N_("the '-' strftime flag"), STD_EXT },
465 { '0', 0, 0, N_("'0' flag"), N_("the '0' strftime flag"), STD_EXT },
466 { '^', 0, 0, N_("'^' flag"), N_("the '^' strftime flag"), STD_EXT },
467 { '#', 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), STD_EXT },
468 { 'w', 0, 0, N_("field width"), N_("field width in strftime format"), STD_EXT },
469 { 'E', 0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"), STD_C99 },
470 { 'O', 0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"), STD_C99 },
471 { 'O', 'o', 0, NULL, N_("the 'O' modifier"), STD_EXT },
472 { 0, 0, 0, NULL, NULL, STD_C89 }
476 static const format_flag_pair strftime_flag_pairs[] =
478 { 'E', 'O', 0, 0 },
479 { '_', '-', 0, 0 },
480 { '_', '0', 0, 0 },
481 { '-', '0', 0, 0 },
482 { '^', '#', 0, 0 },
483 { 0, 0, 0, 0 }
487 static const format_flag_spec strfmon_flag_specs[] =
489 { '=', 0, 1, N_("fill character"), N_("fill character in strfmon format"), STD_C89 },
490 { '^', 0, 0, N_("'^' flag"), N_("the '^' strfmon flag"), STD_C89 },
491 { '+', 0, 0, N_("'+' flag"), N_("the '+' strfmon flag"), STD_C89 },
492 { '(', 0, 0, N_("'(' flag"), N_("the '(' strfmon flag"), STD_C89 },
493 { '!', 0, 0, N_("'!' flag"), N_("the '!' strfmon flag"), STD_C89 },
494 { '-', 0, 0, N_("'-' flag"), N_("the '-' strfmon flag"), STD_C89 },
495 { 'w', 0, 0, N_("field width"), N_("field width in strfmon format"), STD_C89 },
496 { '#', 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 },
497 { 'p', 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
498 { 'L', 0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 },
499 { 0, 0, 0, NULL, NULL, STD_C89 }
502 static const format_flag_pair strfmon_flag_pairs[] =
504 { '+', '(', 0, 0 },
505 { 0, 0, 0, 0 }
509 static const format_char_info print_char_table[] =
511 /* C89 conversion specifiers. */
512 { "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 },
513 { "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 },
514 { "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 },
515 { "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 },
516 { "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 },
517 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
518 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
519 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
520 { "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 },
521 /* C99 conversion specifiers. */
522 { "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 },
523 { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
524 /* X/Open conversion specifiers. */
525 { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
526 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
527 /* GNU conversion specifiers. */
528 { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL },
529 /* BSD conversion specifiers. */
530 /* DragonFly kernel extensions (src/sys/kern/subr_prf.c).
531 The format %b is supported to decode error registers.
532 Its usage is: printf("reg=%b\n", regval, "<base><arg>*");
533 which produces: reg=3<BITTWO,BITONE>
534 The format %D provides a hexdump given a pointer and separator string:
535 ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
536 ("%*D", len, ptr, " ") -> XX XX XX XX ...
538 { "D", 1, STD_EXT, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
539 { "b", 1, STD_EXT, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL },
540 { "ry", 0, STD_EXT, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "i", NULL },
541 { "z", 0, STD_EXT, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
542 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
545 static const format_char_info asm_fprintf_char_table[] =
547 /* C89 conversion specifiers. */
548 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL },
549 { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
550 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL },
551 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
552 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
554 /* asm_fprintf conversion specifiers. */
555 { "O", 0, STD_C89, NOARGUMENTS, "", "", NULL },
556 { "R", 0, STD_C89, NOARGUMENTS, "", "", NULL },
557 { "I", 0, STD_C89, NOARGUMENTS, "", "", NULL },
558 { "L", 0, STD_C89, NOARGUMENTS, "", "", NULL },
559 { "U", 0, STD_C89, NOARGUMENTS, "", "", NULL },
560 { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
561 { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL },
562 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
565 static const format_char_info gcc_diag_char_table[] =
567 /* C89 conversion specifiers. */
568 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
569 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
570 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
571 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
572 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
573 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
575 /* Custom conversion specifiers. */
577 /* %H will require "location_t" at runtime. */
578 { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
580 /* These will require a "tree" at runtime. */
581 { "JK", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
583 { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
584 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
585 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
588 static const format_char_info gcc_tdiag_char_table[] =
590 /* C89 conversion specifiers. */
591 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
592 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
593 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
594 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
595 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
596 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
598 /* Custom conversion specifiers. */
600 /* %H will require "location_t" at runtime. */
601 { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
603 /* These will require a "tree" at runtime. */
604 { "DFJKT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
606 { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
607 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
608 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
611 static const format_char_info gcc_cdiag_char_table[] =
613 /* C89 conversion specifiers. */
614 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
615 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
616 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
617 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
618 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
619 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
621 /* Custom conversion specifiers. */
623 /* %H will require "location_t" at runtime. */
624 { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
626 /* These will require a "tree" at runtime. */
627 { "DEFJKT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
629 { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
630 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
631 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
634 static const format_char_info gcc_cxxdiag_char_table[] =
636 /* C89 conversion specifiers. */
637 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
638 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
639 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
640 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
641 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
642 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
644 /* Custom conversion specifiers. */
646 /* %H will require "location_t" at runtime. */
647 { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
649 /* These will require a "tree" at runtime. */
650 { "ADEFJKTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
652 /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
653 { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
655 { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
656 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
657 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
660 static const format_char_info gcc_gfc_char_table[] =
662 /* C89 conversion specifiers. */
663 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
664 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
665 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
666 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
668 /* gfc conversion specifiers. */
670 { "C", 0, STD_C89, NOARGUMENTS, "", "", NULL },
672 /* This will require a "locus" at runtime. */
673 { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL },
675 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
678 static const format_char_info scan_char_table[] =
680 /* C89 conversion specifiers. */
681 { "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 },
682 { "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 },
683 { "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 },
684 { "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 },
685 { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "cW", NULL },
686 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW", NULL },
687 { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW[", NULL },
688 { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
689 { "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 },
690 /* C99 conversion specifiers. */
691 { "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 },
692 { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
693 /* X/Open conversion specifiers. */
694 { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "W", NULL },
695 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "W", NULL },
696 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
699 static const format_char_info time_char_table[] =
701 /* C89 conversion specifiers. */
702 { "ABZab", 0, STD_C89, NOLENGTHS, "^#", "", NULL },
703 { "cx", 0, STD_C89, NOLENGTHS, "E", "3", NULL },
704 { "HIMSUWdmw", 0, STD_C89, NOLENGTHS, "-_0Ow", "", NULL },
705 { "j", 0, STD_C89, NOLENGTHS, "-_0Ow", "o", NULL },
706 { "p", 0, STD_C89, NOLENGTHS, "#", "", NULL },
707 { "X", 0, STD_C89, NOLENGTHS, "E", "", NULL },
708 { "y", 0, STD_C89, NOLENGTHS, "EO-_0w", "4", NULL },
709 { "Y", 0, STD_C89, NOLENGTHS, "-_0EOw", "o", NULL },
710 { "%", 0, STD_C89, NOLENGTHS, "", "", NULL },
711 /* C99 conversion specifiers. */
712 { "C", 0, STD_C99, NOLENGTHS, "-_0EOw", "o", NULL },
713 { "D", 0, STD_C99, NOLENGTHS, "", "2", NULL },
714 { "eVu", 0, STD_C99, NOLENGTHS, "-_0Ow", "", NULL },
715 { "FRTnrt", 0, STD_C99, NOLENGTHS, "", "", NULL },
716 { "g", 0, STD_C99, NOLENGTHS, "O-_0w", "2o", NULL },
717 { "G", 0, STD_C99, NOLENGTHS, "-_0Ow", "o", NULL },
718 { "h", 0, STD_C99, NOLENGTHS, "^#", "", NULL },
719 { "z", 0, STD_C99, NOLENGTHS, "O", "o", NULL },
720 /* GNU conversion specifiers. */
721 { "kls", 0, STD_EXT, NOLENGTHS, "-_0Ow", "", NULL },
722 { "P", 0, STD_EXT, NOLENGTHS, "", "", NULL },
723 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
726 static const format_char_info monetary_char_table[] =
728 { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL },
729 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
732 /* This must be in the same order as enum format_type. */
733 static const format_kind_info format_types_orig[] =
735 { "gnu_printf", printf_length_specs, print_char_table, " +#0-'I", NULL,
736 printf_flag_specs, printf_flag_pairs,
737 FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
738 'w', 0, 'p', 0, 'L', 0,
739 &integer_type_node, &integer_type_node
741 { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL,
742 asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
743 FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
744 'w', 0, 'p', 0, 'L', 0,
745 NULL, NULL
747 { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+", NULL,
748 gcc_diag_flag_specs, gcc_diag_flag_pairs,
749 FMT_FLAG_ARG_CONVERT,
750 0, 0, 'p', 0, 'L', 0,
751 NULL, &integer_type_node
753 { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+", NULL,
754 gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs,
755 FMT_FLAG_ARG_CONVERT,
756 0, 0, 'p', 0, 'L', 0,
757 NULL, &integer_type_node
759 { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+", NULL,
760 gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
761 FMT_FLAG_ARG_CONVERT,
762 0, 0, 'p', 0, 'L', 0,
763 NULL, &integer_type_node
765 { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL,
766 gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
767 FMT_FLAG_ARG_CONVERT,
768 0, 0, 'p', 0, 'L', 0,
769 NULL, &integer_type_node
771 { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "", NULL,
772 NULL, gcc_gfc_flag_pairs,
773 FMT_FLAG_ARG_CONVERT,
774 0, 0, 0, 0, 0, 0,
775 NULL, NULL
777 { "gnu_scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
778 scanf_flag_specs, scanf_flag_pairs,
779 FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
780 'w', 0, 0, '*', 'L', 'm',
781 NULL, NULL
783 { "gnu_strftime", NULL, time_char_table, "_-0^#", "EO",
784 strftime_flag_specs, strftime_flag_pairs,
785 FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, 0,
786 NULL, NULL
788 { "gnu_strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL,
789 strfmon_flag_specs, strfmon_flag_pairs,
790 FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0,
791 NULL, NULL
795 /* This layer of indirection allows GCC to reassign format_types with
796 new data if necessary, while still allowing the original data to be
797 const. */
798 static const format_kind_info *format_types = format_types_orig;
799 /* We can modify this one. We also add target-specific format types
800 to the end of the array. */
801 static format_kind_info *dynamic_format_types;
803 static int n_format_types = ARRAY_SIZE (format_types_orig);
805 /* Structure detailing the results of checking a format function call
806 where the format expression may be a conditional expression with
807 many leaves resulting from nested conditional expressions. */
808 typedef struct
810 /* Number of leaves of the format argument that could not be checked
811 as they were not string literals. */
812 int number_non_literal;
813 /* Number of leaves of the format argument that were null pointers or
814 string literals, but had extra format arguments. */
815 int number_extra_args;
816 /* Number of leaves of the format argument that were null pointers or
817 string literals, but had extra format arguments and used $ operand
818 numbers. */
819 int number_dollar_extra_args;
820 /* Number of leaves of the format argument that were wide string
821 literals. */
822 int number_wide;
823 /* Number of leaves of the format argument that were empty strings. */
824 int number_empty;
825 /* Number of leaves of the format argument that were unterminated
826 strings. */
827 int number_unterminated;
828 /* Number of leaves of the format argument that were not counted above. */
829 int number_other;
830 } format_check_results;
832 typedef struct
834 format_check_results *res;
835 function_format_info *info;
836 tree params;
837 } format_check_context;
839 static void check_format_info (function_format_info *, tree);
840 static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
841 static void check_format_info_main (format_check_results *,
842 function_format_info *,
843 const char *, int, tree,
844 unsigned HOST_WIDE_INT, alloc_pool);
846 static void init_dollar_format_checking (int, tree);
847 static int maybe_read_dollar_number (const char **, int,
848 tree, tree *, const format_kind_info *);
849 static bool avoid_dollar_number (const char *);
850 static void finish_dollar_format_checking (format_check_results *, int);
852 static const format_flag_spec *get_flag_spec (const format_flag_spec *,
853 int, const char *);
855 static void check_format_types (format_wanted_type *, const char *, int);
856 static void format_type_warning (const char *, const char *, int, tree,
857 int, const char *, tree, int);
859 /* Decode a format type from a string, returning the type, or
860 format_type_error if not valid, in which case the caller should print an
861 error message. */
862 static int
863 decode_format_type (const char *s)
865 int i;
866 int slen;
868 s = convert_format_name_to_system_name (s);
869 slen = strlen (s);
870 for (i = 0; i < n_format_types; i++)
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;
881 return format_type_error;
885 /* Check the argument list of a call to printf, scanf, etc.
886 ATTRS are the attributes on the function type. There are NARGS argument
887 values in the array ARGARRAY.
888 Also, if -Wmissing-format-attribute,
889 warn for calls to vprintf or vscanf in functions with no such format
890 attribute themselves. */
892 void
893 check_function_format (tree attrs, int nargs, tree *argarray)
895 tree a;
897 /* See if this function has any format attributes. */
898 for (a = attrs; a; a = TREE_CHAIN (a))
900 if (is_attribute_p ("format", TREE_PURPOSE (a)))
902 /* Yup; check it. */
903 function_format_info info;
904 decode_format_attr (TREE_VALUE (a), &info, 1);
905 if (warn_format)
907 /* FIXME: Rewrite all the internal functions in this file
908 to use the ARGARRAY directly instead of constructing this
909 temporary list. */
910 tree params = NULL_TREE;
911 int i;
912 for (i = nargs - 1; i >= 0; i--)
913 params = tree_cons (NULL_TREE, argarray[i], params);
914 check_format_info (&info, params);
916 if (warn_missing_format_attribute && info.first_arg_num == 0
917 && (format_types[info.format_type].flags
918 & (int) FMT_FLAG_ARG_CONVERT))
920 tree c;
921 for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
923 c = TREE_CHAIN (c))
924 if (is_attribute_p ("format", TREE_PURPOSE (c))
925 && (decode_format_type (IDENTIFIER_POINTER
926 (TREE_VALUE (TREE_VALUE (c))))
927 == info.format_type))
928 break;
929 if (c == NULL_TREE)
931 /* Check if the current function has a parameter to which
932 the format attribute could be attached; if not, it
933 can't be a candidate for a format attribute, despite
934 the vprintf-like or vscanf-like call. */
935 tree args;
936 for (args = DECL_ARGUMENTS (current_function_decl);
937 args != 0;
938 args = TREE_CHAIN (args))
940 if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
941 && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
942 == char_type_node))
943 break;
945 if (args != 0)
946 warning (OPT_Wmissing_format_attribute, "function might "
947 "be possible candidate for %qs format attribute",
948 format_types[info.format_type].name);
956 /* Variables used by the checking of $ operand number formats. */
957 static char *dollar_arguments_used = NULL;
958 static char *dollar_arguments_pointer_p = NULL;
959 static int dollar_arguments_alloc = 0;
960 static int dollar_arguments_count;
961 static int dollar_first_arg_num;
962 static int dollar_max_arg_used;
963 static int dollar_format_warned;
965 /* Initialize the checking for a format string that may contain $
966 parameter number specifications; we will need to keep track of whether
967 each parameter has been used. FIRST_ARG_NUM is the number of the first
968 argument that is a parameter to the format, or 0 for a vprintf-style
969 function; PARAMS is the list of arguments starting at this argument. */
971 static void
972 init_dollar_format_checking (int first_arg_num, tree params)
974 tree oparams = params;
976 dollar_first_arg_num = first_arg_num;
977 dollar_arguments_count = 0;
978 dollar_max_arg_used = 0;
979 dollar_format_warned = 0;
980 if (first_arg_num > 0)
982 while (params)
984 dollar_arguments_count++;
985 params = TREE_CHAIN (params);
988 if (dollar_arguments_alloc < dollar_arguments_count)
990 if (dollar_arguments_used)
991 free (dollar_arguments_used);
992 if (dollar_arguments_pointer_p)
993 free (dollar_arguments_pointer_p);
994 dollar_arguments_alloc = dollar_arguments_count;
995 dollar_arguments_used = XNEWVEC (char, dollar_arguments_alloc);
996 dollar_arguments_pointer_p = XNEWVEC (char, dollar_arguments_alloc);
998 if (dollar_arguments_alloc)
1000 memset (dollar_arguments_used, 0, dollar_arguments_alloc);
1001 if (first_arg_num > 0)
1003 int i = 0;
1004 params = oparams;
1005 while (params)
1007 dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params)))
1008 == POINTER_TYPE);
1009 params = TREE_CHAIN (params);
1010 i++;
1017 /* Look for a decimal number followed by a $ in *FORMAT. If DOLLAR_NEEDED
1018 is set, it is an error if one is not found; otherwise, it is OK. If
1019 such a number is found, check whether it is within range and mark that
1020 numbered operand as being used for later checking. Returns the operand
1021 number if found and within range, zero if no such number was found and
1022 this is OK, or -1 on error. PARAMS points to the first operand of the
1023 format; PARAM_PTR is made to point to the parameter referred to. If
1024 a $ format is found, *FORMAT is updated to point just after it. */
1026 static int
1027 maybe_read_dollar_number (const char **format,
1028 int dollar_needed, tree params, tree *param_ptr,
1029 const format_kind_info *fki)
1031 int argnum;
1032 int overflow_flag;
1033 const char *fcp = *format;
1034 if (!ISDIGIT (*fcp))
1036 if (dollar_needed)
1038 warning (OPT_Wformat, "missing $ operand number in format");
1039 return -1;
1041 else
1042 return 0;
1044 argnum = 0;
1045 overflow_flag = 0;
1046 while (ISDIGIT (*fcp))
1048 int nargnum;
1049 nargnum = 10 * argnum + (*fcp - '0');
1050 if (nargnum < 0 || nargnum / 10 != argnum)
1051 overflow_flag = 1;
1052 argnum = nargnum;
1053 fcp++;
1055 if (*fcp != '$')
1057 if (dollar_needed)
1059 warning (OPT_Wformat, "missing $ operand number in format");
1060 return -1;
1062 else
1063 return 0;
1065 *format = fcp + 1;
1066 if (pedantic && !dollar_format_warned)
1068 warning (OPT_Wformat, "%s does not support %%n$ operand number formats",
1069 C_STD_NAME (STD_EXT));
1070 dollar_format_warned = 1;
1072 if (overflow_flag || argnum == 0
1073 || (dollar_first_arg_num && argnum > dollar_arguments_count))
1075 warning (OPT_Wformat, "operand number out of range in format");
1076 return -1;
1078 if (argnum > dollar_max_arg_used)
1079 dollar_max_arg_used = argnum;
1080 /* For vprintf-style functions we may need to allocate more memory to
1081 track which arguments are used. */
1082 while (dollar_arguments_alloc < dollar_max_arg_used)
1084 int nalloc;
1085 nalloc = 2 * dollar_arguments_alloc + 16;
1086 dollar_arguments_used = XRESIZEVEC (char, dollar_arguments_used,
1087 nalloc);
1088 dollar_arguments_pointer_p = XRESIZEVEC (char, dollar_arguments_pointer_p,
1089 nalloc);
1090 memset (dollar_arguments_used + dollar_arguments_alloc, 0,
1091 nalloc - dollar_arguments_alloc);
1092 dollar_arguments_alloc = nalloc;
1094 if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE)
1095 && dollar_arguments_used[argnum - 1] == 1)
1097 dollar_arguments_used[argnum - 1] = 2;
1098 warning (OPT_Wformat, "format argument %d used more than once in %s format",
1099 argnum, fki->name);
1101 else
1102 dollar_arguments_used[argnum - 1] = 1;
1103 if (dollar_first_arg_num)
1105 int i;
1106 *param_ptr = params;
1107 for (i = 1; i < argnum && *param_ptr != 0; i++)
1108 *param_ptr = TREE_CHAIN (*param_ptr);
1110 /* This case shouldn't be caught here. */
1111 gcc_assert (*param_ptr);
1113 else
1114 *param_ptr = 0;
1115 return argnum;
1118 /* Ensure that FORMAT does not start with a decimal number followed by
1119 a $; give a diagnostic and return true if it does, false otherwise. */
1121 static bool
1122 avoid_dollar_number (const char *format)
1124 if (!ISDIGIT (*format))
1125 return false;
1126 while (ISDIGIT (*format))
1127 format++;
1128 if (*format == '$')
1130 warning (OPT_Wformat, "$ operand number used after format without operand number");
1131 return true;
1133 return false;
1137 /* Finish the checking for a format string that used $ operand number formats
1138 instead of non-$ formats. We check for unused operands before used ones
1139 (a serious error, since the implementation of the format function
1140 can't know what types to pass to va_arg to find the later arguments).
1141 and for unused operands at the end of the format (if we know how many
1142 arguments the format had, so not for vprintf). If there were operand
1143 numbers out of range on a non-vprintf-style format, we won't have reached
1144 here. If POINTER_GAP_OK, unused arguments are OK if all arguments are
1145 pointers. */
1147 static void
1148 finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok)
1150 int i;
1151 bool found_pointer_gap = false;
1152 for (i = 0; i < dollar_max_arg_used; i++)
1154 if (!dollar_arguments_used[i])
1156 if (pointer_gap_ok && (dollar_first_arg_num == 0
1157 || dollar_arguments_pointer_p[i]))
1158 found_pointer_gap = true;
1159 else
1160 warning (OPT_Wformat,
1161 "format argument %d unused before used argument %d in $-style format",
1162 i + 1, dollar_max_arg_used);
1165 if (found_pointer_gap
1166 || (dollar_first_arg_num
1167 && dollar_max_arg_used < dollar_arguments_count))
1169 res->number_other--;
1170 res->number_dollar_extra_args++;
1175 /* Retrieve the specification for a format flag. SPEC contains the
1176 specifications for format flags for the applicable kind of format.
1177 FLAG is the flag in question. If PREDICATES is NULL, the basic
1178 spec for that flag must be retrieved and must exist. If
1179 PREDICATES is not NULL, it is a string listing possible predicates
1180 for the spec entry; if an entry predicated on any of these is
1181 found, it is returned, otherwise NULL is returned. */
1183 static const format_flag_spec *
1184 get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
1186 int i;
1187 for (i = 0; spec[i].flag_char != 0; i++)
1189 if (spec[i].flag_char != flag)
1190 continue;
1191 if (predicates != NULL)
1193 if (spec[i].predicate != 0
1194 && strchr (predicates, spec[i].predicate) != 0)
1195 return &spec[i];
1197 else if (spec[i].predicate == 0)
1198 return &spec[i];
1200 gcc_assert (predicates);
1201 return NULL;
1205 /* Check the argument list of a call to printf, scanf, etc.
1206 INFO points to the function_format_info structure.
1207 PARAMS is the list of argument values. */
1209 static void
1210 check_format_info (function_format_info *info, tree params)
1212 format_check_context format_ctx;
1213 unsigned HOST_WIDE_INT arg_num;
1214 tree format_tree;
1215 format_check_results res;
1216 /* Skip to format argument. If the argument isn't available, there's
1217 no work for us to do; prototype checking will catch the problem. */
1218 for (arg_num = 1; ; ++arg_num)
1220 if (params == 0)
1221 return;
1222 if (arg_num == info->format_num)
1223 break;
1224 params = TREE_CHAIN (params);
1226 format_tree = TREE_VALUE (params);
1227 params = TREE_CHAIN (params);
1228 if (format_tree == 0)
1229 return;
1231 res.number_non_literal = 0;
1232 res.number_extra_args = 0;
1233 res.number_dollar_extra_args = 0;
1234 res.number_wide = 0;
1235 res.number_empty = 0;
1236 res.number_unterminated = 0;
1237 res.number_other = 0;
1239 format_ctx.res = &res;
1240 format_ctx.info = info;
1241 format_ctx.params = params;
1243 check_function_arguments_recurse (check_format_arg, &format_ctx,
1244 format_tree, arg_num);
1246 if (res.number_non_literal > 0)
1248 /* Functions taking a va_list normally pass a non-literal format
1249 string. These functions typically are declared with
1250 first_arg_num == 0, so avoid warning in those cases. */
1251 if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT))
1253 /* For strftime-like formats, warn for not checking the format
1254 string; but there are no arguments to check. */
1255 warning (OPT_Wformat_nonliteral,
1256 "format not a string literal, format string not checked");
1258 else if (info->first_arg_num != 0)
1260 /* If there are no arguments for the format at all, we may have
1261 printf (foo) which is likely to be a security hole. */
1262 while (arg_num + 1 < info->first_arg_num)
1264 if (params == 0)
1265 break;
1266 params = TREE_CHAIN (params);
1267 ++arg_num;
1269 if (params == 0 && warn_format_security)
1270 warning (OPT_Wformat_security,
1271 "format not a string literal and no format arguments");
1272 else if (params == 0 && warn_format_nonliteral)
1273 warning (OPT_Wformat_nonliteral,
1274 "format not a string literal and no format arguments");
1275 else
1276 warning (OPT_Wformat_nonliteral,
1277 "format not a string literal, argument types not checked");
1281 /* If there were extra arguments to the format, normally warn. However,
1282 the standard does say extra arguments are ignored, so in the specific
1283 case where we have multiple leaves (conditional expressions or
1284 ngettext) allow extra arguments if at least one leaf didn't have extra
1285 arguments, but was otherwise OK (either non-literal or checked OK).
1286 If the format is an empty string, this should be counted similarly to the
1287 case of extra format arguments. */
1288 if (res.number_extra_args > 0 && res.number_non_literal == 0
1289 && res.number_other == 0)
1290 warning (OPT_Wformat_extra_args, "too many arguments for format");
1291 if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
1292 && res.number_other == 0)
1293 warning (OPT_Wformat_extra_args, "unused arguments in $-style format");
1294 if (res.number_empty > 0 && res.number_non_literal == 0
1295 && res.number_other == 0)
1296 warning (OPT_Wformat_zero_length, "zero-length %s format string",
1297 format_types[info->format_type].name);
1299 if (res.number_wide > 0)
1300 warning (OPT_Wformat, "format is a wide character string");
1302 if (res.number_unterminated > 0)
1303 warning (OPT_Wformat, "unterminated format string");
1306 /* Callback from check_function_arguments_recurse to check a
1307 format string. FORMAT_TREE is the format parameter. ARG_NUM
1308 is the number of the format argument. CTX points to a
1309 format_check_context. */
1311 static void
1312 check_format_arg (void *ctx, tree format_tree,
1313 unsigned HOST_WIDE_INT arg_num)
1315 format_check_context *format_ctx = (format_check_context *) ctx;
1316 format_check_results *res = format_ctx->res;
1317 function_format_info *info = format_ctx->info;
1318 tree params = format_ctx->params;
1320 int format_length;
1321 HOST_WIDE_INT offset;
1322 const char *format_chars;
1323 tree array_size = 0;
1324 tree array_init;
1325 alloc_pool fwt_pool;
1327 if (integer_zerop (format_tree))
1329 /* Skip to first argument to check, so we can see if this format
1330 has any arguments (it shouldn't). */
1331 while (arg_num + 1 < info->first_arg_num)
1333 if (params == 0)
1334 return;
1335 params = TREE_CHAIN (params);
1336 ++arg_num;
1339 if (params == 0)
1340 res->number_other++;
1341 else
1342 res->number_extra_args++;
1344 return;
1347 offset = 0;
1348 if (TREE_CODE (format_tree) == POINTER_PLUS_EXPR)
1350 tree arg0, arg1;
1352 arg0 = TREE_OPERAND (format_tree, 0);
1353 arg1 = TREE_OPERAND (format_tree, 1);
1354 STRIP_NOPS (arg0);
1355 STRIP_NOPS (arg1);
1356 if (TREE_CODE (arg1) == INTEGER_CST)
1357 format_tree = arg0;
1358 else
1360 res->number_non_literal++;
1361 return;
1363 if (!host_integerp (arg1, 0)
1364 || (offset = tree_low_cst (arg1, 0)) < 0)
1366 res->number_non_literal++;
1367 return;
1370 if (TREE_CODE (format_tree) != ADDR_EXPR)
1372 res->number_non_literal++;
1373 return;
1375 format_tree = TREE_OPERAND (format_tree, 0);
1376 if (TREE_CODE (format_tree) == ARRAY_REF
1377 && host_integerp (TREE_OPERAND (format_tree, 1), 0)
1378 && (offset += tree_low_cst (TREE_OPERAND (format_tree, 1), 0)) >= 0)
1379 format_tree = TREE_OPERAND (format_tree, 0);
1380 if (TREE_CODE (format_tree) == VAR_DECL
1381 && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
1382 && (array_init = decl_constant_value (format_tree)) != format_tree
1383 && TREE_CODE (array_init) == STRING_CST)
1385 /* Extract the string constant initializer. Note that this may include
1386 a trailing NUL character that is not in the array (e.g.
1387 const char a[3] = "foo";). */
1388 array_size = DECL_SIZE_UNIT (format_tree);
1389 format_tree = array_init;
1391 if (TREE_CODE (format_tree) != STRING_CST)
1393 res->number_non_literal++;
1394 return;
1396 if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
1398 res->number_wide++;
1399 return;
1401 format_chars = TREE_STRING_POINTER (format_tree);
1402 format_length = TREE_STRING_LENGTH (format_tree);
1403 if (array_size != 0)
1405 /* Variable length arrays can't be initialized. */
1406 gcc_assert (TREE_CODE (array_size) == INTEGER_CST);
1408 if (host_integerp (array_size, 0))
1410 HOST_WIDE_INT array_size_value = TREE_INT_CST_LOW (array_size);
1411 if (array_size_value > 0
1412 && array_size_value == (int) array_size_value
1413 && format_length > array_size_value)
1414 format_length = array_size_value;
1417 if (offset)
1419 if (offset >= format_length)
1421 res->number_non_literal++;
1422 return;
1424 format_chars += offset;
1425 format_length -= offset;
1427 if (format_length < 1 || format_chars[--format_length] != 0)
1429 res->number_unterminated++;
1430 return;
1432 if (format_length == 0)
1434 res->number_empty++;
1435 return;
1438 /* Skip to first argument to check. */
1439 while (arg_num + 1 < info->first_arg_num)
1441 if (params == 0)
1442 return;
1443 params = TREE_CHAIN (params);
1444 ++arg_num;
1446 /* Provisionally increment res->number_other; check_format_info_main
1447 will decrement it if it finds there are extra arguments, but this way
1448 need not adjust it for every return. */
1449 res->number_other++;
1450 fwt_pool = create_alloc_pool ("format_wanted_type pool",
1451 sizeof (format_wanted_type), 10);
1452 check_format_info_main (res, info, format_chars, format_length,
1453 params, arg_num, fwt_pool);
1454 free_alloc_pool (fwt_pool);
1458 /* Do the main part of checking a call to a format function. FORMAT_CHARS
1459 is the NUL-terminated format string (which at this point may contain
1460 internal NUL characters); FORMAT_LENGTH is its length (excluding the
1461 terminating NUL character). ARG_NUM is one less than the number of
1462 the first format argument to check; PARAMS points to that format
1463 argument in the list of arguments. */
1465 static void
1466 check_format_info_main (format_check_results *res,
1467 function_format_info *info, const char *format_chars,
1468 int format_length, tree params,
1469 unsigned HOST_WIDE_INT arg_num, alloc_pool fwt_pool)
1471 const char *orig_format_chars = format_chars;
1472 tree first_fillin_param = params;
1474 const format_kind_info *fki = &format_types[info->format_type];
1475 const format_flag_spec *flag_specs = fki->flag_specs;
1476 const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs;
1478 /* -1 if no conversions taking an operand have been found; 0 if one has
1479 and it didn't use $; 1 if $ formats are in use. */
1480 int has_operand_number = -1;
1482 init_dollar_format_checking (info->first_arg_num, first_fillin_param);
1484 while (1)
1486 int i;
1487 int suppressed = FALSE;
1488 const char *length_chars = NULL;
1489 enum format_lengths length_chars_val = FMT_LEN_none;
1490 enum format_std_version length_chars_std = STD_C89;
1491 int format_char;
1492 tree cur_param;
1493 tree wanted_type;
1494 int main_arg_num = 0;
1495 tree main_arg_params = 0;
1496 enum format_std_version wanted_type_std;
1497 const char *wanted_type_name;
1498 format_wanted_type width_wanted_type;
1499 format_wanted_type precision_wanted_type;
1500 format_wanted_type main_wanted_type;
1501 format_wanted_type *first_wanted_type = NULL;
1502 format_wanted_type *last_wanted_type = NULL;
1503 const format_length_info *fli = NULL;
1504 const format_char_info *fci = NULL;
1505 char flag_chars[256];
1506 int alloc_flag = 0;
1507 const char *format_start = format_chars;
1508 if (*format_chars == 0)
1510 if (format_chars - orig_format_chars != format_length)
1511 warning (OPT_Wformat_contains_nul, "embedded %<\\0%> in format");
1512 if (info->first_arg_num != 0 && params != 0
1513 && has_operand_number <= 0)
1515 res->number_other--;
1516 res->number_extra_args++;
1518 if (has_operand_number > 0)
1519 finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
1520 return;
1522 if (*format_chars++ != '%')
1523 continue;
1524 if (*format_chars == 0)
1526 warning (OPT_Wformat, "spurious trailing %<%%%> in format");
1527 continue;
1529 if (*format_chars == '%')
1531 ++format_chars;
1532 continue;
1534 flag_chars[0] = 0;
1536 if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
1538 /* Possibly read a $ operand number at the start of the format.
1539 If one was previously used, one is required here. If one
1540 is not used here, we can't immediately conclude this is a
1541 format without them, since it could be printf %m or scanf %*. */
1542 int opnum;
1543 opnum = maybe_read_dollar_number (&format_chars, 0,
1544 first_fillin_param,
1545 &main_arg_params, fki);
1546 if (opnum == -1)
1547 return;
1548 else if (opnum > 0)
1550 has_operand_number = 1;
1551 main_arg_num = opnum + info->first_arg_num - 1;
1554 else if (fki->flags & FMT_FLAG_USE_DOLLAR)
1556 if (avoid_dollar_number (format_chars))
1557 return;
1560 /* Read any format flags, but do not yet validate them beyond removing
1561 duplicates, since in general validation depends on the rest of
1562 the format. */
1563 while (*format_chars != 0
1564 && strchr (fki->flag_chars, *format_chars) != 0)
1566 const format_flag_spec *s = get_flag_spec (flag_specs,
1567 *format_chars, NULL);
1568 if (strchr (flag_chars, *format_chars) != 0)
1570 warning (OPT_Wformat, "repeated %s in format", _(s->name));
1572 else
1574 i = strlen (flag_chars);
1575 flag_chars[i++] = *format_chars;
1576 flag_chars[i] = 0;
1578 if (s->skip_next_char)
1580 ++format_chars;
1581 if (*format_chars == 0)
1583 warning (OPT_Wformat, "missing fill character at end of strfmon format");
1584 return;
1587 ++format_chars;
1590 /* Read any format width, possibly * or *m$. */
1591 if (fki->width_char != 0)
1593 if (fki->width_type != NULL && *format_chars == '*')
1595 i = strlen (flag_chars);
1596 flag_chars[i++] = fki->width_char;
1597 flag_chars[i] = 0;
1598 /* "...a field width...may be indicated by an asterisk.
1599 In this case, an int argument supplies the field width..." */
1600 ++format_chars;
1601 if (has_operand_number != 0)
1603 int opnum;
1604 opnum = maybe_read_dollar_number (&format_chars,
1605 has_operand_number == 1,
1606 first_fillin_param,
1607 &params, fki);
1608 if (opnum == -1)
1609 return;
1610 else if (opnum > 0)
1612 has_operand_number = 1;
1613 arg_num = opnum + info->first_arg_num - 1;
1615 else
1616 has_operand_number = 0;
1618 else
1620 if (avoid_dollar_number (format_chars))
1621 return;
1623 if (info->first_arg_num != 0)
1625 if (params == 0)
1627 warning (OPT_Wformat, "too few arguments for format");
1628 return;
1630 cur_param = TREE_VALUE (params);
1631 if (has_operand_number <= 0)
1633 params = TREE_CHAIN (params);
1634 ++arg_num;
1636 width_wanted_type.wanted_type = *fki->width_type;
1637 width_wanted_type.wanted_type_name = NULL;
1638 width_wanted_type.pointer_count = 0;
1639 width_wanted_type.char_lenient_flag = 0;
1640 width_wanted_type.writing_in_flag = 0;
1641 width_wanted_type.reading_from_flag = 0;
1642 width_wanted_type.name = _("field width");
1643 width_wanted_type.param = cur_param;
1644 width_wanted_type.arg_num = arg_num;
1645 width_wanted_type.next = NULL;
1646 if (last_wanted_type != 0)
1647 last_wanted_type->next = &width_wanted_type;
1648 if (first_wanted_type == 0)
1649 first_wanted_type = &width_wanted_type;
1650 last_wanted_type = &width_wanted_type;
1653 else
1655 /* Possibly read a numeric width. If the width is zero,
1656 we complain if appropriate. */
1657 int non_zero_width_char = FALSE;
1658 int found_width = FALSE;
1659 while (ISDIGIT (*format_chars))
1661 found_width = TRUE;
1662 if (*format_chars != '0')
1663 non_zero_width_char = TRUE;
1664 ++format_chars;
1666 if (found_width && !non_zero_width_char &&
1667 (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
1668 warning (OPT_Wformat, "zero width in %s format", fki->name);
1669 if (found_width)
1671 i = strlen (flag_chars);
1672 flag_chars[i++] = fki->width_char;
1673 flag_chars[i] = 0;
1678 /* Read any format left precision (must be a number, not *). */
1679 if (fki->left_precision_char != 0 && *format_chars == '#')
1681 ++format_chars;
1682 i = strlen (flag_chars);
1683 flag_chars[i++] = fki->left_precision_char;
1684 flag_chars[i] = 0;
1685 if (!ISDIGIT (*format_chars))
1686 warning (OPT_Wformat, "empty left precision in %s format", fki->name);
1687 while (ISDIGIT (*format_chars))
1688 ++format_chars;
1691 /* Read any format precision, possibly * or *m$. */
1692 if (fki->precision_char != 0 && *format_chars == '.')
1694 ++format_chars;
1695 i = strlen (flag_chars);
1696 flag_chars[i++] = fki->precision_char;
1697 flag_chars[i] = 0;
1698 if (fki->precision_type != NULL && *format_chars == '*')
1700 /* "...a...precision...may be indicated by an asterisk.
1701 In this case, an int argument supplies the...precision." */
1702 ++format_chars;
1703 if (has_operand_number != 0)
1705 int opnum;
1706 opnum = maybe_read_dollar_number (&format_chars,
1707 has_operand_number == 1,
1708 first_fillin_param,
1709 &params, fki);
1710 if (opnum == -1)
1711 return;
1712 else if (opnum > 0)
1714 has_operand_number = 1;
1715 arg_num = opnum + info->first_arg_num - 1;
1717 else
1718 has_operand_number = 0;
1720 else
1722 if (avoid_dollar_number (format_chars))
1723 return;
1725 if (info->first_arg_num != 0)
1727 if (params == 0)
1729 warning (OPT_Wformat, "too few arguments for format");
1730 return;
1732 cur_param = TREE_VALUE (params);
1733 if (has_operand_number <= 0)
1735 params = TREE_CHAIN (params);
1736 ++arg_num;
1738 precision_wanted_type.wanted_type = *fki->precision_type;
1739 precision_wanted_type.wanted_type_name = NULL;
1740 precision_wanted_type.pointer_count = 0;
1741 precision_wanted_type.char_lenient_flag = 0;
1742 precision_wanted_type.writing_in_flag = 0;
1743 precision_wanted_type.reading_from_flag = 0;
1744 precision_wanted_type.name = _("field precision");
1745 precision_wanted_type.param = cur_param;
1746 precision_wanted_type.arg_num = arg_num;
1747 precision_wanted_type.next = NULL;
1748 if (last_wanted_type != 0)
1749 last_wanted_type->next = &precision_wanted_type;
1750 if (first_wanted_type == 0)
1751 first_wanted_type = &precision_wanted_type;
1752 last_wanted_type = &precision_wanted_type;
1755 else
1757 if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
1758 && !ISDIGIT (*format_chars))
1759 warning (OPT_Wformat, "empty precision in %s format", fki->name);
1760 while (ISDIGIT (*format_chars))
1761 ++format_chars;
1765 if (fki->alloc_char && fki->alloc_char == *format_chars)
1767 i = strlen (flag_chars);
1768 flag_chars[i++] = fki->alloc_char;
1769 flag_chars[i] = 0;
1770 format_chars++;
1773 /* Handle the scanf allocation kludge. */
1774 if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1776 if (*format_chars == 'a' && !flag_isoc99)
1778 if (format_chars[1] == 's' || format_chars[1] == 'S'
1779 || format_chars[1] == '[')
1781 /* 'a' is used as a flag. */
1782 i = strlen (flag_chars);
1783 flag_chars[i++] = 'a';
1784 flag_chars[i] = 0;
1785 format_chars++;
1790 /* Read any length modifier, if this kind of format has them. */
1791 fli = fki->length_char_specs;
1792 length_chars = NULL;
1793 length_chars_val = FMT_LEN_none;
1794 length_chars_std = STD_C89;
1795 if (fli)
1797 while (fli->name != 0
1798 && strncmp (fli->name, format_chars, strlen (fli->name)))
1799 fli++;
1800 if (fli->name != 0)
1802 format_chars += strlen (fli->name);
1803 if (fli->double_name != 0 && fli->name[0] == *format_chars)
1805 format_chars++;
1806 length_chars = fli->double_name;
1807 length_chars_val = fli->double_index;
1808 length_chars_std = fli->double_std;
1810 else
1812 length_chars = fli->name;
1813 length_chars_val = fli->index;
1814 length_chars_std = fli->std;
1816 i = strlen (flag_chars);
1817 flag_chars[i++] = fki->length_code_char;
1818 flag_chars[i] = 0;
1820 if (pedantic)
1822 /* Warn if the length modifier is non-standard. */
1823 if (ADJ_STD (length_chars_std) > C_STD_VER)
1824 warning (OPT_Wformat,
1825 "%s does not support the %qs %s length modifier",
1826 C_STD_NAME (length_chars_std), length_chars,
1827 fki->name);
1831 /* Read any modifier (strftime E/O). */
1832 if (fki->modifier_chars != NULL)
1834 while (*format_chars != 0
1835 && strchr (fki->modifier_chars, *format_chars) != 0)
1837 if (strchr (flag_chars, *format_chars) != 0)
1839 const format_flag_spec *s = get_flag_spec (flag_specs,
1840 *format_chars, NULL);
1841 warning (OPT_Wformat, "repeated %s in format", _(s->name));
1843 else
1845 i = strlen (flag_chars);
1846 flag_chars[i++] = *format_chars;
1847 flag_chars[i] = 0;
1849 ++format_chars;
1853 if (*format_chars == 'b')
1855 /* There should be an int arg to control the string arg. */
1856 if (params == 0)
1858 warning (OPT_Wformat, "too few arguments for format");
1859 return;
1861 if (info->first_arg_num != 0)
1863 cur_param = TREE_VALUE (params);
1864 params = TREE_CHAIN (params);
1865 ++arg_num;
1866 if ((TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
1867 != integer_type_node)
1869 (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
1870 != unsigned_type_node))
1872 warning (OPT_Wformat, "bitmap is not type int (arg %d)",
1873 arg_num);
1877 if (*format_chars == 'D')
1879 /* There should be an unsigned char * arg before the string arg. */
1880 if (params == 0)
1882 warning (OPT_Wformat, "too few arguments for format");
1883 return;
1885 if (info->first_arg_num != 0)
1887 tree cur_type;
1889 cur_param = TREE_VALUE (params);
1890 params = TREE_CHAIN (params);
1891 ++arg_num;
1892 cur_type = TREE_TYPE (cur_param);
1893 if (TREE_CODE (cur_type) != POINTER_TYPE
1894 || TYPE_MAIN_VARIANT (TREE_TYPE (cur_type))
1895 != unsigned_char_type_node)
1897 warning (OPT_Wformat, "ethernet address is not type unsigned char * (arg %d)",
1898 arg_num);
1903 format_char = *format_chars;
1904 if (format_char == 0
1905 || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
1906 && format_char == '%'))
1908 warning (OPT_Wformat, "conversion lacks type at end of format");
1909 continue;
1911 format_chars++;
1912 fci = fki->conversion_specs;
1913 while (fci->format_chars != 0
1914 && strchr (fci->format_chars, format_char) == 0)
1915 ++fci;
1916 if (fci->format_chars == 0)
1918 if (ISGRAPH (format_char))
1919 warning (OPT_Wformat, "unknown conversion type character %qc in format",
1920 format_char);
1921 else
1922 warning (OPT_Wformat, "unknown conversion type character 0x%x in format",
1923 format_char);
1924 continue;
1926 if (pedantic)
1928 if (ADJ_STD (fci->std) > C_STD_VER)
1929 warning (OPT_Wformat, "%s does not support the %<%%%c%> %s format",
1930 C_STD_NAME (fci->std), format_char, fki->name);
1933 /* Validate the individual flags used, removing any that are invalid. */
1935 int d = 0;
1936 for (i = 0; flag_chars[i] != 0; i++)
1938 const format_flag_spec *s = get_flag_spec (flag_specs,
1939 flag_chars[i], NULL);
1940 flag_chars[i - d] = flag_chars[i];
1941 if (flag_chars[i] == fki->length_code_char)
1942 continue;
1943 if (strchr (fci->flag_chars, flag_chars[i]) == 0)
1945 warning (OPT_Wformat, "%s used with %<%%%c%> %s format",
1946 _(s->name), format_char, fki->name);
1947 d++;
1948 continue;
1950 if (pedantic)
1952 const format_flag_spec *t;
1953 if (ADJ_STD (s->std) > C_STD_VER)
1954 warning (OPT_Wformat, "%s does not support %s",
1955 C_STD_NAME (s->std), _(s->long_name));
1956 t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
1957 if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
1959 const char *long_name = (t->long_name != NULL
1960 ? t->long_name
1961 : s->long_name);
1962 if (ADJ_STD (t->std) > C_STD_VER)
1963 warning (OPT_Wformat,
1964 "%s does not support %s with the %<%%%c%> %s format",
1965 C_STD_NAME (t->std), _(long_name),
1966 format_char, fki->name);
1970 flag_chars[i - d] = 0;
1973 if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1974 && strchr (flag_chars, 'a') != 0)
1975 alloc_flag = 1;
1976 if (fki->alloc_char && strchr (flag_chars, fki->alloc_char) != 0)
1977 alloc_flag = 1;
1979 if (fki->suppression_char
1980 && strchr (flag_chars, fki->suppression_char) != 0)
1981 suppressed = 1;
1983 /* Validate the pairs of flags used. */
1984 for (i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
1986 const format_flag_spec *s, *t;
1987 if (strchr (flag_chars, bad_flag_pairs[i].flag_char1) == 0)
1988 continue;
1989 if (strchr (flag_chars, bad_flag_pairs[i].flag_char2) == 0)
1990 continue;
1991 if (bad_flag_pairs[i].predicate != 0
1992 && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
1993 continue;
1994 s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
1995 t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
1996 if (bad_flag_pairs[i].ignored)
1998 if (bad_flag_pairs[i].predicate != 0)
1999 warning (OPT_Wformat,
2000 "%s ignored with %s and %<%%%c%> %s format",
2001 _(s->name), _(t->name), format_char,
2002 fki->name);
2003 else
2004 warning (OPT_Wformat, "%s ignored with %s in %s format",
2005 _(s->name), _(t->name), fki->name);
2007 else
2009 if (bad_flag_pairs[i].predicate != 0)
2010 warning (OPT_Wformat,
2011 "use of %s and %s together with %<%%%c%> %s format",
2012 _(s->name), _(t->name), format_char,
2013 fki->name);
2014 else
2015 warning (OPT_Wformat, "use of %s and %s together in %s format",
2016 _(s->name), _(t->name), fki->name);
2020 /* Give Y2K warnings. */
2021 if (warn_format_y2k)
2023 int y2k_level = 0;
2024 if (strchr (fci->flags2, '4') != 0)
2025 if (strchr (flag_chars, 'E') != 0)
2026 y2k_level = 3;
2027 else
2028 y2k_level = 2;
2029 else if (strchr (fci->flags2, '3') != 0)
2030 y2k_level = 3;
2031 else if (strchr (fci->flags2, '2') != 0)
2032 y2k_level = 2;
2033 if (y2k_level == 3)
2034 warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of "
2035 "year in some locales on non-BSD systems", format_char);
2036 else if (y2k_level == 2)
2037 warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of "
2038 "year", format_char);
2041 if (strchr (fci->flags2, '[') != 0)
2043 /* Skip over scan set, in case it happens to have '%' in it. */
2044 if (*format_chars == '^')
2045 ++format_chars;
2046 /* Find closing bracket; if one is hit immediately, then
2047 it's part of the scan set rather than a terminator. */
2048 if (*format_chars == ']')
2049 ++format_chars;
2050 while (*format_chars && *format_chars != ']')
2051 ++format_chars;
2052 if (*format_chars != ']')
2053 /* The end of the format string was reached. */
2054 warning (OPT_Wformat, "no closing %<]%> for %<%%[%> format");
2057 wanted_type = 0;
2058 wanted_type_name = 0;
2059 if (fki->flags & (int) FMT_FLAG_ARG_CONVERT)
2061 wanted_type = (fci->types[length_chars_val].type
2062 ? *fci->types[length_chars_val].type : 0);
2063 wanted_type_name = fci->types[length_chars_val].name;
2064 wanted_type_std = fci->types[length_chars_val].std;
2065 if (wanted_type == 0)
2067 warning (OPT_Wformat,
2068 "use of %qs length modifier with %qc type character",
2069 length_chars, format_char);
2070 /* Heuristic: skip one argument when an invalid length/type
2071 combination is encountered. */
2072 arg_num++;
2073 if (params == 0)
2075 warning (OPT_Wformat, "too few arguments for format");
2076 return;
2078 params = TREE_CHAIN (params);
2079 continue;
2081 else if (pedantic
2082 /* Warn if non-standard, provided it is more non-standard
2083 than the length and type characters that may already
2084 have been warned for. */
2085 && ADJ_STD (wanted_type_std) > ADJ_STD (length_chars_std)
2086 && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
2088 if (ADJ_STD (wanted_type_std) > C_STD_VER)
2089 warning (OPT_Wformat,
2090 "%s does not support the %<%%%s%c%> %s format",
2091 C_STD_NAME (wanted_type_std), length_chars,
2092 format_char, fki->name);
2096 main_wanted_type.next = NULL;
2098 /* Finally. . .check type of argument against desired type! */
2099 if (info->first_arg_num == 0)
2100 continue;
2101 if ((fci->pointer_count == 0 && wanted_type == void_type_node)
2102 || suppressed)
2104 if (main_arg_num != 0)
2106 if (suppressed)
2107 warning (OPT_Wformat, "operand number specified with "
2108 "suppressed assignment");
2109 else
2110 warning (OPT_Wformat, "operand number specified for format "
2111 "taking no argument");
2114 else
2116 format_wanted_type *wanted_type_ptr;
2118 if (main_arg_num != 0)
2120 arg_num = main_arg_num;
2121 params = main_arg_params;
2123 else
2125 ++arg_num;
2126 if (has_operand_number > 0)
2128 warning (OPT_Wformat, "missing $ operand number in format");
2129 return;
2131 else
2132 has_operand_number = 0;
2135 wanted_type_ptr = &main_wanted_type;
2136 while (fci)
2138 if (params == 0)
2140 warning (OPT_Wformat, "too few arguments for format");
2141 return;
2144 cur_param = TREE_VALUE (params);
2145 params = TREE_CHAIN (params);
2147 wanted_type_ptr->wanted_type = wanted_type;
2148 wanted_type_ptr->wanted_type_name = wanted_type_name;
2149 wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag;
2150 wanted_type_ptr->char_lenient_flag = 0;
2151 if (strchr (fci->flags2, 'c') != 0)
2152 wanted_type_ptr->char_lenient_flag = 1;
2153 wanted_type_ptr->writing_in_flag = 0;
2154 wanted_type_ptr->reading_from_flag = 0;
2155 if (alloc_flag)
2156 wanted_type_ptr->writing_in_flag = 1;
2157 else
2159 if (strchr (fci->flags2, 'W') != 0)
2160 wanted_type_ptr->writing_in_flag = 1;
2161 if (strchr (fci->flags2, 'R') != 0)
2162 wanted_type_ptr->reading_from_flag = 1;
2164 wanted_type_ptr->name = NULL;
2165 wanted_type_ptr->param = cur_param;
2166 wanted_type_ptr->arg_num = arg_num;
2167 wanted_type_ptr->next = NULL;
2168 if (last_wanted_type != 0)
2169 last_wanted_type->next = wanted_type_ptr;
2170 if (first_wanted_type == 0)
2171 first_wanted_type = wanted_type_ptr;
2172 last_wanted_type = wanted_type_ptr;
2174 fci = fci->chain;
2175 if (fci)
2177 wanted_type_ptr = (format_wanted_type *)
2178 pool_alloc (fwt_pool);
2179 arg_num++;
2180 wanted_type = *fci->types[length_chars_val].type;
2181 wanted_type_name = fci->types[length_chars_val].name;
2186 if (first_wanted_type != 0)
2187 check_format_types (first_wanted_type, format_start,
2188 format_chars - format_start);
2193 /* Check the argument types from a single format conversion (possibly
2194 including width and precision arguments). */
2195 static void
2196 check_format_types (format_wanted_type *types, const char *format_start,
2197 int format_length)
2199 for (; types != 0; types = types->next)
2201 tree cur_param;
2202 tree cur_type;
2203 tree orig_cur_type;
2204 tree wanted_type;
2205 int arg_num;
2206 int i;
2207 int char_type_flag;
2208 cur_param = types->param;
2209 cur_type = TREE_TYPE (cur_param);
2210 if (cur_type == error_mark_node)
2211 continue;
2212 orig_cur_type = cur_type;
2213 char_type_flag = 0;
2214 wanted_type = types->wanted_type;
2215 arg_num = types->arg_num;
2217 /* The following should not occur here. */
2218 gcc_assert (wanted_type);
2219 gcc_assert (wanted_type != void_type_node || types->pointer_count);
2221 if (types->pointer_count == 0)
2222 wanted_type = lang_hooks.types.type_promotes_to (wanted_type);
2224 wanted_type = TYPE_MAIN_VARIANT (wanted_type);
2226 STRIP_NOPS (cur_param);
2228 /* Check the types of any additional pointer arguments
2229 that precede the "real" argument. */
2230 for (i = 0; i < types->pointer_count; ++i)
2232 if (TREE_CODE (cur_type) == POINTER_TYPE)
2234 cur_type = TREE_TYPE (cur_type);
2235 if (cur_type == error_mark_node)
2236 break;
2238 /* Check for writing through a NULL pointer. */
2239 if (types->writing_in_flag
2240 && i == 0
2241 && cur_param != 0
2242 && integer_zerop (cur_param))
2243 warning (OPT_Wformat, "writing through null pointer "
2244 "(argument %d)", arg_num);
2246 /* Check for reading through a NULL pointer. */
2247 if (types->reading_from_flag
2248 && i == 0
2249 && cur_param != 0
2250 && integer_zerop (cur_param))
2251 warning (OPT_Wformat, "reading through null pointer "
2252 "(argument %d)", arg_num);
2254 if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
2255 cur_param = TREE_OPERAND (cur_param, 0);
2256 else
2257 cur_param = 0;
2259 /* See if this is an attempt to write into a const type with
2260 scanf or with printf "%n". Note: the writing in happens
2261 at the first indirection only, if for example
2262 void * const * is passed to scanf %p; passing
2263 const void ** is simply passing an incompatible type. */
2264 if (types->writing_in_flag
2265 && i == 0
2266 && (TYPE_READONLY (cur_type)
2267 || (cur_param != 0
2268 && (CONSTANT_CLASS_P (cur_param)
2269 || (DECL_P (cur_param)
2270 && TREE_READONLY (cur_param))))))
2271 warning (OPT_Wformat, "writing into constant object "
2272 "(argument %d)", arg_num);
2274 /* If there are extra type qualifiers beyond the first
2275 indirection, then this makes the types technically
2276 incompatible. */
2277 if (i > 0
2278 && pedantic
2279 && (TYPE_READONLY (cur_type)
2280 || TYPE_VOLATILE (cur_type)
2281 || TYPE_RESTRICT (cur_type)))
2282 warning (OPT_Wformat, "extra type qualifiers in format "
2283 "argument (argument %d)",
2284 arg_num);
2287 else
2289 format_type_warning (types->name, format_start, format_length,
2290 wanted_type, types->pointer_count,
2291 types->wanted_type_name, orig_cur_type,
2292 arg_num);
2293 break;
2297 if (i < types->pointer_count)
2298 continue;
2300 cur_type = TYPE_MAIN_VARIANT (cur_type);
2302 /* Check whether the argument type is a character type. This leniency
2303 only applies to certain formats, flagged with 'c'.
2305 if (types->char_lenient_flag)
2306 char_type_flag = (cur_type == char_type_node
2307 || cur_type == signed_char_type_node
2308 || cur_type == unsigned_char_type_node);
2310 /* Check the type of the "real" argument, if there's a type we want. */
2311 if (lang_hooks.types_compatible_p (wanted_type, cur_type))
2312 continue;
2313 /* If we want 'void *', allow any pointer type.
2314 (Anything else would already have got a warning.)
2315 With -pedantic, only allow pointers to void and to character
2316 types. */
2317 if (wanted_type == void_type_node
2318 && (!pedantic || (i == 1 && char_type_flag)))
2319 continue;
2320 /* Don't warn about differences merely in signedness, unless
2321 -pedantic. With -pedantic, warn if the type is a pointer
2322 target and not a character type, and for character types at
2323 a second level of indirection. */
2324 if (TREE_CODE (wanted_type) == INTEGER_TYPE
2325 && TREE_CODE (cur_type) == INTEGER_TYPE
2326 && (!pedantic || i == 0 || (i == 1 && char_type_flag))
2327 && (TYPE_UNSIGNED (wanted_type)
2328 ? wanted_type == c_common_unsigned_type (cur_type)
2329 : wanted_type == c_common_signed_type (cur_type)))
2330 continue;
2331 /* Likewise, "signed char", "unsigned char" and "char" are
2332 equivalent but the above test won't consider them equivalent. */
2333 if (wanted_type == char_type_node
2334 && (!pedantic || i < 2)
2335 && char_type_flag)
2336 continue;
2337 /* Now we have a type mismatch. */
2338 format_type_warning (types->name, format_start, format_length,
2339 wanted_type, types->pointer_count,
2340 types->wanted_type_name, orig_cur_type, arg_num);
2345 /* Give a warning about a format argument of different type from that
2346 expected. DESCR is a description such as "field precision", or
2347 NULL for an ordinary format. For an ordinary format, FORMAT_START
2348 points to where the format starts in the format string and
2349 FORMAT_LENGTH is its length. WANTED_TYPE is the type the argument
2350 should have after POINTER_COUNT pointer dereferences.
2351 WANTED_NAME_NAME is a possibly more friendly name of WANTED_TYPE,
2352 or NULL if the ordinary name of the type should be used. ARG_TYPE
2353 is the type of the actual argument. ARG_NUM is the number of that
2354 argument. */
2355 static void
2356 format_type_warning (const char *descr, const char *format_start,
2357 int format_length, tree wanted_type, int pointer_count,
2358 const char *wanted_type_name, tree arg_type, int arg_num)
2360 char *p;
2361 /* If ARG_TYPE is a typedef with a misleading name (for example,
2362 size_t but not the standard size_t expected by printf %zu), avoid
2363 printing the typedef name. */
2364 if (wanted_type_name
2365 && TYPE_NAME (arg_type)
2366 && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL
2367 && DECL_NAME (TYPE_NAME (arg_type))
2368 && !strcmp (wanted_type_name,
2369 lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2)))
2370 arg_type = TYPE_MAIN_VARIANT (arg_type);
2371 /* The format type and name exclude any '*' for pointers, so those
2372 must be formatted manually. For all the types we currently have,
2373 this is adequate, but formats taking pointers to functions or
2374 arrays would require the full type to be built up in order to
2375 print it with %T. */
2376 p = (char *) alloca (pointer_count + 2);
2377 if (pointer_count == 0)
2378 p[0] = 0;
2379 else if (c_dialect_cxx ())
2381 memset (p, '*', pointer_count);
2382 p[pointer_count] = 0;
2384 else
2386 p[0] = ' ';
2387 memset (p + 1, '*', pointer_count);
2388 p[pointer_count + 1] = 0;
2390 if (wanted_type_name)
2392 if (descr)
2393 warning (OPT_Wformat, "%s should have type %<%s%s%>, "
2394 "but argument %d has type %qT",
2395 descr, wanted_type_name, p, arg_num, arg_type);
2396 else
2397 warning (OPT_Wformat, "format %q.*s expects type %<%s%s%>, "
2398 "but argument %d has type %qT",
2399 format_length, format_start, wanted_type_name, p,
2400 arg_num, arg_type);
2402 else
2404 if (descr)
2405 warning (OPT_Wformat, "%s should have type %<%T%s%>, "
2406 "but argument %d has type %qT",
2407 descr, wanted_type, p, arg_num, arg_type);
2408 else
2409 warning (OPT_Wformat, "format %q.*s expects type %<%T%s%>, "
2410 "but argument %d has type %qT",
2411 format_length, format_start, wanted_type, p, arg_num, arg_type);
2416 /* Given a format_char_info array FCI, and a character C, this function
2417 returns the index into the conversion_specs where that specifier's
2418 data is located. The character must exist. */
2419 static unsigned int
2420 find_char_info_specifier_index (const format_char_info *fci, int c)
2422 unsigned i;
2424 for (i = 0; fci->format_chars; i++, fci++)
2425 if (strchr (fci->format_chars, c))
2426 return i;
2428 /* We shouldn't be looking for a non-existent specifier. */
2429 gcc_unreachable ();
2432 /* Given a format_length_info array FLI, and a character C, this
2433 function returns the index into the conversion_specs where that
2434 modifier's data is located. The character must exist. */
2435 static unsigned int
2436 find_length_info_modifier_index (const format_length_info *fli, int c)
2438 unsigned i;
2440 for (i = 0; fli->name; i++, fli++)
2441 if (strchr (fli->name, c))
2442 return i;
2444 /* We shouldn't be looking for a non-existent modifier. */
2445 gcc_unreachable ();
2448 /* Determine the type of HOST_WIDE_INT in the code being compiled for
2449 use in GCC's __asm_fprintf__ custom format attribute. You must
2450 have set dynamic_format_types before calling this function. */
2451 static void
2452 init_dynamic_asm_fprintf_info (void)
2454 static tree hwi;
2456 if (!hwi)
2458 format_length_info *new_asm_fprintf_length_specs;
2459 unsigned int i;
2461 /* Find the underlying type for HOST_WIDE_INT. For the %w
2462 length modifier to work, one must have issued: "typedef
2463 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2464 prior to using that modifier. */
2465 hwi = maybe_get_identifier ("__gcc_host_wide_int__");
2466 if (!hwi)
2468 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2469 return;
2471 hwi = identifier_global_value (hwi);
2472 if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
2474 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2475 return;
2477 hwi = DECL_ORIGINAL_TYPE (hwi);
2478 gcc_assert (hwi);
2479 if (hwi != long_integer_type_node && hwi != long_long_integer_type_node)
2481 error ("%<__gcc_host_wide_int__%> is not defined as %<long%>"
2482 " or %<long long%>");
2483 return;
2486 /* Create a new (writable) copy of asm_fprintf_length_specs. */
2487 new_asm_fprintf_length_specs = (format_length_info *)
2488 xmemdup (asm_fprintf_length_specs,
2489 sizeof (asm_fprintf_length_specs),
2490 sizeof (asm_fprintf_length_specs));
2492 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
2493 i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
2494 if (hwi == long_integer_type_node)
2495 new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
2496 else if (hwi == long_long_integer_type_node)
2497 new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
2498 else
2499 gcc_unreachable ();
2501 /* Assign the new data for use. */
2502 dynamic_format_types[asm_fprintf_format_type].length_char_specs =
2503 new_asm_fprintf_length_specs;
2507 /* Determine the type of a "locus" in the code being compiled for use
2508 in GCC's __gcc_gfc__ custom format attribute. You must have set
2509 dynamic_format_types before calling this function. */
2510 static void
2511 init_dynamic_gfc_info (void)
2513 static tree locus;
2515 if (!locus)
2517 static format_char_info *gfc_fci;
2519 /* For the GCC __gcc_gfc__ custom format specifier to work, one
2520 must have declared 'locus' prior to using this attribute. If
2521 we haven't seen this declarations then you shouldn't use the
2522 specifier requiring that type. */
2523 if ((locus = maybe_get_identifier ("locus")))
2525 locus = identifier_global_value (locus);
2526 if (locus)
2528 if (TREE_CODE (locus) != TYPE_DECL
2529 || TREE_TYPE (locus) == error_mark_node)
2531 error ("%<locus%> is not defined as a type");
2532 locus = 0;
2534 else
2535 locus = TREE_TYPE (locus);
2539 /* Assign the new data for use. */
2541 /* Handle the __gcc_gfc__ format specifics. */
2542 if (!gfc_fci)
2543 dynamic_format_types[gcc_gfc_format_type].conversion_specs =
2544 gfc_fci = (format_char_info *)
2545 xmemdup (gcc_gfc_char_table,
2546 sizeof (gcc_gfc_char_table),
2547 sizeof (gcc_gfc_char_table));
2548 if (locus)
2550 const unsigned i = find_char_info_specifier_index (gfc_fci, 'L');
2551 gfc_fci[i].types[0].type = &locus;
2552 gfc_fci[i].pointer_count = 1;
2557 /* Determine the types of "tree" and "location_t" in the code being
2558 compiled for use in GCC's diagnostic custom format attributes. You
2559 must have set dynamic_format_types before calling this function. */
2560 static void
2561 init_dynamic_diag_info (void)
2563 static tree t, loc, hwi;
2565 if (!loc || !t || !hwi)
2567 static format_char_info *diag_fci, *tdiag_fci, *cdiag_fci, *cxxdiag_fci;
2568 static format_length_info *diag_ls;
2569 unsigned int i;
2571 /* For the GCC-diagnostics custom format specifiers to work, one
2572 must have declared 'tree' and/or 'location_t' prior to using
2573 those attributes. If we haven't seen these declarations then
2574 you shouldn't use the specifiers requiring these types.
2575 However we don't force a hard ICE because we may see only one
2576 or the other type. */
2577 if ((loc = maybe_get_identifier ("location_t")))
2579 loc = identifier_global_value (loc);
2580 if (loc)
2582 if (TREE_CODE (loc) != TYPE_DECL)
2584 error ("%<location_t%> is not defined as a type");
2585 loc = 0;
2587 else
2588 loc = TREE_TYPE (loc);
2592 /* We need to grab the underlying 'union tree_node' so peek into
2593 an extra type level. */
2594 if ((t = maybe_get_identifier ("tree")))
2596 t = identifier_global_value (t);
2597 if (t)
2599 if (TREE_CODE (t) != TYPE_DECL)
2601 error ("%<tree%> is not defined as a type");
2602 t = 0;
2604 else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
2606 error ("%<tree%> is not defined as a pointer type");
2607 t = 0;
2609 else
2610 t = TREE_TYPE (TREE_TYPE (t));
2614 /* Find the underlying type for HOST_WIDE_INT. For the %w
2615 length modifier to work, one must have issued: "typedef
2616 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2617 prior to using that modifier. */
2618 if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
2620 hwi = identifier_global_value (hwi);
2621 if (hwi)
2623 if (TREE_CODE (hwi) != TYPE_DECL)
2625 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2626 hwi = 0;
2628 else
2630 hwi = DECL_ORIGINAL_TYPE (hwi);
2631 gcc_assert (hwi);
2632 if (hwi != long_integer_type_node
2633 && hwi != long_long_integer_type_node)
2635 error ("%<__gcc_host_wide_int__%> is not defined"
2636 " as %<long%> or %<long long%>");
2637 hwi = 0;
2643 /* Assign the new data for use. */
2645 /* All the GCC diag formats use the same length specs. */
2646 if (!diag_ls)
2647 dynamic_format_types[gcc_diag_format_type].length_char_specs =
2648 dynamic_format_types[gcc_tdiag_format_type].length_char_specs =
2649 dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
2650 dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
2651 diag_ls = (format_length_info *)
2652 xmemdup (gcc_diag_length_specs,
2653 sizeof (gcc_diag_length_specs),
2654 sizeof (gcc_diag_length_specs));
2655 if (hwi)
2657 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
2658 i = find_length_info_modifier_index (diag_ls, 'w');
2659 if (hwi == long_integer_type_node)
2660 diag_ls[i].index = FMT_LEN_l;
2661 else if (hwi == long_long_integer_type_node)
2662 diag_ls[i].index = FMT_LEN_ll;
2663 else
2664 gcc_unreachable ();
2667 /* Handle the __gcc_diag__ format specifics. */
2668 if (!diag_fci)
2669 dynamic_format_types[gcc_diag_format_type].conversion_specs =
2670 diag_fci = (format_char_info *)
2671 xmemdup (gcc_diag_char_table,
2672 sizeof (gcc_diag_char_table),
2673 sizeof (gcc_diag_char_table));
2674 if (loc)
2676 i = find_char_info_specifier_index (diag_fci, 'H');
2677 diag_fci[i].types[0].type = &loc;
2678 diag_fci[i].pointer_count = 1;
2680 if (t)
2682 i = find_char_info_specifier_index (diag_fci, 'J');
2683 diag_fci[i].types[0].type = &t;
2684 diag_fci[i].pointer_count = 1;
2685 i = find_char_info_specifier_index (diag_fci, 'K');
2686 diag_fci[i].types[0].type = &t;
2687 diag_fci[i].pointer_count = 1;
2690 /* Handle the __gcc_tdiag__ format specifics. */
2691 if (!tdiag_fci)
2692 dynamic_format_types[gcc_tdiag_format_type].conversion_specs =
2693 tdiag_fci = (format_char_info *)
2694 xmemdup (gcc_tdiag_char_table,
2695 sizeof (gcc_tdiag_char_table),
2696 sizeof (gcc_tdiag_char_table));
2697 if (loc)
2699 i = find_char_info_specifier_index (tdiag_fci, 'H');
2700 tdiag_fci[i].types[0].type = &loc;
2701 tdiag_fci[i].pointer_count = 1;
2703 if (t)
2705 /* All specifiers taking a tree share the same struct. */
2706 i = find_char_info_specifier_index (tdiag_fci, 'D');
2707 tdiag_fci[i].types[0].type = &t;
2708 tdiag_fci[i].pointer_count = 1;
2709 i = find_char_info_specifier_index (tdiag_fci, 'J');
2710 tdiag_fci[i].types[0].type = &t;
2711 tdiag_fci[i].pointer_count = 1;
2712 i = find_char_info_specifier_index (tdiag_fci, 'K');
2713 tdiag_fci[i].types[0].type = &t;
2714 tdiag_fci[i].pointer_count = 1;
2717 /* Handle the __gcc_cdiag__ format specifics. */
2718 if (!cdiag_fci)
2719 dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
2720 cdiag_fci = (format_char_info *)
2721 xmemdup (gcc_cdiag_char_table,
2722 sizeof (gcc_cdiag_char_table),
2723 sizeof (gcc_cdiag_char_table));
2724 if (loc)
2726 i = find_char_info_specifier_index (cdiag_fci, 'H');
2727 cdiag_fci[i].types[0].type = &loc;
2728 cdiag_fci[i].pointer_count = 1;
2730 if (t)
2732 /* All specifiers taking a tree share the same struct. */
2733 i = find_char_info_specifier_index (cdiag_fci, 'D');
2734 cdiag_fci[i].types[0].type = &t;
2735 cdiag_fci[i].pointer_count = 1;
2736 i = find_char_info_specifier_index (cdiag_fci, 'J');
2737 cdiag_fci[i].types[0].type = &t;
2738 cdiag_fci[i].pointer_count = 1;
2739 i = find_char_info_specifier_index (cdiag_fci, 'K');
2740 cdiag_fci[i].types[0].type = &t;
2741 cdiag_fci[i].pointer_count = 1;
2744 /* Handle the __gcc_cxxdiag__ format specifics. */
2745 if (!cxxdiag_fci)
2746 dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
2747 cxxdiag_fci = (format_char_info *)
2748 xmemdup (gcc_cxxdiag_char_table,
2749 sizeof (gcc_cxxdiag_char_table),
2750 sizeof (gcc_cxxdiag_char_table));
2751 if (loc)
2753 i = find_char_info_specifier_index (cxxdiag_fci, 'H');
2754 cxxdiag_fci[i].types[0].type = &loc;
2755 cxxdiag_fci[i].pointer_count = 1;
2757 if (t)
2759 /* All specifiers taking a tree share the same struct. */
2760 i = find_char_info_specifier_index (cxxdiag_fci, 'D');
2761 cxxdiag_fci[i].types[0].type = &t;
2762 cxxdiag_fci[i].pointer_count = 1;
2763 i = find_char_info_specifier_index (cxxdiag_fci, 'J');
2764 cxxdiag_fci[i].types[0].type = &t;
2765 cxxdiag_fci[i].pointer_count = 1;
2766 i = find_char_info_specifier_index (cxxdiag_fci, 'K');
2767 cxxdiag_fci[i].types[0].type = &t;
2768 cxxdiag_fci[i].pointer_count = 1;
2773 #ifdef TARGET_FORMAT_TYPES
2774 extern const format_kind_info TARGET_FORMAT_TYPES[];
2775 #endif
2777 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
2778 extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[];
2779 #endif
2780 #ifdef TARGET_OVERRIDES_FORMAT_INIT
2781 extern void TARGET_OVERRIDES_FORMAT_INIT (void);
2782 #endif
2784 /* Attributes such as "printf" are equivalent to those such as
2785 "gnu_printf" unless this is overridden by a target. */
2786 static const target_ovr_attr gnu_target_overrides_format_attributes[] =
2788 { "gnu_printf", "printf" },
2789 { "gnu_scanf", "scanf" },
2790 { "gnu_strftime", "strftime" },
2791 { "gnu_strfmon", "strfmon" },
2792 { NULL, NULL }
2795 /* Translate to unified attribute name. This is used in decode_format_type and
2796 decode_format_attr. In attr_name the user specified argument is passed. It
2797 returns the unified format name from TARGET_OVERRIDES_FORMAT_ATTRIBUTES
2798 or the attr_name passed to this function, if there is no matching entry. */
2799 static const char *
2800 convert_format_name_to_system_name (const char *attr_name)
2802 int i;
2804 if (attr_name == NULL || *attr_name == 0
2805 || strncmp (attr_name, "gcc_", 4) == 0)
2806 return attr_name;
2807 #ifdef TARGET_OVERRIDES_FORMAT_INIT
2808 TARGET_OVERRIDES_FORMAT_INIT ();
2809 #endif
2811 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
2812 /* Check if format attribute is overridden by target. */
2813 if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL
2814 && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0)
2816 for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i)
2818 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src,
2819 attr_name))
2820 return attr_name;
2821 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_dst,
2822 attr_name))
2823 return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src;
2826 #endif
2827 /* Otherwise default to gnu format. */
2828 for (i = 0;
2829 gnu_target_overrides_format_attributes[i].named_attr_src != NULL;
2830 ++i)
2832 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_src,
2833 attr_name))
2834 return attr_name;
2835 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_dst,
2836 attr_name))
2837 return gnu_target_overrides_format_attributes[i].named_attr_src;
2840 return attr_name;
2843 /* Return true if TATTR_NAME and ATTR_NAME are the same format attribute,
2844 counting "name" and "__name__" as the same, false otherwise. */
2845 static bool
2846 cmp_attribs (const char *tattr_name, const char *attr_name)
2848 int alen = strlen (attr_name);
2849 int slen = (tattr_name ? strlen (tattr_name) : 0);
2850 if (alen > 4 && attr_name[0] == '_' && attr_name[1] == '_'
2851 && attr_name[alen - 1] == '_' && attr_name[alen - 2] == '_')
2853 attr_name += 2;
2854 alen -= 4;
2856 if (alen != slen || strncmp (tattr_name, attr_name, alen) != 0)
2857 return false;
2858 return true;
2861 /* Handle a "format" attribute; arguments as in
2862 struct attribute_spec.handler. */
2863 tree
2864 handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args,
2865 int flags, bool *no_add_attrs)
2867 tree type = *node;
2868 function_format_info info;
2869 tree argument;
2871 #ifdef TARGET_FORMAT_TYPES
2872 /* If the target provides additional format types, we need to
2873 add them to FORMAT_TYPES at first use. */
2874 if (TARGET_FORMAT_TYPES != NULL && !dynamic_format_types)
2876 dynamic_format_types = XNEWVEC (format_kind_info,
2877 n_format_types + TARGET_N_FORMAT_TYPES);
2878 memcpy (dynamic_format_types, format_types_orig,
2879 sizeof (format_types_orig));
2880 memcpy (&dynamic_format_types[n_format_types], TARGET_FORMAT_TYPES,
2881 TARGET_N_FORMAT_TYPES * sizeof (dynamic_format_types[0]));
2883 format_types = dynamic_format_types;
2884 n_format_types += TARGET_N_FORMAT_TYPES;
2886 #endif
2888 if (!decode_format_attr (args, &info, 0))
2890 *no_add_attrs = true;
2891 return NULL_TREE;
2894 argument = TYPE_ARG_TYPES (type);
2895 if (argument)
2897 if (!check_format_string (argument, info.format_num, flags,
2898 no_add_attrs))
2899 return NULL_TREE;
2901 if (info.first_arg_num != 0)
2903 unsigned HOST_WIDE_INT arg_num = 1;
2905 /* Verify that first_arg_num points to the last arg,
2906 the ... */
2907 while (argument)
2908 arg_num++, argument = TREE_CHAIN (argument);
2910 if (arg_num != info.first_arg_num)
2912 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
2913 error ("args to be formatted is not %<...%>");
2914 *no_add_attrs = true;
2915 return NULL_TREE;
2920 /* Check if this is a strftime variant. Just for this variant
2921 FMT_FLAG_ARG_CONVERT is not set. */
2922 if ((format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT) == 0
2923 && info.first_arg_num != 0)
2925 error ("strftime formats cannot format arguments");
2926 *no_add_attrs = true;
2927 return NULL_TREE;
2930 /* If this is a custom GCC-internal format type, we have to
2931 initialize certain bits a runtime. */
2932 if (info.format_type == asm_fprintf_format_type
2933 || info.format_type == gcc_gfc_format_type
2934 || info.format_type == gcc_diag_format_type
2935 || info.format_type == gcc_tdiag_format_type
2936 || info.format_type == gcc_cdiag_format_type
2937 || info.format_type == gcc_cxxdiag_format_type)
2939 /* Our first time through, we have to make sure that our
2940 format_type data is allocated dynamically and is modifiable. */
2941 if (!dynamic_format_types)
2942 format_types = dynamic_format_types = (format_kind_info *)
2943 xmemdup (format_types_orig, sizeof (format_types_orig),
2944 sizeof (format_types_orig));
2946 /* If this is format __asm_fprintf__, we have to initialize
2947 GCC's notion of HOST_WIDE_INT for checking %wd. */
2948 if (info.format_type == asm_fprintf_format_type)
2949 init_dynamic_asm_fprintf_info ();
2950 /* If this is format __gcc_gfc__, we have to initialize GCC's
2951 notion of 'locus' at runtime for %L. */
2952 else if (info.format_type == gcc_gfc_format_type)
2953 init_dynamic_gfc_info ();
2954 /* If this is one of the diagnostic attributes, then we have to
2955 initialize 'location_t' and 'tree' at runtime. */
2956 else if (info.format_type == gcc_diag_format_type
2957 || info.format_type == gcc_tdiag_format_type
2958 || info.format_type == gcc_cdiag_format_type
2959 || info.format_type == gcc_cxxdiag_format_type)
2960 init_dynamic_diag_info ();
2961 else
2962 gcc_unreachable ();
2965 return NULL_TREE;