* doc/extend.texi: Use @pxref instead of @xref.
[official-gcc.git] / gcc / c-family / c-format.c
blob145bbfd393f09f18d28acfea3bbc6e17825162e0
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 /* Given a string S of length LINE_WIDTH, find the visual column
82 corresponding to OFFSET bytes. */
84 static unsigned int
85 location_column_from_byte_offset (const char *s, int line_width,
86 unsigned int offset)
88 const char * c = s;
89 if (*c != '"')
90 return 0;
92 c++, offset--;
93 while (offset > 0)
95 if (c - s >= line_width)
96 return 0;
98 switch (*c)
100 case '\\':
101 c++;
102 if (c - s >= line_width)
103 return 0;
104 switch (*c)
106 case '\\': case '\'': case '"': case '?':
107 case '(': case '{': case '[': case '%':
108 case 'a': case 'b': case 'f': case 'n':
109 case 'r': case 't': case 'v':
110 case 'e': case 'E':
111 c++, offset--;
112 break;
114 default:
115 return 0;
117 break;
119 case '"':
120 /* We found the end of the string too early. */
121 return 0;
123 default:
124 c++, offset--;
125 break;
128 return c - s;
131 /* Return a location that encodes the same location as LOC but shifted
132 by OFFSET bytes. */
134 static location_t
135 location_from_offset (location_t loc, int offset)
137 gcc_checking_assert (offset >= 0);
138 if (linemap_location_from_macro_expansion_p (line_table, loc)
139 || offset < 0)
140 return loc;
142 expanded_location s = expand_location_to_spelling_point (loc);
143 int line_width;
144 const char *line = location_get_source_line (s, &line_width);
145 line += s.column - 1 ;
146 line_width -= s.column - 1;
147 unsigned int column =
148 location_column_from_byte_offset (line, line_width, (unsigned) offset);
150 return linemap_position_for_loc_and_offset (line_table, loc, column);
153 /* Check that we have a pointer to a string suitable for use as a format.
154 The default is to check for a char type.
155 For objective-c dialects, this is extended to include references to string
156 objects validated by objc_string_ref_type_p ().
157 Targets may also provide a string object type that can be used within c and
158 c++ and shared with their respective objective-c dialects. In this case the
159 reference to a format string is checked for validity via a hook.
161 The function returns true if strref points to any string type valid for the
162 language dialect and target. */
164 static bool
165 valid_stringptr_type_p (tree strref)
167 return (strref != NULL
168 && TREE_CODE (strref) == POINTER_TYPE
169 && (TYPE_MAIN_VARIANT (TREE_TYPE (strref)) == char_type_node
170 || objc_string_ref_type_p (strref)
171 || (*targetcm.string_object_ref_type_p) ((const_tree) strref)));
174 /* Handle a "format_arg" attribute; arguments as in
175 struct attribute_spec.handler. */
176 tree
177 handle_format_arg_attribute (tree *node, tree ARG_UNUSED (name),
178 tree args, int flags, bool *no_add_attrs)
180 tree type = *node;
181 tree format_num_expr = TREE_VALUE (args);
182 unsigned HOST_WIDE_INT format_num = 0;
184 if (!get_constant (format_num_expr, &format_num, 0))
186 error ("format string has invalid operand number");
187 *no_add_attrs = true;
188 return NULL_TREE;
191 if (prototype_p (type))
193 /* The format arg can be any string reference valid for the language and
194 target. We cannot be more specific in this case. */
195 if (!check_format_string (type, format_num, flags, no_add_attrs, -1))
196 return NULL_TREE;
199 if (!valid_stringptr_type_p (TREE_TYPE (type)))
201 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
202 error ("function does not return string type");
203 *no_add_attrs = true;
204 return NULL_TREE;
207 return NULL_TREE;
210 /* Verify that the format_num argument is actually a string reference suitable,
211 for the language dialect and target (in case the format attribute is in
212 error). When we know the specific reference type expected, this is also
213 checked. */
214 static bool
215 check_format_string (tree fntype, unsigned HOST_WIDE_INT format_num,
216 int flags, bool *no_add_attrs, int expected_format_type)
218 unsigned HOST_WIDE_INT i;
219 bool is_objc_sref, is_target_sref, is_char_ref;
220 tree ref;
221 int fmt_flags;
222 function_args_iterator iter;
224 i = 1;
225 FOREACH_FUNCTION_ARGS (fntype, ref, iter)
227 if (i == format_num)
228 break;
229 i++;
232 if (!ref
233 || !valid_stringptr_type_p (ref))
235 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
236 error ("format string argument is not a string type");
237 *no_add_attrs = true;
238 return false;
241 /* We only know that we want a suitable string reference. */
242 if (expected_format_type < 0)
243 return true;
245 /* Now check that the arg matches the expected type. */
246 is_char_ref =
247 (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node);
249 fmt_flags = format_flags (expected_format_type);
250 is_objc_sref = is_target_sref = false;
251 if (!is_char_ref)
252 is_objc_sref = objc_string_ref_type_p (ref);
254 if (!(fmt_flags & FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL))
256 if (is_char_ref)
257 return true; /* OK, we expected a char and found one. */
258 else
260 /* We expected a char but found an extended string type. */
261 if (is_objc_sref)
262 error ("found a %<%s%> reference but the format argument should"
263 " be a string", format_name (gcc_objc_string_format_type));
264 else
265 error ("found a %qT but the format argument should be a string",
266 ref);
267 *no_add_attrs = true;
268 return false;
272 /* We expect a string object type as the format arg. */
273 if (is_char_ref)
275 error ("format argument should be a %<%s%> reference but"
276 " a string was found", format_name (expected_format_type));
277 *no_add_attrs = true;
278 return false;
281 /* We will assert that objective-c will support either its own string type
282 or the target-supplied variant. */
283 if (!is_objc_sref)
284 is_target_sref = (*targetcm.string_object_ref_type_p) ((const_tree) ref);
286 if (expected_format_type == (int) gcc_objc_string_format_type
287 && (is_objc_sref || is_target_sref))
288 return true;
290 /* We will allow a target string ref to match only itself. */
291 if (first_target_format_type
292 && expected_format_type >= first_target_format_type
293 && is_target_sref)
294 return true;
295 else
297 error ("format argument should be a %<%s%> reference",
298 format_name (expected_format_type));
299 *no_add_attrs = true;
300 return false;
303 gcc_unreachable ();
306 /* Verify EXPR is a constant, and store its value.
307 If validated_p is true there should be no errors.
308 Returns true on success, false otherwise. */
309 static bool
310 get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
312 if (!tree_fits_uhwi_p (expr))
314 gcc_assert (!validated_p);
315 return false;
318 *value = TREE_INT_CST_LOW (expr);
320 return true;
323 /* Decode the arguments to a "format" attribute into a
324 function_format_info structure. It is already known that the list
325 is of the right length. If VALIDATED_P is true, then these
326 attributes have already been validated and must not be erroneous;
327 if false, it will give an error message. Returns true if the
328 attributes are successfully decoded, false otherwise. */
330 static bool
331 decode_format_attr (tree args, function_format_info *info, int validated_p)
333 tree format_type_id = TREE_VALUE (args);
334 tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
335 tree first_arg_num_expr
336 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
338 if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
340 gcc_assert (!validated_p);
341 error ("unrecognized format specifier");
342 return false;
344 else
346 const char *p = IDENTIFIER_POINTER (format_type_id);
348 p = convert_format_name_to_system_name (p);
350 info->format_type = decode_format_type (p);
352 if (!c_dialect_objc ()
353 && info->format_type == gcc_objc_string_format_type)
355 gcc_assert (!validated_p);
356 warning (OPT_Wformat_, "%qE is only allowed in Objective-C dialects",
357 format_type_id);
358 info->format_type = format_type_error;
359 return false;
362 if (info->format_type == format_type_error)
364 gcc_assert (!validated_p);
365 warning (OPT_Wformat_, "%qE is an unrecognized format function type",
366 format_type_id);
367 return false;
371 if (!get_constant (format_num_expr, &info->format_num, validated_p))
373 error ("format string has invalid operand number");
374 return false;
377 if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
379 error ("%<...%> has invalid operand number");
380 return false;
383 if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
385 gcc_assert (!validated_p);
386 error ("format string argument follows the args to be formatted");
387 return false;
390 return true;
393 /* Check a call to a format function against a parameter list. */
395 /* The C standard version C++ is treated as equivalent to
396 or inheriting from, for the purpose of format features supported. */
397 #define CPLUSPLUS_STD_VER (cxx_dialect < cxx11 ? STD_C94 : STD_C99)
398 /* The C standard version we are checking formats against when pedantic. */
399 #define C_STD_VER ((int) (c_dialect_cxx () \
400 ? CPLUSPLUS_STD_VER \
401 : (flag_isoc99 \
402 ? STD_C99 \
403 : (flag_isoc94 ? STD_C94 : STD_C89))))
404 /* The name to give to the standard version we are warning about when
405 pedantic. FEATURE_VER is the version in which the feature warned out
406 appeared, which is higher than C_STD_VER. */
407 #define C_STD_NAME(FEATURE_VER) (c_dialect_cxx () \
408 ? (cxx_dialect < cxx11 ? "ISO C++98" \
409 : "ISO C++11") \
410 : ((FEATURE_VER) == STD_EXT \
411 ? "ISO C" \
412 : "ISO C90"))
413 /* Adjust a C standard version, which may be STD_C9L, to account for
414 -Wno-long-long. Returns other standard versions unchanged. */
415 #define ADJ_STD(VER) ((int) ((VER) == STD_C9L \
416 ? (warn_long_long ? STD_C99 : STD_C89) \
417 : (VER)))
419 /* Enum describing the kind of specifiers present in the format and
420 requiring an argument. */
421 enum format_specifier_kind {
422 CF_KIND_FORMAT,
423 CF_KIND_FIELD_WIDTH,
424 CF_KIND_FIELD_PRECISION
427 static const char *kind_descriptions[] = {
428 N_("format"),
429 N_("field width specifier"),
430 N_("field precision specifier")
433 /* Structure describing details of a type expected in format checking,
434 and the type to check against it. */
435 typedef struct format_wanted_type
437 /* The type wanted. */
438 tree wanted_type;
439 /* The name of this type to use in diagnostics. */
440 const char *wanted_type_name;
441 /* Should be type checked just for scalar width identity. */
442 int scalar_identity_flag;
443 /* The level of indirection through pointers at which this type occurs. */
444 int pointer_count;
445 /* Whether, when pointer_count is 1, to allow any character type when
446 pedantic, rather than just the character or void type specified. */
447 int char_lenient_flag;
448 /* Whether the argument, dereferenced once, is written into and so the
449 argument must not be a pointer to a const-qualified type. */
450 int writing_in_flag;
451 /* Whether the argument, dereferenced once, is read from and so
452 must not be a NULL pointer. */
453 int reading_from_flag;
454 /* The kind of specifier that this type is used for. */
455 enum format_specifier_kind kind;
456 /* The starting character of the specifier. This never includes the
457 initial percent sign. */
458 const char *format_start;
459 /* The length of the specifier. */
460 int format_length;
461 /* The actual parameter to check against the wanted type. */
462 tree param;
463 /* The argument number of that parameter. */
464 int arg_num;
465 /* The offset location of this argument with respect to the format
466 string location. */
467 unsigned int offset_loc;
468 /* The next type to check for this format conversion, or NULL if none. */
469 struct format_wanted_type *next;
470 } format_wanted_type;
472 /* Convenience macro for format_length_info meaning unused. */
473 #define NO_FMT NULL, FMT_LEN_none, STD_C89
475 static const format_length_info printf_length_specs[] =
477 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
478 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 },
479 { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 },
480 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
481 { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
482 { "Z", FMT_LEN_z, STD_EXT, NO_FMT, 0 },
483 { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
484 { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 },
485 { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 },
486 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 },
487 { NO_FMT, NO_FMT, 0 }
490 /* Length specifiers valid for asm_fprintf. */
491 static const format_length_info asm_fprintf_length_specs[] =
493 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
494 { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
495 { NO_FMT, NO_FMT, 0 }
498 /* Length specifiers valid for GCC diagnostics. */
499 static const format_length_info gcc_diag_length_specs[] =
501 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
502 { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
503 { NO_FMT, NO_FMT, 0 }
506 /* The custom diagnostics all accept the same length specifiers. */
507 #define gcc_tdiag_length_specs gcc_diag_length_specs
508 #define gcc_cdiag_length_specs gcc_diag_length_specs
509 #define gcc_cxxdiag_length_specs gcc_diag_length_specs
511 /* This differs from printf_length_specs only in that "Z" is not accepted. */
512 static const format_length_info scanf_length_specs[] =
514 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
515 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 },
516 { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 },
517 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
518 { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
519 { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
520 { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 },
521 { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 },
522 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 },
523 { NO_FMT, NO_FMT, 0 }
527 /* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings
528 make no sense for a format type not part of any C standard version. */
529 static const format_length_info strfmon_length_specs[] =
531 /* A GNU extension. */
532 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
533 { NO_FMT, NO_FMT, 0 }
537 /* For now, the Fortran front-end routines only use l as length modifier. */
538 static const format_length_info gcc_gfc_length_specs[] =
540 { "l", FMT_LEN_l, STD_C89, NO_FMT, 0 },
541 { NO_FMT, NO_FMT, 0 }
545 static const format_flag_spec printf_flag_specs[] =
547 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
548 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
549 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
550 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
551 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
552 { '\'', 0, 0, N_("''' flag"), N_("the ''' printf flag"), STD_EXT },
553 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' printf flag"), STD_EXT },
554 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
555 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
556 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
557 { 0, 0, 0, NULL, NULL, STD_C89 }
561 static const format_flag_pair printf_flag_pairs[] =
563 { ' ', '+', 1, 0 },
564 { '0', '-', 1, 0 },
565 { '0', 'p', 1, 'i' },
566 { 0, 0, 0, 0 }
569 static const format_flag_spec asm_fprintf_flag_specs[] =
571 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
572 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
573 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
574 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
575 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
576 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
577 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
578 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
579 { 0, 0, 0, NULL, NULL, STD_C89 }
582 static const format_flag_pair asm_fprintf_flag_pairs[] =
584 { ' ', '+', 1, 0 },
585 { '0', '-', 1, 0 },
586 { '0', 'p', 1, 'i' },
587 { 0, 0, 0, 0 }
590 static const format_flag_pair gcc_diag_flag_pairs[] =
592 { 0, 0, 0, 0 }
595 #define gcc_tdiag_flag_pairs gcc_diag_flag_pairs
596 #define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
597 #define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
598 #define gcc_gfc_flag_pairs gcc_diag_flag_pairs
600 static const format_flag_spec gcc_diag_flag_specs[] =
602 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
603 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
604 { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 },
605 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
606 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
607 { 0, 0, 0, NULL, NULL, STD_C89 }
610 #define gcc_tdiag_flag_specs gcc_diag_flag_specs
611 #define gcc_cdiag_flag_specs gcc_diag_flag_specs
612 #define gcc_cxxdiag_flag_specs gcc_diag_flag_specs
613 #define gcc_gfc_flag_specs gcc_diag_flag_specs
615 static const format_flag_spec scanf_flag_specs[] =
617 { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
618 { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
619 { 'm', 0, 0, N_("'m' flag"), N_("the 'm' scanf flag"), STD_EXT },
620 { 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
621 { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
622 { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT },
623 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT },
624 { 0, 0, 0, NULL, NULL, STD_C89 }
628 static const format_flag_pair scanf_flag_pairs[] =
630 { '*', 'L', 0, 0 },
631 { 'a', 'm', 0, 0 },
632 { 0, 0, 0, 0 }
636 static const format_flag_spec strftime_flag_specs[] =
638 { '_', 0, 0, N_("'_' flag"), N_("the '_' strftime flag"), STD_EXT },
639 { '-', 0, 0, N_("'-' flag"), N_("the '-' strftime flag"), STD_EXT },
640 { '0', 0, 0, N_("'0' flag"), N_("the '0' strftime flag"), STD_EXT },
641 { '^', 0, 0, N_("'^' flag"), N_("the '^' strftime flag"), STD_EXT },
642 { '#', 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), STD_EXT },
643 { 'w', 0, 0, N_("field width"), N_("field width in strftime format"), STD_EXT },
644 { 'E', 0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"), STD_C99 },
645 { 'O', 0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"), STD_C99 },
646 { 'O', 'o', 0, NULL, N_("the 'O' modifier"), STD_EXT },
647 { 0, 0, 0, NULL, NULL, STD_C89 }
651 static const format_flag_pair strftime_flag_pairs[] =
653 { 'E', 'O', 0, 0 },
654 { '_', '-', 0, 0 },
655 { '_', '0', 0, 0 },
656 { '-', '0', 0, 0 },
657 { '^', '#', 0, 0 },
658 { 0, 0, 0, 0 }
662 static const format_flag_spec strfmon_flag_specs[] =
664 { '=', 0, 1, N_("fill character"), N_("fill character in strfmon format"), STD_C89 },
665 { '^', 0, 0, N_("'^' flag"), N_("the '^' strfmon flag"), STD_C89 },
666 { '+', 0, 0, N_("'+' flag"), N_("the '+' strfmon flag"), STD_C89 },
667 { '(', 0, 0, N_("'(' flag"), N_("the '(' strfmon flag"), STD_C89 },
668 { '!', 0, 0, N_("'!' flag"), N_("the '!' strfmon flag"), STD_C89 },
669 { '-', 0, 0, N_("'-' flag"), N_("the '-' strfmon flag"), STD_C89 },
670 { 'w', 0, 0, N_("field width"), N_("field width in strfmon format"), STD_C89 },
671 { '#', 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 },
672 { 'p', 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
673 { 'L', 0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 },
674 { 0, 0, 0, NULL, NULL, STD_C89 }
677 static const format_flag_pair strfmon_flag_pairs[] =
679 { '+', '(', 0, 0 },
680 { 0, 0, 0, 0 }
684 static const format_char_info print_char_table[] =
686 /* C89 conversion specifiers. */
687 { "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 },
688 { "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 },
689 { "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 },
690 { "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 },
691 { "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 },
692 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
693 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
694 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
695 { "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 },
696 /* C99 conversion specifiers. */
697 { "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 },
698 { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
699 /* X/Open conversion specifiers. */
700 { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
701 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
702 /* GNU conversion specifiers. */
703 { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL },
704 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
707 static const format_char_info asm_fprintf_char_table[] =
709 /* C89 conversion specifiers. */
710 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL },
711 { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
712 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL },
713 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
714 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
716 /* asm_fprintf conversion specifiers. */
717 { "O", 0, STD_C89, NOARGUMENTS, "", "", NULL },
718 { "R", 0, STD_C89, NOARGUMENTS, "", "", NULL },
719 { "I", 0, STD_C89, NOARGUMENTS, "", "", NULL },
720 { "L", 0, STD_C89, NOARGUMENTS, "", "", NULL },
721 { "U", 0, STD_C89, NOARGUMENTS, "", "", NULL },
722 { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
723 { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL },
724 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
727 static const format_char_info gcc_diag_char_table[] =
729 /* C89 conversion specifiers. */
730 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
731 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
732 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
733 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
734 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
735 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
737 /* Custom conversion specifiers. */
739 /* These will require a "tree" at runtime. */
740 { "K", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
742 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
743 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
744 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
745 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
748 static const format_char_info gcc_tdiag_char_table[] =
750 /* C89 conversion specifiers. */
751 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
752 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
753 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
754 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
755 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
756 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
758 /* Custom conversion specifiers. */
760 /* These will require a "tree" at runtime. */
761 { "DFKTEV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
763 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
765 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
766 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
767 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
768 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
771 static const format_char_info gcc_cdiag_char_table[] =
773 /* C89 conversion specifiers. */
774 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
775 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
776 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
777 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
778 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
779 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
781 /* Custom conversion specifiers. */
783 /* These will require a "tree" at runtime. */
784 { "DEFKTV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
786 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
788 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
789 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
790 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
791 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
794 static const format_char_info gcc_cxxdiag_char_table[] =
796 /* C89 conversion specifiers. */
797 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
798 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
799 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
800 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
801 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
802 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
804 /* Custom conversion specifiers. */
806 /* These will require a "tree" at runtime. */
807 { "ADEFKSTVX",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
809 { "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
811 /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
812 { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
814 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
815 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
816 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
817 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
820 static const format_char_info gcc_gfc_char_table[] =
822 /* C89 conversion specifiers. */
823 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
824 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
825 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
826 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "cR", NULL },
828 /* gfc conversion specifiers. */
830 { "C", 0, STD_C89, NOARGUMENTS, "", "", NULL },
832 /* This will require a "locus" at runtime. */
833 { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL },
835 /* These will require nothing. */
836 { "<>",0, STD_C89, NOARGUMENTS, "", "", NULL },
837 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
840 static const format_char_info scan_char_table[] =
842 /* C89 conversion specifiers. */
843 { "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 },
844 { "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 },
845 { "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 },
846 { "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 },
847 { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "cW", NULL },
848 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW", NULL },
849 { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW[", NULL },
850 { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
851 { "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 },
852 /* C99 conversion specifiers. */
853 { "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 },
854 { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
855 /* X/Open conversion specifiers. */
856 { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "W", NULL },
857 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "W", NULL },
858 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
861 static const format_char_info time_char_table[] =
863 /* C89 conversion specifiers. */
864 { "ABZab", 0, STD_C89, NOLENGTHS, "^#", "", NULL },
865 { "cx", 0, STD_C89, NOLENGTHS, "E", "3", NULL },
866 { "HIMSUWdmw", 0, STD_C89, NOLENGTHS, "-_0Ow", "", NULL },
867 { "j", 0, STD_C89, NOLENGTHS, "-_0Ow", "o", NULL },
868 { "p", 0, STD_C89, NOLENGTHS, "#", "", NULL },
869 { "X", 0, STD_C89, NOLENGTHS, "E", "", NULL },
870 { "y", 0, STD_C89, NOLENGTHS, "EO-_0w", "4", NULL },
871 { "Y", 0, STD_C89, NOLENGTHS, "-_0EOw", "o", NULL },
872 { "%", 0, STD_C89, NOLENGTHS, "", "", NULL },
873 /* C99 conversion specifiers. */
874 { "C", 0, STD_C99, NOLENGTHS, "-_0EOw", "o", NULL },
875 { "D", 0, STD_C99, NOLENGTHS, "", "2", NULL },
876 { "eVu", 0, STD_C99, NOLENGTHS, "-_0Ow", "", NULL },
877 { "FRTnrt", 0, STD_C99, NOLENGTHS, "", "", NULL },
878 { "g", 0, STD_C99, NOLENGTHS, "O-_0w", "2o", NULL },
879 { "G", 0, STD_C99, NOLENGTHS, "-_0Ow", "o", NULL },
880 { "h", 0, STD_C99, NOLENGTHS, "^#", "", NULL },
881 { "z", 0, STD_C99, NOLENGTHS, "O", "o", NULL },
882 /* GNU conversion specifiers. */
883 { "kls", 0, STD_EXT, NOLENGTHS, "-_0Ow", "", NULL },
884 { "P", 0, STD_EXT, NOLENGTHS, "", "", NULL },
885 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
888 static const format_char_info monetary_char_table[] =
890 { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL },
891 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
894 /* This must be in the same order as enum format_type. */
895 static const format_kind_info format_types_orig[] =
897 { "gnu_printf", printf_length_specs, print_char_table, " +#0-'I", NULL,
898 printf_flag_specs, printf_flag_pairs,
899 FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
900 'w', 0, 'p', 0, 'L', 0,
901 &integer_type_node, &integer_type_node
903 { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL,
904 asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
905 FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
906 'w', 0, 'p', 0, 'L', 0,
907 NULL, NULL
909 { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+#", NULL,
910 gcc_diag_flag_specs, gcc_diag_flag_pairs,
911 FMT_FLAG_ARG_CONVERT,
912 0, 0, 'p', 0, 'L', 0,
913 NULL, &integer_type_node
915 { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+#", NULL,
916 gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs,
917 FMT_FLAG_ARG_CONVERT,
918 0, 0, 'p', 0, 'L', 0,
919 NULL, &integer_type_node
921 { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+#", NULL,
922 gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
923 FMT_FLAG_ARG_CONVERT,
924 0, 0, 'p', 0, 'L', 0,
925 NULL, &integer_type_node
927 { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL,
928 gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
929 FMT_FLAG_ARG_CONVERT,
930 0, 0, 'p', 0, 'L', 0,
931 NULL, &integer_type_node
933 { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "q+#", NULL,
934 gcc_gfc_flag_specs, gcc_gfc_flag_pairs,
935 FMT_FLAG_ARG_CONVERT,
936 0, 0, 0, 0, 0, 0,
937 NULL, NULL
939 { "NSString", NULL, NULL, NULL, NULL,
940 NULL, NULL,
941 FMT_FLAG_ARG_CONVERT|FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL, 0, 0, 0, 0, 0, 0,
942 NULL, NULL
944 { "gnu_scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
945 scanf_flag_specs, scanf_flag_pairs,
946 FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
947 'w', 0, 0, '*', 'L', 'm',
948 NULL, NULL
950 { "gnu_strftime", NULL, time_char_table, "_-0^#", "EO",
951 strftime_flag_specs, strftime_flag_pairs,
952 FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, 0,
953 NULL, NULL
955 { "gnu_strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL,
956 strfmon_flag_specs, strfmon_flag_pairs,
957 FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0,
958 NULL, NULL
962 /* This layer of indirection allows GCC to reassign format_types with
963 new data if necessary, while still allowing the original data to be
964 const. */
965 static const format_kind_info *format_types = format_types_orig;
966 /* We can modify this one. We also add target-specific format types
967 to the end of the array. */
968 static format_kind_info *dynamic_format_types;
970 static int n_format_types = ARRAY_SIZE (format_types_orig);
972 /* Structure detailing the results of checking a format function call
973 where the format expression may be a conditional expression with
974 many leaves resulting from nested conditional expressions. */
975 typedef struct
977 /* Number of leaves of the format argument that could not be checked
978 as they were not string literals. */
979 int number_non_literal;
980 /* Number of leaves of the format argument that were null pointers or
981 string literals, but had extra format arguments. */
982 int number_extra_args;
983 location_t extra_arg_loc;
984 /* Number of leaves of the format argument that were null pointers or
985 string literals, but had extra format arguments and used $ operand
986 numbers. */
987 int number_dollar_extra_args;
988 /* Number of leaves of the format argument that were wide string
989 literals. */
990 int number_wide;
991 /* Number of leaves of the format argument that were empty strings. */
992 int number_empty;
993 /* Number of leaves of the format argument that were unterminated
994 strings. */
995 int number_unterminated;
996 /* Number of leaves of the format argument that were not counted above. */
997 int number_other;
998 /* Location of the format string. */
999 location_t format_string_loc;
1000 } format_check_results;
1002 typedef struct
1004 format_check_results *res;
1005 function_format_info *info;
1006 tree params;
1007 } format_check_context;
1009 /* Return the format name (as specified in the original table) for the format
1010 type indicated by format_num. */
1011 static const char *
1012 format_name (int format_num)
1014 if (format_num >= 0 && format_num < n_format_types)
1015 return format_types[format_num].name;
1016 gcc_unreachable ();
1019 /* Return the format flags (as specified in the original table) for the format
1020 type indicated by format_num. */
1021 static int
1022 format_flags (int format_num)
1024 if (format_num >= 0 && format_num < n_format_types)
1025 return format_types[format_num].flags;
1026 gcc_unreachable ();
1029 static void check_format_info (function_format_info *, tree);
1030 static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
1031 static void check_format_info_main (format_check_results *,
1032 function_format_info *,
1033 const char *, int, tree,
1034 unsigned HOST_WIDE_INT, alloc_pool);
1036 static void init_dollar_format_checking (int, tree);
1037 static int maybe_read_dollar_number (const char **, int,
1038 tree, tree *, const format_kind_info *);
1039 static bool avoid_dollar_number (const char *);
1040 static void finish_dollar_format_checking (format_check_results *, int);
1042 static const format_flag_spec *get_flag_spec (const format_flag_spec *,
1043 int, const char *);
1045 static void check_format_types (location_t, format_wanted_type *);
1046 static void format_type_warning (location_t, format_wanted_type *, tree, tree);
1048 /* Decode a format type from a string, returning the type, or
1049 format_type_error if not valid, in which case the caller should print an
1050 error message. */
1051 static int
1052 decode_format_type (const char *s)
1054 int i;
1055 int slen;
1057 s = convert_format_name_to_system_name (s);
1058 slen = strlen (s);
1059 for (i = 0; i < n_format_types; i++)
1061 int alen;
1062 if (!strcmp (s, format_types[i].name))
1063 return i;
1064 alen = strlen (format_types[i].name);
1065 if (slen == alen + 4 && s[0] == '_' && s[1] == '_'
1066 && s[slen - 1] == '_' && s[slen - 2] == '_'
1067 && !strncmp (s + 2, format_types[i].name, alen))
1068 return i;
1070 return format_type_error;
1074 /* Check the argument list of a call to printf, scanf, etc.
1075 ATTRS are the attributes on the function type. There are NARGS argument
1076 values in the array ARGARRAY.
1077 Also, if -Wsuggest-attribute=format,
1078 warn for calls to vprintf or vscanf in functions with no such format
1079 attribute themselves. */
1081 void
1082 check_function_format (tree attrs, int nargs, tree *argarray)
1084 tree a;
1086 /* See if this function has any format attributes. */
1087 for (a = attrs; a; a = TREE_CHAIN (a))
1089 if (is_attribute_p ("format", TREE_PURPOSE (a)))
1091 /* Yup; check it. */
1092 function_format_info info;
1093 decode_format_attr (TREE_VALUE (a), &info, /*validated=*/true);
1094 if (warn_format)
1096 /* FIXME: Rewrite all the internal functions in this file
1097 to use the ARGARRAY directly instead of constructing this
1098 temporary list. */
1099 tree params = NULL_TREE;
1100 int i;
1101 for (i = nargs - 1; i >= 0; i--)
1102 params = tree_cons (NULL_TREE, argarray[i], params);
1103 check_format_info (&info, params);
1105 if (warn_suggest_attribute_format && info.first_arg_num == 0
1106 && (format_types[info.format_type].flags
1107 & (int) FMT_FLAG_ARG_CONVERT))
1109 tree c;
1110 for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
1112 c = TREE_CHAIN (c))
1113 if (is_attribute_p ("format", TREE_PURPOSE (c))
1114 && (decode_format_type (IDENTIFIER_POINTER
1115 (TREE_VALUE (TREE_VALUE (c))))
1116 == info.format_type))
1117 break;
1118 if (c == NULL_TREE)
1120 /* Check if the current function has a parameter to which
1121 the format attribute could be attached; if not, it
1122 can't be a candidate for a format attribute, despite
1123 the vprintf-like or vscanf-like call. */
1124 tree args;
1125 for (args = DECL_ARGUMENTS (current_function_decl);
1126 args != 0;
1127 args = DECL_CHAIN (args))
1129 if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
1130 && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
1131 == char_type_node))
1132 break;
1134 if (args != 0)
1135 warning (OPT_Wsuggest_attribute_format, "function might "
1136 "be possible candidate for %qs format attribute",
1137 format_types[info.format_type].name);
1145 /* Variables used by the checking of $ operand number formats. */
1146 static char *dollar_arguments_used = NULL;
1147 static char *dollar_arguments_pointer_p = NULL;
1148 static int dollar_arguments_alloc = 0;
1149 static int dollar_arguments_count;
1150 static int dollar_first_arg_num;
1151 static int dollar_max_arg_used;
1152 static int dollar_format_warned;
1154 /* Initialize the checking for a format string that may contain $
1155 parameter number specifications; we will need to keep track of whether
1156 each parameter has been used. FIRST_ARG_NUM is the number of the first
1157 argument that is a parameter to the format, or 0 for a vprintf-style
1158 function; PARAMS is the list of arguments starting at this argument. */
1160 static void
1161 init_dollar_format_checking (int first_arg_num, tree params)
1163 tree oparams = params;
1165 dollar_first_arg_num = first_arg_num;
1166 dollar_arguments_count = 0;
1167 dollar_max_arg_used = 0;
1168 dollar_format_warned = 0;
1169 if (first_arg_num > 0)
1171 while (params)
1173 dollar_arguments_count++;
1174 params = TREE_CHAIN (params);
1177 if (dollar_arguments_alloc < dollar_arguments_count)
1179 free (dollar_arguments_used);
1180 free (dollar_arguments_pointer_p);
1181 dollar_arguments_alloc = dollar_arguments_count;
1182 dollar_arguments_used = XNEWVEC (char, dollar_arguments_alloc);
1183 dollar_arguments_pointer_p = XNEWVEC (char, dollar_arguments_alloc);
1185 if (dollar_arguments_alloc)
1187 memset (dollar_arguments_used, 0, dollar_arguments_alloc);
1188 if (first_arg_num > 0)
1190 int i = 0;
1191 params = oparams;
1192 while (params)
1194 dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params)))
1195 == POINTER_TYPE);
1196 params = TREE_CHAIN (params);
1197 i++;
1204 /* Look for a decimal number followed by a $ in *FORMAT. If DOLLAR_NEEDED
1205 is set, it is an error if one is not found; otherwise, it is OK. If
1206 such a number is found, check whether it is within range and mark that
1207 numbered operand as being used for later checking. Returns the operand
1208 number if found and within range, zero if no such number was found and
1209 this is OK, or -1 on error. PARAMS points to the first operand of the
1210 format; PARAM_PTR is made to point to the parameter referred to. If
1211 a $ format is found, *FORMAT is updated to point just after it. */
1213 static int
1214 maybe_read_dollar_number (const char **format,
1215 int dollar_needed, tree params, tree *param_ptr,
1216 const format_kind_info *fki)
1218 int argnum;
1219 int overflow_flag;
1220 const char *fcp = *format;
1221 if (!ISDIGIT (*fcp))
1223 if (dollar_needed)
1225 warning (OPT_Wformat_, "missing $ operand number in format");
1226 return -1;
1228 else
1229 return 0;
1231 argnum = 0;
1232 overflow_flag = 0;
1233 while (ISDIGIT (*fcp))
1235 int nargnum;
1236 nargnum = 10 * argnum + (*fcp - '0');
1237 if (nargnum < 0 || nargnum / 10 != argnum)
1238 overflow_flag = 1;
1239 argnum = nargnum;
1240 fcp++;
1242 if (*fcp != '$')
1244 if (dollar_needed)
1246 warning (OPT_Wformat_, "missing $ operand number in format");
1247 return -1;
1249 else
1250 return 0;
1252 *format = fcp + 1;
1253 if (pedantic && !dollar_format_warned)
1255 warning (OPT_Wformat_, "%s does not support %%n$ operand number formats",
1256 C_STD_NAME (STD_EXT));
1257 dollar_format_warned = 1;
1259 if (overflow_flag || argnum == 0
1260 || (dollar_first_arg_num && argnum > dollar_arguments_count))
1262 warning (OPT_Wformat_, "operand number out of range in format");
1263 return -1;
1265 if (argnum > dollar_max_arg_used)
1266 dollar_max_arg_used = argnum;
1267 /* For vprintf-style functions we may need to allocate more memory to
1268 track which arguments are used. */
1269 while (dollar_arguments_alloc < dollar_max_arg_used)
1271 int nalloc;
1272 nalloc = 2 * dollar_arguments_alloc + 16;
1273 dollar_arguments_used = XRESIZEVEC (char, dollar_arguments_used,
1274 nalloc);
1275 dollar_arguments_pointer_p = XRESIZEVEC (char, dollar_arguments_pointer_p,
1276 nalloc);
1277 memset (dollar_arguments_used + dollar_arguments_alloc, 0,
1278 nalloc - dollar_arguments_alloc);
1279 dollar_arguments_alloc = nalloc;
1281 if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE)
1282 && dollar_arguments_used[argnum - 1] == 1)
1284 dollar_arguments_used[argnum - 1] = 2;
1285 warning (OPT_Wformat_, "format argument %d used more than once in %s format",
1286 argnum, fki->name);
1288 else
1289 dollar_arguments_used[argnum - 1] = 1;
1290 if (dollar_first_arg_num)
1292 int i;
1293 *param_ptr = params;
1294 for (i = 1; i < argnum && *param_ptr != 0; i++)
1295 *param_ptr = TREE_CHAIN (*param_ptr);
1297 /* This case shouldn't be caught here. */
1298 gcc_assert (*param_ptr);
1300 else
1301 *param_ptr = 0;
1302 return argnum;
1305 /* Ensure that FORMAT does not start with a decimal number followed by
1306 a $; give a diagnostic and return true if it does, false otherwise. */
1308 static bool
1309 avoid_dollar_number (const char *format)
1311 if (!ISDIGIT (*format))
1312 return false;
1313 while (ISDIGIT (*format))
1314 format++;
1315 if (*format == '$')
1317 warning (OPT_Wformat_, "$ operand number used after format without operand number");
1318 return true;
1320 return false;
1324 /* Finish the checking for a format string that used $ operand number formats
1325 instead of non-$ formats. We check for unused operands before used ones
1326 (a serious error, since the implementation of the format function
1327 can't know what types to pass to va_arg to find the later arguments).
1328 and for unused operands at the end of the format (if we know how many
1329 arguments the format had, so not for vprintf). If there were operand
1330 numbers out of range on a non-vprintf-style format, we won't have reached
1331 here. If POINTER_GAP_OK, unused arguments are OK if all arguments are
1332 pointers. */
1334 static void
1335 finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok)
1337 int i;
1338 bool found_pointer_gap = false;
1339 for (i = 0; i < dollar_max_arg_used; i++)
1341 if (!dollar_arguments_used[i])
1343 if (pointer_gap_ok && (dollar_first_arg_num == 0
1344 || dollar_arguments_pointer_p[i]))
1345 found_pointer_gap = true;
1346 else
1347 warning_at (res->format_string_loc, OPT_Wformat_,
1348 "format argument %d unused before used argument %d in $-style format",
1349 i + 1, dollar_max_arg_used);
1352 if (found_pointer_gap
1353 || (dollar_first_arg_num
1354 && dollar_max_arg_used < dollar_arguments_count))
1356 res->number_other--;
1357 res->number_dollar_extra_args++;
1362 /* Retrieve the specification for a format flag. SPEC contains the
1363 specifications for format flags for the applicable kind of format.
1364 FLAG is the flag in question. If PREDICATES is NULL, the basic
1365 spec for that flag must be retrieved and must exist. If
1366 PREDICATES is not NULL, it is a string listing possible predicates
1367 for the spec entry; if an entry predicated on any of these is
1368 found, it is returned, otherwise NULL is returned. */
1370 static const format_flag_spec *
1371 get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
1373 int i;
1374 for (i = 0; spec[i].flag_char != 0; i++)
1376 if (spec[i].flag_char != flag)
1377 continue;
1378 if (predicates != NULL)
1380 if (spec[i].predicate != 0
1381 && strchr (predicates, spec[i].predicate) != 0)
1382 return &spec[i];
1384 else if (spec[i].predicate == 0)
1385 return &spec[i];
1387 gcc_assert (predicates);
1388 return NULL;
1392 /* Check the argument list of a call to printf, scanf, etc.
1393 INFO points to the function_format_info structure.
1394 PARAMS is the list of argument values. */
1396 static void
1397 check_format_info (function_format_info *info, tree params)
1399 format_check_context format_ctx;
1400 unsigned HOST_WIDE_INT arg_num;
1401 tree format_tree;
1402 format_check_results res;
1403 /* Skip to format argument. If the argument isn't available, there's
1404 no work for us to do; prototype checking will catch the problem. */
1405 for (arg_num = 1; ; ++arg_num)
1407 if (params == 0)
1408 return;
1409 if (arg_num == info->format_num)
1410 break;
1411 params = TREE_CHAIN (params);
1413 format_tree = TREE_VALUE (params);
1414 params = TREE_CHAIN (params);
1415 if (format_tree == 0)
1416 return;
1418 res.number_non_literal = 0;
1419 res.number_extra_args = 0;
1420 res.extra_arg_loc = UNKNOWN_LOCATION;
1421 res.number_dollar_extra_args = 0;
1422 res.number_wide = 0;
1423 res.number_empty = 0;
1424 res.number_unterminated = 0;
1425 res.number_other = 0;
1426 res.format_string_loc = input_location;
1428 format_ctx.res = &res;
1429 format_ctx.info = info;
1430 format_ctx.params = params;
1432 check_function_arguments_recurse (check_format_arg, &format_ctx,
1433 format_tree, arg_num);
1435 location_t loc = format_ctx.res->format_string_loc;
1437 if (res.number_non_literal > 0)
1439 /* Functions taking a va_list normally pass a non-literal format
1440 string. These functions typically are declared with
1441 first_arg_num == 0, so avoid warning in those cases. */
1442 if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT))
1444 /* For strftime-like formats, warn for not checking the format
1445 string; but there are no arguments to check. */
1446 warning_at (loc, OPT_Wformat_nonliteral,
1447 "format not a string literal, format string not checked");
1449 else if (info->first_arg_num != 0)
1451 /* If there are no arguments for the format at all, we may have
1452 printf (foo) which is likely to be a security hole. */
1453 while (arg_num + 1 < info->first_arg_num)
1455 if (params == 0)
1456 break;
1457 params = TREE_CHAIN (params);
1458 ++arg_num;
1460 if (params == 0 && warn_format_security)
1461 warning_at (loc, OPT_Wformat_security,
1462 "format not a string literal and no format arguments");
1463 else if (params == 0 && warn_format_nonliteral)
1464 warning_at (loc, OPT_Wformat_nonliteral,
1465 "format not a string literal and no format arguments");
1466 else
1467 warning_at (loc, OPT_Wformat_nonliteral,
1468 "format not a string literal, argument types not checked");
1472 /* If there were extra arguments to the format, normally warn. However,
1473 the standard does say extra arguments are ignored, so in the specific
1474 case where we have multiple leaves (conditional expressions or
1475 ngettext) allow extra arguments if at least one leaf didn't have extra
1476 arguments, but was otherwise OK (either non-literal or checked OK).
1477 If the format is an empty string, this should be counted similarly to the
1478 case of extra format arguments. */
1479 if (res.number_extra_args > 0 && res.number_non_literal == 0
1480 && res.number_other == 0)
1482 if (res.extra_arg_loc == UNKNOWN_LOCATION)
1483 res.extra_arg_loc = loc;
1484 warning_at (res.extra_arg_loc, OPT_Wformat_extra_args,
1485 "too many arguments for format");
1487 if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
1488 && res.number_other == 0)
1489 warning_at (loc, OPT_Wformat_extra_args, "unused arguments in $-style format");
1490 if (res.number_empty > 0 && res.number_non_literal == 0
1491 && res.number_other == 0)
1492 warning_at (loc, OPT_Wformat_zero_length, "zero-length %s format string",
1493 format_types[info->format_type].name);
1495 if (res.number_wide > 0)
1496 warning_at (loc, OPT_Wformat_, "format is a wide character string");
1498 if (res.number_unterminated > 0)
1499 warning_at (loc, OPT_Wformat_, "unterminated format string");
1502 /* Callback from check_function_arguments_recurse to check a
1503 format string. FORMAT_TREE is the format parameter. ARG_NUM
1504 is the number of the format argument. CTX points to a
1505 format_check_context. */
1507 static void
1508 check_format_arg (void *ctx, tree format_tree,
1509 unsigned HOST_WIDE_INT arg_num)
1511 format_check_context *format_ctx = (format_check_context *) ctx;
1512 format_check_results *res = format_ctx->res;
1513 function_format_info *info = format_ctx->info;
1514 tree params = format_ctx->params;
1516 int format_length;
1517 HOST_WIDE_INT offset;
1518 const char *format_chars;
1519 tree array_size = 0;
1520 tree array_init;
1521 alloc_pool fwt_pool;
1523 if (TREE_CODE (format_tree) == VAR_DECL)
1525 /* Pull out a constant value if the front end didn't. */
1526 format_tree = decl_constant_value (format_tree);
1527 STRIP_NOPS (format_tree);
1530 if (integer_zerop (format_tree))
1532 /* Skip to first argument to check, so we can see if this format
1533 has any arguments (it shouldn't). */
1534 while (arg_num + 1 < info->first_arg_num)
1536 if (params == 0)
1537 return;
1538 params = TREE_CHAIN (params);
1539 ++arg_num;
1542 if (params == 0)
1543 res->number_other++;
1544 else
1546 if (res->number_extra_args == 0)
1547 res->extra_arg_loc = EXPR_LOC_OR_LOC (TREE_VALUE (params),
1548 input_location);
1549 res->number_extra_args++;
1551 return;
1554 offset = 0;
1555 if (TREE_CODE (format_tree) == POINTER_PLUS_EXPR)
1557 tree arg0, arg1;
1559 arg0 = TREE_OPERAND (format_tree, 0);
1560 arg1 = TREE_OPERAND (format_tree, 1);
1561 STRIP_NOPS (arg0);
1562 STRIP_NOPS (arg1);
1563 if (TREE_CODE (arg1) == INTEGER_CST)
1564 format_tree = arg0;
1565 else
1567 res->number_non_literal++;
1568 return;
1570 /* POINTER_PLUS_EXPR offsets are to be interpreted signed. */
1571 if (!cst_and_fits_in_hwi (arg1))
1573 res->number_non_literal++;
1574 return;
1576 offset = int_cst_value (arg1);
1578 if (TREE_CODE (format_tree) != ADDR_EXPR)
1580 res->number_non_literal++;
1581 return;
1583 res->format_string_loc = EXPR_LOC_OR_LOC (format_tree, input_location);
1584 format_tree = TREE_OPERAND (format_tree, 0);
1585 if (format_types[info->format_type].flags
1586 & (int) FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL)
1588 bool objc_str = (info->format_type == gcc_objc_string_format_type);
1589 /* We cannot examine this string here - but we can check that it is
1590 a valid type. */
1591 if (TREE_CODE (format_tree) != CONST_DECL
1592 || !((objc_str && objc_string_ref_type_p (TREE_TYPE (format_tree)))
1593 || (*targetcm.string_object_ref_type_p)
1594 ((const_tree) TREE_TYPE (format_tree))))
1596 res->number_non_literal++;
1597 return;
1599 /* Skip to first argument to check. */
1600 while (arg_num + 1 < info->first_arg_num)
1602 if (params == 0)
1603 return;
1604 params = TREE_CHAIN (params);
1605 ++arg_num;
1607 /* So, we have a valid literal string object and one or more params.
1608 We need to use an external helper to parse the string into format
1609 info. For Objective-C variants we provide the resource within the
1610 objc tree, for target variants, via a hook. */
1611 if (objc_str)
1612 objc_check_format_arg (format_tree, params);
1613 else if (targetcm.check_string_object_format_arg)
1614 (*targetcm.check_string_object_format_arg) (format_tree, params);
1615 /* Else we can't handle it and retire quietly. */
1616 return;
1618 if (TREE_CODE (format_tree) == ARRAY_REF
1619 && tree_fits_shwi_p (TREE_OPERAND (format_tree, 1))
1620 && (offset += tree_to_shwi (TREE_OPERAND (format_tree, 1))) >= 0)
1621 format_tree = TREE_OPERAND (format_tree, 0);
1622 if (offset < 0)
1624 res->number_non_literal++;
1625 return;
1627 if (TREE_CODE (format_tree) == VAR_DECL
1628 && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
1629 && (array_init = decl_constant_value (format_tree)) != format_tree
1630 && TREE_CODE (array_init) == STRING_CST)
1632 /* Extract the string constant initializer. Note that this may include
1633 a trailing NUL character that is not in the array (e.g.
1634 const char a[3] = "foo";). */
1635 array_size = DECL_SIZE_UNIT (format_tree);
1636 format_tree = array_init;
1638 if (TREE_CODE (format_tree) != STRING_CST)
1640 res->number_non_literal++;
1641 return;
1643 if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
1645 res->number_wide++;
1646 return;
1648 format_chars = TREE_STRING_POINTER (format_tree);
1649 format_length = TREE_STRING_LENGTH (format_tree);
1650 if (array_size != 0)
1652 /* Variable length arrays can't be initialized. */
1653 gcc_assert (TREE_CODE (array_size) == INTEGER_CST);
1655 if (tree_fits_shwi_p (array_size))
1657 HOST_WIDE_INT array_size_value = tree_to_shwi (array_size);
1658 if (array_size_value > 0
1659 && array_size_value == (int) array_size_value
1660 && format_length > array_size_value)
1661 format_length = array_size_value;
1664 if (offset)
1666 if (offset >= format_length)
1668 res->number_non_literal++;
1669 return;
1671 format_chars += offset;
1672 format_length -= offset;
1674 if (format_length < 1 || format_chars[--format_length] != 0)
1676 res->number_unterminated++;
1677 return;
1679 if (format_length == 0)
1681 res->number_empty++;
1682 return;
1685 /* Skip to first argument to check. */
1686 while (arg_num + 1 < info->first_arg_num)
1688 if (params == 0)
1689 return;
1690 params = TREE_CHAIN (params);
1691 ++arg_num;
1693 /* Provisionally increment res->number_other; check_format_info_main
1694 will decrement it if it finds there are extra arguments, but this way
1695 need not adjust it for every return. */
1696 res->number_other++;
1697 fwt_pool = create_alloc_pool ("format_wanted_type pool",
1698 sizeof (format_wanted_type), 10);
1699 check_format_info_main (res, info, format_chars, format_length,
1700 params, arg_num, fwt_pool);
1701 free_alloc_pool (fwt_pool);
1705 /* Do the main part of checking a call to a format function. FORMAT_CHARS
1706 is the NUL-terminated format string (which at this point may contain
1707 internal NUL characters); FORMAT_LENGTH is its length (excluding the
1708 terminating NUL character). ARG_NUM is one less than the number of
1709 the first format argument to check; PARAMS points to that format
1710 argument in the list of arguments. */
1712 static void
1713 check_format_info_main (format_check_results *res,
1714 function_format_info *info, const char *format_chars,
1715 int format_length, tree params,
1716 unsigned HOST_WIDE_INT arg_num, alloc_pool fwt_pool)
1718 const char *orig_format_chars = format_chars;
1719 tree first_fillin_param = params;
1721 const format_kind_info *fki = &format_types[info->format_type];
1722 const format_flag_spec *flag_specs = fki->flag_specs;
1723 const format_flag_pair *bad_flag_pairs = fki->bad_flag_pairs;
1724 location_t format_string_loc = res->format_string_loc;
1726 /* -1 if no conversions taking an operand have been found; 0 if one has
1727 and it didn't use $; 1 if $ formats are in use. */
1728 int has_operand_number = -1;
1730 init_dollar_format_checking (info->first_arg_num, first_fillin_param);
1732 while (*format_chars != 0)
1734 int i;
1735 int suppressed = FALSE;
1736 const char *length_chars = NULL;
1737 enum format_lengths length_chars_val = FMT_LEN_none;
1738 enum format_std_version length_chars_std = STD_C89;
1739 int format_char;
1740 tree cur_param;
1741 tree wanted_type;
1742 int main_arg_num = 0;
1743 tree main_arg_params = 0;
1744 enum format_std_version wanted_type_std;
1745 const char *wanted_type_name;
1746 format_wanted_type width_wanted_type;
1747 format_wanted_type precision_wanted_type;
1748 format_wanted_type main_wanted_type;
1749 format_wanted_type *first_wanted_type = NULL;
1750 format_wanted_type *last_wanted_type = NULL;
1751 const format_length_info *fli = NULL;
1752 const format_char_info *fci = NULL;
1753 char flag_chars[256];
1754 int alloc_flag = 0;
1755 int scalar_identity_flag = 0;
1756 const char *format_start;
1758 if (*format_chars++ != '%')
1759 continue;
1760 if (*format_chars == 0)
1762 warning_at (location_from_offset (format_string_loc,
1763 format_chars - orig_format_chars),
1764 OPT_Wformat_,
1765 "spurious trailing %<%%%> in format");
1766 continue;
1768 if (*format_chars == '%')
1770 ++format_chars;
1771 continue;
1773 flag_chars[0] = 0;
1775 if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
1777 /* Possibly read a $ operand number at the start of the format.
1778 If one was previously used, one is required here. If one
1779 is not used here, we can't immediately conclude this is a
1780 format without them, since it could be printf %m or scanf %*. */
1781 int opnum;
1782 opnum = maybe_read_dollar_number (&format_chars, 0,
1783 first_fillin_param,
1784 &main_arg_params, fki);
1785 if (opnum == -1)
1786 return;
1787 else if (opnum > 0)
1789 has_operand_number = 1;
1790 main_arg_num = opnum + info->first_arg_num - 1;
1793 else if (fki->flags & FMT_FLAG_USE_DOLLAR)
1795 if (avoid_dollar_number (format_chars))
1796 return;
1799 /* Read any format flags, but do not yet validate them beyond removing
1800 duplicates, since in general validation depends on the rest of
1801 the format. */
1802 while (*format_chars != 0
1803 && strchr (fki->flag_chars, *format_chars) != 0)
1805 const format_flag_spec *s = get_flag_spec (flag_specs,
1806 *format_chars, NULL);
1807 if (strchr (flag_chars, *format_chars) != 0)
1809 warning_at (location_from_offset (format_string_loc,
1810 format_chars + 1
1811 - orig_format_chars),
1812 OPT_Wformat_,
1813 "repeated %s in format", _(s->name));
1815 else
1817 i = strlen (flag_chars);
1818 flag_chars[i++] = *format_chars;
1819 flag_chars[i] = 0;
1821 if (s->skip_next_char)
1823 ++format_chars;
1824 if (*format_chars == 0)
1826 warning_at (format_string_loc, OPT_Wformat_,
1827 "missing fill character at end of strfmon format");
1828 return;
1831 ++format_chars;
1834 /* Read any format width, possibly * or *m$. */
1835 if (fki->width_char != 0)
1837 if (fki->width_type != NULL && *format_chars == '*')
1839 i = strlen (flag_chars);
1840 flag_chars[i++] = fki->width_char;
1841 flag_chars[i] = 0;
1842 /* "...a field width...may be indicated by an asterisk.
1843 In this case, an int argument supplies the field width..." */
1844 ++format_chars;
1845 if (has_operand_number != 0)
1847 int opnum;
1848 opnum = maybe_read_dollar_number (&format_chars,
1849 has_operand_number == 1,
1850 first_fillin_param,
1851 &params, fki);
1852 if (opnum == -1)
1853 return;
1854 else if (opnum > 0)
1856 has_operand_number = 1;
1857 arg_num = opnum + info->first_arg_num - 1;
1859 else
1860 has_operand_number = 0;
1862 else
1864 if (avoid_dollar_number (format_chars))
1865 return;
1867 if (info->first_arg_num != 0)
1869 if (params == 0)
1870 cur_param = NULL;
1871 else
1873 cur_param = TREE_VALUE (params);
1874 if (has_operand_number <= 0)
1876 params = TREE_CHAIN (params);
1877 ++arg_num;
1880 width_wanted_type.wanted_type = *fki->width_type;
1881 width_wanted_type.wanted_type_name = NULL;
1882 width_wanted_type.pointer_count = 0;
1883 width_wanted_type.char_lenient_flag = 0;
1884 width_wanted_type.scalar_identity_flag = 0;
1885 width_wanted_type.writing_in_flag = 0;
1886 width_wanted_type.reading_from_flag = 0;
1887 width_wanted_type.kind = CF_KIND_FIELD_WIDTH;
1888 width_wanted_type.format_start = format_chars - 1;
1889 width_wanted_type.format_length = 1;
1890 width_wanted_type.param = cur_param;
1891 width_wanted_type.arg_num = arg_num;
1892 width_wanted_type.offset_loc =
1893 format_chars - orig_format_chars;
1894 width_wanted_type.next = NULL;
1895 if (last_wanted_type != 0)
1896 last_wanted_type->next = &width_wanted_type;
1897 if (first_wanted_type == 0)
1898 first_wanted_type = &width_wanted_type;
1899 last_wanted_type = &width_wanted_type;
1902 else
1904 /* Possibly read a numeric width. If the width is zero,
1905 we complain if appropriate. */
1906 int non_zero_width_char = FALSE;
1907 int found_width = FALSE;
1908 while (ISDIGIT (*format_chars))
1910 found_width = TRUE;
1911 if (*format_chars != '0')
1912 non_zero_width_char = TRUE;
1913 ++format_chars;
1915 if (found_width && !non_zero_width_char &&
1916 (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
1917 warning_at (format_string_loc, OPT_Wformat_,
1918 "zero width in %s format", fki->name);
1919 if (found_width)
1921 i = strlen (flag_chars);
1922 flag_chars[i++] = fki->width_char;
1923 flag_chars[i] = 0;
1928 /* Read any format left precision (must be a number, not *). */
1929 if (fki->left_precision_char != 0 && *format_chars == '#')
1931 ++format_chars;
1932 i = strlen (flag_chars);
1933 flag_chars[i++] = fki->left_precision_char;
1934 flag_chars[i] = 0;
1935 if (!ISDIGIT (*format_chars))
1936 warning_at (location_from_offset (format_string_loc,
1937 format_chars - orig_format_chars),
1938 OPT_Wformat_,
1939 "empty left precision in %s format", fki->name);
1940 while (ISDIGIT (*format_chars))
1941 ++format_chars;
1944 /* Read any format precision, possibly * or *m$. */
1945 if (fki->precision_char != 0 && *format_chars == '.')
1947 ++format_chars;
1948 i = strlen (flag_chars);
1949 flag_chars[i++] = fki->precision_char;
1950 flag_chars[i] = 0;
1951 if (fki->precision_type != NULL && *format_chars == '*')
1953 /* "...a...precision...may be indicated by an asterisk.
1954 In this case, an int argument supplies the...precision." */
1955 ++format_chars;
1956 if (has_operand_number != 0)
1958 int opnum;
1959 opnum = maybe_read_dollar_number (&format_chars,
1960 has_operand_number == 1,
1961 first_fillin_param,
1962 &params, fki);
1963 if (opnum == -1)
1964 return;
1965 else if (opnum > 0)
1967 has_operand_number = 1;
1968 arg_num = opnum + info->first_arg_num - 1;
1970 else
1971 has_operand_number = 0;
1973 else
1975 if (avoid_dollar_number (format_chars))
1976 return;
1978 if (info->first_arg_num != 0)
1980 if (params == 0)
1981 cur_param = NULL;
1982 else
1984 cur_param = TREE_VALUE (params);
1985 if (has_operand_number <= 0)
1987 params = TREE_CHAIN (params);
1988 ++arg_num;
1991 precision_wanted_type.wanted_type = *fki->precision_type;
1992 precision_wanted_type.wanted_type_name = NULL;
1993 precision_wanted_type.pointer_count = 0;
1994 precision_wanted_type.char_lenient_flag = 0;
1995 precision_wanted_type.scalar_identity_flag = 0;
1996 precision_wanted_type.writing_in_flag = 0;
1997 precision_wanted_type.reading_from_flag = 0;
1998 precision_wanted_type.kind = CF_KIND_FIELD_PRECISION;
1999 precision_wanted_type.param = cur_param;
2000 precision_wanted_type.format_start = format_chars - 2;
2001 precision_wanted_type.format_length = 2;
2002 precision_wanted_type.arg_num = arg_num;
2003 precision_wanted_type.offset_loc =
2004 format_chars - orig_format_chars;
2005 precision_wanted_type.next = NULL;
2006 if (last_wanted_type != 0)
2007 last_wanted_type->next = &precision_wanted_type;
2008 if (first_wanted_type == 0)
2009 first_wanted_type = &precision_wanted_type;
2010 last_wanted_type = &precision_wanted_type;
2013 else
2015 if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
2016 && !ISDIGIT (*format_chars))
2017 warning_at (location_from_offset (format_string_loc,
2018 format_chars - orig_format_chars),
2019 OPT_Wformat_,
2020 "empty precision in %s format", fki->name);
2021 while (ISDIGIT (*format_chars))
2022 ++format_chars;
2026 format_start = format_chars;
2027 if (fki->alloc_char && fki->alloc_char == *format_chars)
2029 i = strlen (flag_chars);
2030 flag_chars[i++] = fki->alloc_char;
2031 flag_chars[i] = 0;
2032 format_chars++;
2035 /* Handle the scanf allocation kludge. */
2036 if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
2038 if (*format_chars == 'a' && !flag_isoc99)
2040 if (format_chars[1] == 's' || format_chars[1] == 'S'
2041 || format_chars[1] == '[')
2043 /* 'a' is used as a flag. */
2044 i = strlen (flag_chars);
2045 flag_chars[i++] = 'a';
2046 flag_chars[i] = 0;
2047 format_chars++;
2052 /* Read any length modifier, if this kind of format has them. */
2053 fli = fki->length_char_specs;
2054 length_chars = NULL;
2055 length_chars_val = FMT_LEN_none;
2056 length_chars_std = STD_C89;
2057 scalar_identity_flag = 0;
2058 if (fli)
2060 while (fli->name != 0
2061 && strncmp (fli->name, format_chars, strlen (fli->name)))
2062 fli++;
2063 if (fli->name != 0)
2065 format_chars += strlen (fli->name);
2066 if (fli->double_name != 0 && fli->name[0] == *format_chars)
2068 format_chars++;
2069 length_chars = fli->double_name;
2070 length_chars_val = fli->double_index;
2071 length_chars_std = fli->double_std;
2073 else
2075 length_chars = fli->name;
2076 length_chars_val = fli->index;
2077 length_chars_std = fli->std;
2078 scalar_identity_flag = fli->scalar_identity_flag;
2080 i = strlen (flag_chars);
2081 flag_chars[i++] = fki->length_code_char;
2082 flag_chars[i] = 0;
2084 if (pedantic)
2086 /* Warn if the length modifier is non-standard. */
2087 if (ADJ_STD (length_chars_std) > C_STD_VER)
2088 warning_at (format_string_loc, OPT_Wformat_,
2089 "%s does not support the %qs %s length modifier",
2090 C_STD_NAME (length_chars_std), length_chars,
2091 fki->name);
2095 /* Read any modifier (strftime E/O). */
2096 if (fki->modifier_chars != NULL)
2098 while (*format_chars != 0
2099 && strchr (fki->modifier_chars, *format_chars) != 0)
2101 if (strchr (flag_chars, *format_chars) != 0)
2103 const format_flag_spec *s = get_flag_spec (flag_specs,
2104 *format_chars, NULL);
2105 warning_at (location_from_offset (format_string_loc,
2106 format_chars
2107 - orig_format_chars),
2108 OPT_Wformat_,
2109 "repeated %s in format", _(s->name));
2111 else
2113 i = strlen (flag_chars);
2114 flag_chars[i++] = *format_chars;
2115 flag_chars[i] = 0;
2117 ++format_chars;
2121 format_char = *format_chars;
2122 if (format_char == 0
2123 || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
2124 && format_char == '%'))
2126 warning_at (location_from_offset (format_string_loc,
2127 format_chars - orig_format_chars),
2128 OPT_Wformat_,
2129 "conversion lacks type at end of format");
2130 continue;
2132 format_chars++;
2133 fci = fki->conversion_specs;
2134 while (fci->format_chars != 0
2135 && strchr (fci->format_chars, format_char) == 0)
2136 ++fci;
2137 if (fci->format_chars == 0)
2139 if (ISGRAPH (format_char))
2140 warning_at (location_from_offset (format_string_loc,
2141 format_chars - orig_format_chars),
2142 OPT_Wformat_,
2143 "unknown conversion type character %qc in format",
2144 format_char);
2145 else
2146 warning_at (location_from_offset (format_string_loc,
2147 format_chars - orig_format_chars),
2148 OPT_Wformat_,
2149 "unknown conversion type character 0x%x in format",
2150 format_char);
2151 continue;
2153 if (pedantic)
2155 if (ADJ_STD (fci->std) > C_STD_VER)
2156 warning_at (location_from_offset (format_string_loc,
2157 format_chars - orig_format_chars),
2158 OPT_Wformat_,
2159 "%s does not support the %<%%%c%> %s format",
2160 C_STD_NAME (fci->std), format_char, fki->name);
2163 /* Validate the individual flags used, removing any that are invalid. */
2165 int d = 0;
2166 for (i = 0; flag_chars[i] != 0; i++)
2168 const format_flag_spec *s = get_flag_spec (flag_specs,
2169 flag_chars[i], NULL);
2170 flag_chars[i - d] = flag_chars[i];
2171 if (flag_chars[i] == fki->length_code_char)
2172 continue;
2173 if (strchr (fci->flag_chars, flag_chars[i]) == 0)
2175 warning_at (location_from_offset (format_string_loc,
2176 format_chars
2177 - orig_format_chars),
2178 OPT_Wformat_, "%s used with %<%%%c%> %s format",
2179 _(s->name), format_char, fki->name);
2180 d++;
2181 continue;
2183 if (pedantic)
2185 const format_flag_spec *t;
2186 if (ADJ_STD (s->std) > C_STD_VER)
2187 warning_at (format_string_loc, OPT_Wformat_,
2188 "%s does not support %s",
2189 C_STD_NAME (s->std), _(s->long_name));
2190 t = get_flag_spec (flag_specs, flag_chars[i], fci->flags2);
2191 if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
2193 const char *long_name = (t->long_name != NULL
2194 ? t->long_name
2195 : s->long_name);
2196 if (ADJ_STD (t->std) > C_STD_VER)
2197 warning_at (format_string_loc, OPT_Wformat_,
2198 "%s does not support %s with the %<%%%c%> %s format",
2199 C_STD_NAME (t->std), _(long_name),
2200 format_char, fki->name);
2204 flag_chars[i - d] = 0;
2207 if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
2208 && strchr (flag_chars, 'a') != 0)
2209 alloc_flag = 1;
2210 if (fki->alloc_char && strchr (flag_chars, fki->alloc_char) != 0)
2211 alloc_flag = 1;
2213 if (fki->suppression_char
2214 && strchr (flag_chars, fki->suppression_char) != 0)
2215 suppressed = 1;
2217 /* Validate the pairs of flags used. */
2218 for (i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
2220 const format_flag_spec *s, *t;
2221 if (strchr (flag_chars, bad_flag_pairs[i].flag_char1) == 0)
2222 continue;
2223 if (strchr (flag_chars, bad_flag_pairs[i].flag_char2) == 0)
2224 continue;
2225 if (bad_flag_pairs[i].predicate != 0
2226 && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
2227 continue;
2228 s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
2229 t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
2230 if (bad_flag_pairs[i].ignored)
2232 if (bad_flag_pairs[i].predicate != 0)
2233 warning_at (format_string_loc, OPT_Wformat_,
2234 "%s ignored with %s and %<%%%c%> %s format",
2235 _(s->name), _(t->name), format_char,
2236 fki->name);
2237 else
2238 warning_at (format_string_loc, OPT_Wformat_,
2239 "%s ignored with %s in %s format",
2240 _(s->name), _(t->name), fki->name);
2242 else
2244 if (bad_flag_pairs[i].predicate != 0)
2245 warning_at (format_string_loc, OPT_Wformat_,
2246 "use of %s and %s together with %<%%%c%> %s format",
2247 _(s->name), _(t->name), format_char,
2248 fki->name);
2249 else
2250 warning_at (format_string_loc, OPT_Wformat_,
2251 "use of %s and %s together in %s format",
2252 _(s->name), _(t->name), fki->name);
2256 /* Give Y2K warnings. */
2257 if (warn_format_y2k)
2259 int y2k_level = 0;
2260 if (strchr (fci->flags2, '4') != 0)
2261 if (strchr (flag_chars, 'E') != 0)
2262 y2k_level = 3;
2263 else
2264 y2k_level = 2;
2265 else if (strchr (fci->flags2, '3') != 0)
2266 y2k_level = 3;
2267 else if (strchr (fci->flags2, '2') != 0)
2268 y2k_level = 2;
2269 if (y2k_level == 3)
2270 warning_at (format_string_loc, OPT_Wformat_y2k,
2271 "%<%%%c%> yields only last 2 digits of "
2272 "year in some locales", format_char);
2273 else if (y2k_level == 2)
2274 warning_at (format_string_loc, OPT_Wformat_y2k,
2275 "%<%%%c%> yields only last 2 digits of year",
2276 format_char);
2279 if (strchr (fci->flags2, '[') != 0)
2281 /* Skip over scan set, in case it happens to have '%' in it. */
2282 if (*format_chars == '^')
2283 ++format_chars;
2284 /* Find closing bracket; if one is hit immediately, then
2285 it's part of the scan set rather than a terminator. */
2286 if (*format_chars == ']')
2287 ++format_chars;
2288 while (*format_chars && *format_chars != ']')
2289 ++format_chars;
2290 if (*format_chars != ']')
2291 /* The end of the format string was reached. */
2292 warning_at (location_from_offset (format_string_loc,
2293 format_chars - orig_format_chars),
2294 OPT_Wformat_,
2295 "no closing %<]%> for %<%%[%> format");
2298 wanted_type = 0;
2299 wanted_type_name = 0;
2300 if (fki->flags & (int) FMT_FLAG_ARG_CONVERT)
2302 wanted_type = (fci->types[length_chars_val].type
2303 ? *fci->types[length_chars_val].type : 0);
2304 wanted_type_name = fci->types[length_chars_val].name;
2305 wanted_type_std = fci->types[length_chars_val].std;
2306 if (wanted_type == 0)
2308 warning_at (location_from_offset (format_string_loc,
2309 format_chars - orig_format_chars),
2310 OPT_Wformat_,
2311 "use of %qs length modifier with %qc type character"
2312 " has either no effect or undefined behavior",
2313 length_chars, format_char);
2314 /* Heuristic: skip one argument when an invalid length/type
2315 combination is encountered. */
2316 arg_num++;
2317 if (params != 0)
2318 params = TREE_CHAIN (params);
2319 continue;
2321 else if (pedantic
2322 /* Warn if non-standard, provided it is more non-standard
2323 than the length and type characters that may already
2324 have been warned for. */
2325 && ADJ_STD (wanted_type_std) > ADJ_STD (length_chars_std)
2326 && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
2328 if (ADJ_STD (wanted_type_std) > C_STD_VER)
2329 warning_at (location_from_offset (format_string_loc,
2330 format_chars - orig_format_chars),
2331 OPT_Wformat_,
2332 "%s does not support the %<%%%s%c%> %s format",
2333 C_STD_NAME (wanted_type_std), length_chars,
2334 format_char, fki->name);
2338 main_wanted_type.next = NULL;
2340 /* Finally. . .check type of argument against desired type! */
2341 if (info->first_arg_num == 0)
2342 continue;
2343 if ((fci->pointer_count == 0 && wanted_type == void_type_node)
2344 || suppressed)
2346 if (main_arg_num != 0)
2348 if (suppressed)
2349 warning_at (format_string_loc, OPT_Wformat_,
2350 "operand number specified with "
2351 "suppressed assignment");
2352 else
2353 warning_at (format_string_loc, OPT_Wformat_,
2354 "operand number specified for format "
2355 "taking no argument");
2358 else
2360 format_wanted_type *wanted_type_ptr;
2362 if (main_arg_num != 0)
2364 arg_num = main_arg_num;
2365 params = main_arg_params;
2367 else
2369 ++arg_num;
2370 if (has_operand_number > 0)
2372 warning_at (format_string_loc, OPT_Wformat_,
2373 "missing $ operand number in format");
2374 return;
2376 else
2377 has_operand_number = 0;
2380 wanted_type_ptr = &main_wanted_type;
2381 while (fci)
2383 if (params == 0)
2384 cur_param = NULL;
2385 else
2387 cur_param = TREE_VALUE (params);
2388 params = TREE_CHAIN (params);
2391 wanted_type_ptr->wanted_type = wanted_type;
2392 wanted_type_ptr->wanted_type_name = wanted_type_name;
2393 wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag;
2394 wanted_type_ptr->char_lenient_flag = 0;
2395 if (strchr (fci->flags2, 'c') != 0)
2396 wanted_type_ptr->char_lenient_flag = 1;
2397 wanted_type_ptr->scalar_identity_flag = 0;
2398 if (scalar_identity_flag)
2399 wanted_type_ptr->scalar_identity_flag = 1;
2400 wanted_type_ptr->writing_in_flag = 0;
2401 wanted_type_ptr->reading_from_flag = 0;
2402 if (alloc_flag)
2403 wanted_type_ptr->writing_in_flag = 1;
2404 else
2406 if (strchr (fci->flags2, 'W') != 0)
2407 wanted_type_ptr->writing_in_flag = 1;
2408 if (strchr (fci->flags2, 'R') != 0)
2409 wanted_type_ptr->reading_from_flag = 1;
2411 wanted_type_ptr->kind = CF_KIND_FORMAT;
2412 wanted_type_ptr->param = cur_param;
2413 wanted_type_ptr->arg_num = arg_num;
2414 wanted_type_ptr->format_start = format_start;
2415 wanted_type_ptr->format_length = format_chars - format_start;
2416 wanted_type_ptr->offset_loc = format_chars - orig_format_chars;
2417 wanted_type_ptr->next = NULL;
2418 if (last_wanted_type != 0)
2419 last_wanted_type->next = wanted_type_ptr;
2420 if (first_wanted_type == 0)
2421 first_wanted_type = wanted_type_ptr;
2422 last_wanted_type = wanted_type_ptr;
2424 fci = fci->chain;
2425 if (fci)
2427 wanted_type_ptr = (format_wanted_type *)
2428 pool_alloc (fwt_pool);
2429 arg_num++;
2430 wanted_type = *fci->types[length_chars_val].type;
2431 wanted_type_name = fci->types[length_chars_val].name;
2436 if (first_wanted_type != 0)
2437 check_format_types (format_string_loc, first_wanted_type);
2440 if (format_chars - orig_format_chars != format_length)
2441 warning_at (location_from_offset (format_string_loc,
2442 format_chars + 1 - orig_format_chars),
2443 OPT_Wformat_contains_nul,
2444 "embedded %<\\0%> in format");
2445 if (info->first_arg_num != 0 && params != 0
2446 && has_operand_number <= 0)
2448 res->number_other--;
2449 res->number_extra_args++;
2451 if (has_operand_number > 0)
2452 finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
2456 /* Check the argument types from a single format conversion (possibly
2457 including width and precision arguments). LOC is the location of
2458 the format string. */
2459 static void
2460 check_format_types (location_t loc, format_wanted_type *types)
2462 for (; types != 0; types = types->next)
2464 tree cur_param;
2465 tree cur_type;
2466 tree orig_cur_type;
2467 tree wanted_type;
2468 int arg_num;
2469 int i;
2470 int char_type_flag;
2472 wanted_type = types->wanted_type;
2473 arg_num = types->arg_num;
2475 /* The following should not occur here. */
2476 gcc_assert (wanted_type);
2477 gcc_assert (wanted_type != void_type_node || types->pointer_count);
2479 if (types->pointer_count == 0)
2480 wanted_type = lang_hooks.types.type_promotes_to (wanted_type);
2482 wanted_type = TYPE_MAIN_VARIANT (wanted_type);
2484 cur_param = types->param;
2485 if (!cur_param)
2487 format_type_warning (loc, types, wanted_type, NULL);
2488 continue;
2491 cur_type = TREE_TYPE (cur_param);
2492 if (cur_type == error_mark_node)
2493 continue;
2494 orig_cur_type = cur_type;
2495 char_type_flag = 0;
2497 STRIP_NOPS (cur_param);
2499 /* Check the types of any additional pointer arguments
2500 that precede the "real" argument. */
2501 for (i = 0; i < types->pointer_count; ++i)
2503 if (TREE_CODE (cur_type) == POINTER_TYPE)
2505 cur_type = TREE_TYPE (cur_type);
2506 if (cur_type == error_mark_node)
2507 break;
2509 /* Check for writing through a NULL pointer. */
2510 if (types->writing_in_flag
2511 && i == 0
2512 && cur_param != 0
2513 && integer_zerop (cur_param))
2514 warning (OPT_Wformat_, "writing through null pointer "
2515 "(argument %d)", arg_num);
2517 /* Check for reading through a NULL pointer. */
2518 if (types->reading_from_flag
2519 && i == 0
2520 && cur_param != 0
2521 && integer_zerop (cur_param))
2522 warning (OPT_Wformat_, "reading through null pointer "
2523 "(argument %d)", arg_num);
2525 if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
2526 cur_param = TREE_OPERAND (cur_param, 0);
2527 else
2528 cur_param = 0;
2530 /* See if this is an attempt to write into a const type with
2531 scanf or with printf "%n". Note: the writing in happens
2532 at the first indirection only, if for example
2533 void * const * is passed to scanf %p; passing
2534 const void ** is simply passing an incompatible type. */
2535 if (types->writing_in_flag
2536 && i == 0
2537 && (TYPE_READONLY (cur_type)
2538 || (cur_param != 0
2539 && (CONSTANT_CLASS_P (cur_param)
2540 || (DECL_P (cur_param)
2541 && TREE_READONLY (cur_param))))))
2542 warning (OPT_Wformat_, "writing into constant object "
2543 "(argument %d)", arg_num);
2545 /* If there are extra type qualifiers beyond the first
2546 indirection, then this makes the types technically
2547 incompatible. */
2548 if (i > 0
2549 && pedantic
2550 && (TYPE_READONLY (cur_type)
2551 || TYPE_VOLATILE (cur_type)
2552 || TYPE_ATOMIC (cur_type)
2553 || TYPE_RESTRICT (cur_type)))
2554 warning (OPT_Wformat_, "extra type qualifiers in format "
2555 "argument (argument %d)",
2556 arg_num);
2559 else
2561 format_type_warning (loc, types, wanted_type, orig_cur_type);
2562 break;
2566 if (i < types->pointer_count)
2567 continue;
2569 cur_type = TYPE_MAIN_VARIANT (cur_type);
2571 /* Check whether the argument type is a character type. This leniency
2572 only applies to certain formats, flagged with 'c'. */
2573 if (types->char_lenient_flag)
2574 char_type_flag = (cur_type == char_type_node
2575 || cur_type == signed_char_type_node
2576 || cur_type == unsigned_char_type_node);
2578 /* Check the type of the "real" argument, if there's a type we want. */
2579 if (lang_hooks.types_compatible_p (wanted_type, cur_type))
2580 continue;
2581 /* If we want 'void *', allow any pointer type.
2582 (Anything else would already have got a warning.)
2583 With -Wpedantic, only allow pointers to void and to character
2584 types. */
2585 if (wanted_type == void_type_node
2586 && (!pedantic || (i == 1 && char_type_flag)))
2587 continue;
2588 /* Don't warn about differences merely in signedness, unless
2589 -Wpedantic. With -Wpedantic, warn if the type is a pointer
2590 target and not a character type, and for character types at
2591 a second level of indirection. */
2592 if (TREE_CODE (wanted_type) == INTEGER_TYPE
2593 && TREE_CODE (cur_type) == INTEGER_TYPE
2594 && ((!pedantic && !warn_format_signedness)
2595 || (i == 0 && !warn_format_signedness)
2596 || (i == 1 && char_type_flag))
2597 && (TYPE_UNSIGNED (wanted_type)
2598 ? wanted_type == c_common_unsigned_type (cur_type)
2599 : wanted_type == c_common_signed_type (cur_type)))
2600 continue;
2601 /* Don't warn about differences merely in signedness if we know
2602 that the current type is integer-promoted and its original type
2603 was unsigned such as that it is in the range of WANTED_TYPE. */
2604 if (TREE_CODE (wanted_type) == INTEGER_TYPE
2605 && TREE_CODE (cur_type) == INTEGER_TYPE
2606 && warn_format_signedness
2607 && TYPE_UNSIGNED (wanted_type)
2608 && cur_param != NULL_TREE
2609 && TREE_CODE (cur_param) == NOP_EXPR)
2611 tree t = TREE_TYPE (TREE_OPERAND (cur_param, 0));
2612 if (TYPE_UNSIGNED (t)
2613 && cur_type == lang_hooks.types.type_promotes_to (t))
2614 continue;
2616 /* Likewise, "signed char", "unsigned char" and "char" are
2617 equivalent but the above test won't consider them equivalent. */
2618 if (wanted_type == char_type_node
2619 && (!pedantic || i < 2)
2620 && char_type_flag)
2621 continue;
2622 if (types->scalar_identity_flag
2623 && (TREE_CODE (cur_type) == TREE_CODE (wanted_type)
2624 || (INTEGRAL_TYPE_P (cur_type)
2625 && INTEGRAL_TYPE_P (wanted_type)))
2626 && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type))
2627 continue;
2628 /* Now we have a type mismatch. */
2629 format_type_warning (loc, types, wanted_type, orig_cur_type);
2634 /* Give a warning at LOC about a format argument of different type from that
2635 expected. WANTED_TYPE is the type the argument should have, possibly
2636 stripped of pointer dereferences. The description (such as "field
2637 precision"), the placement in the format string, a possibly more
2638 friendly name of WANTED_TYPE, and the number of pointer dereferences
2639 are taken from TYPE. ARG_TYPE is the type of the actual argument,
2640 or NULL if it is missing. */
2641 static void
2642 format_type_warning (location_t loc, format_wanted_type *type,
2643 tree wanted_type, tree arg_type)
2645 int kind = type->kind;
2646 const char *wanted_type_name = type->wanted_type_name;
2647 const char *format_start = type->format_start;
2648 int format_length = type->format_length;
2649 int pointer_count = type->pointer_count;
2650 int arg_num = type->arg_num;
2651 unsigned int offset_loc = type->offset_loc;
2653 char *p;
2654 /* If ARG_TYPE is a typedef with a misleading name (for example,
2655 size_t but not the standard size_t expected by printf %zu), avoid
2656 printing the typedef name. */
2657 if (wanted_type_name
2658 && arg_type
2659 && TYPE_NAME (arg_type)
2660 && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL
2661 && DECL_NAME (TYPE_NAME (arg_type))
2662 && !strcmp (wanted_type_name,
2663 lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2)))
2664 arg_type = TYPE_MAIN_VARIANT (arg_type);
2665 /* The format type and name exclude any '*' for pointers, so those
2666 must be formatted manually. For all the types we currently have,
2667 this is adequate, but formats taking pointers to functions or
2668 arrays would require the full type to be built up in order to
2669 print it with %T. */
2670 p = (char *) alloca (pointer_count + 2);
2671 if (pointer_count == 0)
2672 p[0] = 0;
2673 else if (c_dialect_cxx ())
2675 memset (p, '*', pointer_count);
2676 p[pointer_count] = 0;
2678 else
2680 p[0] = ' ';
2681 memset (p + 1, '*', pointer_count);
2682 p[pointer_count + 1] = 0;
2685 loc = location_from_offset (loc, offset_loc);
2687 if (wanted_type_name)
2689 if (arg_type)
2690 warning_at (loc, OPT_Wformat_,
2691 "%s %<%s%.*s%> expects argument of type %<%s%s%>, "
2692 "but argument %d has type %qT",
2693 gettext (kind_descriptions[kind]),
2694 (kind == CF_KIND_FORMAT ? "%" : ""),
2695 format_length, format_start,
2696 wanted_type_name, p, arg_num, arg_type);
2697 else
2698 warning_at (loc, OPT_Wformat_,
2699 "%s %<%s%.*s%> expects a matching %<%s%s%> argument",
2700 gettext (kind_descriptions[kind]),
2701 (kind == CF_KIND_FORMAT ? "%" : ""),
2702 format_length, format_start, wanted_type_name, p);
2704 else
2706 if (arg_type)
2707 warning_at (loc, OPT_Wformat_,
2708 "%s %<%s%.*s%> expects argument of type %<%T%s%>, "
2709 "but argument %d has type %qT",
2710 gettext (kind_descriptions[kind]),
2711 (kind == CF_KIND_FORMAT ? "%" : ""),
2712 format_length, format_start,
2713 wanted_type, p, arg_num, arg_type);
2714 else
2715 warning_at (loc, OPT_Wformat_,
2716 "%s %<%s%.*s%> expects a matching %<%T%s%> argument",
2717 gettext (kind_descriptions[kind]),
2718 (kind == CF_KIND_FORMAT ? "%" : ""),
2719 format_length, format_start, wanted_type, p);
2724 /* Given a format_char_info array FCI, and a character C, this function
2725 returns the index into the conversion_specs where that specifier's
2726 data is located. The character must exist. */
2727 static unsigned int
2728 find_char_info_specifier_index (const format_char_info *fci, int c)
2730 unsigned i;
2732 for (i = 0; fci->format_chars; i++, fci++)
2733 if (strchr (fci->format_chars, c))
2734 return i;
2736 /* We shouldn't be looking for a non-existent specifier. */
2737 gcc_unreachable ();
2740 /* Given a format_length_info array FLI, and a character C, this
2741 function returns the index into the conversion_specs where that
2742 modifier's data is located. The character must exist. */
2743 static unsigned int
2744 find_length_info_modifier_index (const format_length_info *fli, int c)
2746 unsigned i;
2748 for (i = 0; fli->name; i++, fli++)
2749 if (strchr (fli->name, c))
2750 return i;
2752 /* We shouldn't be looking for a non-existent modifier. */
2753 gcc_unreachable ();
2756 /* Determine the type of HOST_WIDE_INT in the code being compiled for
2757 use in GCC's __asm_fprintf__ custom format attribute. You must
2758 have set dynamic_format_types before calling this function. */
2759 static void
2760 init_dynamic_asm_fprintf_info (void)
2762 static tree hwi;
2764 if (!hwi)
2766 format_length_info *new_asm_fprintf_length_specs;
2767 unsigned int i;
2769 /* Find the underlying type for HOST_WIDE_INT. For the %w
2770 length modifier to work, one must have issued: "typedef
2771 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2772 prior to using that modifier. */
2773 hwi = maybe_get_identifier ("__gcc_host_wide_int__");
2774 if (!hwi)
2776 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2777 return;
2779 hwi = identifier_global_value (hwi);
2780 if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
2782 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2783 return;
2785 hwi = DECL_ORIGINAL_TYPE (hwi);
2786 gcc_assert (hwi);
2787 if (hwi != long_integer_type_node && hwi != long_long_integer_type_node)
2789 error ("%<__gcc_host_wide_int__%> is not defined as %<long%>"
2790 " or %<long long%>");
2791 return;
2794 /* Create a new (writable) copy of asm_fprintf_length_specs. */
2795 new_asm_fprintf_length_specs = (format_length_info *)
2796 xmemdup (asm_fprintf_length_specs,
2797 sizeof (asm_fprintf_length_specs),
2798 sizeof (asm_fprintf_length_specs));
2800 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
2801 i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
2802 if (hwi == long_integer_type_node)
2803 new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
2804 else if (hwi == long_long_integer_type_node)
2805 new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
2806 else
2807 gcc_unreachable ();
2809 /* Assign the new data for use. */
2810 dynamic_format_types[asm_fprintf_format_type].length_char_specs =
2811 new_asm_fprintf_length_specs;
2815 /* Determine the type of a "locus" in the code being compiled for use
2816 in GCC's __gcc_gfc__ custom format attribute. You must have set
2817 dynamic_format_types before calling this function. */
2818 static void
2819 init_dynamic_gfc_info (void)
2821 static tree locus;
2823 if (!locus)
2825 static format_char_info *gfc_fci;
2827 /* For the GCC __gcc_gfc__ custom format specifier to work, one
2828 must have declared 'locus' prior to using this attribute. If
2829 we haven't seen this declarations then you shouldn't use the
2830 specifier requiring that type. */
2831 if ((locus = maybe_get_identifier ("locus")))
2833 locus = identifier_global_value (locus);
2834 if (locus)
2836 if (TREE_CODE (locus) != TYPE_DECL
2837 || TREE_TYPE (locus) == error_mark_node)
2839 error ("%<locus%> is not defined as a type");
2840 locus = 0;
2842 else
2843 locus = TREE_TYPE (locus);
2847 /* Assign the new data for use. */
2849 /* Handle the __gcc_gfc__ format specifics. */
2850 if (!gfc_fci)
2851 dynamic_format_types[gcc_gfc_format_type].conversion_specs =
2852 gfc_fci = (format_char_info *)
2853 xmemdup (gcc_gfc_char_table,
2854 sizeof (gcc_gfc_char_table),
2855 sizeof (gcc_gfc_char_table));
2856 if (locus)
2858 const unsigned i = find_char_info_specifier_index (gfc_fci, 'L');
2859 gfc_fci[i].types[0].type = &locus;
2860 gfc_fci[i].pointer_count = 1;
2865 /* Determine the types of "tree" and "location_t" in the code being
2866 compiled for use in GCC's diagnostic custom format attributes. You
2867 must have set dynamic_format_types before calling this function. */
2868 static void
2869 init_dynamic_diag_info (void)
2871 static tree t, loc, hwi;
2873 if (!loc || !t || !hwi)
2875 static format_char_info *diag_fci, *tdiag_fci, *cdiag_fci, *cxxdiag_fci;
2876 static format_length_info *diag_ls;
2877 unsigned int i;
2879 /* For the GCC-diagnostics custom format specifiers to work, one
2880 must have declared 'tree' and/or 'location_t' prior to using
2881 those attributes. If we haven't seen these declarations then
2882 you shouldn't use the specifiers requiring these types.
2883 However we don't force a hard ICE because we may see only one
2884 or the other type. */
2885 if ((loc = maybe_get_identifier ("location_t")))
2887 loc = identifier_global_value (loc);
2888 if (loc)
2890 if (TREE_CODE (loc) != TYPE_DECL)
2892 error ("%<location_t%> is not defined as a type");
2893 loc = 0;
2895 else
2896 loc = TREE_TYPE (loc);
2900 /* We need to grab the underlying 'union tree_node' so peek into
2901 an extra type level. */
2902 if ((t = maybe_get_identifier ("tree")))
2904 t = identifier_global_value (t);
2905 if (t)
2907 if (TREE_CODE (t) != TYPE_DECL)
2909 error ("%<tree%> is not defined as a type");
2910 t = 0;
2912 else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
2914 error ("%<tree%> is not defined as a pointer type");
2915 t = 0;
2917 else
2918 t = TREE_TYPE (TREE_TYPE (t));
2922 /* Find the underlying type for HOST_WIDE_INT. For the %w
2923 length modifier to work, one must have issued: "typedef
2924 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
2925 prior to using that modifier. */
2926 if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
2928 hwi = identifier_global_value (hwi);
2929 if (hwi)
2931 if (TREE_CODE (hwi) != TYPE_DECL)
2933 error ("%<__gcc_host_wide_int__%> is not defined as a type");
2934 hwi = 0;
2936 else
2938 hwi = DECL_ORIGINAL_TYPE (hwi);
2939 gcc_assert (hwi);
2940 if (hwi != long_integer_type_node
2941 && hwi != long_long_integer_type_node)
2943 error ("%<__gcc_host_wide_int__%> is not defined"
2944 " as %<long%> or %<long long%>");
2945 hwi = 0;
2951 /* Assign the new data for use. */
2953 /* All the GCC diag formats use the same length specs. */
2954 if (!diag_ls)
2955 dynamic_format_types[gcc_diag_format_type].length_char_specs =
2956 dynamic_format_types[gcc_tdiag_format_type].length_char_specs =
2957 dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
2958 dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
2959 diag_ls = (format_length_info *)
2960 xmemdup (gcc_diag_length_specs,
2961 sizeof (gcc_diag_length_specs),
2962 sizeof (gcc_diag_length_specs));
2963 if (hwi)
2965 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
2966 i = find_length_info_modifier_index (diag_ls, 'w');
2967 if (hwi == long_integer_type_node)
2968 diag_ls[i].index = FMT_LEN_l;
2969 else if (hwi == long_long_integer_type_node)
2970 diag_ls[i].index = FMT_LEN_ll;
2971 else
2972 gcc_unreachable ();
2975 /* Handle the __gcc_diag__ format specifics. */
2976 if (!diag_fci)
2977 dynamic_format_types[gcc_diag_format_type].conversion_specs =
2978 diag_fci = (format_char_info *)
2979 xmemdup (gcc_diag_char_table,
2980 sizeof (gcc_diag_char_table),
2981 sizeof (gcc_diag_char_table));
2982 if (t)
2984 i = find_char_info_specifier_index (diag_fci, 'K');
2985 diag_fci[i].types[0].type = &t;
2986 diag_fci[i].pointer_count = 1;
2989 /* Handle the __gcc_tdiag__ format specifics. */
2990 if (!tdiag_fci)
2991 dynamic_format_types[gcc_tdiag_format_type].conversion_specs =
2992 tdiag_fci = (format_char_info *)
2993 xmemdup (gcc_tdiag_char_table,
2994 sizeof (gcc_tdiag_char_table),
2995 sizeof (gcc_tdiag_char_table));
2996 if (t)
2998 /* All specifiers taking a tree share the same struct. */
2999 i = find_char_info_specifier_index (tdiag_fci, 'D');
3000 tdiag_fci[i].types[0].type = &t;
3001 tdiag_fci[i].pointer_count = 1;
3002 i = find_char_info_specifier_index (tdiag_fci, 'K');
3003 tdiag_fci[i].types[0].type = &t;
3004 tdiag_fci[i].pointer_count = 1;
3007 /* Handle the __gcc_cdiag__ format specifics. */
3008 if (!cdiag_fci)
3009 dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
3010 cdiag_fci = (format_char_info *)
3011 xmemdup (gcc_cdiag_char_table,
3012 sizeof (gcc_cdiag_char_table),
3013 sizeof (gcc_cdiag_char_table));
3014 if (t)
3016 /* All specifiers taking a tree share the same struct. */
3017 i = find_char_info_specifier_index (cdiag_fci, 'D');
3018 cdiag_fci[i].types[0].type = &t;
3019 cdiag_fci[i].pointer_count = 1;
3020 i = find_char_info_specifier_index (cdiag_fci, 'K');
3021 cdiag_fci[i].types[0].type = &t;
3022 cdiag_fci[i].pointer_count = 1;
3025 /* Handle the __gcc_cxxdiag__ format specifics. */
3026 if (!cxxdiag_fci)
3027 dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
3028 cxxdiag_fci = (format_char_info *)
3029 xmemdup (gcc_cxxdiag_char_table,
3030 sizeof (gcc_cxxdiag_char_table),
3031 sizeof (gcc_cxxdiag_char_table));
3032 if (t)
3034 /* All specifiers taking a tree share the same struct. */
3035 i = find_char_info_specifier_index (cxxdiag_fci, 'D');
3036 cxxdiag_fci[i].types[0].type = &t;
3037 cxxdiag_fci[i].pointer_count = 1;
3038 i = find_char_info_specifier_index (cxxdiag_fci, 'K');
3039 cxxdiag_fci[i].types[0].type = &t;
3040 cxxdiag_fci[i].pointer_count = 1;
3045 #ifdef TARGET_FORMAT_TYPES
3046 extern const format_kind_info TARGET_FORMAT_TYPES[];
3047 #endif
3049 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
3050 extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[];
3051 #endif
3052 #ifdef TARGET_OVERRIDES_FORMAT_INIT
3053 extern void TARGET_OVERRIDES_FORMAT_INIT (void);
3054 #endif
3056 /* Attributes such as "printf" are equivalent to those such as
3057 "gnu_printf" unless this is overridden by a target. */
3058 static const target_ovr_attr gnu_target_overrides_format_attributes[] =
3060 { "gnu_printf", "printf" },
3061 { "gnu_scanf", "scanf" },
3062 { "gnu_strftime", "strftime" },
3063 { "gnu_strfmon", "strfmon" },
3064 { NULL, NULL }
3067 /* Translate to unified attribute name. This is used in decode_format_type and
3068 decode_format_attr. In attr_name the user specified argument is passed. It
3069 returns the unified format name from TARGET_OVERRIDES_FORMAT_ATTRIBUTES
3070 or the attr_name passed to this function, if there is no matching entry. */
3071 static const char *
3072 convert_format_name_to_system_name (const char *attr_name)
3074 int i;
3076 if (attr_name == NULL || *attr_name == 0
3077 || strncmp (attr_name, "gcc_", 4) == 0)
3078 return attr_name;
3079 #ifdef TARGET_OVERRIDES_FORMAT_INIT
3080 TARGET_OVERRIDES_FORMAT_INIT ();
3081 #endif
3083 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
3084 /* Check if format attribute is overridden by target. */
3085 if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL
3086 && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0)
3088 for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i)
3090 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src,
3091 attr_name))
3092 return attr_name;
3093 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_dst,
3094 attr_name))
3095 return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src;
3098 #endif
3099 /* Otherwise default to gnu format. */
3100 for (i = 0;
3101 gnu_target_overrides_format_attributes[i].named_attr_src != NULL;
3102 ++i)
3104 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_src,
3105 attr_name))
3106 return attr_name;
3107 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_dst,
3108 attr_name))
3109 return gnu_target_overrides_format_attributes[i].named_attr_src;
3112 return attr_name;
3115 /* Return true if TATTR_NAME and ATTR_NAME are the same format attribute,
3116 counting "name" and "__name__" as the same, false otherwise. */
3117 static bool
3118 cmp_attribs (const char *tattr_name, const char *attr_name)
3120 int alen = strlen (attr_name);
3121 int slen = (tattr_name ? strlen (tattr_name) : 0);
3122 if (alen > 4 && attr_name[0] == '_' && attr_name[1] == '_'
3123 && attr_name[alen - 1] == '_' && attr_name[alen - 2] == '_')
3125 attr_name += 2;
3126 alen -= 4;
3128 if (alen != slen || strncmp (tattr_name, attr_name, alen) != 0)
3129 return false;
3130 return true;
3133 /* Handle a "format" attribute; arguments as in
3134 struct attribute_spec.handler. */
3135 tree
3136 handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args,
3137 int flags, bool *no_add_attrs)
3139 tree type = *node;
3140 function_format_info info;
3142 #ifdef TARGET_FORMAT_TYPES
3143 /* If the target provides additional format types, we need to
3144 add them to FORMAT_TYPES at first use. */
3145 if (TARGET_FORMAT_TYPES != NULL && !dynamic_format_types)
3147 dynamic_format_types = XNEWVEC (format_kind_info,
3148 n_format_types + TARGET_N_FORMAT_TYPES);
3149 memcpy (dynamic_format_types, format_types_orig,
3150 sizeof (format_types_orig));
3151 memcpy (&dynamic_format_types[n_format_types], TARGET_FORMAT_TYPES,
3152 TARGET_N_FORMAT_TYPES * sizeof (dynamic_format_types[0]));
3154 format_types = dynamic_format_types;
3155 /* Provide a reference for the first potential external type. */
3156 first_target_format_type = n_format_types;
3157 n_format_types += TARGET_N_FORMAT_TYPES;
3159 #endif
3161 if (!decode_format_attr (args, &info, 0))
3163 *no_add_attrs = true;
3164 return NULL_TREE;
3167 if (prototype_p (type))
3169 if (!check_format_string (type, info.format_num, flags,
3170 no_add_attrs, info.format_type))
3171 return NULL_TREE;
3173 if (info.first_arg_num != 0)
3175 unsigned HOST_WIDE_INT arg_num = 1;
3176 function_args_iterator iter;
3177 tree arg_type;
3179 /* Verify that first_arg_num points to the last arg,
3180 the ... */
3181 FOREACH_FUNCTION_ARGS (type, arg_type, iter)
3182 arg_num++;
3184 if (arg_num != info.first_arg_num)
3186 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
3187 error ("args to be formatted is not %<...%>");
3188 *no_add_attrs = true;
3189 return NULL_TREE;
3194 /* Check if this is a strftime variant. Just for this variant
3195 FMT_FLAG_ARG_CONVERT is not set. */
3196 if ((format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT) == 0
3197 && info.first_arg_num != 0)
3199 error ("strftime formats cannot format arguments");
3200 *no_add_attrs = true;
3201 return NULL_TREE;
3204 /* If this is a custom GCC-internal format type, we have to
3205 initialize certain bits at runtime. */
3206 if (info.format_type == asm_fprintf_format_type
3207 || info.format_type == gcc_gfc_format_type
3208 || info.format_type == gcc_diag_format_type
3209 || info.format_type == gcc_tdiag_format_type
3210 || info.format_type == gcc_cdiag_format_type
3211 || info.format_type == gcc_cxxdiag_format_type)
3213 /* Our first time through, we have to make sure that our
3214 format_type data is allocated dynamically and is modifiable. */
3215 if (!dynamic_format_types)
3216 format_types = dynamic_format_types = (format_kind_info *)
3217 xmemdup (format_types_orig, sizeof (format_types_orig),
3218 sizeof (format_types_orig));
3220 /* If this is format __asm_fprintf__, we have to initialize
3221 GCC's notion of HOST_WIDE_INT for checking %wd. */
3222 if (info.format_type == asm_fprintf_format_type)
3223 init_dynamic_asm_fprintf_info ();
3224 /* If this is format __gcc_gfc__, we have to initialize GCC's
3225 notion of 'locus' at runtime for %L. */
3226 else if (info.format_type == gcc_gfc_format_type)
3227 init_dynamic_gfc_info ();
3228 /* If this is one of the diagnostic attributes, then we have to
3229 initialize 'location_t' and 'tree' at runtime. */
3230 else if (info.format_type == gcc_diag_format_type
3231 || info.format_type == gcc_tdiag_format_type
3232 || info.format_type == gcc_cdiag_format_type
3233 || info.format_type == gcc_cxxdiag_format_type)
3234 init_dynamic_diag_info ();
3235 else
3236 gcc_unreachable ();
3239 return NULL_TREE;