1 /* Check calls to formatted I/O functions (-Wformat).
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
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 2, or (at your option) any later
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
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "coretypes.h"
33 #include "diagnostic.h"
34 #include "langhooks.h"
37 /* Set format warning options according to a -Wformat=n option. */
40 set_Wformat (int setting)
42 warn_format = setting;
43 warn_format_extra_args = setting;
44 warn_format_zero_length = setting;
47 warn_format_nonliteral = setting;
48 warn_format_security = setting;
49 warn_format_y2k = setting;
51 /* Make sure not to disable -Wnonnull if -Wformat=0 is specified. */
53 warn_nonnull = setting;
57 /* Handle attributes associated with format checking. */
59 /* This must be in the same order as format_types, except for
60 format_type_error. Target-specific format types do not have
61 matching enum values. */
62 enum format_type { printf_format_type, asm_fprintf_format_type,
63 gcc_diag_format_type, gcc_tdiag_format_type,
64 gcc_cdiag_format_type,
65 gcc_cxxdiag_format_type, gcc_gfc_format_type,
66 scanf_format_type, strftime_format_type,
67 strfmon_format_type, format_type_error = -1};
69 typedef struct function_format_info
71 int format_type; /* type of format (printf, scanf, etc.) */
72 unsigned HOST_WIDE_INT format_num; /* number of format argument */
73 unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */
74 } function_format_info;
76 static bool decode_format_attr (tree, function_format_info *, int);
77 static int decode_format_type (const char *);
79 static bool check_format_string (tree argument,
80 unsigned HOST_WIDE_INT format_num,
81 int flags, bool *no_add_attrs);
82 static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value,
86 /* Handle a "format_arg" attribute; arguments as in
87 struct attribute_spec.handler. */
89 handle_format_arg_attribute (tree *node, tree ARG_UNUSED (name),
90 tree args, int flags, bool *no_add_attrs)
93 tree format_num_expr = TREE_VALUE (args);
94 unsigned HOST_WIDE_INT format_num = 0;
97 if (!get_constant (format_num_expr, &format_num, 0))
99 error ("format string has invalid operand number");
100 *no_add_attrs = true;
104 argument = TYPE_ARG_TYPES (type);
107 if (!check_format_string (argument, format_num, flags, no_add_attrs))
111 if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
112 || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
115 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
116 error ("function does not return string type");
117 *no_add_attrs = true;
124 /* Verify that the format_num argument is actually a string, in case
125 the format attribute is in error. */
127 check_format_string (tree argument, unsigned HOST_WIDE_INT format_num,
128 int flags, bool *no_add_attrs)
130 unsigned HOST_WIDE_INT i;
132 for (i = 1; i != format_num; i++)
136 argument = TREE_CHAIN (argument);
140 || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
141 || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
144 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
145 error ("format string argument not a string type");
146 *no_add_attrs = true;
153 /* Verify EXPR is a constant, and store its value.
154 If validated_p is true there should be no errors.
155 Returns true on success, false otherwise. */
157 get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
159 if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0)
161 gcc_assert (!validated_p);
165 *value = TREE_INT_CST_LOW (expr);
170 /* Decode the arguments to a "format" attribute into a
171 function_format_info structure. It is already known that the list
172 is of the right length. If VALIDATED_P is true, then these
173 attributes have already been validated and must not be erroneous;
174 if false, it will give an error message. Returns true if the
175 attributes are successfully decoded, false otherwise. */
178 decode_format_attr (tree args, function_format_info *info, int validated_p)
180 tree format_type_id = TREE_VALUE (args);
181 tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
182 tree first_arg_num_expr
183 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
185 if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
187 gcc_assert (!validated_p);
188 error ("%Junrecognized format specifier", lang_hooks.decls.getdecls ());
193 const char *p = IDENTIFIER_POINTER (format_type_id);
195 info->format_type = decode_format_type (p);
197 if (info->format_type == format_type_error)
199 gcc_assert (!validated_p);
200 warning (OPT_Wformat, "%qE is an unrecognized format function type",
206 if (!get_constant (format_num_expr, &info->format_num, validated_p))
208 error ("format string has invalid operand number");
212 if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
214 error ("%<...%> has invalid operand number");
218 if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
220 gcc_assert (!validated_p);
221 error ("format string argument follows the args to be formatted");
228 /* Check a call to a format function against a parameter list. */
230 /* The C standard version C++ is treated as equivalent to
231 or inheriting from, for the purpose of format features supported. */
232 #define CPLUSPLUS_STD_VER STD_C94
233 /* The C standard version we are checking formats against when pedantic. */
234 #define C_STD_VER ((int) (c_dialect_cxx () \
235 ? CPLUSPLUS_STD_VER \
238 : (flag_isoc94 ? STD_C94 : STD_C89))))
239 /* The name to give to the standard version we are warning about when
240 pedantic. FEATURE_VER is the version in which the feature warned out
241 appeared, which is higher than C_STD_VER. */
242 #define C_STD_NAME(FEATURE_VER) (c_dialect_cxx () \
244 : ((FEATURE_VER) == STD_EXT \
247 /* Adjust a C standard version, which may be STD_C9L, to account for
248 -Wno-long-long. Returns other standard versions unchanged. */
249 #define ADJ_STD(VER) ((int) ((VER) == STD_C9L \
250 ? (warn_long_long ? STD_C99 : STD_C89) \
253 /* Structure describing details of a type expected in format checking,
254 and the type to check against it. */
255 typedef struct format_wanted_type
257 /* The type wanted. */
259 /* The name of this type to use in diagnostics. */
260 const char *wanted_type_name;
261 /* The level of indirection through pointers at which this type occurs. */
263 /* Whether, when pointer_count is 1, to allow any character type when
264 pedantic, rather than just the character or void type specified. */
265 int char_lenient_flag;
266 /* Whether the argument, dereferenced once, is written into and so the
267 argument must not be a pointer to a const-qualified type. */
269 /* Whether the argument, dereferenced once, is read from and so
270 must not be a NULL pointer. */
271 int reading_from_flag;
272 /* If warnings should be of the form "field precision should have
273 type 'int'", the name to use (in this case "field precision"),
274 otherwise NULL, for "format expects type 'long'" type
277 /* The actual parameter to check against the wanted type. */
279 /* The argument number of that parameter. */
281 /* The next type to check for this format conversion, or NULL if none. */
282 struct format_wanted_type *next;
283 } format_wanted_type;
286 static const format_length_info printf_length_specs[] =
288 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
289 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
291 { "q", FMT_LEN_l, STD_EXT, NULL, 0, 0 },
293 { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
295 { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
296 { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
297 { "Z", FMT_LEN_z, STD_EXT, NULL, 0, 0 },
298 { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
299 { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
300 { "H", FMT_LEN_H, STD_EXT, NULL, 0, 0 },
301 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT },
302 { NULL, 0, 0, NULL, 0, 0 }
305 /* Length specifiers valid for asm_fprintf. */
306 static const format_length_info asm_fprintf_length_specs[] =
308 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
309 { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 },
310 { NULL, 0, 0, NULL, 0, 0 }
313 /* Length specifiers valid for GCC diagnostics. */
314 static const format_length_info gcc_diag_length_specs[] =
316 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
317 { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 },
318 { NULL, 0, 0, NULL, 0, 0 }
321 /* The custom diagnostics all accept the same length specifiers. */
322 #define gcc_tdiag_length_specs gcc_diag_length_specs
323 #define gcc_cdiag_length_specs gcc_diag_length_specs
324 #define gcc_cxxdiag_length_specs gcc_diag_length_specs
326 /* This differs from printf_length_specs only in that "Z" is not accepted. */
327 static const format_length_info scanf_length_specs[] =
329 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99 },
330 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L },
331 { "q", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
332 { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
333 { "z", FMT_LEN_z, STD_C99, NULL, 0, 0 },
334 { "t", FMT_LEN_t, STD_C99, NULL, 0, 0 },
335 { "j", FMT_LEN_j, STD_C99, NULL, 0, 0 },
336 { "H", FMT_LEN_H, STD_EXT, NULL, 0, 0 },
337 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT },
338 { NULL, 0, 0, NULL, 0, 0 }
342 /* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings
343 make no sense for a format type not part of any C standard version. */
344 static const format_length_info strfmon_length_specs[] =
346 /* A GNU extension. */
347 { "L", FMT_LEN_L, STD_C89, NULL, 0, 0 },
348 { NULL, 0, 0, NULL, 0, 0 }
351 static const format_flag_spec printf_flag_specs[] =
353 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
354 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
355 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
356 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
357 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
358 { '\'', 0, 0, N_("''' flag"), N_("the ''' printf flag"), STD_EXT },
359 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' printf flag"), STD_EXT },
360 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
361 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
362 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
363 { 0, 0, 0, NULL, NULL, 0 }
367 static const format_flag_pair printf_flag_pairs[] =
371 { '0', 'p', 1, 'i' },
375 static const format_flag_spec asm_fprintf_flag_specs[] =
377 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
378 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
379 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
380 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
381 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
382 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
383 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
384 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
385 { 0, 0, 0, NULL, NULL, 0 }
388 static const format_flag_pair asm_fprintf_flag_pairs[] =
392 { '0', 'p', 1, 'i' },
396 static const format_flag_pair gcc_diag_flag_pairs[] =
401 #define gcc_tdiag_flag_pairs gcc_diag_flag_pairs
402 #define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
403 #define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
405 static const format_flag_pair gcc_gfc_flag_pairs[] =
410 static const format_flag_spec gcc_diag_flag_specs[] =
412 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
413 { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 },
414 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
415 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
416 { 0, 0, 0, NULL, NULL, 0 }
419 #define gcc_tdiag_flag_specs gcc_diag_flag_specs
420 #define gcc_cdiag_flag_specs gcc_diag_flag_specs
422 static const format_flag_spec gcc_cxxdiag_flag_specs[] =
424 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
425 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
426 { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 },
427 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
428 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
429 { 0, 0, 0, NULL, NULL, 0 }
432 static const format_flag_spec scanf_flag_specs[] =
434 { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
435 { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
436 { 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
437 { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
438 { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT },
439 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT },
440 { 0, 0, 0, NULL, NULL, 0 }
444 static const format_flag_pair scanf_flag_pairs[] =
451 static const format_flag_spec strftime_flag_specs[] =
453 { '_', 0, 0, N_("'_' flag"), N_("the '_' strftime flag"), STD_EXT },
454 { '-', 0, 0, N_("'-' flag"), N_("the '-' strftime flag"), STD_EXT },
455 { '0', 0, 0, N_("'0' flag"), N_("the '0' strftime flag"), STD_EXT },
456 { '^', 0, 0, N_("'^' flag"), N_("the '^' strftime flag"), STD_EXT },
457 { '#', 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), STD_EXT },
458 { 'w', 0, 0, N_("field width"), N_("field width in strftime format"), STD_EXT },
459 { 'E', 0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"), STD_C99 },
460 { 'O', 0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"), STD_C99 },
461 { 'O', 'o', 0, NULL, N_("the 'O' modifier"), STD_EXT },
462 { 0, 0, 0, NULL, NULL, 0 }
466 static const format_flag_pair strftime_flag_pairs[] =
477 static const format_flag_spec strfmon_flag_specs[] =
479 { '=', 0, 1, N_("fill character"), N_("fill character in strfmon format"), STD_C89 },
480 { '^', 0, 0, N_("'^' flag"), N_("the '^' strfmon flag"), STD_C89 },
481 { '+', 0, 0, N_("'+' flag"), N_("the '+' strfmon flag"), STD_C89 },
482 { '(', 0, 0, N_("'(' flag"), N_("the '(' strfmon flag"), STD_C89 },
483 { '!', 0, 0, N_("'!' flag"), N_("the '!' strfmon flag"), STD_C89 },
484 { '-', 0, 0, N_("'-' flag"), N_("the '-' strfmon flag"), STD_C89 },
485 { 'w', 0, 0, N_("field width"), N_("field width in strfmon format"), STD_C89 },
486 { '#', 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 },
487 { 'p', 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
488 { 'L', 0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 },
489 { 0, 0, 0, NULL, NULL, 0 }
492 static const format_flag_pair strfmon_flag_pairs[] =
499 static const format_char_info print_char_table[] =
501 /* C89 conversion specifiers. */
502 { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "-wp0 +'I", "i", NULL },
503 { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
504 { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0'I", "i", NULL },
505 { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL },
506 { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#I", "", NULL },
507 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
508 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
509 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
510 { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL },
511 /* C99 conversion specifiers. */
512 { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL },
513 { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
514 /* X/Open conversion specifiers. */
515 { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
516 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
517 /* GNU conversion specifiers. */
518 { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL },
519 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
522 static const format_char_info fbsd_ext_char_info =
523 { NULL, 1, STD_EXT, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL };
525 static const format_char_info fbsd_print_char_table[] =
527 /* BSD conversion specifiers. */
528 /* FreeBSD kernel extensions (src/sys/kern/subr_prf.c).
529 The format %b is supported to decode error registers.
530 Its usage is: printf("reg=%b\n", regval, "<base><arg>*");
531 which produces: reg=3<BITTWO,BITONE>
532 The format %D provides a hexdump given a pointer and separator string:
533 ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
534 ("%*D", len, ptr, " ") -> XX XX XX XX ...
536 { "D", 1, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", &fbsd_ext_char_info },
537 { "b", 0, STD_EXT, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", &fbsd_ext_char_info },
538 { "ry", 0, STD_EXT, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "i", NULL },
539 { NULL, 0, 0, NOLENGTHS, NULL, NULL }
542 static const format_char_info asm_fprintf_char_table[] =
544 /* C89 conversion specifiers. */
545 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL },
546 { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
547 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL },
548 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
549 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
551 /* asm_fprintf conversion specifiers. */
552 { "O", 0, STD_C89, NOARGUMENTS, "", "", NULL },
553 { "R", 0, STD_C89, NOARGUMENTS, "", "", NULL },
554 { "I", 0, STD_C89, NOARGUMENTS, "", "", NULL },
555 { "L", 0, STD_C89, NOARGUMENTS, "", "", NULL },
556 { "U", 0, STD_C89, NOARGUMENTS, "", "", NULL },
557 { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
558 { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL },
559 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
562 static const format_char_info gcc_diag_char_table[] =
564 /* C89 conversion specifiers. */
565 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
566 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
567 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
568 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
569 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
570 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
572 /* Custom conversion specifiers. */
574 /* %H will require "location_t" at runtime. */
575 { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
577 /* These will require a "tree" at runtime. */
578 { "J", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
580 { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
581 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
582 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
585 static const format_char_info gcc_tdiag_char_table[] =
587 /* C89 conversion specifiers. */
588 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
589 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
590 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
591 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
592 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
593 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
595 /* Custom conversion specifiers. */
597 /* %H will require "location_t" at runtime. */
598 { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
600 /* These will require a "tree" at runtime. */
601 { "DFJT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
603 { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
604 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
605 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
608 static const format_char_info gcc_cdiag_char_table[] =
610 /* C89 conversion specifiers. */
611 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
612 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
613 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
614 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
615 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
616 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
618 /* Custom conversion specifiers. */
620 /* %H will require "location_t" at runtime. */
621 { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
623 /* These will require a "tree" at runtime. */
624 { "DEFJT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
626 { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
627 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
628 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
631 static const format_char_info gcc_cxxdiag_char_table[] =
633 /* C89 conversion specifiers. */
634 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
635 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
636 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
637 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
638 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
639 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
641 /* Custom conversion specifiers. */
643 /* %H will require "location_t" at runtime. */
644 { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
646 /* These will require a "tree" at runtime. */
647 { "ADEFJTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
649 /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
650 { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
652 { "<>'", 0, STD_C89, NOARGUMENTS, "", "", NULL },
653 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
654 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
657 static const format_char_info gcc_gfc_char_table[] =
659 /* C89 conversion specifiers. */
660 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
661 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
662 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
664 /* gfc conversion specifiers. */
666 { "C", 0, STD_C89, NOARGUMENTS, "", "", NULL },
668 /* This will require a "locus" at runtime. */
669 { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL },
671 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
674 static const format_char_info scan_char_table[] =
676 /* C89 conversion specifiers. */
677 { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL },
678 { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL },
679 { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
680 { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL },
681 { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW", NULL },
682 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW", NULL },
683 { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[", NULL },
684 { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
685 { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL },
686 /* C99 conversion specifiers. */
687 { "F", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL },
688 { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
689 /* X/Open conversion specifiers. */
690 { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
691 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL },
692 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
695 static const format_char_info time_char_table[] =
697 /* C89 conversion specifiers. */
698 { "ABZab", 0, STD_C89, NOLENGTHS, "^#", "", NULL },
699 { "cx", 0, STD_C89, NOLENGTHS, "E", "3", NULL },
700 { "HIMSUWdmw", 0, STD_C89, NOLENGTHS, "-_0Ow", "", NULL },
701 { "j", 0, STD_C89, NOLENGTHS, "-_0Ow", "o", NULL },
702 { "p", 0, STD_C89, NOLENGTHS, "#", "", NULL },
703 { "X", 0, STD_C89, NOLENGTHS, "E", "", NULL },
704 { "y", 0, STD_C89, NOLENGTHS, "EO-_0w", "4", NULL },
705 { "Y", 0, STD_C89, NOLENGTHS, "-_0EOw", "o", NULL },
706 { "%", 0, STD_C89, NOLENGTHS, "", "", NULL },
707 /* C99 conversion specifiers. */
708 { "C", 0, STD_C99, NOLENGTHS, "-_0EOw", "o", NULL },
709 { "D", 0, STD_C99, NOLENGTHS, "", "2", NULL },
710 { "eVu", 0, STD_C99, NOLENGTHS, "-_0Ow", "", NULL },
711 { "FRTnrt", 0, STD_C99, NOLENGTHS, "", "", NULL },
712 { "g", 0, STD_C99, NOLENGTHS, "O-_0w", "2o", NULL },
713 { "G", 0, STD_C99, NOLENGTHS, "-_0Ow", "o", NULL },
714 { "h", 0, STD_C99, NOLENGTHS, "^#", "", NULL },
715 { "z", 0, STD_C99, NOLENGTHS, "O", "o", NULL },
716 /* GNU conversion specifiers. */
717 { "kls", 0, STD_EXT, NOLENGTHS, "-_0Ow", "", NULL },
718 { "P", 0, STD_EXT, NOLENGTHS, "", "", NULL },
719 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
722 static const format_char_info monetary_char_table[] =
724 { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL },
725 { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
728 /* This must be in the same order as enum format_type. */
729 static const format_kind_info format_types_orig[] =
731 { "printf", printf_length_specs, print_char_table, " +#0-'I", NULL,
732 printf_flag_specs, printf_flag_pairs,
733 FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
735 &integer_type_node, &integer_type_node
737 { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL,
738 asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
739 FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
743 { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+", NULL,
744 gcc_diag_flag_specs, gcc_diag_flag_pairs,
745 FMT_FLAG_ARG_CONVERT,
747 NULL, &integer_type_node
749 { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+", NULL,
750 gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs,
751 FMT_FLAG_ARG_CONVERT,
753 NULL, &integer_type_node
755 { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+", NULL,
756 gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
757 FMT_FLAG_ARG_CONVERT,
759 NULL, &integer_type_node
761 { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL,
762 gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
763 FMT_FLAG_ARG_CONVERT,
765 NULL, &integer_type_node
767 { "gcc_gfc", NULL, gcc_gfc_char_table, "", NULL,
768 NULL, gcc_gfc_flag_pairs,
769 FMT_FLAG_ARG_CONVERT,
773 { "scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
774 scanf_flag_specs, scanf_flag_pairs,
775 FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
779 { "strftime", NULL, time_char_table, "_-0^#", "EO",
780 strftime_flag_specs, strftime_flag_pairs,
781 FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0,
784 { "strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL,
785 strfmon_flag_specs, strfmon_flag_pairs,
786 FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L',
789 { "printf0", printf_length_specs, print_char_table, " +#0-'I", NULL,
790 printf_flag_specs, printf_flag_pairs,
791 FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK|FMT_FLAG_NULL_FORMAT_OK,
793 &integer_type_node, &integer_type_node
797 /* This layer of indirection allows GCC to reassign format_types with
798 new data if necessary, while still allowing the original data to be
800 static const format_kind_info *format_types = format_types_orig;
801 /* We can modify this one. We also add target-specific format types
802 to the end of the array. */
803 static format_kind_info *dynamic_format_types;
805 static int n_format_types = ARRAY_SIZE (format_types_orig);
807 /* Structure detailing the results of checking a format function call
808 where the format expression may be a conditional expression with
809 many leaves resulting from nested conditional expressions. */
812 /* Number of leaves of the format argument that could not be checked
813 as they were not string literals. */
814 int number_non_literal;
815 /* Number of leaves of the format argument that were null pointers or
816 string literals, but had extra format arguments. */
817 int number_extra_args;
818 /* Number of leaves of the format argument that were null pointers or
819 string literals, but had extra format arguments and used $ operand
821 int number_dollar_extra_args;
822 /* Number of leaves of the format argument that were wide string
825 /* Number of leaves of the format argument that were empty strings. */
827 /* Number of leaves of the format argument that were unterminated
829 int number_unterminated;
830 /* Number of leaves of the format argument that were not counted above. */
832 } format_check_results;
836 format_check_results *res;
837 function_format_info *info;
839 } format_check_context;
841 static void check_format_info (function_format_info *, tree);
842 static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
843 static void check_format_info_main (format_check_results *,
844 function_format_info *,
845 const char *, int, tree,
846 unsigned HOST_WIDE_INT);
848 static void init_dollar_format_checking (int, tree);
849 static int maybe_read_dollar_number (const char **, int,
850 tree, tree *, const format_kind_info *);
851 static bool avoid_dollar_number (const char *);
852 static void finish_dollar_format_checking (format_check_results *, int);
854 static const format_flag_spec *get_flag_spec (const format_flag_spec *,
857 static void check_format_types (format_wanted_type *, const char *, int);
858 static void format_type_warning (const char *, const char *, int, tree,
859 int, const char *, tree, int);
861 /* Decode a format type from a string, returning the type, or
862 format_type_error if not valid, in which case the caller should print an
865 decode_format_type (const char *s)
870 for (i = 0; i < n_format_types; i++)
873 if (!strcmp (s, format_types[i].name))
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))
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.
887 PARAMS is the list of argument values. Also, if -Wmissing-format-attribute,
888 warn for calls to vprintf or vscanf in functions with no such format
889 attribute themselves. */
892 check_function_format (tree attrs, tree params)
896 /* See if this function has any format attributes. */
897 for (a = attrs; a; a = TREE_CHAIN (a))
899 if (is_attribute_p ("format", TREE_PURPOSE (a)))
902 function_format_info info;
903 decode_format_attr (TREE_VALUE (a), &info, 1);
905 check_format_info (&info, params);
906 if (warn_missing_format_attribute && info.first_arg_num == 0
907 && (format_types[info.format_type].flags
908 & (int) FMT_FLAG_ARG_CONVERT))
911 for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
914 if (is_attribute_p ("format", TREE_PURPOSE (c))
915 && (decode_format_type (IDENTIFIER_POINTER
916 (TREE_VALUE (TREE_VALUE (c))))
917 == info.format_type))
921 /* Check if the current function has a parameter to which
922 the format attribute could be attached; if not, it
923 can't be a candidate for a format attribute, despite
924 the vprintf-like or vscanf-like call. */
926 for (args = DECL_ARGUMENTS (current_function_decl);
928 args = TREE_CHAIN (args))
930 if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
931 && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
936 warning (OPT_Wmissing_format_attribute, "function might "
937 "be possible candidate for %qs format attribute",
938 format_types[info.format_type].name);
946 /* Variables used by the checking of $ operand number formats. */
947 static char *dollar_arguments_used = NULL;
948 static char *dollar_arguments_pointer_p = NULL;
949 static int dollar_arguments_alloc = 0;
950 static int dollar_arguments_count;
951 static int dollar_first_arg_num;
952 static int dollar_max_arg_used;
953 static int dollar_format_warned;
955 /* Initialize the checking for a format string that may contain $
956 parameter number specifications; we will need to keep track of whether
957 each parameter has been used. FIRST_ARG_NUM is the number of the first
958 argument that is a parameter to the format, or 0 for a vprintf-style
959 function; PARAMS is the list of arguments starting at this argument. */
962 init_dollar_format_checking (int first_arg_num, tree params)
964 tree oparams = params;
966 dollar_first_arg_num = first_arg_num;
967 dollar_arguments_count = 0;
968 dollar_max_arg_used = 0;
969 dollar_format_warned = 0;
970 if (first_arg_num > 0)
974 dollar_arguments_count++;
975 params = TREE_CHAIN (params);
978 if (dollar_arguments_alloc < dollar_arguments_count)
980 if (dollar_arguments_used)
981 free (dollar_arguments_used);
982 if (dollar_arguments_pointer_p)
983 free (dollar_arguments_pointer_p);
984 dollar_arguments_alloc = dollar_arguments_count;
985 dollar_arguments_used = XNEWVEC (char, dollar_arguments_alloc);
986 dollar_arguments_pointer_p = XNEWVEC (char, dollar_arguments_alloc);
988 if (dollar_arguments_alloc)
990 memset (dollar_arguments_used, 0, dollar_arguments_alloc);
991 if (first_arg_num > 0)
997 dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params)))
999 params = TREE_CHAIN (params);
1007 /* Look for a decimal number followed by a $ in *FORMAT. If DOLLAR_NEEDED
1008 is set, it is an error if one is not found; otherwise, it is OK. If
1009 such a number is found, check whether it is within range and mark that
1010 numbered operand as being used for later checking. Returns the operand
1011 number if found and within range, zero if no such number was found and
1012 this is OK, or -1 on error. PARAMS points to the first operand of the
1013 format; PARAM_PTR is made to point to the parameter referred to. If
1014 a $ format is found, *FORMAT is updated to point just after it. */
1017 maybe_read_dollar_number (const char **format,
1018 int dollar_needed, tree params, tree *param_ptr,
1019 const format_kind_info *fki)
1023 const char *fcp = *format;
1024 if (!ISDIGIT (*fcp))
1028 warning (OPT_Wformat, "missing $ operand number in format");
1036 while (ISDIGIT (*fcp))
1039 nargnum = 10 * argnum + (*fcp - '0');
1040 if (nargnum < 0 || nargnum / 10 != argnum)
1049 warning (OPT_Wformat, "missing $ operand number in format");
1056 if (pedantic && !dollar_format_warned)
1058 warning (OPT_Wformat, "%s does not support %%n$ operand number formats",
1059 C_STD_NAME (STD_EXT));
1060 dollar_format_warned = 1;
1062 if (overflow_flag || argnum == 0
1063 || (dollar_first_arg_num && argnum > dollar_arguments_count))
1065 warning (OPT_Wformat, "operand number out of range in format");
1068 if (argnum > dollar_max_arg_used)
1069 dollar_max_arg_used = argnum;
1070 /* For vprintf-style functions we may need to allocate more memory to
1071 track which arguments are used. */
1072 while (dollar_arguments_alloc < dollar_max_arg_used)
1075 nalloc = 2 * dollar_arguments_alloc + 16;
1076 dollar_arguments_used = XRESIZEVEC (char, dollar_arguments_used,
1078 dollar_arguments_pointer_p = XRESIZEVEC (char, dollar_arguments_pointer_p,
1080 memset (dollar_arguments_used + dollar_arguments_alloc, 0,
1081 nalloc - dollar_arguments_alloc);
1082 dollar_arguments_alloc = nalloc;
1084 if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE)
1085 && dollar_arguments_used[argnum - 1] == 1)
1087 dollar_arguments_used[argnum - 1] = 2;
1088 warning (OPT_Wformat, "format argument %d used more than once in %s format",
1092 dollar_arguments_used[argnum - 1] = 1;
1093 if (dollar_first_arg_num)
1096 *param_ptr = params;
1097 for (i = 1; i < argnum && *param_ptr != 0; i++)
1098 *param_ptr = TREE_CHAIN (*param_ptr);
1100 /* This case shouldn't be caught here. */
1101 gcc_assert (*param_ptr);
1108 /* Ensure that FORMAT does not start with a decimal number followed by
1109 a $; give a diagnostic and return true if it does, false otherwise. */
1112 avoid_dollar_number (const char *format)
1114 if (!ISDIGIT (*format))
1116 while (ISDIGIT (*format))
1120 warning (OPT_Wformat, "$ operand number used after format without operand number");
1127 /* Finish the checking for a format string that used $ operand number formats
1128 instead of non-$ formats. We check for unused operands before used ones
1129 (a serious error, since the implementation of the format function
1130 can't know what types to pass to va_arg to find the later arguments).
1131 and for unused operands at the end of the format (if we know how many
1132 arguments the format had, so not for vprintf). If there were operand
1133 numbers out of range on a non-vprintf-style format, we won't have reached
1134 here. If POINTER_GAP_OK, unused arguments are OK if all arguments are
1138 finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok)
1141 bool found_pointer_gap = false;
1142 for (i = 0; i < dollar_max_arg_used; i++)
1144 if (!dollar_arguments_used[i])
1146 if (pointer_gap_ok && (dollar_first_arg_num == 0
1147 || dollar_arguments_pointer_p[i]))
1148 found_pointer_gap = true;
1150 warning (OPT_Wformat,
1151 "format argument %d unused before used argument %d in $-style format",
1152 i + 1, dollar_max_arg_used);
1155 if (found_pointer_gap
1156 || (dollar_first_arg_num
1157 && dollar_max_arg_used < dollar_arguments_count))
1159 res->number_other--;
1160 res->number_dollar_extra_args++;
1165 /* Retrieve the specification for a format flag. SPEC contains the
1166 specifications for format flags for the applicable kind of format.
1167 FLAG is the flag in question. If PREDICATES is NULL, the basic
1168 spec for that flag must be retrieved and must exist. If
1169 PREDICATES is not NULL, it is a string listing possible predicates
1170 for the spec entry; if an entry predicated on any of these is
1171 found, it is returned, otherwise NULL is returned. */
1173 static const format_flag_spec *
1174 get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
1177 for (i = 0; spec[i].flag_char != 0; i++)
1179 if (spec[i].flag_char != flag)
1181 if (predicates != NULL)
1183 if (spec[i].predicate != 0
1184 && strchr (predicates, spec[i].predicate) != 0)
1187 else if (spec[i].predicate == 0)
1190 gcc_assert (predicates);
1195 /* Check the argument list of a call to printf, scanf, etc.
1196 INFO points to the function_format_info structure.
1197 PARAMS is the list of argument values. */
1200 check_format_info (function_format_info *info, tree params)
1202 format_check_context format_ctx;
1203 unsigned HOST_WIDE_INT arg_num;
1205 format_check_results res;
1206 /* Skip to format argument. If the argument isn't available, there's
1207 no work for us to do; prototype checking will catch the problem. */
1208 for (arg_num = 1; ; ++arg_num)
1212 if (arg_num == info->format_num)
1214 params = TREE_CHAIN (params);
1216 format_tree = TREE_VALUE (params);
1217 params = TREE_CHAIN (params);
1218 if (format_tree == 0)
1221 res.number_non_literal = 0;
1222 res.number_extra_args = 0;
1223 res.number_dollar_extra_args = 0;
1224 res.number_wide = 0;
1225 res.number_empty = 0;
1226 res.number_unterminated = 0;
1227 res.number_other = 0;
1229 format_ctx.res = &res;
1230 format_ctx.info = info;
1231 format_ctx.params = params;
1233 check_function_arguments_recurse (check_format_arg, &format_ctx,
1234 format_tree, arg_num);
1236 if (res.number_non_literal > 0)
1238 /* Functions taking a va_list normally pass a non-literal format
1239 string. These functions typically are declared with
1240 first_arg_num == 0, so avoid warning in those cases. */
1241 if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT))
1243 /* For strftime-like formats, warn for not checking the format
1244 string; but there are no arguments to check. */
1245 warning (OPT_Wformat_nonliteral,
1246 "format not a string literal, format string not checked");
1248 else if (info->first_arg_num != 0)
1250 /* If there are no arguments for the format at all, we may have
1251 printf (foo) which is likely to be a security hole. */
1252 while (arg_num + 1 < info->first_arg_num)
1256 params = TREE_CHAIN (params);
1259 if (params == 0 && warn_format_security)
1260 warning (OPT_Wformat_security,
1261 "format not a string literal and no format arguments");
1262 else if (params == 0 && warn_format_nonliteral)
1263 warning (OPT_Wformat_nonliteral,
1264 "format not a string literal and no format arguments");
1266 warning (OPT_Wformat_nonliteral,
1267 "format not a string literal, argument types not checked");
1271 /* If there were extra arguments to the format, normally warn. However,
1272 the standard does say extra arguments are ignored, so in the specific
1273 case where we have multiple leaves (conditional expressions or
1274 ngettext) allow extra arguments if at least one leaf didn't have extra
1275 arguments, but was otherwise OK (either non-literal or checked OK).
1276 If the format is an empty string, this should be counted similarly to the
1277 case of extra format arguments. */
1278 if (res.number_extra_args > 0 && res.number_non_literal == 0
1279 && res.number_other == 0)
1280 warning (OPT_Wformat_extra_args, "too many arguments for format");
1281 if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
1282 && res.number_other == 0)
1283 warning (OPT_Wformat_extra_args, "unused arguments in $-style format");
1284 if (res.number_empty > 0 && res.number_non_literal == 0
1285 && res.number_other == 0)
1286 warning (OPT_Wformat_zero_length, "zero-length %s format string",
1287 format_types[info->format_type].name);
1289 if (res.number_wide > 0)
1290 warning (OPT_Wformat, "format is a wide character string");
1292 if (res.number_unterminated > 0)
1293 warning (OPT_Wformat, "unterminated format string");
1296 /* Callback from check_function_arguments_recurse to check a
1297 format string. FORMAT_TREE is the format parameter. ARG_NUM
1298 is the number of the format argument. CTX points to a
1299 format_check_context. */
1302 check_format_arg (void *ctx, tree format_tree,
1303 unsigned HOST_WIDE_INT arg_num)
1305 format_check_context *format_ctx = (format_check_context *) ctx;
1306 format_check_results *res = format_ctx->res;
1307 function_format_info *info = format_ctx->info;
1308 tree params = format_ctx->params;
1311 HOST_WIDE_INT offset;
1312 const char *format_chars;
1313 tree array_size = 0;
1316 if (integer_zerop (format_tree))
1318 /* FIXME: this warning should go away once Marc Espie's
1319 __attribute__((nonnull)) patch is in. Instead, checking for
1320 nonnull attributes should probably change this function to act
1321 specially if info == NULL and add a res->number_null entry for
1322 that case, or maybe add a function pointer to be called at
1323 the end instead of hardcoding check_format_info_main. */
1324 if (!(format_types[info->format_type].flags & FMT_FLAG_NULL_FORMAT_OK))
1325 warning (OPT_Wformat, "null format string");
1327 /* Skip to first argument to check, so we can see if this format
1328 has any arguments (it shouldn't). */
1329 while (arg_num + 1 < info->first_arg_num)
1333 params = TREE_CHAIN (params);
1338 res->number_other++;
1340 res->number_extra_args++;
1346 if (TREE_CODE (format_tree) == PLUS_EXPR)
1350 arg0 = TREE_OPERAND (format_tree, 0);
1351 arg1 = TREE_OPERAND (format_tree, 1);
1354 if (TREE_CODE (arg1) == INTEGER_CST)
1356 else if (TREE_CODE (arg0) == INTEGER_CST)
1363 res->number_non_literal++;
1366 if (!host_integerp (arg1, 0)
1367 || (offset = tree_low_cst (arg1, 0)) < 0)
1369 res->number_non_literal++;
1373 if (TREE_CODE (format_tree) != ADDR_EXPR)
1375 res->number_non_literal++;
1378 format_tree = TREE_OPERAND (format_tree, 0);
1379 if (TREE_CODE (format_tree) == ARRAY_REF
1380 && host_integerp (TREE_OPERAND (format_tree, 1), 0)
1381 && (offset += tree_low_cst (TREE_OPERAND (format_tree, 1), 0)) >= 0)
1382 format_tree = TREE_OPERAND (format_tree, 0);
1383 if (TREE_CODE (format_tree) == VAR_DECL
1384 && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
1385 && (array_init = decl_constant_value (format_tree)) != format_tree
1386 && TREE_CODE (array_init) == STRING_CST)
1388 /* Extract the string constant initializer. Note that this may include
1389 a trailing NUL character that is not in the array (e.g.
1390 const char a[3] = "foo";). */
1391 array_size = DECL_SIZE_UNIT (format_tree);
1392 format_tree = array_init;
1394 if (TREE_CODE (format_tree) != STRING_CST)
1396 res->number_non_literal++;
1399 if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
1404 format_chars = TREE_STRING_POINTER (format_tree);
1405 format_length = TREE_STRING_LENGTH (format_tree);
1406 if (array_size != 0)
1408 /* Variable length arrays can't be initialized. */
1409 gcc_assert (TREE_CODE (array_size) == INTEGER_CST);
1411 if (host_integerp (array_size, 0))
1413 HOST_WIDE_INT array_size_value = TREE_INT_CST_LOW (array_size);
1414 if (array_size_value > 0
1415 && array_size_value == (int) array_size_value
1416 && format_length > array_size_value)
1417 format_length = array_size_value;
1422 if (offset >= format_length)
1424 res->number_non_literal++;
1427 format_chars += offset;
1428 format_length -= offset;
1430 if (format_length < 1)
1432 res->number_unterminated++;
1435 if (format_length == 1)
1437 res->number_empty++;
1440 if (format_chars[--format_length] != 0)
1442 res->number_unterminated++;
1446 /* Skip to first argument to check. */
1447 while (arg_num + 1 < info->first_arg_num)
1451 params = TREE_CHAIN (params);
1454 /* Provisionally increment res->number_other; check_format_info_main
1455 will decrement it if it finds there are extra arguments, but this way
1456 need not adjust it for every return. */
1457 res->number_other++;
1458 check_format_info_main (res, info, format_chars, format_length,
1463 /* Do the main part of checking a call to a format function. FORMAT_CHARS
1464 is the NUL-terminated format string (which at this point may contain
1465 internal NUL characters); FORMAT_LENGTH is its length (excluding the
1466 terminating NUL character). ARG_NUM is one less than the number of
1467 the first format argument to check; PARAMS points to that format
1468 argument in the list of arguments. */
1471 check_format_info_main (format_check_results *res,
1472 function_format_info *info, const char *format_chars,
1473 int format_length, tree params,
1474 unsigned HOST_WIDE_INT arg_num)
1476 const char *orig_format_chars = format_chars;
1477 tree first_fillin_param = params;
1479 const format_kind_info *fki = &format_types[info->format_type];
1480 const format_flag_spec *flag_specs = fki->flag_specs;
1481 const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs;
1483 /* -1 if no conversions taking an operand have been found; 0 if one has
1484 and it didn't use $; 1 if $ formats are in use. */
1485 int has_operand_number = -1;
1487 init_dollar_format_checking (info->first_arg_num, first_fillin_param);
1492 int suppressed = FALSE;
1493 const char *length_chars = NULL;
1494 enum format_lengths length_chars_val = FMT_LEN_none;
1495 enum format_std_version length_chars_std = STD_C89;
1499 int main_arg_num = 0;
1500 tree main_arg_params = 0;
1501 enum format_std_version wanted_type_std;
1502 const char *wanted_type_name;
1503 format_wanted_type width_wanted_type;
1504 format_wanted_type precision_wanted_type;
1505 format_wanted_type main_wanted_type;
1506 format_wanted_type *first_wanted_type = NULL;
1507 format_wanted_type *last_wanted_type = NULL;
1508 const format_length_info *fli = NULL;
1509 const format_char_info *fci = NULL;
1510 char flag_chars[256];
1512 const char *format_start = format_chars;
1513 if (*format_chars == 0)
1515 if (format_chars - orig_format_chars != format_length)
1516 warning (OPT_Wformat, "embedded %<\\0%> in format");
1517 if (info->first_arg_num != 0 && params != 0
1518 && has_operand_number <= 0)
1520 res->number_other--;
1521 res->number_extra_args++;
1523 if (has_operand_number > 0)
1524 finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
1527 if (*format_chars++ != '%')
1529 if (*format_chars == 0)
1531 warning (OPT_Wformat, "spurious trailing %<%%%> in format");
1534 if (*format_chars == '%')
1541 if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
1543 /* Possibly read a $ operand number at the start of the format.
1544 If one was previously used, one is required here. If one
1545 is not used here, we can't immediately conclude this is a
1546 format without them, since it could be printf %m or scanf %*. */
1548 opnum = maybe_read_dollar_number (&format_chars, 0,
1550 &main_arg_params, fki);
1555 has_operand_number = 1;
1556 main_arg_num = opnum + info->first_arg_num - 1;
1559 else if (fki->flags & FMT_FLAG_USE_DOLLAR)
1561 if (avoid_dollar_number (format_chars))
1565 /* Read any format flags, but do not yet validate them beyond removing
1566 duplicates, since in general validation depends on the rest of
1568 while (*format_chars != 0
1569 && strchr (fki->flag_chars, *format_chars) != 0)
1571 const format_flag_spec *s = get_flag_spec (flag_specs,
1572 *format_chars, NULL);
1573 if (strchr (flag_chars, *format_chars) != 0)
1575 warning (OPT_Wformat, "repeated %s in format", _(s->name));
1579 i = strlen (flag_chars);
1580 flag_chars[i++] = *format_chars;
1583 if (s->skip_next_char)
1586 if (*format_chars == 0)
1588 warning (OPT_Wformat, "missing fill character at end of strfmon format");
1595 /* Read any format width, possibly * or *m$. */
1596 if (fki->width_char != 0)
1598 if (fki->width_type != NULL && *format_chars == '*')
1600 i = strlen (flag_chars);
1601 flag_chars[i++] = fki->width_char;
1603 /* "...a field width...may be indicated by an asterisk.
1604 In this case, an int argument supplies the field width..." */
1606 if (has_operand_number != 0)
1609 opnum = maybe_read_dollar_number (&format_chars,
1610 has_operand_number == 1,
1617 has_operand_number = 1;
1618 arg_num = opnum + info->first_arg_num - 1;
1621 has_operand_number = 0;
1625 if (avoid_dollar_number (format_chars))
1628 if (info->first_arg_num != 0)
1632 warning (OPT_Wformat, "too few arguments for format");
1635 cur_param = TREE_VALUE (params);
1636 if (has_operand_number <= 0)
1638 params = TREE_CHAIN (params);
1641 width_wanted_type.wanted_type = *fki->width_type;
1642 width_wanted_type.wanted_type_name = NULL;
1643 width_wanted_type.pointer_count = 0;
1644 width_wanted_type.char_lenient_flag = 0;
1645 width_wanted_type.writing_in_flag = 0;
1646 width_wanted_type.reading_from_flag = 0;
1647 width_wanted_type.name = _("field width");
1648 width_wanted_type.param = cur_param;
1649 width_wanted_type.arg_num = arg_num;
1650 width_wanted_type.next = NULL;
1651 if (last_wanted_type != 0)
1652 last_wanted_type->next = &width_wanted_type;
1653 if (first_wanted_type == 0)
1654 first_wanted_type = &width_wanted_type;
1655 last_wanted_type = &width_wanted_type;
1660 /* Possibly read a numeric width. If the width is zero,
1661 we complain if appropriate. */
1662 int non_zero_width_char = FALSE;
1663 int found_width = FALSE;
1664 while (ISDIGIT (*format_chars))
1667 if (*format_chars != '0')
1668 non_zero_width_char = TRUE;
1671 if (found_width && !non_zero_width_char &&
1672 (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
1673 warning (OPT_Wformat, "zero width in %s format", fki->name);
1676 i = strlen (flag_chars);
1677 flag_chars[i++] = fki->width_char;
1683 /* Read any format left precision (must be a number, not *). */
1684 if (fki->left_precision_char != 0 && *format_chars == '#')
1687 i = strlen (flag_chars);
1688 flag_chars[i++] = fki->left_precision_char;
1690 if (!ISDIGIT (*format_chars))
1691 warning (OPT_Wformat, "empty left precision in %s format", fki->name);
1692 while (ISDIGIT (*format_chars))
1696 /* Read any format precision, possibly * or *m$. */
1697 if (fki->precision_char != 0 && *format_chars == '.')
1700 i = strlen (flag_chars);
1701 flag_chars[i++] = fki->precision_char;
1703 if (fki->precision_type != NULL && *format_chars == '*')
1705 /* "...a...precision...may be indicated by an asterisk.
1706 In this case, an int argument supplies the...precision." */
1708 if (has_operand_number != 0)
1711 opnum = maybe_read_dollar_number (&format_chars,
1712 has_operand_number == 1,
1719 has_operand_number = 1;
1720 arg_num = opnum + info->first_arg_num - 1;
1723 has_operand_number = 0;
1727 if (avoid_dollar_number (format_chars))
1730 if (info->first_arg_num != 0)
1734 warning (OPT_Wformat, "too few arguments for format");
1737 cur_param = TREE_VALUE (params);
1738 if (has_operand_number <= 0)
1740 params = TREE_CHAIN (params);
1743 precision_wanted_type.wanted_type = *fki->precision_type;
1744 precision_wanted_type.wanted_type_name = NULL;
1745 precision_wanted_type.pointer_count = 0;
1746 precision_wanted_type.char_lenient_flag = 0;
1747 precision_wanted_type.writing_in_flag = 0;
1748 precision_wanted_type.reading_from_flag = 0;
1749 precision_wanted_type.name = _("field precision");
1750 precision_wanted_type.param = cur_param;
1751 precision_wanted_type.arg_num = arg_num;
1752 precision_wanted_type.next = NULL;
1753 if (last_wanted_type != 0)
1754 last_wanted_type->next = &precision_wanted_type;
1755 if (first_wanted_type == 0)
1756 first_wanted_type = &precision_wanted_type;
1757 last_wanted_type = &precision_wanted_type;
1762 if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
1763 && !ISDIGIT (*format_chars))
1764 warning (OPT_Wformat, "empty precision in %s format", fki->name);
1765 while (ISDIGIT (*format_chars))
1770 /* Read any length modifier, if this kind of format has them. */
1771 fli = fki->length_char_specs;
1772 length_chars = NULL;
1773 length_chars_val = FMT_LEN_none;
1774 length_chars_std = STD_C89;
1777 while (fli->name != 0 && fli->name[0] != *format_chars)
1780 * Make sure FreeBSD's D format char takes preference
1781 * over new DD length specifier if FreeBSD format
1782 * extensions are requested.
1784 if (fli->index == FMT_LEN_D && flag_format_extensions
1785 && fki->conversion_specs == print_char_table)
1786 while (fli->name != 0) fli++;
1790 if (fli->double_name != 0 && fli->name[0] == *format_chars)
1793 length_chars = fli->double_name;
1794 length_chars_val = fli->double_index;
1795 length_chars_std = fli->double_std;
1799 length_chars = fli->name;
1800 length_chars_val = fli->index;
1801 length_chars_std = fli->std;
1803 i = strlen (flag_chars);
1804 flag_chars[i++] = fki->length_code_char;
1809 /* Warn if the length modifier is non-standard. */
1810 if (ADJ_STD (length_chars_std) > C_STD_VER)
1811 warning (OPT_Wformat,
1812 "%s does not support the %qs %s length modifier",
1813 C_STD_NAME (length_chars_std), length_chars,
1818 /* Read any modifier (strftime E/O). */
1819 if (fki->modifier_chars != NULL)
1821 while (*format_chars != 0
1822 && strchr (fki->modifier_chars, *format_chars) != 0)
1824 if (strchr (flag_chars, *format_chars) != 0)
1826 const format_flag_spec *s = get_flag_spec (flag_specs,
1827 *format_chars, NULL);
1828 warning (OPT_Wformat, "repeated %s in format", _(s->name));
1832 i = strlen (flag_chars);
1833 flag_chars[i++] = *format_chars;
1840 /* Handle the scanf allocation kludge. */
1841 if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1843 if (*format_chars == 'a' && !flag_isoc99)
1845 if (format_chars[1] == 's' || format_chars[1] == 'S'
1846 || format_chars[1] == '[')
1848 /* 'a' is used as a flag. */
1849 i = strlen (flag_chars);
1850 flag_chars[i++] = 'a';
1857 format_char = *format_chars;
1858 if (format_char == 0
1859 || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
1860 && format_char == '%'))
1862 warning (OPT_Wformat, "conversion lacks type at end of format");
1866 fci = fki->conversion_specs;
1867 while (fci->format_chars != 0
1868 && strchr (fci->format_chars, format_char) == 0)
1870 if (fci->format_chars == 0 && flag_format_extensions
1871 && fki->conversion_specs == print_char_table)
1873 fci = fbsd_print_char_table;
1874 while (fci->format_chars != 0
1875 && strchr (fci->format_chars, format_char) == 0)
1878 if (fci->format_chars == 0)
1880 if (ISGRAPH (format_char))
1881 warning (OPT_Wformat, "unknown conversion type character %qc in format",
1884 warning (OPT_Wformat, "unknown conversion type character 0x%x in format",
1890 if (ADJ_STD (fci->std) > C_STD_VER)
1891 warning (OPT_Wformat, "%s does not support the %<%%%c%> %s format",
1892 C_STD_NAME (fci->std), format_char, fki->name);
1895 /* Validate the individual flags used, removing any that are invalid. */
1898 for (i = 0; flag_chars[i] != 0; i++)
1900 const format_flag_spec *s = get_flag_spec (flag_specs,
1901 flag_chars[i], NULL);
1902 flag_chars[i - d] = flag_chars[i];
1903 if (flag_chars[i] == fki->length_code_char)
1905 if (strchr (fci->flag_chars, flag_chars[i]) == 0)
1907 warning (OPT_Wformat, "%s used with %<%%%c%> %s format",
1908 _(s->name), format_char, fki->name);
1914 const format_flag_spec *t;
1915 if (ADJ_STD (s->std) > C_STD_VER)
1916 warning (OPT_Wformat, "%s does not support %s",
1917 C_STD_NAME (s->std), _(s->long_name));
1918 t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
1919 if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
1921 const char *long_name = (t->long_name != NULL
1924 if (ADJ_STD (t->std) > C_STD_VER)
1925 warning (OPT_Wformat,
1926 "%s does not support %s with the %<%%%c%> %s format",
1927 C_STD_NAME (t->std), _(long_name),
1928 format_char, fki->name);
1932 flag_chars[i - d] = 0;
1935 if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1936 && strchr (flag_chars, 'a') != 0)
1939 if (fki->suppression_char
1940 && strchr (flag_chars, fki->suppression_char) != 0)
1943 /* Validate the pairs of flags used. */
1944 for (i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
1946 const format_flag_spec *s, *t;
1947 if (strchr (flag_chars, bad_flag_pairs[i].flag_char1) == 0)
1949 if (strchr (flag_chars, bad_flag_pairs[i].flag_char2) == 0)
1951 if (bad_flag_pairs[i].predicate != 0
1952 && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
1954 s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
1955 t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
1956 if (bad_flag_pairs[i].ignored)
1958 if (bad_flag_pairs[i].predicate != 0)
1959 warning (OPT_Wformat,
1960 "%s ignored with %s and %<%%%c%> %s format",
1961 _(s->name), _(t->name), format_char,
1964 warning (OPT_Wformat, "%s ignored with %s in %s format",
1965 _(s->name), _(t->name), fki->name);
1969 if (bad_flag_pairs[i].predicate != 0)
1970 warning (OPT_Wformat,
1971 "use of %s and %s together with %<%%%c%> %s format",
1972 _(s->name), _(t->name), format_char,
1975 warning (OPT_Wformat, "use of %s and %s together in %s format",
1976 _(s->name), _(t->name), fki->name);
1980 /* Give Y2K warnings. */
1981 if (warn_format_y2k)
1984 if (strchr (fci->flags2, '4') != 0)
1985 if (strchr (flag_chars, 'E') != 0)
1989 else if (strchr (fci->flags2, '3') != 0)
1991 else if (strchr (fci->flags2, '2') != 0)
1994 warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of "
1995 "year in some locales on non-BSD systems", format_char);
1996 else if (y2k_level == 2)
1997 warning (OPT_Wformat_y2k, "%<%%%c%> yields only last 2 digits of "
1998 "year", format_char);
2001 if (strchr (fci->flags2, '[') != 0)
2003 /* Skip over scan set, in case it happens to have '%' in it. */
2004 if (*format_chars == '^')
2006 /* Find closing bracket; if one is hit immediately, then
2007 it's part of the scan set rather than a terminator. */
2008 if (*format_chars == ']')
2010 while (*format_chars && *format_chars != ']')
2012 if (*format_chars != ']')
2013 /* The end of the format string was reached. */
2014 warning (OPT_Wformat, "no closing %<]%> for %<%%[%> format");
2018 wanted_type_name = 0;
2019 if (fki->flags & (int) FMT_FLAG_ARG_CONVERT)
2021 wanted_type = (fci->types[length_chars_val].type
2022 ? *fci->types[length_chars_val].type : 0);
2023 wanted_type_name = fci->types[length_chars_val].name;
2024 wanted_type_std = fci->types[length_chars_val].std;
2025 if (wanted_type == 0)
2027 warning (OPT_Wformat,
2028 "use of %qs length modifier with %qc type character",
2029 length_chars, format_char);
2030 /* Heuristic: skip one argument when an invalid length/type
2031 combination is encountered. */
2035 warning (OPT_Wformat, "too few arguments for format");
2038 params = TREE_CHAIN (params);
2042 /* Warn if non-standard, provided it is more non-standard
2043 than the length and type characters that may already
2044 have been warned for. */
2045 && ADJ_STD (wanted_type_std) > ADJ_STD (length_chars_std)
2046 && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
2048 if (ADJ_STD (wanted_type_std) > C_STD_VER)
2049 warning (OPT_Wformat,
2050 "%s does not support the %<%%%s%c%> %s format",
2051 C_STD_NAME (wanted_type_std), length_chars,
2052 format_char, fki->name);
2056 main_wanted_type.next = NULL;
2058 /* Finally. . .check type of argument against desired type! */
2059 if (info->first_arg_num == 0)
2061 if ((fci->pointer_count == 0 && wanted_type == void_type_node)
2064 if (main_arg_num != 0)
2067 warning (OPT_Wformat, "operand number specified with "
2068 "suppressed assignment");
2070 warning (OPT_Wformat, "operand number specified for format "
2071 "taking no argument");
2076 format_wanted_type *wanted_type_ptr;
2078 if (main_arg_num != 0)
2080 arg_num = main_arg_num;
2081 params = main_arg_params;
2086 if (has_operand_number > 0)
2088 warning (OPT_Wformat, "missing $ operand number in format");
2092 has_operand_number = 0;
2095 wanted_type_ptr = &main_wanted_type;
2100 warning (OPT_Wformat, "too few arguments for format");
2104 cur_param = TREE_VALUE (params);
2105 params = TREE_CHAIN (params);
2107 wanted_type_ptr->wanted_type = wanted_type;
2108 wanted_type_ptr->wanted_type_name = wanted_type_name;
2109 wanted_type_ptr->pointer_count = fci->pointer_count + aflag;
2110 wanted_type_ptr->char_lenient_flag = 0;
2111 if (strchr (fci->flags2, 'c') != 0)
2112 wanted_type_ptr->char_lenient_flag = 1;
2113 wanted_type_ptr->writing_in_flag = 0;
2114 wanted_type_ptr->reading_from_flag = 0;
2116 wanted_type_ptr->writing_in_flag = 1;
2119 if (strchr (fci->flags2, 'W') != 0)
2120 wanted_type_ptr->writing_in_flag = 1;
2121 if (strchr (fci->flags2, 'R') != 0)
2122 wanted_type_ptr->reading_from_flag = 1;
2124 wanted_type_ptr->name = NULL;
2125 wanted_type_ptr->param = cur_param;
2126 wanted_type_ptr->arg_num = arg_num;
2127 wanted_type_ptr->next = NULL;
2128 if (last_wanted_type != 0)
2129 last_wanted_type->next = wanted_type_ptr;
2130 if (first_wanted_type == 0)
2131 first_wanted_type = wanted_type_ptr;
2132 last_wanted_type = wanted_type_ptr;
2137 wanted_type_ptr = GGC_NEW (format_wanted_type);
2139 wanted_type = *fci->types[length_chars_val].type;
2140 wanted_type_name = fci->types[length_chars_val].name;
2145 if (first_wanted_type != 0)
2146 check_format_types (first_wanted_type, format_start,
2147 format_chars - format_start);
2149 if (main_wanted_type.next != NULL)
2151 format_wanted_type *wanted_type_ptr = main_wanted_type.next;
2152 while (wanted_type_ptr)
2154 format_wanted_type *next = wanted_type_ptr->next;
2155 ggc_free (wanted_type_ptr);
2156 wanted_type_ptr = next;
2163 /* Check the argument types from a single format conversion (possibly
2164 including width and precision arguments). */
2166 check_format_types (format_wanted_type *types, const char *format_start,
2169 for (; types != 0; types = types->next)
2178 cur_param = types->param;
2179 cur_type = TREE_TYPE (cur_param);
2180 if (cur_type == error_mark_node)
2182 orig_cur_type = cur_type;
2184 wanted_type = types->wanted_type;
2185 arg_num = types->arg_num;
2187 /* The following should not occur here. */
2188 gcc_assert (wanted_type);
2189 gcc_assert (wanted_type != void_type_node || types->pointer_count);
2191 if (types->pointer_count == 0)
2192 wanted_type = lang_hooks.types.type_promotes_to (wanted_type);
2194 wanted_type = TYPE_MAIN_VARIANT (wanted_type);
2196 STRIP_NOPS (cur_param);
2198 /* Check the types of any additional pointer arguments
2199 that precede the "real" argument. */
2200 for (i = 0; i < types->pointer_count; ++i)
2202 if (TREE_CODE (cur_type) == POINTER_TYPE)
2204 cur_type = TREE_TYPE (cur_type);
2205 if (cur_type == error_mark_node)
2208 /* Check for writing through a NULL pointer. */
2209 if (types->writing_in_flag
2212 && integer_zerop (cur_param))
2213 warning (OPT_Wformat, "writing through null pointer "
2214 "(argument %d)", arg_num);
2216 /* Check for reading through a NULL pointer. */
2217 if (types->reading_from_flag
2220 && integer_zerop (cur_param))
2221 warning (OPT_Wformat, "reading through null pointer "
2222 "(argument %d)", arg_num);
2224 if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
2225 cur_param = TREE_OPERAND (cur_param, 0);
2229 /* See if this is an attempt to write into a const type with
2230 scanf or with printf "%n". Note: the writing in happens
2231 at the first indirection only, if for example
2232 void * const * is passed to scanf %p; passing
2233 const void ** is simply passing an incompatible type. */
2234 if (types->writing_in_flag
2236 && (TYPE_READONLY (cur_type)
2238 && (CONSTANT_CLASS_P (cur_param)
2239 || (DECL_P (cur_param)
2240 && TREE_READONLY (cur_param))))))
2241 warning (OPT_Wformat, "writing into constant object "
2242 "(argument %d)", arg_num);
2244 /* If there are extra type qualifiers beyond the first
2245 indirection, then this makes the types technically
2249 && (TYPE_READONLY (cur_type)
2250 || TYPE_VOLATILE (cur_type)
2251 || TYPE_RESTRICT (cur_type)))
2252 warning (OPT_Wformat, "extra type qualifiers in format "
2253 "argument (argument %d)",
2259 format_type_warning (types->name, format_start, format_length,
2260 wanted_type, types->pointer_count,
2261 types->wanted_type_name, orig_cur_type,
2267 if (i < types->pointer_count)
2270 cur_type = TYPE_MAIN_VARIANT (cur_type);
2272 /* Check whether the argument type is a character type. This leniency
2273 only applies to certain formats, flagged with 'c'.
2275 if (types->char_lenient_flag)
2276 char_type_flag = (cur_type == char_type_node
2277 || cur_type == signed_char_type_node
2278 || cur_type == unsigned_char_type_node);
2280 /* Check the type of the "real" argument, if there's a type we want. */
2281 if (lang_hooks.types_compatible_p (wanted_type, cur_type))
2283 /* If we want 'void *', allow any pointer type.
2284 (Anything else would already have got a warning.)
2285 With -pedantic, only allow pointers to void and to character
2287 if (wanted_type == void_type_node
2288 && (!pedantic || (i == 1 && char_type_flag)))
2290 /* Don't warn about differences merely in signedness, unless
2291 -pedantic. With -pedantic, warn if the type is a pointer
2292 target and not a character type, and for character types at
2293 a second level of indirection. */
2294 if (TREE_CODE (wanted_type) == INTEGER_TYPE
2295 && TREE_CODE (cur_type) == INTEGER_TYPE
2296 && (!pedantic || i == 0 || (i == 1 && char_type_flag))
2297 && (TYPE_UNSIGNED (wanted_type)
2298 ? wanted_type == c_common_unsigned_type (cur_type)
2299 : wanted_type == c_common_signed_type (cur_type)))
2301 /* Likewise, "signed char", "unsigned char" and "char" are
2302 equivalent but the above test won't consider them equivalent. */
2303 if (wanted_type == char_type_node
2304 && (!pedantic || i < 2)
2307 /* Now we have a type mismatch. */
2308 format_type_warning (types->name, format_start, format_length,
2309 wanted_type, types->pointer_count,
2310 types->wanted_type_name, orig_cur_type, arg_num);
2315 /* Give a warning about a format argument of different type from that
2316 expected. DESCR is a description such as "field precision", or
2317 NULL for an ordinary format. For an ordinary format, FORMAT_START
2318 points to where the format starts in the format string and
2319 FORMAT_LENGTH is its length. WANTED_TYPE is the type the argument
2320 should have after POINTER_COUNT pointer dereferences.
2321 WANTED_NAME_NAME is a possibly more friendly name of WANTED_TYPE,
2322 or NULL if the ordinary name of the type should be used. ARG_TYPE
2323 is the type of the actual argument. ARG_NUM is the number of that
2326 format_type_warning (const char *descr, const char *format_start,
2327 int format_length, tree wanted_type, int pointer_count,
2328 const char *wanted_type_name, tree arg_type, int arg_num)
2331 /* If ARG_TYPE is a typedef with a misleading name (for example,
2332 size_t but not the standard size_t expected by printf %zu), avoid
2333 printing the typedef name. */
2334 if (wanted_type_name
2335 && TYPE_NAME (arg_type)
2336 && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL
2337 && DECL_NAME (TYPE_NAME (arg_type))
2338 && !strcmp (wanted_type_name,
2339 lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2)))
2340 arg_type = TYPE_MAIN_VARIANT (arg_type);
2341 /* The format type and name exclude any '*' for pointers, so those
2342 must be formatted manually. For all the types we currently have,
2343 this is adequate, but formats taking pointers to functions or
2344 arrays would require the full type to be built up in order to
2345 print it with %T. */
2346 p = (char *) alloca (pointer_count + 2);
2347 if (pointer_count == 0)
2349 else if (c_dialect_cxx ())
2351 memset (p, '*', pointer_count);
2352 p[pointer_count] = 0;
2357 memset (p + 1, '*', pointer_count);
2358 p[pointer_count + 1] = 0;
2360 if (wanted_type_name)
2363 warning (OPT_Wformat, "%s should have type %<%s%s%>, "
2364 "but argument %d has type %qT",
2365 descr, wanted_type_name, p, arg_num, arg_type);
2367 warning (OPT_Wformat, "format %q.*s expects type %<%s%s%>, "
2368 "but argument %d has type %qT",
2369 format_length, format_start, wanted_type_name, p,
2375 warning (OPT_Wformat, "%s should have type %<%T%s%>, "
2376 "but argument %d has type %qT",
2377 descr, wanted_type, p, arg_num, arg_type);
2379 warning (OPT_Wformat, "format %q.*s expects type %<%T%s%>, "
2380 "but argument %d has type %qT",
2381 format_length, format_start, wanted_type, p, arg_num, arg_type);
2386 /* Given a format_char_info array FCI, and a character C, this function
2387 returns the index into the conversion_specs where that specifier's
2388 data is located. The character must exist. */
2390 find_char_info_specifier_index (const format_char_info *fci, int c)
2394 for (i = 0; fci->format_chars; i++, fci++)
2395 if (strchr (fci->format_chars, c))
2398 /* We shouldn't be looking for a non-existent specifier. */
2402 /* Given a format_length_info array FLI, and a character C, this
2403 function returns the index into the conversion_specs where that
2404 modifier's data is located. The character must exist. */
2406 find_length_info_modifier_index (const format_length_info *fli, int c)
2410 for (i = 0; fli->name; i++, fli++)
2411 if (strchr (fli->name, c))
2414 /* We shouldn't be looking for a non-existent modifier. */
2418 /* Determine the type of HOST_WIDE_INT in the code being compiled for
2419 use in GCC's __asm_fprintf__ custom format attribute. You must
2420 have set dynamic_format_types before calling this function. */
2422 init_dynamic_asm_fprintf_info (void)
2428 format_length_info *new_asm_fprintf_length_specs;
2431 /* Find the underlying type for HOST_WIDE_INT. For the %w
2432 length modifier to work, one must have issued: "typedef
2433 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2434 prior to using that modifier. */
2435 hwi = maybe_get_identifier ("__gcc_host_wide_int__");
2438 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2441 hwi = identifier_global_value (hwi);
2442 if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
2444 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2447 hwi = DECL_ORIGINAL_TYPE (hwi);
2449 if (hwi != long_integer_type_node && hwi != long_long_integer_type_node)
2451 error ("%<__gcc_host_wide_int__%> is not defined as %<long%>"
2452 " or %<long long%>");
2456 /* Create a new (writable) copy of asm_fprintf_length_specs. */
2457 new_asm_fprintf_length_specs = (format_length_info *)
2458 xmemdup (asm_fprintf_length_specs,
2459 sizeof (asm_fprintf_length_specs),
2460 sizeof (asm_fprintf_length_specs));
2462 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
2463 i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
2464 if (hwi == long_integer_type_node)
2465 new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
2466 else if (hwi == long_long_integer_type_node)
2467 new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
2471 /* Assign the new data for use. */
2472 dynamic_format_types[asm_fprintf_format_type].length_char_specs =
2473 new_asm_fprintf_length_specs;
2477 /* Determine the type of a "locus" in the code being compiled for use
2478 in GCC's __gcc_gfc__ custom format attribute. You must have set
2479 dynamic_format_types before calling this function. */
2481 init_dynamic_gfc_info (void)
2487 static format_char_info *gfc_fci;
2489 /* For the GCC __gcc_gfc__ custom format specifier to work, one
2490 must have declared 'locus' prior to using this attribute. If
2491 we haven't seen this declarations then you shouldn't use the
2492 specifier requiring that type. */
2493 if ((locus = maybe_get_identifier ("locus")))
2495 locus = identifier_global_value (locus);
2498 if (TREE_CODE (locus) != TYPE_DECL)
2500 error ("%<locus%> is not defined as a type");
2504 locus = TREE_TYPE (locus);
2508 /* Assign the new data for use. */
2510 /* Handle the __gcc_gfc__ format specifics. */
2512 dynamic_format_types[gcc_gfc_format_type].conversion_specs =
2513 gfc_fci = (format_char_info *)
2514 xmemdup (gcc_gfc_char_table,
2515 sizeof (gcc_gfc_char_table),
2516 sizeof (gcc_gfc_char_table));
2519 const unsigned i = find_char_info_specifier_index (gfc_fci, 'L');
2520 gfc_fci[i].types[0].type = &locus;
2521 gfc_fci[i].pointer_count = 1;
2526 /* Determine the types of "tree" and "location_t" in the code being
2527 compiled for use in GCC's diagnostic custom format attributes. You
2528 must have set dynamic_format_types before calling this function. */
2530 init_dynamic_diag_info (void)
2532 static tree t, loc, hwi;
2534 if (!loc || !t || !hwi)
2536 static format_char_info *diag_fci, *tdiag_fci, *cdiag_fci, *cxxdiag_fci;
2537 static format_length_info *diag_ls;
2540 /* For the GCC-diagnostics custom format specifiers to work, one
2541 must have declared 'tree' and/or 'location_t' prior to using
2542 those attributes. If we haven't seen these declarations then
2543 you shouldn't use the specifiers requiring these types.
2544 However we don't force a hard ICE because we may see only one
2545 or the other type. */
2546 if ((loc = maybe_get_identifier ("location_t")))
2548 loc = identifier_global_value (loc);
2551 if (TREE_CODE (loc) != TYPE_DECL)
2553 error ("%<location_t%> is not defined as a type");
2557 loc = TREE_TYPE (loc);
2561 /* We need to grab the underlying 'union tree_node' so peek into
2562 an extra type level. */
2563 if ((t = maybe_get_identifier ("tree")))
2565 t = identifier_global_value (t);
2568 if (TREE_CODE (t) != TYPE_DECL)
2570 error ("%<tree%> is not defined as a type");
2573 else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
2575 error ("%<tree%> is not defined as a pointer type");
2579 t = TREE_TYPE (TREE_TYPE (t));
2583 /* Find the underlying type for HOST_WIDE_INT. For the %w
2584 length modifier to work, one must have issued: "typedef
2585 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2586 prior to using that modifier. */
2587 if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
2589 hwi = identifier_global_value (hwi);
2592 if (TREE_CODE (hwi) != TYPE_DECL)
2594 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2599 hwi = DECL_ORIGINAL_TYPE (hwi);
2601 if (hwi != long_integer_type_node
2602 && hwi != long_long_integer_type_node)
2604 error ("%<__gcc_host_wide_int__%> is not defined"
2605 " as %<long%> or %<long long%>");
2612 /* Assign the new data for use. */
2614 /* All the GCC diag formats use the same length specs. */
2616 dynamic_format_types[gcc_diag_format_type].length_char_specs =
2617 dynamic_format_types[gcc_tdiag_format_type].length_char_specs =
2618 dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
2619 dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
2620 diag_ls = (format_length_info *)
2621 xmemdup (gcc_diag_length_specs,
2622 sizeof (gcc_diag_length_specs),
2623 sizeof (gcc_diag_length_specs));
2626 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
2627 i = find_length_info_modifier_index (diag_ls, 'w');
2628 if (hwi == long_integer_type_node)
2629 diag_ls[i].index = FMT_LEN_l;
2630 else if (hwi == long_long_integer_type_node)
2631 diag_ls[i].index = FMT_LEN_ll;
2636 /* Handle the __gcc_diag__ format specifics. */
2638 dynamic_format_types[gcc_diag_format_type].conversion_specs =
2639 diag_fci = (format_char_info *)
2640 xmemdup (gcc_diag_char_table,
2641 sizeof (gcc_diag_char_table),
2642 sizeof (gcc_diag_char_table));
2645 i = find_char_info_specifier_index (diag_fci, 'H');
2646 diag_fci[i].types[0].type = &loc;
2647 diag_fci[i].pointer_count = 1;
2651 i = find_char_info_specifier_index (diag_fci, 'J');
2652 diag_fci[i].types[0].type = &t;
2653 diag_fci[i].pointer_count = 1;
2656 /* Handle the __gcc_tdiag__ format specifics. */
2658 dynamic_format_types[gcc_tdiag_format_type].conversion_specs =
2659 tdiag_fci = (format_char_info *)
2660 xmemdup (gcc_tdiag_char_table,
2661 sizeof (gcc_tdiag_char_table),
2662 sizeof (gcc_tdiag_char_table));
2665 i = find_char_info_specifier_index (tdiag_fci, 'H');
2666 tdiag_fci[i].types[0].type = &loc;
2667 tdiag_fci[i].pointer_count = 1;
2671 /* All specifiers taking a tree share the same struct. */
2672 i = find_char_info_specifier_index (tdiag_fci, 'D');
2673 tdiag_fci[i].types[0].type = &t;
2674 tdiag_fci[i].pointer_count = 1;
2675 i = find_char_info_specifier_index (tdiag_fci, 'J');
2676 tdiag_fci[i].types[0].type = &t;
2677 tdiag_fci[i].pointer_count = 1;
2680 /* Handle the __gcc_cdiag__ format specifics. */
2682 dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
2683 cdiag_fci = (format_char_info *)
2684 xmemdup (gcc_cdiag_char_table,
2685 sizeof (gcc_cdiag_char_table),
2686 sizeof (gcc_cdiag_char_table));
2689 i = find_char_info_specifier_index (cdiag_fci, 'H');
2690 cdiag_fci[i].types[0].type = &loc;
2691 cdiag_fci[i].pointer_count = 1;
2695 /* All specifiers taking a tree share the same struct. */
2696 i = find_char_info_specifier_index (cdiag_fci, 'D');
2697 cdiag_fci[i].types[0].type = &t;
2698 cdiag_fci[i].pointer_count = 1;
2699 i = find_char_info_specifier_index (cdiag_fci, 'J');
2700 cdiag_fci[i].types[0].type = &t;
2701 cdiag_fci[i].pointer_count = 1;
2704 /* Handle the __gcc_cxxdiag__ format specifics. */
2706 dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
2707 cxxdiag_fci = (format_char_info *)
2708 xmemdup (gcc_cxxdiag_char_table,
2709 sizeof (gcc_cxxdiag_char_table),
2710 sizeof (gcc_cxxdiag_char_table));
2713 i = find_char_info_specifier_index (cxxdiag_fci, 'H');
2714 cxxdiag_fci[i].types[0].type = &loc;
2715 cxxdiag_fci[i].pointer_count = 1;
2719 /* All specifiers taking a tree share the same struct. */
2720 i = find_char_info_specifier_index (cxxdiag_fci, 'D');
2721 cxxdiag_fci[i].types[0].type = &t;
2722 cxxdiag_fci[i].pointer_count = 1;
2723 i = find_char_info_specifier_index (cxxdiag_fci, 'J');
2724 cxxdiag_fci[i].types[0].type = &t;
2725 cxxdiag_fci[i].pointer_count = 1;
2730 #ifdef TARGET_FORMAT_TYPES
2731 extern const format_kind_info TARGET_FORMAT_TYPES[];
2734 /* Handle a "format" attribute; arguments as in
2735 struct attribute_spec.handler. */
2737 handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args,
2738 int flags, bool *no_add_attrs)
2741 function_format_info info;
2744 #ifdef TARGET_FORMAT_TYPES
2745 /* If the target provides additional format types, we need to
2746 add them to FORMAT_TYPES at first use. */
2747 if (TARGET_FORMAT_TYPES != NULL && !dynamic_format_types)
2749 dynamic_format_types = xmalloc ((n_format_types + TARGET_N_FORMAT_TYPES)
2750 * sizeof (dynamic_format_types[0]));
2751 memcpy (dynamic_format_types, format_types_orig,
2752 sizeof (format_types_orig));
2753 memcpy (&dynamic_format_types[n_format_types], TARGET_FORMAT_TYPES,
2754 TARGET_N_FORMAT_TYPES * sizeof (dynamic_format_types[0]));
2756 format_types = dynamic_format_types;
2757 n_format_types += TARGET_N_FORMAT_TYPES;
2761 if (!decode_format_attr (args, &info, 0))
2763 *no_add_attrs = true;
2767 argument = TYPE_ARG_TYPES (type);
2770 if (!check_format_string (argument, info.format_num, flags,
2774 if (info.first_arg_num != 0)
2776 unsigned HOST_WIDE_INT arg_num = 1;
2778 /* Verify that first_arg_num points to the last arg,
2781 arg_num++, argument = TREE_CHAIN (argument);
2783 if (arg_num != info.first_arg_num)
2785 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
2786 error ("args to be formatted is not %<...%>");
2787 *no_add_attrs = true;
2793 if (info.format_type == strftime_format_type && info.first_arg_num != 0)
2795 error ("strftime formats cannot format arguments");
2796 *no_add_attrs = true;
2800 /* If this is a custom GCC-internal format type, we have to
2801 initialize certain bits a runtime. */
2802 if (info.format_type == asm_fprintf_format_type
2803 || info.format_type == gcc_gfc_format_type
2804 || info.format_type == gcc_diag_format_type
2805 || info.format_type == gcc_tdiag_format_type
2806 || info.format_type == gcc_cdiag_format_type
2807 || info.format_type == gcc_cxxdiag_format_type)
2809 /* Our first time through, we have to make sure that our
2810 format_type data is allocated dynamically and is modifiable. */
2811 if (!dynamic_format_types)
2812 format_types = dynamic_format_types = (format_kind_info *)
2813 xmemdup (format_types_orig, sizeof (format_types_orig),
2814 sizeof (format_types_orig));
2816 /* If this is format __asm_fprintf__, we have to initialize
2817 GCC's notion of HOST_WIDE_INT for checking %wd. */
2818 if (info.format_type == asm_fprintf_format_type)
2819 init_dynamic_asm_fprintf_info ();
2820 /* If this is format __gcc_gfc__, we have to initialize GCC's
2821 notion of 'locus' at runtime for %L. */
2822 else if (info.format_type == gcc_gfc_format_type)
2823 init_dynamic_gfc_info ();
2824 /* If this is one of the diagnostic attributes, then we have to
2825 initialize 'location_t' and 'tree' at runtime. */
2826 else if (info.format_type == gcc_diag_format_type
2827 || info.format_type == gcc_tdiag_format_type
2828 || info.format_type == gcc_cdiag_format_type
2829 || info.format_type == gcc_cxxdiag_format_type)
2830 init_dynamic_diag_info ();