Merge from trunk
[official-gcc.git] / gcc / c-family / c-format.c
blobfabefafa23b5b96198931a9dfab737c0ae74620d
1 /* Check calls to formatted I/O functions (-Wformat).
2 Copyright (C) 1992-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "wide-int.h"
32 #include "inchash.h"
33 #include "real.h"
34 #include "tree.h"
35 #include "stringpool.h"
36 #include "flags.h"
37 #include "c-common.h"
38 #include "c-objc.h"
39 #include "intl.h"
40 #include "diagnostic-core.h"
41 #include "langhooks.h"
42 #include "c-format.h"
43 #include "alloc-pool.h"
44 #include "c-target.h"
46 /* Handle attributes associated with format checking. */
48 /* This must be in the same order as format_types, except for
49 format_type_error. Target-specific format types do not have
50 matching enum values. */
51 enum format_type { printf_format_type, asm_fprintf_format_type,
52 gcc_diag_format_type, gcc_tdiag_format_type,
53 gcc_cdiag_format_type,
54 gcc_cxxdiag_format_type, gcc_gfc_format_type,
55 gcc_objc_string_format_type,
56 format_type_error = -1};
58 typedef struct function_format_info
60 int format_type; /* type of format (printf, scanf, etc.) */
61 unsigned HOST_WIDE_INT format_num; /* number of format argument */
62 unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */
63 } function_format_info;
65 static bool decode_format_attr (tree, function_format_info *, int);
66 static int decode_format_type (const char *);
68 static bool check_format_string (tree argument,
69 unsigned HOST_WIDE_INT format_num,
70 int flags, bool *no_add_attrs,
71 int expected_format_type);
72 static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value,
73 int validated_p);
74 static const char *convert_format_name_to_system_name (const char *attr_name);
75 static bool cmp_attribs (const char *tattr_name, const char *attr_name);
77 static int first_target_format_type;
78 static const char *format_name (int format_num);
79 static int format_flags (int format_num);
81 /* Check that we have a pointer to a string suitable for use as a format.
82 The default is to check for a char type.
83 For objective-c dialects, this is extended to include references to string
84 objects validated by objc_string_ref_type_p ().
85 Targets may also provide a string object type that can be used within c and
86 c++ and shared with their respective objective-c dialects. In this case the
87 reference to a format string is checked for validity via a hook.
89 The function returns true if strref points to any string type valid for the
90 language dialect and target. */
92 static bool
93 valid_stringptr_type_p (tree strref)
95 return (strref != NULL
96 && TREE_CODE (strref) == POINTER_TYPE
97 && (TYPE_MAIN_VARIANT (TREE_TYPE (strref)) == char_type_node
98 || objc_string_ref_type_p (strref)
99 || (*targetcm.string_object_ref_type_p) ((const_tree) strref)));
102 /* Handle a "format_arg" attribute; arguments as in
103 struct attribute_spec.handler. */
104 tree
105 handle_format_arg_attribute (tree *node, tree ARG_UNUSED (name),
106 tree args, int flags, bool *no_add_attrs)
108 tree type = *node;
109 tree format_num_expr = TREE_VALUE (args);
110 unsigned HOST_WIDE_INT format_num = 0;
112 if (!get_constant (format_num_expr, &format_num, 0))
114 error ("format string has invalid operand number");
115 *no_add_attrs = true;
116 return NULL_TREE;
119 if (prototype_p (type))
121 /* The format arg can be any string reference valid for the language and
122 target. We cannot be more specific in this case. */
123 if (!check_format_string (type, format_num, flags, no_add_attrs, -1))
124 return NULL_TREE;
127 if (!valid_stringptr_type_p (TREE_TYPE (type)))
129 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
130 error ("function does not return string type");
131 *no_add_attrs = true;
132 return NULL_TREE;
135 return NULL_TREE;
138 /* Verify that the format_num argument is actually a string reference suitable,
139 for the language dialect and target (in case the format attribute is in
140 error). When we know the specific reference type expected, this is also
141 checked. */
142 static bool
143 check_format_string (tree fntype, unsigned HOST_WIDE_INT format_num,
144 int flags, bool *no_add_attrs, int expected_format_type)
146 unsigned HOST_WIDE_INT i;
147 bool is_objc_sref, is_target_sref, is_char_ref;
148 tree ref;
149 int fmt_flags;
150 function_args_iterator iter;
152 i = 1;
153 FOREACH_FUNCTION_ARGS (fntype, ref, iter)
155 if (i == format_num)
156 break;
157 i++;
160 if (!ref
161 || !valid_stringptr_type_p (ref))
163 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
164 error ("format string argument is not a string type");
165 *no_add_attrs = true;
166 return false;
169 /* We only know that we want a suitable string reference. */
170 if (expected_format_type < 0)
171 return true;
173 /* Now check that the arg matches the expected type. */
174 is_char_ref =
175 (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node);
177 fmt_flags = format_flags (expected_format_type);
178 is_objc_sref = is_target_sref = false;
179 if (!is_char_ref)
180 is_objc_sref = objc_string_ref_type_p (ref);
182 if (!(fmt_flags & FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL))
184 if (is_char_ref)
185 return true; /* OK, we expected a char and found one. */
186 else
188 /* We expected a char but found an extended string type. */
189 if (is_objc_sref)
190 error ("found a %<%s%> reference but the format argument should"
191 " be a string", format_name (gcc_objc_string_format_type));
192 else
193 error ("found a %qT but the format argument should be a string",
194 ref);
195 *no_add_attrs = true;
196 return false;
200 /* We expect a string object type as the format arg. */
201 if (is_char_ref)
203 error ("format argument should be a %<%s%> reference but"
204 " a string was found", format_name (expected_format_type));
205 *no_add_attrs = true;
206 return false;
209 /* We will assert that objective-c will support either its own string type
210 or the target-supplied variant. */
211 if (!is_objc_sref)
212 is_target_sref = (*targetcm.string_object_ref_type_p) ((const_tree) ref);
214 if (expected_format_type == (int) gcc_objc_string_format_type
215 && (is_objc_sref || is_target_sref))
216 return true;
218 /* We will allow a target string ref to match only itself. */
219 if (first_target_format_type
220 && expected_format_type >= first_target_format_type
221 && is_target_sref)
222 return true;
223 else
225 error ("format argument should be a %<%s%> reference",
226 format_name (expected_format_type));
227 *no_add_attrs = true;
228 return false;
231 gcc_unreachable ();
234 /* Verify EXPR is a constant, and store its value.
235 If validated_p is true there should be no errors.
236 Returns true on success, false otherwise. */
237 static bool
238 get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
240 if (!tree_fits_uhwi_p (expr))
242 gcc_assert (!validated_p);
243 return false;
246 *value = TREE_INT_CST_LOW (expr);
248 return true;
251 /* Decode the arguments to a "format" attribute into a
252 function_format_info structure. It is already known that the list
253 is of the right length. If VALIDATED_P is true, then these
254 attributes have already been validated and must not be erroneous;
255 if false, it will give an error message. Returns true if the
256 attributes are successfully decoded, false otherwise. */
258 static bool
259 decode_format_attr (tree args, function_format_info *info, int validated_p)
261 tree format_type_id = TREE_VALUE (args);
262 tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
263 tree first_arg_num_expr
264 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
266 if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
268 gcc_assert (!validated_p);
269 error ("unrecognized format specifier");
270 return false;
272 else
274 const char *p = IDENTIFIER_POINTER (format_type_id);
276 p = convert_format_name_to_system_name (p);
278 info->format_type = decode_format_type (p);
280 if (!c_dialect_objc ()
281 && info->format_type == gcc_objc_string_format_type)
283 gcc_assert (!validated_p);
284 warning (OPT_Wformat_, "%qE is only allowed in Objective-C dialects",
285 format_type_id);
286 info->format_type = format_type_error;
287 return false;
290 if (info->format_type == format_type_error)
292 gcc_assert (!validated_p);
293 warning (OPT_Wformat_, "%qE is an unrecognized format function type",
294 format_type_id);
295 return false;
299 if (!get_constant (format_num_expr, &info->format_num, validated_p))
301 error ("format string has invalid operand number");
302 return false;
305 if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
307 error ("%<...%> has invalid operand number");
308 return false;
311 if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
313 gcc_assert (!validated_p);
314 error ("format string argument follows the args to be formatted");
315 return false;
318 return true;
321 /* Check a call to a format function against a parameter list. */
323 /* The C standard version C++ is treated as equivalent to
324 or inheriting from, for the purpose of format features supported. */
325 #define CPLUSPLUS_STD_VER (cxx_dialect < cxx11 ? STD_C94 : STD_C99)
326 /* The C standard version we are checking formats against when pedantic. */
327 #define C_STD_VER ((int) (c_dialect_cxx () \
328 ? CPLUSPLUS_STD_VER \
329 : (flag_isoc99 \
330 ? STD_C99 \
331 : (flag_isoc94 ? STD_C94 : STD_C89))))
332 /* The name to give to the standard version we are warning about when
333 pedantic. FEATURE_VER is the version in which the feature warned out
334 appeared, which is higher than C_STD_VER. */
335 #define C_STD_NAME(FEATURE_VER) (c_dialect_cxx () \
336 ? (cxx_dialect < cxx11 ? "ISO C++98" \
337 : "ISO C++11") \
338 : ((FEATURE_VER) == STD_EXT \
339 ? "ISO C" \
340 : "ISO C90"))
341 /* Adjust a C standard version, which may be STD_C9L, to account for
342 -Wno-long-long. Returns other standard versions unchanged. */
343 #define ADJ_STD(VER) ((int) ((VER) == STD_C9L \
344 ? (warn_long_long ? STD_C99 : STD_C89) \
345 : (VER)))
347 /* Enum describing the kind of specifiers present in the format and
348 requiring an argument. */
349 enum format_specifier_kind {
350 CF_KIND_FORMAT,
351 CF_KIND_FIELD_WIDTH,
352 CF_KIND_FIELD_PRECISION
355 static const char *kind_descriptions[] = {
356 N_("format"),
357 N_("field width specifier"),
358 N_("field precision specifier")
361 /* Structure describing details of a type expected in format checking,
362 and the type to check against it. */
363 typedef struct format_wanted_type
365 /* The type wanted. */
366 tree wanted_type;
367 /* The name of this type to use in diagnostics. */
368 const char *wanted_type_name;
369 /* Should be type checked just for scalar width identity. */
370 int scalar_identity_flag;
371 /* The level of indirection through pointers at which this type occurs. */
372 int pointer_count;
373 /* Whether, when pointer_count is 1, to allow any character type when
374 pedantic, rather than just the character or void type specified. */
375 int char_lenient_flag;
376 /* Whether the argument, dereferenced once, is written into and so the
377 argument must not be a pointer to a const-qualified type. */
378 int writing_in_flag;
379 /* Whether the argument, dereferenced once, is read from and so
380 must not be a NULL pointer. */
381 int reading_from_flag;
382 /* The kind of specifier that this type is used for. */
383 enum format_specifier_kind kind;
384 /* The starting character of the specifier. This never includes the
385 initial percent sign. */
386 const char *format_start;
387 /* The length of the specifier. */
388 int format_length;
389 /* The actual parameter to check against the wanted type. */
390 tree param;
391 /* The argument number of that parameter. */
392 int arg_num;
393 /* The next type to check for this format conversion, or NULL if none. */
394 struct format_wanted_type *next;
395 } format_wanted_type;
397 /* Convenience macro for format_length_info meaning unused. */
398 #define NO_FMT NULL, FMT_LEN_none, STD_C89
400 static const format_length_info printf_length_specs[] =
402 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
403 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 },
404 { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 },
405 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
406 { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
407 { "Z", FMT_LEN_z, STD_EXT, NO_FMT, 0 },
408 { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
409 { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 },
410 { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 },
411 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 },
412 { NO_FMT, NO_FMT, 0 }
415 /* Length specifiers valid for asm_fprintf. */
416 static const format_length_info asm_fprintf_length_specs[] =
418 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
419 { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
420 { NO_FMT, NO_FMT, 0 }
423 /* Length specifiers valid for GCC diagnostics. */
424 static const format_length_info gcc_diag_length_specs[] =
426 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
427 { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
428 { NO_FMT, NO_FMT, 0 }
431 /* The custom diagnostics all accept the same length specifiers. */
432 #define gcc_tdiag_length_specs gcc_diag_length_specs
433 #define gcc_cdiag_length_specs gcc_diag_length_specs
434 #define gcc_cxxdiag_length_specs gcc_diag_length_specs
436 /* This differs from printf_length_specs only in that "Z" is not accepted. */
437 static const format_length_info scanf_length_specs[] =
439 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
440 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 },
441 { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 },
442 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
443 { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
444 { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
445 { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 },
446 { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 },
447 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 },
448 { NO_FMT, NO_FMT, 0 }
452 /* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings
453 make no sense for a format type not part of any C standard version. */
454 static const format_length_info strfmon_length_specs[] =
456 /* A GNU extension. */
457 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
458 { NO_FMT, NO_FMT, 0 }
462 /* For now, the Fortran front-end routines only use l as length modifier. */
463 static const format_length_info gcc_gfc_length_specs[] =
465 { "l", FMT_LEN_l, STD_C89, NO_FMT, 0 },
466 { NO_FMT, NO_FMT, 0 }
470 static const format_flag_spec printf_flag_specs[] =
472 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
473 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
474 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
475 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
476 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
477 { '\'', 0, 0, N_("''' flag"), N_("the ''' printf flag"), STD_EXT },
478 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' printf flag"), STD_EXT },
479 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
480 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
481 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
482 { 0, 0, 0, NULL, NULL, STD_C89 }
486 static const format_flag_pair printf_flag_pairs[] =
488 { ' ', '+', 1, 0 },
489 { '0', '-', 1, 0 },
490 { '0', 'p', 1, 'i' },
491 { 0, 0, 0, 0 }
494 static const format_flag_spec asm_fprintf_flag_specs[] =
496 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
497 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
498 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
499 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
500 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
501 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
502 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
503 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
504 { 0, 0, 0, NULL, NULL, STD_C89 }
507 static const format_flag_pair asm_fprintf_flag_pairs[] =
509 { ' ', '+', 1, 0 },
510 { '0', '-', 1, 0 },
511 { '0', 'p', 1, 'i' },
512 { 0, 0, 0, 0 }
515 static const format_flag_pair gcc_diag_flag_pairs[] =
517 { 0, 0, 0, 0 }
520 #define gcc_tdiag_flag_pairs gcc_diag_flag_pairs
521 #define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
522 #define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
523 #define gcc_gfc_flag_pairs gcc_diag_flag_pairs
525 static const format_flag_spec gcc_diag_flag_specs[] =
527 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
528 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
529 { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 },
530 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
531 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
532 { 0, 0, 0, NULL, NULL, STD_C89 }
535 #define gcc_tdiag_flag_specs gcc_diag_flag_specs
536 #define gcc_cdiag_flag_specs gcc_diag_flag_specs
537 #define gcc_cxxdiag_flag_specs gcc_diag_flag_specs
538 #define gcc_gfc_flag_specs gcc_diag_flag_specs
540 static const format_flag_spec scanf_flag_specs[] =
542 { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
543 { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
544 { 'm', 0, 0, N_("'m' flag"), N_("the 'm' scanf flag"), STD_EXT },
545 { 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
546 { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
547 { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT },
548 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT },
549 { 0, 0, 0, NULL, NULL, STD_C89 }
553 static const format_flag_pair scanf_flag_pairs[] =
555 { '*', 'L', 0, 0 },
556 { 'a', 'm', 0, 0 },
557 { 0, 0, 0, 0 }
561 static const format_flag_spec strftime_flag_specs[] =
563 { '_', 0, 0, N_("'_' flag"), N_("the '_' strftime flag"), STD_EXT },
564 { '-', 0, 0, N_("'-' flag"), N_("the '-' strftime flag"), STD_EXT },
565 { '0', 0, 0, N_("'0' flag"), N_("the '0' strftime flag"), STD_EXT },
566 { '^', 0, 0, N_("'^' flag"), N_("the '^' strftime flag"), STD_EXT },
567 { '#', 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), STD_EXT },
568 { 'w', 0, 0, N_("field width"), N_("field width in strftime format"), STD_EXT },
569 { 'E', 0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"), STD_C99 },
570 { 'O', 0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"), STD_C99 },
571 { 'O', 'o', 0, NULL, N_("the 'O' modifier"), STD_EXT },
572 { 0, 0, 0, NULL, NULL, STD_C89 }
576 static const format_flag_pair strftime_flag_pairs[] =
578 { 'E', 'O', 0, 0 },
579 { '_', '-', 0, 0 },
580 { '_', '0', 0, 0 },
581 { '-', '0', 0, 0 },
582 { '^', '#', 0, 0 },
583 { 0, 0, 0, 0 }
587 static const format_flag_spec strfmon_flag_specs[] =
589 { '=', 0, 1, N_("fill character"), N_("fill character in strfmon format"), STD_C89 },
590 { '^', 0, 0, N_("'^' flag"), N_("the '^' strfmon flag"), STD_C89 },
591 { '+', 0, 0, N_("'+' flag"), N_("the '+' strfmon flag"), STD_C89 },
592 { '(', 0, 0, N_("'(' flag"), N_("the '(' strfmon flag"), STD_C89 },
593 { '!', 0, 0, N_("'!' flag"), N_("the '!' strfmon flag"), STD_C89 },
594 { '-', 0, 0, N_("'-' flag"), N_("the '-' strfmon flag"), STD_C89 },
595 { 'w', 0, 0, N_("field width"), N_("field width in strfmon format"), STD_C89 },
596 { '#', 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 },
597 { 'p', 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
598 { 'L', 0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 },
599 { 0, 0, 0, NULL, NULL, STD_C89 }
602 static const format_flag_pair strfmon_flag_pairs[] =
604 { '+', '(', 0, 0 },
605 { 0, 0, 0, 0 }
609 static const format_char_info print_char_table[] =
611 /* C89 conversion specifiers. */
612 { "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 },
613 { "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 },
614 { "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 },
615 { "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 },
616 { "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 },
617 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
618 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
619 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
620 { "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 },
621 /* C99 conversion specifiers. */
622 { "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 },
623 { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
624 /* X/Open conversion specifiers. */
625 { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
626 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
627 /* GNU conversion specifiers. */
628 { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL },
629 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
632 static const format_char_info asm_fprintf_char_table[] =
634 /* C89 conversion specifiers. */
635 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL },
636 { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
637 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL },
638 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
639 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
641 /* asm_fprintf conversion specifiers. */
642 { "O", 0, STD_C89, NOARGUMENTS, "", "", NULL },
643 { "R", 0, STD_C89, NOARGUMENTS, "", "", NULL },
644 { "I", 0, STD_C89, NOARGUMENTS, "", "", NULL },
645 { "L", 0, STD_C89, NOARGUMENTS, "", "", NULL },
646 { "U", 0, STD_C89, NOARGUMENTS, "", "", NULL },
647 { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
648 { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL },
649 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
652 static const format_char_info gcc_diag_char_table[] =
654 /* C89 conversion specifiers. */
655 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
656 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
657 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
658 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
659 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
660 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
662 /* Custom conversion specifiers. */
664 /* These will require a "tree" at runtime. */
665 { "K", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
667 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
668 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
669 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
670 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
673 static const format_char_info gcc_tdiag_char_table[] =
675 /* C89 conversion specifiers. */
676 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
677 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
678 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
679 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
680 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
681 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
683 /* Custom conversion specifiers. */
685 /* These will require a "tree" at runtime. */
686 { "DFKTEV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
688 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
690 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
691 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
692 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
693 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
696 static const format_char_info gcc_cdiag_char_table[] =
698 /* C89 conversion specifiers. */
699 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
700 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
701 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
702 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
703 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
704 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
706 /* Custom conversion specifiers. */
708 /* These will require a "tree" at runtime. */
709 { "DEFKTV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
711 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
713 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
714 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
715 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
716 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
719 static const format_char_info gcc_cxxdiag_char_table[] =
721 /* C89 conversion specifiers. */
722 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
723 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
724 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
725 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
726 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
727 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
729 /* Custom conversion specifiers. */
731 /* These will require a "tree" at runtime. */
732 { "ADEFKSTVXZ",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
734 { "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
736 /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
737 { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
739 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
740 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
741 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
742 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
745 static const format_char_info gcc_gfc_char_table[] =
747 /* C89 conversion specifiers. */
748 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
749 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
750 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
751 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "cR", NULL },
753 /* gfc conversion specifiers. */
755 { "C", 0, STD_C89, NOARGUMENTS, "", "", NULL },
757 /* This will require a "locus" at runtime. */
758 { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL },
760 /* These will require nothing. */
761 { "<>",0, STD_C89, NOARGUMENTS, "", "", NULL },
762 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
765 static const format_char_info scan_char_table[] =
767 /* C89 conversion specifiers. */
768 { "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 },
769 { "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 },
770 { "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 },
771 { "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 },
772 { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "cW", NULL },
773 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW", NULL },
774 { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW[", NULL },
775 { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
776 { "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 },
777 /* C99 conversion specifiers. */
778 { "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 },
779 { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
780 /* X/Open conversion specifiers. */
781 { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "W", NULL },
782 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "W", NULL },
783 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
786 static const format_char_info time_char_table[] =
788 /* C89 conversion specifiers. */
789 { "ABZab", 0, STD_C89, NOLENGTHS, "^#", "", NULL },
790 { "cx", 0, STD_C89, NOLENGTHS, "E", "3", NULL },
791 { "HIMSUWdmw", 0, STD_C89, NOLENGTHS, "-_0Ow", "", NULL },
792 { "j", 0, STD_C89, NOLENGTHS, "-_0Ow", "o", NULL },
793 { "p", 0, STD_C89, NOLENGTHS, "#", "", NULL },
794 { "X", 0, STD_C89, NOLENGTHS, "E", "", NULL },
795 { "y", 0, STD_C89, NOLENGTHS, "EO-_0w", "4", NULL },
796 { "Y", 0, STD_C89, NOLENGTHS, "-_0EOw", "o", NULL },
797 { "%", 0, STD_C89, NOLENGTHS, "", "", NULL },
798 /* C99 conversion specifiers. */
799 { "C", 0, STD_C99, NOLENGTHS, "-_0EOw", "o", NULL },
800 { "D", 0, STD_C99, NOLENGTHS, "", "2", NULL },
801 { "eVu", 0, STD_C99, NOLENGTHS, "-_0Ow", "", NULL },
802 { "FRTnrt", 0, STD_C99, NOLENGTHS, "", "", NULL },
803 { "g", 0, STD_C99, NOLENGTHS, "O-_0w", "2o", NULL },
804 { "G", 0, STD_C99, NOLENGTHS, "-_0Ow", "o", NULL },
805 { "h", 0, STD_C99, NOLENGTHS, "^#", "", NULL },
806 { "z", 0, STD_C99, NOLENGTHS, "O", "o", NULL },
807 /* GNU conversion specifiers. */
808 { "kls", 0, STD_EXT, NOLENGTHS, "-_0Ow", "", NULL },
809 { "P", 0, STD_EXT, NOLENGTHS, "", "", NULL },
810 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
813 static const format_char_info monetary_char_table[] =
815 { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL },
816 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
819 /* This must be in the same order as enum format_type. */
820 static const format_kind_info format_types_orig[] =
822 { "gnu_printf", printf_length_specs, print_char_table, " +#0-'I", NULL,
823 printf_flag_specs, printf_flag_pairs,
824 FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
825 'w', 0, 'p', 0, 'L', 0,
826 &integer_type_node, &integer_type_node
828 { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL,
829 asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
830 FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
831 'w', 0, 'p', 0, 'L', 0,
832 NULL, NULL
834 { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+#", NULL,
835 gcc_diag_flag_specs, gcc_diag_flag_pairs,
836 FMT_FLAG_ARG_CONVERT,
837 0, 0, 'p', 0, 'L', 0,
838 NULL, &integer_type_node
840 { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+#", NULL,
841 gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs,
842 FMT_FLAG_ARG_CONVERT,
843 0, 0, 'p', 0, 'L', 0,
844 NULL, &integer_type_node
846 { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+#", NULL,
847 gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
848 FMT_FLAG_ARG_CONVERT,
849 0, 0, 'p', 0, 'L', 0,
850 NULL, &integer_type_node
852 { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL,
853 gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
854 FMT_FLAG_ARG_CONVERT,
855 0, 0, 'p', 0, 'L', 0,
856 NULL, &integer_type_node
858 { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "q+#", NULL,
859 gcc_gfc_flag_specs, gcc_gfc_flag_pairs,
860 FMT_FLAG_ARG_CONVERT,
861 0, 0, 0, 0, 0, 0,
862 NULL, NULL
864 { "NSString", NULL, NULL, NULL, NULL,
865 NULL, NULL,
866 FMT_FLAG_ARG_CONVERT|FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL, 0, 0, 0, 0, 0, 0,
867 NULL, NULL
869 { "gnu_scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
870 scanf_flag_specs, scanf_flag_pairs,
871 FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
872 'w', 0, 0, '*', 'L', 'm',
873 NULL, NULL
875 { "gnu_strftime", NULL, time_char_table, "_-0^#", "EO",
876 strftime_flag_specs, strftime_flag_pairs,
877 FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, 0,
878 NULL, NULL
880 { "gnu_strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL,
881 strfmon_flag_specs, strfmon_flag_pairs,
882 FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0,
883 NULL, NULL
887 /* This layer of indirection allows GCC to reassign format_types with
888 new data if necessary, while still allowing the original data to be
889 const. */
890 static const format_kind_info *format_types = format_types_orig;
891 /* We can modify this one. We also add target-specific format types
892 to the end of the array. */
893 static format_kind_info *dynamic_format_types;
895 static int n_format_types = ARRAY_SIZE (format_types_orig);
897 /* Structure detailing the results of checking a format function call
898 where the format expression may be a conditional expression with
899 many leaves resulting from nested conditional expressions. */
900 typedef struct
902 /* Number of leaves of the format argument that could not be checked
903 as they were not string literals. */
904 int number_non_literal;
905 /* Number of leaves of the format argument that were null pointers or
906 string literals, but had extra format arguments. */
907 int number_extra_args;
908 location_t extra_arg_loc;
909 /* Number of leaves of the format argument that were null pointers or
910 string literals, but had extra format arguments and used $ operand
911 numbers. */
912 int number_dollar_extra_args;
913 /* Number of leaves of the format argument that were wide string
914 literals. */
915 int number_wide;
916 /* Number of leaves of the format argument that were empty strings. */
917 int number_empty;
918 /* Number of leaves of the format argument that were unterminated
919 strings. */
920 int number_unterminated;
921 /* Number of leaves of the format argument that were not counted above. */
922 int number_other;
923 /* Location of the format string. */
924 location_t format_string_loc;
925 } format_check_results;
927 typedef struct
929 format_check_results *res;
930 function_format_info *info;
931 tree params;
932 } format_check_context;
934 /* Return the format name (as specified in the original table) for the format
935 type indicated by format_num. */
936 static const char *
937 format_name (int format_num)
939 if (format_num >= 0 && format_num < n_format_types)
940 return format_types[format_num].name;
941 gcc_unreachable ();
944 /* Return the format flags (as specified in the original table) for the format
945 type indicated by format_num. */
946 static int
947 format_flags (int format_num)
949 if (format_num >= 0 && format_num < n_format_types)
950 return format_types[format_num].flags;
951 gcc_unreachable ();
954 static void check_format_info (function_format_info *, tree);
955 static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
956 static void check_format_info_main (format_check_results *,
957 function_format_info *,
958 const char *, int, tree,
959 unsigned HOST_WIDE_INT, alloc_pool);
961 static void init_dollar_format_checking (int, tree);
962 static int maybe_read_dollar_number (const char **, int,
963 tree, tree *, const format_kind_info *);
964 static bool avoid_dollar_number (const char *);
965 static void finish_dollar_format_checking (format_check_results *, int);
967 static const format_flag_spec *get_flag_spec (const format_flag_spec *,
968 int, const char *);
970 static void check_format_types (location_t, format_wanted_type *);
971 static void format_type_warning (location_t, format_wanted_type *, tree, tree);
973 /* Decode a format type from a string, returning the type, or
974 format_type_error if not valid, in which case the caller should print an
975 error message. */
976 static int
977 decode_format_type (const char *s)
979 int i;
980 int slen;
982 s = convert_format_name_to_system_name (s);
983 slen = strlen (s);
984 for (i = 0; i < n_format_types; i++)
986 int alen;
987 if (!strcmp (s, format_types[i].name))
988 return i;
989 alen = strlen (format_types[i].name);
990 if (slen == alen + 4 && s[0] == '_' && s[1] == '_'
991 && s[slen - 1] == '_' && s[slen - 2] == '_'
992 && !strncmp (s + 2, format_types[i].name, alen))
993 return i;
995 return format_type_error;
999 /* Check the argument list of a call to printf, scanf, etc.
1000 ATTRS are the attributes on the function type. There are NARGS argument
1001 values in the array ARGARRAY.
1002 Also, if -Wsuggest-attribute=format,
1003 warn for calls to vprintf or vscanf in functions with no such format
1004 attribute themselves. */
1006 void
1007 check_function_format (tree attrs, int nargs, tree *argarray)
1009 tree a;
1011 /* See if this function has any format attributes. */
1012 for (a = attrs; a; a = TREE_CHAIN (a))
1014 if (is_attribute_p ("format", TREE_PURPOSE (a)))
1016 /* Yup; check it. */
1017 function_format_info info;
1018 decode_format_attr (TREE_VALUE (a), &info, /*validated=*/true);
1019 if (warn_format)
1021 /* FIXME: Rewrite all the internal functions in this file
1022 to use the ARGARRAY directly instead of constructing this
1023 temporary list. */
1024 tree params = NULL_TREE;
1025 int i;
1026 for (i = nargs - 1; i >= 0; i--)
1027 params = tree_cons (NULL_TREE, argarray[i], params);
1028 check_format_info (&info, params);
1030 if (warn_suggest_attribute_format && info.first_arg_num == 0
1031 && (format_types[info.format_type].flags
1032 & (int) FMT_FLAG_ARG_CONVERT))
1034 tree c;
1035 for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
1037 c = TREE_CHAIN (c))
1038 if (is_attribute_p ("format", TREE_PURPOSE (c))
1039 && (decode_format_type (IDENTIFIER_POINTER
1040 (TREE_VALUE (TREE_VALUE (c))))
1041 == info.format_type))
1042 break;
1043 if (c == NULL_TREE)
1045 /* Check if the current function has a parameter to which
1046 the format attribute could be attached; if not, it
1047 can't be a candidate for a format attribute, despite
1048 the vprintf-like or vscanf-like call. */
1049 tree args;
1050 for (args = DECL_ARGUMENTS (current_function_decl);
1051 args != 0;
1052 args = DECL_CHAIN (args))
1054 if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
1055 && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
1056 == char_type_node))
1057 break;
1059 if (args != 0)
1060 warning (OPT_Wsuggest_attribute_format, "function might "
1061 "be possible candidate for %qs format attribute",
1062 format_types[info.format_type].name);
1070 /* Variables used by the checking of $ operand number formats. */
1071 static char *dollar_arguments_used = NULL;
1072 static char *dollar_arguments_pointer_p = NULL;
1073 static int dollar_arguments_alloc = 0;
1074 static int dollar_arguments_count;
1075 static int dollar_first_arg_num;
1076 static int dollar_max_arg_used;
1077 static int dollar_format_warned;
1079 /* Initialize the checking for a format string that may contain $
1080 parameter number specifications; we will need to keep track of whether
1081 each parameter has been used. FIRST_ARG_NUM is the number of the first
1082 argument that is a parameter to the format, or 0 for a vprintf-style
1083 function; PARAMS is the list of arguments starting at this argument. */
1085 static void
1086 init_dollar_format_checking (int first_arg_num, tree params)
1088 tree oparams = params;
1090 dollar_first_arg_num = first_arg_num;
1091 dollar_arguments_count = 0;
1092 dollar_max_arg_used = 0;
1093 dollar_format_warned = 0;
1094 if (first_arg_num > 0)
1096 while (params)
1098 dollar_arguments_count++;
1099 params = TREE_CHAIN (params);
1102 if (dollar_arguments_alloc < dollar_arguments_count)
1104 free (dollar_arguments_used);
1105 free (dollar_arguments_pointer_p);
1106 dollar_arguments_alloc = dollar_arguments_count;
1107 dollar_arguments_used = XNEWVEC (char, dollar_arguments_alloc);
1108 dollar_arguments_pointer_p = XNEWVEC (char, dollar_arguments_alloc);
1110 if (dollar_arguments_alloc)
1112 memset (dollar_arguments_used, 0, dollar_arguments_alloc);
1113 if (first_arg_num > 0)
1115 int i = 0;
1116 params = oparams;
1117 while (params)
1119 dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params)))
1120 == POINTER_TYPE);
1121 params = TREE_CHAIN (params);
1122 i++;
1129 /* Look for a decimal number followed by a $ in *FORMAT. If DOLLAR_NEEDED
1130 is set, it is an error if one is not found; otherwise, it is OK. If
1131 such a number is found, check whether it is within range and mark that
1132 numbered operand as being used for later checking. Returns the operand
1133 number if found and within range, zero if no such number was found and
1134 this is OK, or -1 on error. PARAMS points to the first operand of the
1135 format; PARAM_PTR is made to point to the parameter referred to. If
1136 a $ format is found, *FORMAT is updated to point just after it. */
1138 static int
1139 maybe_read_dollar_number (const char **format,
1140 int dollar_needed, tree params, tree *param_ptr,
1141 const format_kind_info *fki)
1143 int argnum;
1144 int overflow_flag;
1145 const char *fcp = *format;
1146 if (!ISDIGIT (*fcp))
1148 if (dollar_needed)
1150 warning (OPT_Wformat_, "missing $ operand number in format");
1151 return -1;
1153 else
1154 return 0;
1156 argnum = 0;
1157 overflow_flag = 0;
1158 while (ISDIGIT (*fcp))
1160 int nargnum;
1161 nargnum = 10 * argnum + (*fcp - '0');
1162 if (nargnum < 0 || nargnum / 10 != argnum)
1163 overflow_flag = 1;
1164 argnum = nargnum;
1165 fcp++;
1167 if (*fcp != '$')
1169 if (dollar_needed)
1171 warning (OPT_Wformat_, "missing $ operand number in format");
1172 return -1;
1174 else
1175 return 0;
1177 *format = fcp + 1;
1178 if (pedantic && !dollar_format_warned)
1180 warning (OPT_Wformat_, "%s does not support %%n$ operand number formats",
1181 C_STD_NAME (STD_EXT));
1182 dollar_format_warned = 1;
1184 if (overflow_flag || argnum == 0
1185 || (dollar_first_arg_num && argnum > dollar_arguments_count))
1187 warning (OPT_Wformat_, "operand number out of range in format");
1188 return -1;
1190 if (argnum > dollar_max_arg_used)
1191 dollar_max_arg_used = argnum;
1192 /* For vprintf-style functions we may need to allocate more memory to
1193 track which arguments are used. */
1194 while (dollar_arguments_alloc < dollar_max_arg_used)
1196 int nalloc;
1197 nalloc = 2 * dollar_arguments_alloc + 16;
1198 dollar_arguments_used = XRESIZEVEC (char, dollar_arguments_used,
1199 nalloc);
1200 dollar_arguments_pointer_p = XRESIZEVEC (char, dollar_arguments_pointer_p,
1201 nalloc);
1202 memset (dollar_arguments_used + dollar_arguments_alloc, 0,
1203 nalloc - dollar_arguments_alloc);
1204 dollar_arguments_alloc = nalloc;
1206 if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE)
1207 && dollar_arguments_used[argnum - 1] == 1)
1209 dollar_arguments_used[argnum - 1] = 2;
1210 warning (OPT_Wformat_, "format argument %d used more than once in %s format",
1211 argnum, fki->name);
1213 else
1214 dollar_arguments_used[argnum - 1] = 1;
1215 if (dollar_first_arg_num)
1217 int i;
1218 *param_ptr = params;
1219 for (i = 1; i < argnum && *param_ptr != 0; i++)
1220 *param_ptr = TREE_CHAIN (*param_ptr);
1222 /* This case shouldn't be caught here. */
1223 gcc_assert (*param_ptr);
1225 else
1226 *param_ptr = 0;
1227 return argnum;
1230 /* Ensure that FORMAT does not start with a decimal number followed by
1231 a $; give a diagnostic and return true if it does, false otherwise. */
1233 static bool
1234 avoid_dollar_number (const char *format)
1236 if (!ISDIGIT (*format))
1237 return false;
1238 while (ISDIGIT (*format))
1239 format++;
1240 if (*format == '$')
1242 warning (OPT_Wformat_, "$ operand number used after format without operand number");
1243 return true;
1245 return false;
1249 /* Finish the checking for a format string that used $ operand number formats
1250 instead of non-$ formats. We check for unused operands before used ones
1251 (a serious error, since the implementation of the format function
1252 can't know what types to pass to va_arg to find the later arguments).
1253 and for unused operands at the end of the format (if we know how many
1254 arguments the format had, so not for vprintf). If there were operand
1255 numbers out of range on a non-vprintf-style format, we won't have reached
1256 here. If POINTER_GAP_OK, unused arguments are OK if all arguments are
1257 pointers. */
1259 static void
1260 finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok)
1262 int i;
1263 bool found_pointer_gap = false;
1264 for (i = 0; i < dollar_max_arg_used; i++)
1266 if (!dollar_arguments_used[i])
1268 if (pointer_gap_ok && (dollar_first_arg_num == 0
1269 || dollar_arguments_pointer_p[i]))
1270 found_pointer_gap = true;
1271 else
1272 warning_at (res->format_string_loc, OPT_Wformat_,
1273 "format argument %d unused before used argument %d in $-style format",
1274 i + 1, dollar_max_arg_used);
1277 if (found_pointer_gap
1278 || (dollar_first_arg_num
1279 && dollar_max_arg_used < dollar_arguments_count))
1281 res->number_other--;
1282 res->number_dollar_extra_args++;
1287 /* Retrieve the specification for a format flag. SPEC contains the
1288 specifications for format flags for the applicable kind of format.
1289 FLAG is the flag in question. If PREDICATES is NULL, the basic
1290 spec for that flag must be retrieved and must exist. If
1291 PREDICATES is not NULL, it is a string listing possible predicates
1292 for the spec entry; if an entry predicated on any of these is
1293 found, it is returned, otherwise NULL is returned. */
1295 static const format_flag_spec *
1296 get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
1298 int i;
1299 for (i = 0; spec[i].flag_char != 0; i++)
1301 if (spec[i].flag_char != flag)
1302 continue;
1303 if (predicates != NULL)
1305 if (spec[i].predicate != 0
1306 && strchr (predicates, spec[i].predicate) != 0)
1307 return &spec[i];
1309 else if (spec[i].predicate == 0)
1310 return &spec[i];
1312 gcc_assert (predicates);
1313 return NULL;
1317 /* Check the argument list of a call to printf, scanf, etc.
1318 INFO points to the function_format_info structure.
1319 PARAMS is the list of argument values. */
1321 static void
1322 check_format_info (function_format_info *info, tree params)
1324 format_check_context format_ctx;
1325 unsigned HOST_WIDE_INT arg_num;
1326 tree format_tree;
1327 format_check_results res;
1328 /* Skip to format argument. If the argument isn't available, there's
1329 no work for us to do; prototype checking will catch the problem. */
1330 for (arg_num = 1; ; ++arg_num)
1332 if (params == 0)
1333 return;
1334 if (arg_num == info->format_num)
1335 break;
1336 params = TREE_CHAIN (params);
1338 format_tree = TREE_VALUE (params);
1339 params = TREE_CHAIN (params);
1340 if (format_tree == 0)
1341 return;
1343 res.number_non_literal = 0;
1344 res.number_extra_args = 0;
1345 res.extra_arg_loc = UNKNOWN_LOCATION;
1346 res.number_dollar_extra_args = 0;
1347 res.number_wide = 0;
1348 res.number_empty = 0;
1349 res.number_unterminated = 0;
1350 res.number_other = 0;
1351 res.format_string_loc = input_location;
1353 format_ctx.res = &res;
1354 format_ctx.info = info;
1355 format_ctx.params = params;
1357 check_function_arguments_recurse (check_format_arg, &format_ctx,
1358 format_tree, arg_num);
1360 location_t loc = format_ctx.res->format_string_loc;
1361 if (res.extra_arg_loc == UNKNOWN_LOCATION)
1362 res.extra_arg_loc = loc;
1364 if (res.number_non_literal > 0)
1366 /* Functions taking a va_list normally pass a non-literal format
1367 string. These functions typically are declared with
1368 first_arg_num == 0, so avoid warning in those cases. */
1369 if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT))
1371 /* For strftime-like formats, warn for not checking the format
1372 string; but there are no arguments to check. */
1373 warning_at (loc, OPT_Wformat_nonliteral,
1374 "format not a string literal, format string not checked");
1376 else if (info->first_arg_num != 0)
1378 /* If there are no arguments for the format at all, we may have
1379 printf (foo) which is likely to be a security hole. */
1380 while (arg_num + 1 < info->first_arg_num)
1382 if (params == 0)
1383 break;
1384 params = TREE_CHAIN (params);
1385 ++arg_num;
1387 if (params == 0 && warn_format_security)
1388 warning_at (loc, OPT_Wformat_security,
1389 "format not a string literal and no format arguments");
1390 else if (params == 0 && warn_format_nonliteral)
1391 warning_at (loc, OPT_Wformat_nonliteral,
1392 "format not a string literal and no format arguments");
1393 else
1394 warning_at (loc, OPT_Wformat_nonliteral,
1395 "format not a string literal, argument types not checked");
1399 /* If there were extra arguments to the format, normally warn. However,
1400 the standard does say extra arguments are ignored, so in the specific
1401 case where we have multiple leaves (conditional expressions or
1402 ngettext) allow extra arguments if at least one leaf didn't have extra
1403 arguments, but was otherwise OK (either non-literal or checked OK).
1404 If the format is an empty string, this should be counted similarly to the
1405 case of extra format arguments. */
1406 if (res.number_extra_args > 0 && res.number_non_literal == 0
1407 && res.number_other == 0)
1408 warning_at (res.extra_arg_loc, OPT_Wformat_extra_args,
1409 "too many arguments for format");
1410 if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
1411 && res.number_other == 0)
1412 warning_at (loc, OPT_Wformat_extra_args, "unused arguments in $-style format");
1413 if (res.number_empty > 0 && res.number_non_literal == 0
1414 && res.number_other == 0)
1415 warning_at (loc, OPT_Wformat_zero_length, "zero-length %s format string",
1416 format_types[info->format_type].name);
1418 if (res.number_wide > 0)
1419 warning_at (loc, OPT_Wformat_, "format is a wide character string");
1421 if (res.number_unterminated > 0)
1422 warning_at (loc, OPT_Wformat_, "unterminated format string");
1425 /* Callback from check_function_arguments_recurse to check a
1426 format string. FORMAT_TREE is the format parameter. ARG_NUM
1427 is the number of the format argument. CTX points to a
1428 format_check_context. */
1430 static void
1431 check_format_arg (void *ctx, tree format_tree,
1432 unsigned HOST_WIDE_INT arg_num)
1434 format_check_context *format_ctx = (format_check_context *) ctx;
1435 format_check_results *res = format_ctx->res;
1436 function_format_info *info = format_ctx->info;
1437 tree params = format_ctx->params;
1439 int format_length;
1440 HOST_WIDE_INT offset;
1441 const char *format_chars;
1442 tree array_size = 0;
1443 tree array_init;
1444 alloc_pool fwt_pool;
1446 if (TREE_CODE (format_tree) == VAR_DECL)
1448 /* Pull out a constant value if the front end didn't. */
1449 format_tree = decl_constant_value (format_tree);
1450 STRIP_NOPS (format_tree);
1453 if (integer_zerop (format_tree))
1455 /* Skip to first argument to check, so we can see if this format
1456 has any arguments (it shouldn't). */
1457 while (arg_num + 1 < info->first_arg_num)
1459 if (params == 0)
1460 return;
1461 params = TREE_CHAIN (params);
1462 ++arg_num;
1465 if (params == 0)
1466 res->number_other++;
1467 else
1469 if (res->number_extra_args == 0)
1470 res->extra_arg_loc = EXPR_LOC_OR_LOC (TREE_VALUE (params),
1471 input_location);
1472 res->number_extra_args++;
1474 return;
1477 offset = 0;
1478 if (TREE_CODE (format_tree) == POINTER_PLUS_EXPR)
1480 tree arg0, arg1;
1482 arg0 = TREE_OPERAND (format_tree, 0);
1483 arg1 = TREE_OPERAND (format_tree, 1);
1484 STRIP_NOPS (arg0);
1485 STRIP_NOPS (arg1);
1486 if (TREE_CODE (arg1) == INTEGER_CST)
1487 format_tree = arg0;
1488 else
1490 res->number_non_literal++;
1491 return;
1493 /* POINTER_PLUS_EXPR offsets are to be interpreted signed. */
1494 if (!cst_and_fits_in_hwi (arg1))
1496 res->number_non_literal++;
1497 return;
1499 offset = int_cst_value (arg1);
1501 if (TREE_CODE (format_tree) != ADDR_EXPR)
1503 res->number_non_literal++;
1504 return;
1506 res->format_string_loc = EXPR_LOC_OR_LOC (format_tree, input_location);
1507 format_tree = TREE_OPERAND (format_tree, 0);
1508 if (format_types[info->format_type].flags
1509 & (int) FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL)
1511 bool objc_str = (info->format_type == gcc_objc_string_format_type);
1512 /* We cannot examine this string here - but we can check that it is
1513 a valid type. */
1514 if (TREE_CODE (format_tree) != CONST_DECL
1515 || !((objc_str && objc_string_ref_type_p (TREE_TYPE (format_tree)))
1516 || (*targetcm.string_object_ref_type_p)
1517 ((const_tree) TREE_TYPE (format_tree))))
1519 res->number_non_literal++;
1520 return;
1522 /* Skip to first argument to check. */
1523 while (arg_num + 1 < info->first_arg_num)
1525 if (params == 0)
1526 return;
1527 params = TREE_CHAIN (params);
1528 ++arg_num;
1530 /* So, we have a valid literal string object and one or more params.
1531 We need to use an external helper to parse the string into format
1532 info. For Objective-C variants we provide the resource within the
1533 objc tree, for target variants, via a hook. */
1534 if (objc_str)
1535 objc_check_format_arg (format_tree, params);
1536 else if (targetcm.check_string_object_format_arg)
1537 (*targetcm.check_string_object_format_arg) (format_tree, params);
1538 /* Else we can't handle it and retire quietly. */
1539 return;
1541 if (TREE_CODE (format_tree) == ARRAY_REF
1542 && tree_fits_shwi_p (TREE_OPERAND (format_tree, 1))
1543 && (offset += tree_to_shwi (TREE_OPERAND (format_tree, 1))) >= 0)
1544 format_tree = TREE_OPERAND (format_tree, 0);
1545 if (offset < 0)
1547 res->number_non_literal++;
1548 return;
1550 if (TREE_CODE (format_tree) == VAR_DECL
1551 && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
1552 && (array_init = decl_constant_value (format_tree)) != format_tree
1553 && TREE_CODE (array_init) == STRING_CST)
1555 /* Extract the string constant initializer. Note that this may include
1556 a trailing NUL character that is not in the array (e.g.
1557 const char a[3] = "foo";). */
1558 array_size = DECL_SIZE_UNIT (format_tree);
1559 format_tree = array_init;
1561 if (TREE_CODE (format_tree) != STRING_CST)
1563 res->number_non_literal++;
1564 return;
1566 if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
1568 res->number_wide++;
1569 return;
1571 format_chars = TREE_STRING_POINTER (format_tree);
1572 format_length = TREE_STRING_LENGTH (format_tree);
1573 if (array_size != 0)
1575 /* Variable length arrays can't be initialized. */
1576 gcc_assert (TREE_CODE (array_size) == INTEGER_CST);
1578 if (tree_fits_shwi_p (array_size))
1580 HOST_WIDE_INT array_size_value = tree_to_shwi (array_size);
1581 if (array_size_value > 0
1582 && array_size_value == (int) array_size_value
1583 && format_length > array_size_value)
1584 format_length = array_size_value;
1587 if (offset)
1589 if (offset >= format_length)
1591 res->number_non_literal++;
1592 return;
1594 format_chars += offset;
1595 format_length -= offset;
1597 if (format_length < 1 || format_chars[--format_length] != 0)
1599 res->number_unterminated++;
1600 return;
1602 if (format_length == 0)
1604 res->number_empty++;
1605 return;
1608 /* Skip to first argument to check. */
1609 while (arg_num + 1 < info->first_arg_num)
1611 if (params == 0)
1612 return;
1613 params = TREE_CHAIN (params);
1614 ++arg_num;
1616 /* Provisionally increment res->number_other; check_format_info_main
1617 will decrement it if it finds there are extra arguments, but this way
1618 need not adjust it for every return. */
1619 res->number_other++;
1620 fwt_pool = create_alloc_pool ("format_wanted_type pool",
1621 sizeof (format_wanted_type), 10);
1622 check_format_info_main (res, info, format_chars, format_length,
1623 params, arg_num, fwt_pool);
1624 free_alloc_pool (fwt_pool);
1628 /* Do the main part of checking a call to a format function. FORMAT_CHARS
1629 is the NUL-terminated format string (which at this point may contain
1630 internal NUL characters); FORMAT_LENGTH is its length (excluding the
1631 terminating NUL character). ARG_NUM is one less than the number of
1632 the first format argument to check; PARAMS points to that format
1633 argument in the list of arguments. */
1635 static void
1636 check_format_info_main (format_check_results *res,
1637 function_format_info *info, const char *format_chars,
1638 int format_length, tree params,
1639 unsigned HOST_WIDE_INT arg_num, alloc_pool fwt_pool)
1641 const char *orig_format_chars = format_chars;
1642 tree first_fillin_param = params;
1644 const format_kind_info *fki = &format_types[info->format_type];
1645 const format_flag_spec *flag_specs = fki->flag_specs;
1646 const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs;
1647 location_t format_string_loc = res->format_string_loc;
1649 /* -1 if no conversions taking an operand have been found; 0 if one has
1650 and it didn't use $; 1 if $ formats are in use. */
1651 int has_operand_number = -1;
1653 init_dollar_format_checking (info->first_arg_num, first_fillin_param);
1655 while (*format_chars != 0)
1657 int i;
1658 int suppressed = FALSE;
1659 const char *length_chars = NULL;
1660 enum format_lengths length_chars_val = FMT_LEN_none;
1661 enum format_std_version length_chars_std = STD_C89;
1662 int format_char;
1663 tree cur_param;
1664 tree wanted_type;
1665 int main_arg_num = 0;
1666 tree main_arg_params = 0;
1667 enum format_std_version wanted_type_std;
1668 const char *wanted_type_name;
1669 format_wanted_type width_wanted_type;
1670 format_wanted_type precision_wanted_type;
1671 format_wanted_type main_wanted_type;
1672 format_wanted_type *first_wanted_type = NULL;
1673 format_wanted_type *last_wanted_type = NULL;
1674 const format_length_info *fli = NULL;
1675 const format_char_info *fci = NULL;
1676 char flag_chars[256];
1677 int alloc_flag = 0;
1678 int scalar_identity_flag = 0;
1679 const char *format_start;
1681 if (*format_chars++ != '%')
1682 continue;
1683 if (*format_chars == 0)
1685 warning_at (format_string_loc, OPT_Wformat_,
1686 "spurious trailing %<%%%> in format");
1687 continue;
1689 if (*format_chars == '%')
1691 ++format_chars;
1692 continue;
1694 flag_chars[0] = 0;
1696 if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
1698 /* Possibly read a $ operand number at the start of the format.
1699 If one was previously used, one is required here. If one
1700 is not used here, we can't immediately conclude this is a
1701 format without them, since it could be printf %m or scanf %*. */
1702 int opnum;
1703 opnum = maybe_read_dollar_number (&format_chars, 0,
1704 first_fillin_param,
1705 &main_arg_params, fki);
1706 if (opnum == -1)
1707 return;
1708 else if (opnum > 0)
1710 has_operand_number = 1;
1711 main_arg_num = opnum + info->first_arg_num - 1;
1714 else if (fki->flags & FMT_FLAG_USE_DOLLAR)
1716 if (avoid_dollar_number (format_chars))
1717 return;
1720 /* Read any format flags, but do not yet validate them beyond removing
1721 duplicates, since in general validation depends on the rest of
1722 the format. */
1723 while (*format_chars != 0
1724 && strchr (fki->flag_chars, *format_chars) != 0)
1726 const format_flag_spec *s = get_flag_spec (flag_specs,
1727 *format_chars, NULL);
1728 if (strchr (flag_chars, *format_chars) != 0)
1730 warning_at (format_string_loc, OPT_Wformat_,
1731 "repeated %s in format", _(s->name));
1733 else
1735 i = strlen (flag_chars);
1736 flag_chars[i++] = *format_chars;
1737 flag_chars[i] = 0;
1739 if (s->skip_next_char)
1741 ++format_chars;
1742 if (*format_chars == 0)
1744 warning_at (format_string_loc, OPT_Wformat_,
1745 "missing fill character at end of strfmon format");
1746 return;
1749 ++format_chars;
1752 /* Read any format width, possibly * or *m$. */
1753 if (fki->width_char != 0)
1755 if (fki->width_type != NULL && *format_chars == '*')
1757 i = strlen (flag_chars);
1758 flag_chars[i++] = fki->width_char;
1759 flag_chars[i] = 0;
1760 /* "...a field width...may be indicated by an asterisk.
1761 In this case, an int argument supplies the field width..." */
1762 ++format_chars;
1763 if (has_operand_number != 0)
1765 int opnum;
1766 opnum = maybe_read_dollar_number (&format_chars,
1767 has_operand_number == 1,
1768 first_fillin_param,
1769 &params, fki);
1770 if (opnum == -1)
1771 return;
1772 else if (opnum > 0)
1774 has_operand_number = 1;
1775 arg_num = opnum + info->first_arg_num - 1;
1777 else
1778 has_operand_number = 0;
1780 else
1782 if (avoid_dollar_number (format_chars))
1783 return;
1785 if (info->first_arg_num != 0)
1787 if (params == 0)
1788 cur_param = NULL;
1789 else
1791 cur_param = TREE_VALUE (params);
1792 if (has_operand_number <= 0)
1794 params = TREE_CHAIN (params);
1795 ++arg_num;
1798 width_wanted_type.wanted_type = *fki->width_type;
1799 width_wanted_type.wanted_type_name = NULL;
1800 width_wanted_type.pointer_count = 0;
1801 width_wanted_type.char_lenient_flag = 0;
1802 width_wanted_type.scalar_identity_flag = 0;
1803 width_wanted_type.writing_in_flag = 0;
1804 width_wanted_type.reading_from_flag = 0;
1805 width_wanted_type.kind = CF_KIND_FIELD_WIDTH;
1806 width_wanted_type.format_start = format_chars - 1;
1807 width_wanted_type.format_length = 1;
1808 width_wanted_type.param = cur_param;
1809 width_wanted_type.arg_num = arg_num;
1810 width_wanted_type.next = NULL;
1811 if (last_wanted_type != 0)
1812 last_wanted_type->next = &width_wanted_type;
1813 if (first_wanted_type == 0)
1814 first_wanted_type = &width_wanted_type;
1815 last_wanted_type = &width_wanted_type;
1818 else
1820 /* Possibly read a numeric width. If the width is zero,
1821 we complain if appropriate. */
1822 int non_zero_width_char = FALSE;
1823 int found_width = FALSE;
1824 while (ISDIGIT (*format_chars))
1826 found_width = TRUE;
1827 if (*format_chars != '0')
1828 non_zero_width_char = TRUE;
1829 ++format_chars;
1831 if (found_width && !non_zero_width_char &&
1832 (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
1833 warning_at (format_string_loc, OPT_Wformat_,
1834 "zero width in %s format", fki->name);
1835 if (found_width)
1837 i = strlen (flag_chars);
1838 flag_chars[i++] = fki->width_char;
1839 flag_chars[i] = 0;
1844 /* Read any format left precision (must be a number, not *). */
1845 if (fki->left_precision_char != 0 && *format_chars == '#')
1847 ++format_chars;
1848 i = strlen (flag_chars);
1849 flag_chars[i++] = fki->left_precision_char;
1850 flag_chars[i] = 0;
1851 if (!ISDIGIT (*format_chars))
1852 warning_at (format_string_loc, OPT_Wformat_,
1853 "empty left precision in %s format", fki->name);
1854 while (ISDIGIT (*format_chars))
1855 ++format_chars;
1858 /* Read any format precision, possibly * or *m$. */
1859 if (fki->precision_char != 0 && *format_chars == '.')
1861 ++format_chars;
1862 i = strlen (flag_chars);
1863 flag_chars[i++] = fki->precision_char;
1864 flag_chars[i] = 0;
1865 if (fki->precision_type != NULL && *format_chars == '*')
1867 /* "...a...precision...may be indicated by an asterisk.
1868 In this case, an int argument supplies the...precision." */
1869 ++format_chars;
1870 if (has_operand_number != 0)
1872 int opnum;
1873 opnum = maybe_read_dollar_number (&format_chars,
1874 has_operand_number == 1,
1875 first_fillin_param,
1876 &params, fki);
1877 if (opnum == -1)
1878 return;
1879 else if (opnum > 0)
1881 has_operand_number = 1;
1882 arg_num = opnum + info->first_arg_num - 1;
1884 else
1885 has_operand_number = 0;
1887 else
1889 if (avoid_dollar_number (format_chars))
1890 return;
1892 if (info->first_arg_num != 0)
1894 if (params == 0)
1895 cur_param = NULL;
1896 else
1898 cur_param = TREE_VALUE (params);
1899 if (has_operand_number <= 0)
1901 params = TREE_CHAIN (params);
1902 ++arg_num;
1905 precision_wanted_type.wanted_type = *fki->precision_type;
1906 precision_wanted_type.wanted_type_name = NULL;
1907 precision_wanted_type.pointer_count = 0;
1908 precision_wanted_type.char_lenient_flag = 0;
1909 precision_wanted_type.scalar_identity_flag = 0;
1910 precision_wanted_type.writing_in_flag = 0;
1911 precision_wanted_type.reading_from_flag = 0;
1912 precision_wanted_type.kind = CF_KIND_FIELD_PRECISION;
1913 precision_wanted_type.param = cur_param;
1914 precision_wanted_type.format_start = format_chars - 2;
1915 precision_wanted_type.format_length = 2;
1916 precision_wanted_type.arg_num = arg_num;
1917 precision_wanted_type.next = NULL;
1918 if (last_wanted_type != 0)
1919 last_wanted_type->next = &precision_wanted_type;
1920 if (first_wanted_type == 0)
1921 first_wanted_type = &precision_wanted_type;
1922 last_wanted_type = &precision_wanted_type;
1925 else
1927 if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
1928 && !ISDIGIT (*format_chars))
1929 warning_at (format_string_loc, OPT_Wformat_,
1930 "empty precision in %s format", fki->name);
1931 while (ISDIGIT (*format_chars))
1932 ++format_chars;
1936 format_start = format_chars;
1937 if (fki->alloc_char && fki->alloc_char == *format_chars)
1939 i = strlen (flag_chars);
1940 flag_chars[i++] = fki->alloc_char;
1941 flag_chars[i] = 0;
1942 format_chars++;
1945 /* Handle the scanf allocation kludge. */
1946 if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1948 if (*format_chars == 'a' && !flag_isoc99)
1950 if (format_chars[1] == 's' || format_chars[1] == 'S'
1951 || format_chars[1] == '[')
1953 /* 'a' is used as a flag. */
1954 i = strlen (flag_chars);
1955 flag_chars[i++] = 'a';
1956 flag_chars[i] = 0;
1957 format_chars++;
1962 /* Read any length modifier, if this kind of format has them. */
1963 fli = fki->length_char_specs;
1964 length_chars = NULL;
1965 length_chars_val = FMT_LEN_none;
1966 length_chars_std = STD_C89;
1967 scalar_identity_flag = 0;
1968 if (fli)
1970 while (fli->name != 0
1971 && strncmp (fli->name, format_chars, strlen (fli->name)))
1972 fli++;
1973 if (fli->name != 0)
1975 format_chars += strlen (fli->name);
1976 if (fli->double_name != 0 && fli->name[0] == *format_chars)
1978 format_chars++;
1979 length_chars = fli->double_name;
1980 length_chars_val = fli->double_index;
1981 length_chars_std = fli->double_std;
1983 else
1985 length_chars = fli->name;
1986 length_chars_val = fli->index;
1987 length_chars_std = fli->std;
1988 scalar_identity_flag = fli->scalar_identity_flag;
1990 i = strlen (flag_chars);
1991 flag_chars[i++] = fki->length_code_char;
1992 flag_chars[i] = 0;
1994 if (pedantic)
1996 /* Warn if the length modifier is non-standard. */
1997 if (ADJ_STD (length_chars_std) > C_STD_VER)
1998 warning_at (format_string_loc, OPT_Wformat_,
1999 "%s does not support the %qs %s length modifier",
2000 C_STD_NAME (length_chars_std), length_chars,
2001 fki->name);
2005 /* Read any modifier (strftime E/O). */
2006 if (fki->modifier_chars != NULL)
2008 while (*format_chars != 0
2009 && strchr (fki->modifier_chars, *format_chars) != 0)
2011 if (strchr (flag_chars, *format_chars) != 0)
2013 const format_flag_spec *s = get_flag_spec (flag_specs,
2014 *format_chars, NULL);
2015 warning_at (format_string_loc, OPT_Wformat_,
2016 "repeated %s in format", _(s->name));
2018 else
2020 i = strlen (flag_chars);
2021 flag_chars[i++] = *format_chars;
2022 flag_chars[i] = 0;
2024 ++format_chars;
2028 format_char = *format_chars;
2029 if (format_char == 0
2030 || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
2031 && format_char == '%'))
2033 warning_at (format_string_loc, OPT_Wformat_,
2034 "conversion lacks type at end of format");
2035 continue;
2037 format_chars++;
2038 fci = fki->conversion_specs;
2039 while (fci->format_chars != 0
2040 && strchr (fci->format_chars, format_char) == 0)
2041 ++fci;
2042 if (fci->format_chars == 0)
2044 if (ISGRAPH (format_char))
2045 warning_at (format_string_loc, OPT_Wformat_,
2046 "unknown conversion type character %qc in format",
2047 format_char);
2048 else
2049 warning_at (format_string_loc, OPT_Wformat_,
2050 "unknown conversion type character 0x%x in format",
2051 format_char);
2052 continue;
2054 if (pedantic)
2056 if (ADJ_STD (fci->std) > C_STD_VER)
2057 warning_at (format_string_loc, OPT_Wformat_,
2058 "%s does not support the %<%%%c%> %s format",
2059 C_STD_NAME (fci->std), format_char, fki->name);
2062 /* Validate the individual flags used, removing any that are invalid. */
2064 int d = 0;
2065 for (i = 0; flag_chars[i] != 0; i++)
2067 const format_flag_spec *s = get_flag_spec (flag_specs,
2068 flag_chars[i], NULL);
2069 flag_chars[i - d] = flag_chars[i];
2070 if (flag_chars[i] == fki->length_code_char)
2071 continue;
2072 if (strchr (fci->flag_chars, flag_chars[i]) == 0)
2074 warning_at (format_string_loc,
2075 OPT_Wformat_, "%s used with %<%%%c%> %s format",
2076 _(s->name), format_char, fki->name);
2077 d++;
2078 continue;
2080 if (pedantic)
2082 const format_flag_spec *t;
2083 if (ADJ_STD (s->std) > C_STD_VER)
2084 warning_at (format_string_loc, OPT_Wformat_,
2085 "%s does not support %s",
2086 C_STD_NAME (s->std), _(s->long_name));
2087 t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
2088 if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
2090 const char *long_name = (t->long_name != NULL
2091 ? t->long_name
2092 : s->long_name);
2093 if (ADJ_STD (t->std) > C_STD_VER)
2094 warning_at (format_string_loc, OPT_Wformat_,
2095 "%s does not support %s with the %<%%%c%> %s format",
2096 C_STD_NAME (t->std), _(long_name),
2097 format_char, fki->name);
2101 flag_chars[i - d] = 0;
2104 if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
2105 && strchr (flag_chars, 'a') != 0)
2106 alloc_flag = 1;
2107 if (fki->alloc_char && strchr (flag_chars, fki->alloc_char) != 0)
2108 alloc_flag = 1;
2110 if (fki->suppression_char
2111 && strchr (flag_chars, fki->suppression_char) != 0)
2112 suppressed = 1;
2114 /* Validate the pairs of flags used. */
2115 for (i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
2117 const format_flag_spec *s, *t;
2118 if (strchr (flag_chars, bad_flag_pairs[i].flag_char1) == 0)
2119 continue;
2120 if (strchr (flag_chars, bad_flag_pairs[i].flag_char2) == 0)
2121 continue;
2122 if (bad_flag_pairs[i].predicate != 0
2123 && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
2124 continue;
2125 s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
2126 t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
2127 if (bad_flag_pairs[i].ignored)
2129 if (bad_flag_pairs[i].predicate != 0)
2130 warning_at (format_string_loc, OPT_Wformat_,
2131 "%s ignored with %s and %<%%%c%> %s format",
2132 _(s->name), _(t->name), format_char,
2133 fki->name);
2134 else
2135 warning_at (format_string_loc, OPT_Wformat_,
2136 "%s ignored with %s in %s format",
2137 _(s->name), _(t->name), fki->name);
2139 else
2141 if (bad_flag_pairs[i].predicate != 0)
2142 warning_at (format_string_loc, OPT_Wformat_,
2143 "use of %s and %s together with %<%%%c%> %s format",
2144 _(s->name), _(t->name), format_char,
2145 fki->name);
2146 else
2147 warning_at (format_string_loc, OPT_Wformat_,
2148 "use of %s and %s together in %s format",
2149 _(s->name), _(t->name), fki->name);
2153 /* Give Y2K warnings. */
2154 if (warn_format_y2k)
2156 int y2k_level = 0;
2157 if (strchr (fci->flags2, '4') != 0)
2158 if (strchr (flag_chars, 'E') != 0)
2159 y2k_level = 3;
2160 else
2161 y2k_level = 2;
2162 else if (strchr (fci->flags2, '3') != 0)
2163 y2k_level = 3;
2164 else if (strchr (fci->flags2, '2') != 0)
2165 y2k_level = 2;
2166 if (y2k_level == 3)
2167 warning_at (format_string_loc, OPT_Wformat_y2k,
2168 "%<%%%c%> yields only last 2 digits of "
2169 "year in some locales", format_char);
2170 else if (y2k_level == 2)
2171 warning_at (format_string_loc, OPT_Wformat_y2k,
2172 "%<%%%c%> yields only last 2 digits of year",
2173 format_char);
2176 if (strchr (fci->flags2, '[') != 0)
2178 /* Skip over scan set, in case it happens to have '%' in it. */
2179 if (*format_chars == '^')
2180 ++format_chars;
2181 /* Find closing bracket; if one is hit immediately, then
2182 it's part of the scan set rather than a terminator. */
2183 if (*format_chars == ']')
2184 ++format_chars;
2185 while (*format_chars && *format_chars != ']')
2186 ++format_chars;
2187 if (*format_chars != ']')
2188 /* The end of the format string was reached. */
2189 warning_at (format_string_loc, OPT_Wformat_,
2190 "no closing %<]%> for %<%%[%> format");
2193 wanted_type = 0;
2194 wanted_type_name = 0;
2195 if (fki->flags & (int) FMT_FLAG_ARG_CONVERT)
2197 wanted_type = (fci->types[length_chars_val].type
2198 ? *fci->types[length_chars_val].type : 0);
2199 wanted_type_name = fci->types[length_chars_val].name;
2200 wanted_type_std = fci->types[length_chars_val].std;
2201 if (wanted_type == 0)
2203 warning_at (format_string_loc, OPT_Wformat_,
2204 "use of %qs length modifier with %qc type character",
2205 length_chars, format_char);
2206 /* Heuristic: skip one argument when an invalid length/type
2207 combination is encountered. */
2208 arg_num++;
2209 if (params != 0)
2210 params = TREE_CHAIN (params);
2211 continue;
2213 else if (pedantic
2214 /* Warn if non-standard, provided it is more non-standard
2215 than the length and type characters that may already
2216 have been warned for. */
2217 && ADJ_STD (wanted_type_std) > ADJ_STD (length_chars_std)
2218 && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
2220 if (ADJ_STD (wanted_type_std) > C_STD_VER)
2221 warning_at (format_string_loc, OPT_Wformat_,
2222 "%s does not support the %<%%%s%c%> %s format",
2223 C_STD_NAME (wanted_type_std), length_chars,
2224 format_char, fki->name);
2228 main_wanted_type.next = NULL;
2230 /* Finally. . .check type of argument against desired type! */
2231 if (info->first_arg_num == 0)
2232 continue;
2233 if ((fci->pointer_count == 0 && wanted_type == void_type_node)
2234 || suppressed)
2236 if (main_arg_num != 0)
2238 if (suppressed)
2239 warning_at (format_string_loc, OPT_Wformat_,
2240 "operand number specified with "
2241 "suppressed assignment");
2242 else
2243 warning_at (format_string_loc, OPT_Wformat_,
2244 "operand number specified for format "
2245 "taking no argument");
2248 else
2250 format_wanted_type *wanted_type_ptr;
2252 if (main_arg_num != 0)
2254 arg_num = main_arg_num;
2255 params = main_arg_params;
2257 else
2259 ++arg_num;
2260 if (has_operand_number > 0)
2262 warning_at (format_string_loc, OPT_Wformat_,
2263 "missing $ operand number in format");
2264 return;
2266 else
2267 has_operand_number = 0;
2270 wanted_type_ptr = &main_wanted_type;
2271 while (fci)
2273 if (params == 0)
2274 cur_param = NULL;
2275 else
2277 cur_param = TREE_VALUE (params);
2278 params = TREE_CHAIN (params);
2281 wanted_type_ptr->wanted_type = wanted_type;
2282 wanted_type_ptr->wanted_type_name = wanted_type_name;
2283 wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag;
2284 wanted_type_ptr->char_lenient_flag = 0;
2285 if (strchr (fci->flags2, 'c') != 0)
2286 wanted_type_ptr->char_lenient_flag = 1;
2287 wanted_type_ptr->scalar_identity_flag = 0;
2288 if (scalar_identity_flag)
2289 wanted_type_ptr->scalar_identity_flag = 1;
2290 wanted_type_ptr->writing_in_flag = 0;
2291 wanted_type_ptr->reading_from_flag = 0;
2292 if (alloc_flag)
2293 wanted_type_ptr->writing_in_flag = 1;
2294 else
2296 if (strchr (fci->flags2, 'W') != 0)
2297 wanted_type_ptr->writing_in_flag = 1;
2298 if (strchr (fci->flags2, 'R') != 0)
2299 wanted_type_ptr->reading_from_flag = 1;
2301 wanted_type_ptr->kind = CF_KIND_FORMAT;
2302 wanted_type_ptr->param = cur_param;
2303 wanted_type_ptr->arg_num = arg_num;
2304 wanted_type_ptr->format_start = format_start;
2305 wanted_type_ptr->format_length = format_chars - format_start;
2306 wanted_type_ptr->next = NULL;
2307 if (last_wanted_type != 0)
2308 last_wanted_type->next = wanted_type_ptr;
2309 if (first_wanted_type == 0)
2310 first_wanted_type = wanted_type_ptr;
2311 last_wanted_type = wanted_type_ptr;
2313 fci = fci->chain;
2314 if (fci)
2316 wanted_type_ptr = (format_wanted_type *)
2317 pool_alloc (fwt_pool);
2318 arg_num++;
2319 wanted_type = *fci->types[length_chars_val].type;
2320 wanted_type_name = fci->types[length_chars_val].name;
2325 if (first_wanted_type != 0)
2326 check_format_types (format_string_loc, first_wanted_type);
2329 if (format_chars - orig_format_chars != format_length)
2330 warning_at (format_string_loc, OPT_Wformat_contains_nul,
2331 "embedded %<\\0%> in format");
2332 if (info->first_arg_num != 0 && params != 0
2333 && has_operand_number <= 0)
2335 res->number_other--;
2336 res->number_extra_args++;
2338 if (has_operand_number > 0)
2339 finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
2343 /* Check the argument types from a single format conversion (possibly
2344 including width and precision arguments). LOC is the location of
2345 the format string. */
2346 static void
2347 check_format_types (location_t loc, format_wanted_type *types)
2349 for (; types != 0; types = types->next)
2351 tree cur_param;
2352 tree cur_type;
2353 tree orig_cur_type;
2354 tree wanted_type;
2355 int arg_num;
2356 int i;
2357 int char_type_flag;
2359 wanted_type = types->wanted_type;
2360 arg_num = types->arg_num;
2362 /* The following should not occur here. */
2363 gcc_assert (wanted_type);
2364 gcc_assert (wanted_type != void_type_node || types->pointer_count);
2366 if (types->pointer_count == 0)
2367 wanted_type = lang_hooks.types.type_promotes_to (wanted_type);
2369 wanted_type = TYPE_MAIN_VARIANT (wanted_type);
2371 cur_param = types->param;
2372 if (!cur_param)
2374 format_type_warning (loc, types, wanted_type, NULL);
2375 continue;
2378 cur_type = TREE_TYPE (cur_param);
2379 if (cur_type == error_mark_node)
2380 continue;
2381 orig_cur_type = cur_type;
2382 char_type_flag = 0;
2384 STRIP_NOPS (cur_param);
2386 /* Check the types of any additional pointer arguments
2387 that precede the "real" argument. */
2388 for (i = 0; i < types->pointer_count; ++i)
2390 if (TREE_CODE (cur_type) == POINTER_TYPE)
2392 cur_type = TREE_TYPE (cur_type);
2393 if (cur_type == error_mark_node)
2394 break;
2396 /* Check for writing through a NULL pointer. */
2397 if (types->writing_in_flag
2398 && i == 0
2399 && cur_param != 0
2400 && integer_zerop (cur_param))
2401 warning (OPT_Wformat_, "writing through null pointer "
2402 "(argument %d)", arg_num);
2404 /* Check for reading through a NULL pointer. */
2405 if (types->reading_from_flag
2406 && i == 0
2407 && cur_param != 0
2408 && integer_zerop (cur_param))
2409 warning (OPT_Wformat_, "reading through null pointer "
2410 "(argument %d)", arg_num);
2412 if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
2413 cur_param = TREE_OPERAND (cur_param, 0);
2414 else
2415 cur_param = 0;
2417 /* See if this is an attempt to write into a const type with
2418 scanf or with printf "%n". Note: the writing in happens
2419 at the first indirection only, if for example
2420 void * const * is passed to scanf %p; passing
2421 const void ** is simply passing an incompatible type. */
2422 if (types->writing_in_flag
2423 && i == 0
2424 && (TYPE_READONLY (cur_type)
2425 || (cur_param != 0
2426 && (CONSTANT_CLASS_P (cur_param)
2427 || (DECL_P (cur_param)
2428 && TREE_READONLY (cur_param))))))
2429 warning (OPT_Wformat_, "writing into constant object "
2430 "(argument %d)", arg_num);
2432 /* If there are extra type qualifiers beyond the first
2433 indirection, then this makes the types technically
2434 incompatible. */
2435 if (i > 0
2436 && pedantic
2437 && (TYPE_READONLY (cur_type)
2438 || TYPE_VOLATILE (cur_type)
2439 || TYPE_ATOMIC (cur_type)
2440 || TYPE_RESTRICT (cur_type)))
2441 warning (OPT_Wformat_, "extra type qualifiers in format "
2442 "argument (argument %d)",
2443 arg_num);
2446 else
2448 format_type_warning (loc, types, wanted_type, orig_cur_type);
2449 break;
2453 if (i < types->pointer_count)
2454 continue;
2456 cur_type = TYPE_MAIN_VARIANT (cur_type);
2458 /* Check whether the argument type is a character type. This leniency
2459 only applies to certain formats, flagged with 'c'. */
2460 if (types->char_lenient_flag)
2461 char_type_flag = (cur_type == char_type_node
2462 || cur_type == signed_char_type_node
2463 || cur_type == unsigned_char_type_node);
2465 /* Check the type of the "real" argument, if there's a type we want. */
2466 if (lang_hooks.types_compatible_p (wanted_type, cur_type))
2467 continue;
2468 /* If we want 'void *', allow any pointer type.
2469 (Anything else would already have got a warning.)
2470 With -Wpedantic, only allow pointers to void and to character
2471 types. */
2472 if (wanted_type == void_type_node
2473 && (!pedantic || (i == 1 && char_type_flag)))
2474 continue;
2475 /* Don't warn about differences merely in signedness, unless
2476 -Wpedantic. With -Wpedantic, warn if the type is a pointer
2477 target and not a character type, and for character types at
2478 a second level of indirection. */
2479 if (TREE_CODE (wanted_type) == INTEGER_TYPE
2480 && TREE_CODE (cur_type) == INTEGER_TYPE
2481 && ((!pedantic && !warn_format_signedness)
2482 || (i == 0 && !warn_format_signedness)
2483 || (i == 1 && char_type_flag))
2484 && (TYPE_UNSIGNED (wanted_type)
2485 ? wanted_type == c_common_unsigned_type (cur_type)
2486 : wanted_type == c_common_signed_type (cur_type)))
2487 continue;
2488 /* Don't warn about differences merely in signedness if we know
2489 that the current type is integer-promoted and its original type
2490 was unsigned such as that it is in the range of WANTED_TYPE. */
2491 if (TREE_CODE (wanted_type) == INTEGER_TYPE
2492 && TREE_CODE (cur_type) == INTEGER_TYPE
2493 && warn_format_signedness
2494 && TYPE_UNSIGNED (wanted_type)
2495 && cur_param != NULL_TREE
2496 && TREE_CODE (cur_param) == NOP_EXPR)
2498 tree t = TREE_TYPE (TREE_OPERAND (cur_param, 0));
2499 if (TYPE_UNSIGNED (t)
2500 && cur_type == lang_hooks.types.type_promotes_to (t))
2501 continue;
2503 /* Likewise, "signed char", "unsigned char" and "char" are
2504 equivalent but the above test won't consider them equivalent. */
2505 if (wanted_type == char_type_node
2506 && (!pedantic || i < 2)
2507 && char_type_flag)
2508 continue;
2509 if (types->scalar_identity_flag
2510 && (TREE_CODE (cur_type) == TREE_CODE (wanted_type)
2511 || (INTEGRAL_TYPE_P (cur_type)
2512 && INTEGRAL_TYPE_P (wanted_type)))
2513 && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type))
2514 continue;
2515 /* Now we have a type mismatch. */
2516 format_type_warning (loc, types, wanted_type, orig_cur_type);
2521 /* Give a warning at LOC about a format argument of different type from that
2522 expected. WANTED_TYPE is the type the argument should have, possibly
2523 stripped of pointer dereferences. The description (such as "field
2524 precision"), the placement in the format string, a possibly more
2525 friendly name of WANTED_TYPE, and the number of pointer dereferences
2526 are taken from TYPE. ARG_TYPE is the type of the actual argument,
2527 or NULL if it is missing. */
2528 static void
2529 format_type_warning (location_t loc, format_wanted_type *type,
2530 tree wanted_type, tree arg_type)
2532 int kind = type->kind;
2533 const char *wanted_type_name = type->wanted_type_name;
2534 const char *format_start = type->format_start;
2535 int format_length = type->format_length;
2536 int pointer_count = type->pointer_count;
2537 int arg_num = type->arg_num;
2539 char *p;
2540 /* If ARG_TYPE is a typedef with a misleading name (for example,
2541 size_t but not the standard size_t expected by printf %zu), avoid
2542 printing the typedef name. */
2543 if (wanted_type_name
2544 && arg_type
2545 && TYPE_NAME (arg_type)
2546 && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL
2547 && DECL_NAME (TYPE_NAME (arg_type))
2548 && !strcmp (wanted_type_name,
2549 lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2)))
2550 arg_type = TYPE_MAIN_VARIANT (arg_type);
2551 /* The format type and name exclude any '*' for pointers, so those
2552 must be formatted manually. For all the types we currently have,
2553 this is adequate, but formats taking pointers to functions or
2554 arrays would require the full type to be built up in order to
2555 print it with %T. */
2556 p = (char *) alloca (pointer_count + 2);
2557 if (pointer_count == 0)
2558 p[0] = 0;
2559 else if (c_dialect_cxx ())
2561 memset (p, '*', pointer_count);
2562 p[pointer_count] = 0;
2564 else
2566 p[0] = ' ';
2567 memset (p + 1, '*', pointer_count);
2568 p[pointer_count + 1] = 0;
2571 if (wanted_type_name)
2573 if (arg_type)
2574 warning_at (loc, OPT_Wformat_,
2575 "%s %<%s%.*s%> expects argument of type %<%s%s%>, "
2576 "but argument %d has type %qT",
2577 gettext (kind_descriptions[kind]),
2578 (kind == CF_KIND_FORMAT ? "%" : ""),
2579 format_length, format_start,
2580 wanted_type_name, p, arg_num, arg_type);
2581 else
2582 warning_at (loc, OPT_Wformat_,
2583 "%s %<%s%.*s%> expects a matching %<%s%s%> argument",
2584 gettext (kind_descriptions[kind]),
2585 (kind == CF_KIND_FORMAT ? "%" : ""),
2586 format_length, format_start, wanted_type_name, p);
2588 else
2590 if (arg_type)
2591 warning_at (loc, OPT_Wformat_,
2592 "%s %<%s%.*s%> expects argument of type %<%T%s%>, "
2593 "but argument %d has type %qT",
2594 gettext (kind_descriptions[kind]),
2595 (kind == CF_KIND_FORMAT ? "%" : ""),
2596 format_length, format_start,
2597 wanted_type, p, arg_num, arg_type);
2598 else
2599 warning_at (loc, OPT_Wformat_,
2600 "%s %<%s%.*s%> expects a matching %<%T%s%> argument",
2601 gettext (kind_descriptions[kind]),
2602 (kind == CF_KIND_FORMAT ? "%" : ""),
2603 format_length, format_start, wanted_type, p);
2608 /* Given a format_char_info array FCI, and a character C, this function
2609 returns the index into the conversion_specs where that specifier's
2610 data is located. The character must exist. */
2611 static unsigned int
2612 find_char_info_specifier_index (const format_char_info *fci, int c)
2614 unsigned i;
2616 for (i = 0; fci->format_chars; i++, fci++)
2617 if (strchr (fci->format_chars, c))
2618 return i;
2620 /* We shouldn't be looking for a non-existent specifier. */
2621 gcc_unreachable ();
2624 /* Given a format_length_info array FLI, and a character C, this
2625 function returns the index into the conversion_specs where that
2626 modifier's data is located. The character must exist. */
2627 static unsigned int
2628 find_length_info_modifier_index (const format_length_info *fli, int c)
2630 unsigned i;
2632 for (i = 0; fli->name; i++, fli++)
2633 if (strchr (fli->name, c))
2634 return i;
2636 /* We shouldn't be looking for a non-existent modifier. */
2637 gcc_unreachable ();
2640 /* Determine the type of HOST_WIDE_INT in the code being compiled for
2641 use in GCC's __asm_fprintf__ custom format attribute. You must
2642 have set dynamic_format_types before calling this function. */
2643 static void
2644 init_dynamic_asm_fprintf_info (void)
2646 static tree hwi;
2648 if (!hwi)
2650 format_length_info *new_asm_fprintf_length_specs;
2651 unsigned int i;
2653 /* Find the underlying type for HOST_WIDE_INT. For the %w
2654 length modifier to work, one must have issued: "typedef
2655 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2656 prior to using that modifier. */
2657 hwi = maybe_get_identifier ("__gcc_host_wide_int__");
2658 if (!hwi)
2660 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2661 return;
2663 hwi = identifier_global_value (hwi);
2664 if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
2666 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2667 return;
2669 hwi = DECL_ORIGINAL_TYPE (hwi);
2670 gcc_assert (hwi);
2671 if (hwi != long_integer_type_node && hwi != long_long_integer_type_node)
2673 error ("%<__gcc_host_wide_int__%> is not defined as %<long%>"
2674 " or %<long long%>");
2675 return;
2678 /* Create a new (writable) copy of asm_fprintf_length_specs. */
2679 new_asm_fprintf_length_specs = (format_length_info *)
2680 xmemdup (asm_fprintf_length_specs,
2681 sizeof (asm_fprintf_length_specs),
2682 sizeof (asm_fprintf_length_specs));
2684 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
2685 i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
2686 if (hwi == long_integer_type_node)
2687 new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
2688 else if (hwi == long_long_integer_type_node)
2689 new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
2690 else
2691 gcc_unreachable ();
2693 /* Assign the new data for use. */
2694 dynamic_format_types[asm_fprintf_format_type].length_char_specs =
2695 new_asm_fprintf_length_specs;
2699 /* Determine the type of a "locus" in the code being compiled for use
2700 in GCC's __gcc_gfc__ custom format attribute. You must have set
2701 dynamic_format_types before calling this function. */
2702 static void
2703 init_dynamic_gfc_info (void)
2705 static tree locus;
2707 if (!locus)
2709 static format_char_info *gfc_fci;
2711 /* For the GCC __gcc_gfc__ custom format specifier to work, one
2712 must have declared 'locus' prior to using this attribute. If
2713 we haven't seen this declarations then you shouldn't use the
2714 specifier requiring that type. */
2715 if ((locus = maybe_get_identifier ("locus")))
2717 locus = identifier_global_value (locus);
2718 if (locus)
2720 if (TREE_CODE (locus) != TYPE_DECL
2721 || TREE_TYPE (locus) == error_mark_node)
2723 error ("%<locus%> is not defined as a type");
2724 locus = 0;
2726 else
2727 locus = TREE_TYPE (locus);
2731 /* Assign the new data for use. */
2733 /* Handle the __gcc_gfc__ format specifics. */
2734 if (!gfc_fci)
2735 dynamic_format_types[gcc_gfc_format_type].conversion_specs =
2736 gfc_fci = (format_char_info *)
2737 xmemdup (gcc_gfc_char_table,
2738 sizeof (gcc_gfc_char_table),
2739 sizeof (gcc_gfc_char_table));
2740 if (locus)
2742 const unsigned i = find_char_info_specifier_index (gfc_fci, 'L');
2743 gfc_fci[i].types[0].type = &locus;
2744 gfc_fci[i].pointer_count = 1;
2749 /* Determine the types of "tree" and "location_t" in the code being
2750 compiled for use in GCC's diagnostic custom format attributes. You
2751 must have set dynamic_format_types before calling this function. */
2752 static void
2753 init_dynamic_diag_info (void)
2755 static tree t, loc, hwi;
2757 if (!loc || !t || !hwi)
2759 static format_char_info *diag_fci, *tdiag_fci, *cdiag_fci, *cxxdiag_fci;
2760 static format_length_info *diag_ls;
2761 unsigned int i;
2763 /* For the GCC-diagnostics custom format specifiers to work, one
2764 must have declared 'tree' and/or 'location_t' prior to using
2765 those attributes. If we haven't seen these declarations then
2766 you shouldn't use the specifiers requiring these types.
2767 However we don't force a hard ICE because we may see only one
2768 or the other type. */
2769 if ((loc = maybe_get_identifier ("location_t")))
2771 loc = identifier_global_value (loc);
2772 if (loc)
2774 if (TREE_CODE (loc) != TYPE_DECL)
2776 error ("%<location_t%> is not defined as a type");
2777 loc = 0;
2779 else
2780 loc = TREE_TYPE (loc);
2784 /* We need to grab the underlying 'union tree_node' so peek into
2785 an extra type level. */
2786 if ((t = maybe_get_identifier ("tree")))
2788 t = identifier_global_value (t);
2789 if (t)
2791 if (TREE_CODE (t) != TYPE_DECL)
2793 error ("%<tree%> is not defined as a type");
2794 t = 0;
2796 else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
2798 error ("%<tree%> is not defined as a pointer type");
2799 t = 0;
2801 else
2802 t = TREE_TYPE (TREE_TYPE (t));
2806 /* Find the underlying type for HOST_WIDE_INT. For the %w
2807 length modifier to work, one must have issued: "typedef
2808 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2809 prior to using that modifier. */
2810 if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
2812 hwi = identifier_global_value (hwi);
2813 if (hwi)
2815 if (TREE_CODE (hwi) != TYPE_DECL)
2817 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2818 hwi = 0;
2820 else
2822 hwi = DECL_ORIGINAL_TYPE (hwi);
2823 gcc_assert (hwi);
2824 if (hwi != long_integer_type_node
2825 && hwi != long_long_integer_type_node)
2827 error ("%<__gcc_host_wide_int__%> is not defined"
2828 " as %<long%> or %<long long%>");
2829 hwi = 0;
2835 /* Assign the new data for use. */
2837 /* All the GCC diag formats use the same length specs. */
2838 if (!diag_ls)
2839 dynamic_format_types[gcc_diag_format_type].length_char_specs =
2840 dynamic_format_types[gcc_tdiag_format_type].length_char_specs =
2841 dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
2842 dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
2843 diag_ls = (format_length_info *)
2844 xmemdup (gcc_diag_length_specs,
2845 sizeof (gcc_diag_length_specs),
2846 sizeof (gcc_diag_length_specs));
2847 if (hwi)
2849 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
2850 i = find_length_info_modifier_index (diag_ls, 'w');
2851 if (hwi == long_integer_type_node)
2852 diag_ls[i].index = FMT_LEN_l;
2853 else if (hwi == long_long_integer_type_node)
2854 diag_ls[i].index = FMT_LEN_ll;
2855 else
2856 gcc_unreachable ();
2859 /* Handle the __gcc_diag__ format specifics. */
2860 if (!diag_fci)
2861 dynamic_format_types[gcc_diag_format_type].conversion_specs =
2862 diag_fci = (format_char_info *)
2863 xmemdup (gcc_diag_char_table,
2864 sizeof (gcc_diag_char_table),
2865 sizeof (gcc_diag_char_table));
2866 if (t)
2868 i = find_char_info_specifier_index (diag_fci, 'K');
2869 diag_fci[i].types[0].type = &t;
2870 diag_fci[i].pointer_count = 1;
2873 /* Handle the __gcc_tdiag__ format specifics. */
2874 if (!tdiag_fci)
2875 dynamic_format_types[gcc_tdiag_format_type].conversion_specs =
2876 tdiag_fci = (format_char_info *)
2877 xmemdup (gcc_tdiag_char_table,
2878 sizeof (gcc_tdiag_char_table),
2879 sizeof (gcc_tdiag_char_table));
2880 if (t)
2882 /* All specifiers taking a tree share the same struct. */
2883 i = find_char_info_specifier_index (tdiag_fci, 'D');
2884 tdiag_fci[i].types[0].type = &t;
2885 tdiag_fci[i].pointer_count = 1;
2886 i = find_char_info_specifier_index (tdiag_fci, 'K');
2887 tdiag_fci[i].types[0].type = &t;
2888 tdiag_fci[i].pointer_count = 1;
2891 /* Handle the __gcc_cdiag__ format specifics. */
2892 if (!cdiag_fci)
2893 dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
2894 cdiag_fci = (format_char_info *)
2895 xmemdup (gcc_cdiag_char_table,
2896 sizeof (gcc_cdiag_char_table),
2897 sizeof (gcc_cdiag_char_table));
2898 if (t)
2900 /* All specifiers taking a tree share the same struct. */
2901 i = find_char_info_specifier_index (cdiag_fci, 'D');
2902 cdiag_fci[i].types[0].type = &t;
2903 cdiag_fci[i].pointer_count = 1;
2904 i = find_char_info_specifier_index (cdiag_fci, 'K');
2905 cdiag_fci[i].types[0].type = &t;
2906 cdiag_fci[i].pointer_count = 1;
2909 /* Handle the __gcc_cxxdiag__ format specifics. */
2910 if (!cxxdiag_fci)
2911 dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
2912 cxxdiag_fci = (format_char_info *)
2913 xmemdup (gcc_cxxdiag_char_table,
2914 sizeof (gcc_cxxdiag_char_table),
2915 sizeof (gcc_cxxdiag_char_table));
2916 if (t)
2918 /* All specifiers taking a tree share the same struct. */
2919 i = find_char_info_specifier_index (cxxdiag_fci, 'D');
2920 cxxdiag_fci[i].types[0].type = &t;
2921 cxxdiag_fci[i].pointer_count = 1;
2922 i = find_char_info_specifier_index (cxxdiag_fci, 'K');
2923 cxxdiag_fci[i].types[0].type = &t;
2924 cxxdiag_fci[i].pointer_count = 1;
2929 #ifdef TARGET_FORMAT_TYPES
2930 extern const format_kind_info TARGET_FORMAT_TYPES[];
2931 #endif
2933 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
2934 extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[];
2935 #endif
2936 #ifdef TARGET_OVERRIDES_FORMAT_INIT
2937 extern void TARGET_OVERRIDES_FORMAT_INIT (void);
2938 #endif
2940 /* Attributes such as "printf" are equivalent to those such as
2941 "gnu_printf" unless this is overridden by a target. */
2942 static const target_ovr_attr gnu_target_overrides_format_attributes[] =
2944 { "gnu_printf", "printf" },
2945 { "gnu_scanf", "scanf" },
2946 { "gnu_strftime", "strftime" },
2947 { "gnu_strfmon", "strfmon" },
2948 { NULL, NULL }
2951 /* Translate to unified attribute name. This is used in decode_format_type and
2952 decode_format_attr. In attr_name the user specified argument is passed. It
2953 returns the unified format name from TARGET_OVERRIDES_FORMAT_ATTRIBUTES
2954 or the attr_name passed to this function, if there is no matching entry. */
2955 static const char *
2956 convert_format_name_to_system_name (const char *attr_name)
2958 int i;
2960 if (attr_name == NULL || *attr_name == 0
2961 || strncmp (attr_name, "gcc_", 4) == 0)
2962 return attr_name;
2963 #ifdef TARGET_OVERRIDES_FORMAT_INIT
2964 TARGET_OVERRIDES_FORMAT_INIT ();
2965 #endif
2967 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
2968 /* Check if format attribute is overridden by target. */
2969 if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL
2970 && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0)
2972 for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i)
2974 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src,
2975 attr_name))
2976 return attr_name;
2977 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_dst,
2978 attr_name))
2979 return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src;
2982 #endif
2983 /* Otherwise default to gnu format. */
2984 for (i = 0;
2985 gnu_target_overrides_format_attributes[i].named_attr_src != NULL;
2986 ++i)
2988 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_src,
2989 attr_name))
2990 return attr_name;
2991 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_dst,
2992 attr_name))
2993 return gnu_target_overrides_format_attributes[i].named_attr_src;
2996 return attr_name;
2999 /* Return true if TATTR_NAME and ATTR_NAME are the same format attribute,
3000 counting "name" and "__name__" as the same, false otherwise. */
3001 static bool
3002 cmp_attribs (const char *tattr_name, const char *attr_name)
3004 int alen = strlen (attr_name);
3005 int slen = (tattr_name ? strlen (tattr_name) : 0);
3006 if (alen > 4 && attr_name[0] == '_' && attr_name[1] == '_'
3007 && attr_name[alen - 1] == '_' && attr_name[alen - 2] == '_')
3009 attr_name += 2;
3010 alen -= 4;
3012 if (alen != slen || strncmp (tattr_name, attr_name, alen) != 0)
3013 return false;
3014 return true;
3017 /* Handle a "format" attribute; arguments as in
3018 struct attribute_spec.handler. */
3019 tree
3020 handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args,
3021 int flags, bool *no_add_attrs)
3023 tree type = *node;
3024 function_format_info info;
3026 #ifdef TARGET_FORMAT_TYPES
3027 /* If the target provides additional format types, we need to
3028 add them to FORMAT_TYPES at first use. */
3029 if (TARGET_FORMAT_TYPES != NULL && !dynamic_format_types)
3031 dynamic_format_types = XNEWVEC (format_kind_info,
3032 n_format_types + TARGET_N_FORMAT_TYPES);
3033 memcpy (dynamic_format_types, format_types_orig,
3034 sizeof (format_types_orig));
3035 memcpy (&dynamic_format_types[n_format_types], TARGET_FORMAT_TYPES,
3036 TARGET_N_FORMAT_TYPES * sizeof (dynamic_format_types[0]));
3038 format_types = dynamic_format_types;
3039 /* Provide a reference for the first potential external type. */
3040 first_target_format_type = n_format_types;
3041 n_format_types += TARGET_N_FORMAT_TYPES;
3043 #endif
3045 if (!decode_format_attr (args, &info, 0))
3047 *no_add_attrs = true;
3048 return NULL_TREE;
3051 if (prototype_p (type))
3053 if (!check_format_string (type, info.format_num, flags,
3054 no_add_attrs, info.format_type))
3055 return NULL_TREE;
3057 if (info.first_arg_num != 0)
3059 unsigned HOST_WIDE_INT arg_num = 1;
3060 function_args_iterator iter;
3061 tree arg_type;
3063 /* Verify that first_arg_num points to the last arg,
3064 the ... */
3065 FOREACH_FUNCTION_ARGS (type, arg_type, iter)
3066 arg_num++;
3068 if (arg_num != info.first_arg_num)
3070 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
3071 error ("args to be formatted is not %<...%>");
3072 *no_add_attrs = true;
3073 return NULL_TREE;
3078 /* Check if this is a strftime variant. Just for this variant
3079 FMT_FLAG_ARG_CONVERT is not set. */
3080 if ((format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT) == 0
3081 && info.first_arg_num != 0)
3083 error ("strftime formats cannot format arguments");
3084 *no_add_attrs = true;
3085 return NULL_TREE;
3088 /* If this is a custom GCC-internal format type, we have to
3089 initialize certain bits at runtime. */
3090 if (info.format_type == asm_fprintf_format_type
3091 || info.format_type == gcc_gfc_format_type
3092 || info.format_type == gcc_diag_format_type
3093 || info.format_type == gcc_tdiag_format_type
3094 || info.format_type == gcc_cdiag_format_type
3095 || info.format_type == gcc_cxxdiag_format_type)
3097 /* Our first time through, we have to make sure that our
3098 format_type data is allocated dynamically and is modifiable. */
3099 if (!dynamic_format_types)
3100 format_types = dynamic_format_types = (format_kind_info *)
3101 xmemdup (format_types_orig, sizeof (format_types_orig),
3102 sizeof (format_types_orig));
3104 /* If this is format __asm_fprintf__, we have to initialize
3105 GCC's notion of HOST_WIDE_INT for checking %wd. */
3106 if (info.format_type == asm_fprintf_format_type)
3107 init_dynamic_asm_fprintf_info ();
3108 /* If this is format __gcc_gfc__, we have to initialize GCC's
3109 notion of 'locus' at runtime for %L. */
3110 else if (info.format_type == gcc_gfc_format_type)
3111 init_dynamic_gfc_info ();
3112 /* If this is one of the diagnostic attributes, then we have to
3113 initialize 'location_t' and 'tree' at runtime. */
3114 else if (info.format_type == gcc_diag_format_type
3115 || info.format_type == gcc_tdiag_format_type
3116 || info.format_type == gcc_cdiag_format_type
3117 || info.format_type == gcc_cxxdiag_format_type)
3118 init_dynamic_diag_info ();
3119 else
3120 gcc_unreachable ();
3123 return NULL_TREE;