2017-03-17 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / c-family / c-format.c
blob400eb666d51d5297fe5a6de20f8aeb1e2e42d678
1 /* Check calls to formatted I/O functions (-Wformat).
2 Copyright (C) 1992-2017 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 "c-target.h"
25 #include "c-common.h"
26 #include "alloc-pool.h"
27 #include "stringpool.h"
28 #include "c-objc.h"
29 #include "intl.h"
30 #include "langhooks.h"
31 #include "c-format.h"
32 #include "diagnostic.h"
33 #include "substring-locations.h"
34 #include "selftest.h"
35 #include "builtins.h"
37 /* Handle attributes associated with format checking. */
39 /* This must be in the same order as format_types, except for
40 format_type_error. Target-specific format types do not have
41 matching enum values. */
42 enum format_type { printf_format_type, asm_fprintf_format_type,
43 gcc_diag_format_type, gcc_tdiag_format_type,
44 gcc_cdiag_format_type,
45 gcc_cxxdiag_format_type, gcc_gfc_format_type,
46 gcc_objc_string_format_type,
47 format_type_error = -1};
49 struct function_format_info
51 int format_type; /* type of format (printf, scanf, etc.) */
52 unsigned HOST_WIDE_INT format_num; /* number of format argument */
53 unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */
56 static bool decode_format_attr (tree, function_format_info *, int);
57 static int decode_format_type (const char *);
59 static bool check_format_string (tree argument,
60 unsigned HOST_WIDE_INT format_num,
61 int flags, bool *no_add_attrs,
62 int expected_format_type);
63 static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value,
64 int validated_p);
65 static const char *convert_format_name_to_system_name (const char *attr_name);
66 static bool cmp_attribs (const char *tattr_name, const char *attr_name);
68 static int first_target_format_type;
69 static const char *format_name (int format_num);
70 static int format_flags (int format_num);
72 /* Emit a warning as per format_warning_va, but construct the substring_loc
73 for the character at offset (CHAR_IDX - 1) within a string constant
74 FORMAT_STRING_CST at FMT_STRING_LOC. */
76 ATTRIBUTE_GCC_DIAG (5,6)
77 static bool
78 format_warning_at_char (location_t fmt_string_loc, tree format_string_cst,
79 int char_idx, int opt, const char *gmsgid, ...)
81 va_list ap;
82 va_start (ap, gmsgid);
83 tree string_type = TREE_TYPE (format_string_cst);
85 /* The callers are of the form:
86 format_warning (format_string_loc, format_string_cst,
87 format_chars - orig_format_chars,
88 where format_chars has already been incremented, so that
89 CHAR_IDX is one character beyond where the warning should
90 be emitted. Fix it. */
91 char_idx -= 1;
93 substring_loc fmt_loc (fmt_string_loc, string_type, char_idx, char_idx,
94 char_idx);
95 bool warned = format_warning_va (fmt_loc, NULL, NULL, opt, gmsgid, &ap);
96 va_end (ap);
98 return warned;
101 /* Check that we have a pointer to a string suitable for use as a format.
102 The default is to check for a char type.
103 For objective-c dialects, this is extended to include references to string
104 objects validated by objc_string_ref_type_p ().
105 Targets may also provide a string object type that can be used within c and
106 c++ and shared with their respective objective-c dialects. In this case the
107 reference to a format string is checked for validity via a hook.
109 The function returns true if strref points to any string type valid for the
110 language dialect and target. */
112 static bool
113 valid_stringptr_type_p (tree strref)
115 return (strref != NULL
116 && TREE_CODE (strref) == POINTER_TYPE
117 && (TYPE_MAIN_VARIANT (TREE_TYPE (strref)) == char_type_node
118 || objc_string_ref_type_p (strref)
119 || (*targetcm.string_object_ref_type_p) ((const_tree) strref)));
122 /* Handle a "format_arg" attribute; arguments as in
123 struct attribute_spec.handler. */
124 tree
125 handle_format_arg_attribute (tree *node, tree ARG_UNUSED (name),
126 tree args, int flags, bool *no_add_attrs)
128 tree type = *node;
129 tree format_num_expr = TREE_VALUE (args);
130 unsigned HOST_WIDE_INT format_num = 0;
132 if (!get_constant (format_num_expr, &format_num, 0))
134 error ("format string has invalid operand number");
135 *no_add_attrs = true;
136 return NULL_TREE;
139 if (prototype_p (type))
141 /* The format arg can be any string reference valid for the language and
142 target. We cannot be more specific in this case. */
143 if (!check_format_string (type, format_num, flags, no_add_attrs, -1))
144 return NULL_TREE;
147 if (!valid_stringptr_type_p (TREE_TYPE (type)))
149 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
150 error ("function does not return string type");
151 *no_add_attrs = true;
152 return NULL_TREE;
155 return NULL_TREE;
158 /* Verify that the format_num argument is actually a string reference suitable,
159 for the language dialect and target (in case the format attribute is in
160 error). When we know the specific reference type expected, this is also
161 checked. */
162 static bool
163 check_format_string (tree fntype, unsigned HOST_WIDE_INT format_num,
164 int flags, bool *no_add_attrs, int expected_format_type)
166 unsigned HOST_WIDE_INT i;
167 bool is_objc_sref, is_target_sref, is_char_ref;
168 tree ref;
169 int fmt_flags;
170 function_args_iterator iter;
172 i = 1;
173 FOREACH_FUNCTION_ARGS (fntype, ref, iter)
175 if (i == format_num)
176 break;
177 i++;
180 if (!ref
181 || !valid_stringptr_type_p (ref))
183 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
184 error ("format string argument is not a string type");
185 *no_add_attrs = true;
186 return false;
189 /* We only know that we want a suitable string reference. */
190 if (expected_format_type < 0)
191 return true;
193 /* Now check that the arg matches the expected type. */
194 is_char_ref =
195 (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node);
197 fmt_flags = format_flags (expected_format_type);
198 is_objc_sref = is_target_sref = false;
199 if (!is_char_ref)
200 is_objc_sref = objc_string_ref_type_p (ref);
202 if (!(fmt_flags & FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL))
204 if (is_char_ref)
205 return true; /* OK, we expected a char and found one. */
206 else
208 /* We expected a char but found an extended string type. */
209 if (is_objc_sref)
210 error ("found a %qs reference but the format argument should"
211 " be a string", format_name (gcc_objc_string_format_type));
212 else
213 error ("found a %qT but the format argument should be a string",
214 ref);
215 *no_add_attrs = true;
216 return false;
220 /* We expect a string object type as the format arg. */
221 if (is_char_ref)
223 error ("format argument should be a %qs reference but"
224 " a string was found", format_name (expected_format_type));
225 *no_add_attrs = true;
226 return false;
229 /* We will assert that objective-c will support either its own string type
230 or the target-supplied variant. */
231 if (!is_objc_sref)
232 is_target_sref = (*targetcm.string_object_ref_type_p) ((const_tree) ref);
234 if (expected_format_type == (int) gcc_objc_string_format_type
235 && (is_objc_sref || is_target_sref))
236 return true;
238 /* We will allow a target string ref to match only itself. */
239 if (first_target_format_type
240 && expected_format_type >= first_target_format_type
241 && is_target_sref)
242 return true;
243 else
245 error ("format argument should be a %qs reference",
246 format_name (expected_format_type));
247 *no_add_attrs = true;
248 return false;
251 gcc_unreachable ();
254 /* Verify EXPR is a constant, and store its value.
255 If validated_p is true there should be no errors.
256 Returns true on success, false otherwise. */
257 static bool
258 get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
260 if (!tree_fits_uhwi_p (expr))
262 gcc_assert (!validated_p);
263 return false;
266 *value = TREE_INT_CST_LOW (expr);
268 return true;
271 /* Decode the arguments to a "format" attribute into a
272 function_format_info structure. It is already known that the list
273 is of the right length. If VALIDATED_P is true, then these
274 attributes have already been validated and must not be erroneous;
275 if false, it will give an error message. Returns true if the
276 attributes are successfully decoded, false otherwise. */
278 static bool
279 decode_format_attr (tree args, function_format_info *info, int validated_p)
281 tree format_type_id = TREE_VALUE (args);
282 tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
283 tree first_arg_num_expr
284 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
286 if (TREE_CODE (format_type_id) != IDENTIFIER_NODE)
288 gcc_assert (!validated_p);
289 error ("unrecognized format specifier");
290 return false;
292 else
294 const char *p = IDENTIFIER_POINTER (format_type_id);
296 p = convert_format_name_to_system_name (p);
298 info->format_type = decode_format_type (p);
300 if (!c_dialect_objc ()
301 && info->format_type == gcc_objc_string_format_type)
303 gcc_assert (!validated_p);
304 warning (OPT_Wformat_, "%qE is only allowed in Objective-C dialects",
305 format_type_id);
306 info->format_type = format_type_error;
307 return false;
310 if (info->format_type == format_type_error)
312 gcc_assert (!validated_p);
313 warning (OPT_Wformat_, "%qE is an unrecognized format function type",
314 format_type_id);
315 return false;
319 if (!get_constant (format_num_expr, &info->format_num, validated_p))
321 error ("format string has invalid operand number");
322 return false;
325 if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
327 error ("%<...%> has invalid operand number");
328 return false;
331 if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
333 gcc_assert (!validated_p);
334 error ("format string argument follows the args to be formatted");
335 return false;
338 return true;
341 /* Check a call to a format function against a parameter list. */
343 /* The C standard version C++ is treated as equivalent to
344 or inheriting from, for the purpose of format features supported. */
345 #define CPLUSPLUS_STD_VER (cxx_dialect < cxx11 ? STD_C94 : STD_C99)
346 /* The C standard version we are checking formats against when pedantic. */
347 #define C_STD_VER ((int) (c_dialect_cxx () \
348 ? CPLUSPLUS_STD_VER \
349 : (flag_isoc99 \
350 ? STD_C99 \
351 : (flag_isoc94 ? STD_C94 : STD_C89))))
352 /* The name to give to the standard version we are warning about when
353 pedantic. FEATURE_VER is the version in which the feature warned out
354 appeared, which is higher than C_STD_VER. */
355 #define C_STD_NAME(FEATURE_VER) (c_dialect_cxx () \
356 ? (cxx_dialect < cxx11 ? "ISO C++98" \
357 : "ISO C++11") \
358 : ((FEATURE_VER) == STD_EXT \
359 ? "ISO C" \
360 : "ISO C90"))
361 /* Adjust a C standard version, which may be STD_C9L, to account for
362 -Wno-long-long. Returns other standard versions unchanged. */
363 #define ADJ_STD(VER) ((int) ((VER) == STD_C9L \
364 ? (warn_long_long ? STD_C99 : STD_C89) \
365 : (VER)))
367 /* Enum describing the kind of specifiers present in the format and
368 requiring an argument. */
369 enum format_specifier_kind {
370 CF_KIND_FORMAT,
371 CF_KIND_FIELD_WIDTH,
372 CF_KIND_FIELD_PRECISION
375 static const char *kind_descriptions[] = {
376 N_("format"),
377 N_("field width specifier"),
378 N_("field precision specifier")
381 /* Structure describing details of a type expected in format checking,
382 and the type to check against it. */
383 struct format_wanted_type
385 /* The type wanted. */
386 tree wanted_type;
387 /* The name of this type to use in diagnostics. */
388 const char *wanted_type_name;
389 /* Should be type checked just for scalar width identity. */
390 int scalar_identity_flag;
391 /* The level of indirection through pointers at which this type occurs. */
392 int pointer_count;
393 /* Whether, when pointer_count is 1, to allow any character type when
394 pedantic, rather than just the character or void type specified. */
395 int char_lenient_flag;
396 /* Whether the argument, dereferenced once, is written into and so the
397 argument must not be a pointer to a const-qualified type. */
398 int writing_in_flag;
399 /* Whether the argument, dereferenced once, is read from and so
400 must not be a NULL pointer. */
401 int reading_from_flag;
402 /* The kind of specifier that this type is used for. */
403 enum format_specifier_kind kind;
404 /* The starting character of the specifier. This never includes the
405 initial percent sign. */
406 const char *format_start;
407 /* The length of the specifier. */
408 int format_length;
409 /* The actual parameter to check against the wanted type. */
410 tree param;
411 /* The argument number of that parameter. */
412 int arg_num;
413 /* The offset location of this argument with respect to the format
414 string location. */
415 unsigned int offset_loc;
416 /* The next type to check for this format conversion, or NULL if none. */
417 struct format_wanted_type *next;
420 /* Convenience macro for format_length_info meaning unused. */
421 #define NO_FMT NULL, FMT_LEN_none, STD_C89
423 static const format_length_info printf_length_specs[] =
425 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
426 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 },
427 { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 },
428 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
429 { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
430 { "Z", FMT_LEN_z, STD_EXT, NO_FMT, 0 },
431 { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
432 { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 },
433 { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 },
434 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 },
435 { NO_FMT, NO_FMT, 0 }
438 /* Length specifiers valid for asm_fprintf. */
439 static const format_length_info asm_fprintf_length_specs[] =
441 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
442 { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
443 { NO_FMT, NO_FMT, 0 }
446 /* Length specifiers valid for GCC diagnostics. */
447 static const format_length_info gcc_diag_length_specs[] =
449 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
450 { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
451 { NO_FMT, NO_FMT, 0 }
454 /* The custom diagnostics all accept the same length specifiers. */
455 #define gcc_tdiag_length_specs gcc_diag_length_specs
456 #define gcc_cdiag_length_specs gcc_diag_length_specs
457 #define gcc_cxxdiag_length_specs gcc_diag_length_specs
459 /* This differs from printf_length_specs only in that "Z" is not accepted. */
460 static const format_length_info scanf_length_specs[] =
462 { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
463 { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 },
464 { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 },
465 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
466 { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
467 { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
468 { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 },
469 { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 },
470 { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 },
471 { NO_FMT, NO_FMT, 0 }
475 /* All tables for strfmon use STD_C89 everywhere, since -pedantic warnings
476 make no sense for a format type not part of any C standard version. */
477 static const format_length_info strfmon_length_specs[] =
479 /* A GNU extension. */
480 { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
481 { NO_FMT, NO_FMT, 0 }
485 /* For now, the Fortran front-end routines only use l as length modifier. */
486 static const format_length_info gcc_gfc_length_specs[] =
488 { "l", FMT_LEN_l, STD_C89, NO_FMT, 0 },
489 { NO_FMT, NO_FMT, 0 }
493 static const format_flag_spec printf_flag_specs[] =
495 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
496 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
497 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
498 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
499 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
500 { '\'', 0, 0, N_("''' flag"), N_("the ''' printf flag"), STD_EXT },
501 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' printf flag"), STD_EXT },
502 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
503 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
504 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
505 { 0, 0, 0, NULL, NULL, STD_C89 }
509 static const format_flag_pair printf_flag_pairs[] =
511 { ' ', '+', 1, 0 },
512 { '0', '-', 1, 0 },
513 { '0', 'p', 1, 'i' },
514 { 0, 0, 0, 0 }
517 static const format_flag_spec asm_fprintf_flag_specs[] =
519 { ' ', 0, 0, N_("' ' flag"), N_("the ' ' printf flag"), STD_C89 },
520 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
521 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
522 { '0', 0, 0, N_("'0' flag"), N_("the '0' printf flag"), STD_C89 },
523 { '-', 0, 0, N_("'-' flag"), N_("the '-' printf flag"), STD_C89 },
524 { 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
525 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
526 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
527 { 0, 0, 0, NULL, NULL, STD_C89 }
530 static const format_flag_pair asm_fprintf_flag_pairs[] =
532 { ' ', '+', 1, 0 },
533 { '0', '-', 1, 0 },
534 { '0', 'p', 1, 'i' },
535 { 0, 0, 0, 0 }
538 static const format_flag_pair gcc_diag_flag_pairs[] =
540 { 0, 0, 0, 0 }
543 #define gcc_tdiag_flag_pairs gcc_diag_flag_pairs
544 #define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
545 #define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
546 #define gcc_gfc_flag_pairs gcc_diag_flag_pairs
548 static const format_flag_spec gcc_diag_flag_specs[] =
550 { '+', 0, 0, N_("'+' flag"), N_("the '+' printf flag"), STD_C89 },
551 { '#', 0, 0, N_("'#' flag"), N_("the '#' printf flag"), STD_C89 },
552 { 'q', 0, 0, N_("'q' flag"), N_("the 'q' diagnostic flag"), STD_C89 },
553 { 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
554 { 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
555 { 0, 0, 0, NULL, NULL, STD_C89 }
558 #define gcc_tdiag_flag_specs gcc_diag_flag_specs
559 #define gcc_cdiag_flag_specs gcc_diag_flag_specs
560 #define gcc_cxxdiag_flag_specs gcc_diag_flag_specs
561 #define gcc_gfc_flag_specs gcc_diag_flag_specs
563 static const format_flag_spec scanf_flag_specs[] =
565 { '*', 0, 0, N_("assignment suppression"), N_("the assignment suppression scanf feature"), STD_C89 },
566 { 'a', 0, 0, N_("'a' flag"), N_("the 'a' scanf flag"), STD_EXT },
567 { 'm', 0, 0, N_("'m' flag"), N_("the 'm' scanf flag"), STD_EXT },
568 { 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
569 { 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
570 { '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT },
571 { 'I', 0, 0, N_("'I' flag"), N_("the 'I' scanf flag"), STD_EXT },
572 { 0, 0, 0, NULL, NULL, STD_C89 }
576 static const format_flag_pair scanf_flag_pairs[] =
578 { '*', 'L', 0, 0 },
579 { 'a', 'm', 0, 0 },
580 { 0, 0, 0, 0 }
584 static const format_flag_spec strftime_flag_specs[] =
586 { '_', 0, 0, N_("'_' flag"), N_("the '_' strftime flag"), STD_EXT },
587 { '-', 0, 0, N_("'-' flag"), N_("the '-' strftime flag"), STD_EXT },
588 { '0', 0, 0, N_("'0' flag"), N_("the '0' strftime flag"), STD_EXT },
589 { '^', 0, 0, N_("'^' flag"), N_("the '^' strftime flag"), STD_EXT },
590 { '#', 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), STD_EXT },
591 { 'w', 0, 0, N_("field width"), N_("field width in strftime format"), STD_EXT },
592 { 'E', 0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"), STD_C99 },
593 { 'O', 0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"), STD_C99 },
594 { 'O', 'o', 0, NULL, N_("the 'O' modifier"), STD_EXT },
595 { 0, 0, 0, NULL, NULL, STD_C89 }
599 static const format_flag_pair strftime_flag_pairs[] =
601 { 'E', 'O', 0, 0 },
602 { '_', '-', 0, 0 },
603 { '_', '0', 0, 0 },
604 { '-', '0', 0, 0 },
605 { '^', '#', 0, 0 },
606 { 0, 0, 0, 0 }
610 static const format_flag_spec strfmon_flag_specs[] =
612 { '=', 0, 1, N_("fill character"), N_("fill character in strfmon format"), STD_C89 },
613 { '^', 0, 0, N_("'^' flag"), N_("the '^' strfmon flag"), STD_C89 },
614 { '+', 0, 0, N_("'+' flag"), N_("the '+' strfmon flag"), STD_C89 },
615 { '(', 0, 0, N_("'(' flag"), N_("the '(' strfmon flag"), STD_C89 },
616 { '!', 0, 0, N_("'!' flag"), N_("the '!' strfmon flag"), STD_C89 },
617 { '-', 0, 0, N_("'-' flag"), N_("the '-' strfmon flag"), STD_C89 },
618 { 'w', 0, 0, N_("field width"), N_("field width in strfmon format"), STD_C89 },
619 { '#', 0, 0, N_("left precision"), N_("left precision in strfmon format"), STD_C89 },
620 { 'p', 0, 0, N_("right precision"), N_("right precision in strfmon format"), STD_C89 },
621 { 'L', 0, 0, N_("length modifier"), N_("length modifier in strfmon format"), STD_C89 },
622 { 0, 0, 0, NULL, NULL, STD_C89 }
625 static const format_flag_pair strfmon_flag_pairs[] =
627 { '+', '(', 0, 0 },
628 { 0, 0, 0, 0 }
632 static const format_char_info print_char_table[] =
634 /* C89 conversion specifiers. */
635 { "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 },
636 { "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 },
637 { "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 },
638 { "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 },
639 { "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 },
640 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
641 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
642 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL },
643 { "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 },
644 /* C99 conversion specifiers. */
645 { "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 },
646 { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "", NULL },
647 /* X/Open conversion specifiers. */
648 { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
649 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
650 /* GNU conversion specifiers. */
651 { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "", NULL },
652 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
655 static const format_char_info asm_fprintf_char_table[] =
657 /* C89 conversion specifiers. */
658 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i", NULL },
659 { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL },
660 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i", NULL },
661 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
662 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL },
664 /* asm_fprintf conversion specifiers. */
665 { "O", 0, STD_C89, NOARGUMENTS, "", "", NULL },
666 { "R", 0, STD_C89, NOARGUMENTS, "", "", NULL },
667 { "I", 0, STD_C89, NOARGUMENTS, "", "", NULL },
668 { "L", 0, STD_C89, NOARGUMENTS, "", "", NULL },
669 { "U", 0, STD_C89, NOARGUMENTS, "", "", NULL },
670 { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", NULL },
671 { "@", 0, STD_C89, NOARGUMENTS, "", "", NULL },
672 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
675 static const format_char_info gcc_diag_char_table[] =
677 /* C89 conversion specifiers. */
678 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
679 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
680 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
681 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
682 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
683 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
685 /* Custom conversion specifiers. */
687 /* These will require a "tree" at runtime. */
688 { "K", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
690 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
691 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
692 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
693 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
696 static const format_char_info gcc_tdiag_char_table[] =
698 /* C89 conversion specifiers. */
699 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
700 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
701 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
702 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
703 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
704 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
706 /* Custom conversion specifiers. */
708 /* These will require a "tree" at runtime. */
709 { "DFKTEV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
711 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
713 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
714 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
715 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
716 { "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_tdiag_char_table[0] },
717 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
720 static const format_char_info gcc_cdiag_char_table[] =
722 /* C89 conversion specifiers. */
723 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
724 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
725 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
726 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
727 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
728 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
730 /* Custom conversion specifiers. */
732 /* These will require a "tree" at runtime. */
733 { "DEFKTV", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+", "", NULL },
735 { "v", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
737 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
738 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
739 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
740 { "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_tdiag_char_table[0] },
741 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
744 static const format_char_info gcc_cxxdiag_char_table[] =
746 /* C89 conversion specifiers. */
747 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
748 { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
749 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
750 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
751 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL },
752 { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL },
754 /* Custom conversion specifiers. */
756 /* These will require a "tree" at runtime. */
757 { "ADEFKSTVX",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q+#", "", NULL },
759 { "v", 0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q#", "", NULL },
761 /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.) */
762 { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
764 { "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
765 { "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
766 { "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
767 { "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_tdiag_char_table[0] },
768 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
771 static const format_char_info gcc_gfc_char_table[] =
773 /* C89 conversion specifiers. */
774 { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
775 { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
776 { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
777 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "cR", NULL },
779 /* gfc conversion specifiers. */
781 { "C", 0, STD_C89, NOARGUMENTS, "", "", NULL },
783 /* This will require a "locus" at runtime. */
784 { "L", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "R", NULL },
786 /* These will require nothing. */
787 { "<>",0, STD_C89, NOARGUMENTS, "", "", NULL },
788 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
791 static const format_char_info scan_char_table[] =
793 /* C89 conversion specifiers. */
794 { "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 },
795 { "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 },
796 { "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 },
797 { "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 },
798 { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "cW", NULL },
799 { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW", NULL },
800 { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW[", NULL },
801 { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
802 { "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 },
803 /* C99 conversion specifiers. */
804 { "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 },
805 { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w'", "W", NULL },
806 /* X/Open conversion specifiers. */
807 { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "W", NULL },
808 { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "W", NULL },
809 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
812 static const format_char_info time_char_table[] =
814 /* C89 conversion specifiers. */
815 { "ABZab", 0, STD_C89, NOLENGTHS, "^#", "", NULL },
816 { "cx", 0, STD_C89, NOLENGTHS, "E", "3", NULL },
817 { "HIMSUWdmw", 0, STD_C89, NOLENGTHS, "-_0Ow", "", NULL },
818 { "j", 0, STD_C89, NOLENGTHS, "-_0Ow", "o", NULL },
819 { "p", 0, STD_C89, NOLENGTHS, "#", "", NULL },
820 { "X", 0, STD_C89, NOLENGTHS, "E", "", NULL },
821 { "y", 0, STD_C89, NOLENGTHS, "EO-_0w", "4", NULL },
822 { "Y", 0, STD_C89, NOLENGTHS, "-_0EOw", "o", NULL },
823 { "%", 0, STD_C89, NOLENGTHS, "", "", NULL },
824 /* C99 conversion specifiers. */
825 { "C", 0, STD_C99, NOLENGTHS, "-_0EOw", "o", NULL },
826 { "D", 0, STD_C99, NOLENGTHS, "", "2", NULL },
827 { "eVu", 0, STD_C99, NOLENGTHS, "-_0Ow", "", NULL },
828 { "FRTnrt", 0, STD_C99, NOLENGTHS, "", "", NULL },
829 { "g", 0, STD_C99, NOLENGTHS, "O-_0w", "2o", NULL },
830 { "G", 0, STD_C99, NOLENGTHS, "-_0Ow", "o", NULL },
831 { "h", 0, STD_C99, NOLENGTHS, "^#", "", NULL },
832 { "z", 0, STD_C99, NOLENGTHS, "O", "o", NULL },
833 /* GNU conversion specifiers. */
834 { "kls", 0, STD_EXT, NOLENGTHS, "-_0Ow", "", NULL },
835 { "P", 0, STD_EXT, NOLENGTHS, "", "", NULL },
836 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
839 static const format_char_info monetary_char_table[] =
841 { "in", 0, STD_C89, { T89_D, BADLEN, BADLEN, BADLEN, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "=^+(!-w#p", "", NULL },
842 { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
845 /* This must be in the same order as enum format_type. */
846 static const format_kind_info format_types_orig[] =
848 { "gnu_printf", printf_length_specs, print_char_table, " +#0-'I", NULL,
849 printf_flag_specs, printf_flag_pairs,
850 FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
851 'w', 0, 'p', 0, 'L', 0,
852 &integer_type_node, &integer_type_node
854 { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL,
855 asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
856 FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
857 'w', 0, 'p', 0, 'L', 0,
858 NULL, NULL
860 { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "q+#", NULL,
861 gcc_diag_flag_specs, gcc_diag_flag_pairs,
862 FMT_FLAG_ARG_CONVERT,
863 0, 0, 'p', 0, 'L', 0,
864 NULL, &integer_type_node
866 { "gcc_tdiag", gcc_tdiag_length_specs, gcc_tdiag_char_table, "q+#", NULL,
867 gcc_tdiag_flag_specs, gcc_tdiag_flag_pairs,
868 FMT_FLAG_ARG_CONVERT,
869 0, 0, 'p', 0, 'L', 0,
870 NULL, &integer_type_node
872 { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "q+#", NULL,
873 gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
874 FMT_FLAG_ARG_CONVERT,
875 0, 0, 'p', 0, 'L', 0,
876 NULL, &integer_type_node
878 { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "q+#", NULL,
879 gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
880 FMT_FLAG_ARG_CONVERT,
881 0, 0, 'p', 0, 'L', 0,
882 NULL, &integer_type_node
884 { "gcc_gfc", gcc_gfc_length_specs, gcc_gfc_char_table, "q+#", NULL,
885 gcc_gfc_flag_specs, gcc_gfc_flag_pairs,
886 FMT_FLAG_ARG_CONVERT,
887 0, 0, 0, 0, 0, 0,
888 NULL, NULL
890 { "NSString", NULL, NULL, NULL, NULL,
891 NULL, NULL,
892 FMT_FLAG_ARG_CONVERT|FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL, 0, 0, 0, 0, 0, 0,
893 NULL, NULL
895 { "gnu_scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
896 scanf_flag_specs, scanf_flag_pairs,
897 FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
898 'w', 0, 0, '*', 'L', 'm',
899 NULL, NULL
901 { "gnu_strftime", NULL, time_char_table, "_-0^#", "EO",
902 strftime_flag_specs, strftime_flag_pairs,
903 FMT_FLAG_FANCY_PERCENT_OK, 'w', 0, 0, 0, 0, 0,
904 NULL, NULL
906 { "gnu_strfmon", strfmon_length_specs, monetary_char_table, "=^+(!-", NULL,
907 strfmon_flag_specs, strfmon_flag_pairs,
908 FMT_FLAG_ARG_CONVERT, 'w', '#', 'p', 0, 'L', 0,
909 NULL, NULL
913 /* This layer of indirection allows GCC to reassign format_types with
914 new data if necessary, while still allowing the original data to be
915 const. */
916 static const format_kind_info *format_types = format_types_orig;
917 /* We can modify this one. We also add target-specific format types
918 to the end of the array. */
919 static format_kind_info *dynamic_format_types;
921 static int n_format_types = ARRAY_SIZE (format_types_orig);
923 /* Structure detailing the results of checking a format function call
924 where the format expression may be a conditional expression with
925 many leaves resulting from nested conditional expressions. */
926 struct format_check_results
928 /* Number of leaves of the format argument that could not be checked
929 as they were not string literals. */
930 int number_non_literal;
931 /* Number of leaves of the format argument that were null pointers or
932 string literals, but had extra format arguments. */
933 int number_extra_args;
934 location_t extra_arg_loc;
935 /* Number of leaves of the format argument that were null pointers or
936 string literals, but had extra format arguments and used $ operand
937 numbers. */
938 int number_dollar_extra_args;
939 /* Number of leaves of the format argument that were wide string
940 literals. */
941 int number_wide;
942 /* Number of leaves of the format argument that were empty strings. */
943 int number_empty;
944 /* Number of leaves of the format argument that were unterminated
945 strings. */
946 int number_unterminated;
947 /* Number of leaves of the format argument that were not counted above. */
948 int number_other;
949 /* Location of the format string. */
950 location_t format_string_loc;
953 struct format_check_context
955 format_check_results *res;
956 function_format_info *info;
957 tree params;
960 /* Return the format name (as specified in the original table) for the format
961 type indicated by format_num. */
962 static const char *
963 format_name (int format_num)
965 if (format_num >= 0 && format_num < n_format_types)
966 return format_types[format_num].name;
967 gcc_unreachable ();
970 /* Return the format flags (as specified in the original table) for the format
971 type indicated by format_num. */
972 static int
973 format_flags (int format_num)
975 if (format_num >= 0 && format_num < n_format_types)
976 return format_types[format_num].flags;
977 gcc_unreachable ();
980 static void check_format_info (function_format_info *, tree);
981 static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
982 static void check_format_info_main (format_check_results *,
983 function_format_info *, const char *,
984 location_t, tree,
985 int, tree,
986 unsigned HOST_WIDE_INT,
987 object_allocator<format_wanted_type> &);
989 static void init_dollar_format_checking (int, tree);
990 static int maybe_read_dollar_number (const char **, int,
991 tree, tree *, const format_kind_info *);
992 static bool avoid_dollar_number (const char *);
993 static void finish_dollar_format_checking (format_check_results *, int);
995 static const format_flag_spec *get_flag_spec (const format_flag_spec *,
996 int, const char *);
998 static void check_format_types (const substring_loc &fmt_loc,
999 format_wanted_type *,
1000 const format_kind_info *fki,
1001 int offset_to_type_start,
1002 char conversion_char);
1003 static void format_type_warning (const substring_loc &fmt_loc,
1004 source_range *param_range,
1005 format_wanted_type *, tree,
1006 tree,
1007 const format_kind_info *fki,
1008 int offset_to_type_start,
1009 char conversion_char);
1011 /* Decode a format type from a string, returning the type, or
1012 format_type_error if not valid, in which case the caller should print an
1013 error message. */
1014 static int
1015 decode_format_type (const char *s)
1017 int i;
1018 int slen;
1020 s = convert_format_name_to_system_name (s);
1021 slen = strlen (s);
1022 for (i = 0; i < n_format_types; i++)
1024 int alen;
1025 if (!strcmp (s, format_types[i].name))
1026 return i;
1027 alen = strlen (format_types[i].name);
1028 if (slen == alen + 4 && s[0] == '_' && s[1] == '_'
1029 && s[slen - 1] == '_' && s[slen - 2] == '_'
1030 && !strncmp (s + 2, format_types[i].name, alen))
1031 return i;
1033 return format_type_error;
1037 /* Check the argument list of a call to printf, scanf, etc.
1038 ATTRS are the attributes on the function type. There are NARGS argument
1039 values in the array ARGARRAY.
1040 Also, if -Wsuggest-attribute=format,
1041 warn for calls to vprintf or vscanf in functions with no such format
1042 attribute themselves. */
1044 void
1045 check_function_format (tree attrs, int nargs, tree *argarray)
1047 tree a;
1049 /* See if this function has any format attributes. */
1050 for (a = attrs; a; a = TREE_CHAIN (a))
1052 if (is_attribute_p ("format", TREE_PURPOSE (a)))
1054 /* Yup; check it. */
1055 function_format_info info;
1056 decode_format_attr (TREE_VALUE (a), &info, /*validated=*/true);
1057 if (warn_format)
1059 /* FIXME: Rewrite all the internal functions in this file
1060 to use the ARGARRAY directly instead of constructing this
1061 temporary list. */
1062 tree params = NULL_TREE;
1063 int i;
1064 for (i = nargs - 1; i >= 0; i--)
1065 params = tree_cons (NULL_TREE, argarray[i], params);
1066 check_format_info (&info, params);
1069 /* Attempt to detect whether the current function might benefit
1070 from the format attribute if the called function is decorated
1071 with it. Avoid using calls with string literal formats for
1072 guidance since those are unlikely to be viable candidates. */
1073 if (warn_suggest_attribute_format && info.first_arg_num == 0
1074 && (format_types[info.format_type].flags
1075 & (int) FMT_FLAG_ARG_CONVERT)
1076 /* c_strlen will fail for a function parameter but succeed
1077 for a literal or constant array. */
1078 && !c_strlen (argarray[info.format_num - 1], 1))
1080 tree c;
1081 for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
1083 c = TREE_CHAIN (c))
1084 if (is_attribute_p ("format", TREE_PURPOSE (c))
1085 && (decode_format_type (IDENTIFIER_POINTER
1086 (TREE_VALUE (TREE_VALUE (c))))
1087 == info.format_type))
1088 break;
1089 if (c == NULL_TREE)
1091 /* Check if the current function has a parameter to which
1092 the format attribute could be attached; if not, it
1093 can't be a candidate for a format attribute, despite
1094 the vprintf-like or vscanf-like call. */
1095 tree args;
1096 for (args = DECL_ARGUMENTS (current_function_decl);
1097 args != 0;
1098 args = DECL_CHAIN (args))
1100 if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
1101 && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
1102 == char_type_node))
1103 break;
1105 if (args != 0)
1106 warning (OPT_Wsuggest_attribute_format, "function %qD "
1107 "might be a candidate for %qs format attribute",
1108 current_function_decl,
1109 format_types[info.format_type].name);
1117 /* Variables used by the checking of $ operand number formats. */
1118 static char *dollar_arguments_used = NULL;
1119 static char *dollar_arguments_pointer_p = NULL;
1120 static int dollar_arguments_alloc = 0;
1121 static int dollar_arguments_count;
1122 static int dollar_first_arg_num;
1123 static int dollar_max_arg_used;
1124 static int dollar_format_warned;
1126 /* Initialize the checking for a format string that may contain $
1127 parameter number specifications; we will need to keep track of whether
1128 each parameter has been used. FIRST_ARG_NUM is the number of the first
1129 argument that is a parameter to the format, or 0 for a vprintf-style
1130 function; PARAMS is the list of arguments starting at this argument. */
1132 static void
1133 init_dollar_format_checking (int first_arg_num, tree params)
1135 tree oparams = params;
1137 dollar_first_arg_num = first_arg_num;
1138 dollar_arguments_count = 0;
1139 dollar_max_arg_used = 0;
1140 dollar_format_warned = 0;
1141 if (first_arg_num > 0)
1143 while (params)
1145 dollar_arguments_count++;
1146 params = TREE_CHAIN (params);
1149 if (dollar_arguments_alloc < dollar_arguments_count)
1151 free (dollar_arguments_used);
1152 free (dollar_arguments_pointer_p);
1153 dollar_arguments_alloc = dollar_arguments_count;
1154 dollar_arguments_used = XNEWVEC (char, dollar_arguments_alloc);
1155 dollar_arguments_pointer_p = XNEWVEC (char, dollar_arguments_alloc);
1157 if (dollar_arguments_alloc)
1159 memset (dollar_arguments_used, 0, dollar_arguments_alloc);
1160 if (first_arg_num > 0)
1162 int i = 0;
1163 params = oparams;
1164 while (params)
1166 dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params)))
1167 == POINTER_TYPE);
1168 params = TREE_CHAIN (params);
1169 i++;
1176 /* Look for a decimal number followed by a $ in *FORMAT. If DOLLAR_NEEDED
1177 is set, it is an error if one is not found; otherwise, it is OK. If
1178 such a number is found, check whether it is within range and mark that
1179 numbered operand as being used for later checking. Returns the operand
1180 number if found and within range, zero if no such number was found and
1181 this is OK, or -1 on error. PARAMS points to the first operand of the
1182 format; PARAM_PTR is made to point to the parameter referred to. If
1183 a $ format is found, *FORMAT is updated to point just after it. */
1185 static int
1186 maybe_read_dollar_number (const char **format,
1187 int dollar_needed, tree params, tree *param_ptr,
1188 const format_kind_info *fki)
1190 int argnum;
1191 int overflow_flag;
1192 const char *fcp = *format;
1193 if (!ISDIGIT (*fcp))
1195 if (dollar_needed)
1197 warning (OPT_Wformat_, "missing $ operand number in format");
1198 return -1;
1200 else
1201 return 0;
1203 argnum = 0;
1204 overflow_flag = 0;
1205 while (ISDIGIT (*fcp))
1207 int nargnum;
1208 nargnum = 10 * argnum + (*fcp - '0');
1209 if (nargnum < 0 || nargnum / 10 != argnum)
1210 overflow_flag = 1;
1211 argnum = nargnum;
1212 fcp++;
1214 if (*fcp != '$')
1216 if (dollar_needed)
1218 warning (OPT_Wformat_, "missing $ operand number in format");
1219 return -1;
1221 else
1222 return 0;
1224 *format = fcp + 1;
1225 if (pedantic && !dollar_format_warned)
1227 warning (OPT_Wformat_, "%s does not support %%n$ operand number formats",
1228 C_STD_NAME (STD_EXT));
1229 dollar_format_warned = 1;
1231 if (overflow_flag || argnum == 0
1232 || (dollar_first_arg_num && argnum > dollar_arguments_count))
1234 warning (OPT_Wformat_, "operand number out of range in format");
1235 return -1;
1237 if (argnum > dollar_max_arg_used)
1238 dollar_max_arg_used = argnum;
1239 /* For vprintf-style functions we may need to allocate more memory to
1240 track which arguments are used. */
1241 while (dollar_arguments_alloc < dollar_max_arg_used)
1243 int nalloc;
1244 nalloc = 2 * dollar_arguments_alloc + 16;
1245 dollar_arguments_used = XRESIZEVEC (char, dollar_arguments_used,
1246 nalloc);
1247 dollar_arguments_pointer_p = XRESIZEVEC (char, dollar_arguments_pointer_p,
1248 nalloc);
1249 memset (dollar_arguments_used + dollar_arguments_alloc, 0,
1250 nalloc - dollar_arguments_alloc);
1251 dollar_arguments_alloc = nalloc;
1253 if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE)
1254 && dollar_arguments_used[argnum - 1] == 1)
1256 dollar_arguments_used[argnum - 1] = 2;
1257 warning (OPT_Wformat_, "format argument %d used more than once in %s format",
1258 argnum, fki->name);
1260 else
1261 dollar_arguments_used[argnum - 1] = 1;
1262 if (dollar_first_arg_num)
1264 int i;
1265 *param_ptr = params;
1266 for (i = 1; i < argnum && *param_ptr != 0; i++)
1267 *param_ptr = TREE_CHAIN (*param_ptr);
1269 /* This case shouldn't be caught here. */
1270 gcc_assert (*param_ptr);
1272 else
1273 *param_ptr = 0;
1274 return argnum;
1277 /* Ensure that FORMAT does not start with a decimal number followed by
1278 a $; give a diagnostic and return true if it does, false otherwise. */
1280 static bool
1281 avoid_dollar_number (const char *format)
1283 if (!ISDIGIT (*format))
1284 return false;
1285 while (ISDIGIT (*format))
1286 format++;
1287 if (*format == '$')
1289 warning (OPT_Wformat_, "$ operand number used after format without operand number");
1290 return true;
1292 return false;
1296 /* Finish the checking for a format string that used $ operand number formats
1297 instead of non-$ formats. We check for unused operands before used ones
1298 (a serious error, since the implementation of the format function
1299 can't know what types to pass to va_arg to find the later arguments).
1300 and for unused operands at the end of the format (if we know how many
1301 arguments the format had, so not for vprintf). If there were operand
1302 numbers out of range on a non-vprintf-style format, we won't have reached
1303 here. If POINTER_GAP_OK, unused arguments are OK if all arguments are
1304 pointers. */
1306 static void
1307 finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok)
1309 int i;
1310 bool found_pointer_gap = false;
1311 for (i = 0; i < dollar_max_arg_used; i++)
1313 if (!dollar_arguments_used[i])
1315 if (pointer_gap_ok && (dollar_first_arg_num == 0
1316 || dollar_arguments_pointer_p[i]))
1317 found_pointer_gap = true;
1318 else
1319 warning_at (res->format_string_loc, OPT_Wformat_,
1320 "format argument %d unused before used argument %d in $-style format",
1321 i + 1, dollar_max_arg_used);
1324 if (found_pointer_gap
1325 || (dollar_first_arg_num
1326 && dollar_max_arg_used < dollar_arguments_count))
1328 res->number_other--;
1329 res->number_dollar_extra_args++;
1334 /* Retrieve the specification for a format flag. SPEC contains the
1335 specifications for format flags for the applicable kind of format.
1336 FLAG is the flag in question. If PREDICATES is NULL, the basic
1337 spec for that flag must be retrieved and must exist. If
1338 PREDICATES is not NULL, it is a string listing possible predicates
1339 for the spec entry; if an entry predicated on any of these is
1340 found, it is returned, otherwise NULL is returned. */
1342 static const format_flag_spec *
1343 get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
1345 int i;
1346 for (i = 0; spec[i].flag_char != 0; i++)
1348 if (spec[i].flag_char != flag)
1349 continue;
1350 if (predicates != NULL)
1352 if (spec[i].predicate != 0
1353 && strchr (predicates, spec[i].predicate) != 0)
1354 return &spec[i];
1356 else if (spec[i].predicate == 0)
1357 return &spec[i];
1359 gcc_assert (predicates);
1360 return NULL;
1364 /* Check the argument list of a call to printf, scanf, etc.
1365 INFO points to the function_format_info structure.
1366 PARAMS is the list of argument values. */
1368 static void
1369 check_format_info (function_format_info *info, tree params)
1371 format_check_context format_ctx;
1372 unsigned HOST_WIDE_INT arg_num;
1373 tree format_tree;
1374 format_check_results res;
1375 /* Skip to format argument. If the argument isn't available, there's
1376 no work for us to do; prototype checking will catch the problem. */
1377 for (arg_num = 1; ; ++arg_num)
1379 if (params == 0)
1380 return;
1381 if (arg_num == info->format_num)
1382 break;
1383 params = TREE_CHAIN (params);
1385 format_tree = TREE_VALUE (params);
1386 params = TREE_CHAIN (params);
1387 if (format_tree == 0)
1388 return;
1390 res.number_non_literal = 0;
1391 res.number_extra_args = 0;
1392 res.extra_arg_loc = UNKNOWN_LOCATION;
1393 res.number_dollar_extra_args = 0;
1394 res.number_wide = 0;
1395 res.number_empty = 0;
1396 res.number_unterminated = 0;
1397 res.number_other = 0;
1398 res.format_string_loc = input_location;
1400 format_ctx.res = &res;
1401 format_ctx.info = info;
1402 format_ctx.params = params;
1404 check_function_arguments_recurse (check_format_arg, &format_ctx,
1405 format_tree, arg_num);
1407 location_t loc = format_ctx.res->format_string_loc;
1409 if (res.number_non_literal > 0)
1411 /* Functions taking a va_list normally pass a non-literal format
1412 string. These functions typically are declared with
1413 first_arg_num == 0, so avoid warning in those cases. */
1414 if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT))
1416 /* For strftime-like formats, warn for not checking the format
1417 string; but there are no arguments to check. */
1418 warning_at (loc, OPT_Wformat_nonliteral,
1419 "format not a string literal, format string not checked");
1421 else if (info->first_arg_num != 0)
1423 /* If there are no arguments for the format at all, we may have
1424 printf (foo) which is likely to be a security hole. */
1425 while (arg_num + 1 < info->first_arg_num)
1427 if (params == 0)
1428 break;
1429 params = TREE_CHAIN (params);
1430 ++arg_num;
1432 if (params == 0 && warn_format_security)
1433 warning_at (loc, OPT_Wformat_security,
1434 "format not a string literal and no format arguments");
1435 else if (params == 0 && warn_format_nonliteral)
1436 warning_at (loc, OPT_Wformat_nonliteral,
1437 "format not a string literal and no format arguments");
1438 else
1439 warning_at (loc, OPT_Wformat_nonliteral,
1440 "format not a string literal, argument types not checked");
1444 /* If there were extra arguments to the format, normally warn. However,
1445 the standard does say extra arguments are ignored, so in the specific
1446 case where we have multiple leaves (conditional expressions or
1447 ngettext) allow extra arguments if at least one leaf didn't have extra
1448 arguments, but was otherwise OK (either non-literal or checked OK).
1449 If the format is an empty string, this should be counted similarly to the
1450 case of extra format arguments. */
1451 if (res.number_extra_args > 0 && res.number_non_literal == 0
1452 && res.number_other == 0)
1454 if (res.extra_arg_loc == UNKNOWN_LOCATION)
1455 res.extra_arg_loc = loc;
1456 warning_at (res.extra_arg_loc, OPT_Wformat_extra_args,
1457 "too many arguments for format");
1459 if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
1460 && res.number_other == 0)
1461 warning_at (loc, OPT_Wformat_extra_args, "unused arguments in $-style format");
1462 if (res.number_empty > 0 && res.number_non_literal == 0
1463 && res.number_other == 0)
1464 warning_at (loc, OPT_Wformat_zero_length, "zero-length %s format string",
1465 format_types[info->format_type].name);
1467 if (res.number_wide > 0)
1468 warning_at (loc, OPT_Wformat_, "format is a wide character string");
1470 if (res.number_unterminated > 0)
1471 warning_at (loc, OPT_Wformat_, "unterminated format string");
1474 /* Callback from check_function_arguments_recurse to check a
1475 format string. FORMAT_TREE is the format parameter. ARG_NUM
1476 is the number of the format argument. CTX points to a
1477 format_check_context. */
1479 static void
1480 check_format_arg (void *ctx, tree format_tree,
1481 unsigned HOST_WIDE_INT arg_num)
1483 format_check_context *format_ctx = (format_check_context *) ctx;
1484 format_check_results *res = format_ctx->res;
1485 function_format_info *info = format_ctx->info;
1486 tree params = format_ctx->params;
1488 int format_length;
1489 HOST_WIDE_INT offset;
1490 const char *format_chars;
1491 tree array_size = 0;
1492 tree array_init;
1494 location_t fmt_param_loc = EXPR_LOC_OR_LOC (format_tree, input_location);
1496 if (VAR_P (format_tree))
1498 /* Pull out a constant value if the front end didn't. */
1499 format_tree = decl_constant_value (format_tree);
1500 STRIP_NOPS (format_tree);
1503 if (integer_zerop (format_tree))
1505 /* Skip to first argument to check, so we can see if this format
1506 has any arguments (it shouldn't). */
1507 while (arg_num + 1 < info->first_arg_num)
1509 if (params == 0)
1510 return;
1511 params = TREE_CHAIN (params);
1512 ++arg_num;
1515 if (params == 0)
1516 res->number_other++;
1517 else
1519 if (res->number_extra_args == 0)
1520 res->extra_arg_loc = EXPR_LOC_OR_LOC (TREE_VALUE (params),
1521 input_location);
1522 res->number_extra_args++;
1524 return;
1527 offset = 0;
1528 if (TREE_CODE (format_tree) == POINTER_PLUS_EXPR)
1530 tree arg0, arg1;
1532 arg0 = TREE_OPERAND (format_tree, 0);
1533 arg1 = TREE_OPERAND (format_tree, 1);
1534 STRIP_NOPS (arg0);
1535 STRIP_NOPS (arg1);
1536 if (TREE_CODE (arg1) == INTEGER_CST)
1537 format_tree = arg0;
1538 else
1540 res->number_non_literal++;
1541 return;
1543 /* POINTER_PLUS_EXPR offsets are to be interpreted signed. */
1544 if (!cst_and_fits_in_hwi (arg1))
1546 res->number_non_literal++;
1547 return;
1549 offset = int_cst_value (arg1);
1551 if (TREE_CODE (format_tree) != ADDR_EXPR)
1553 res->number_non_literal++;
1554 return;
1556 res->format_string_loc = EXPR_LOC_OR_LOC (format_tree, input_location);
1557 format_tree = TREE_OPERAND (format_tree, 0);
1558 if (format_types[info->format_type].flags
1559 & (int) FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL)
1561 bool objc_str = (info->format_type == gcc_objc_string_format_type);
1562 /* We cannot examine this string here - but we can check that it is
1563 a valid type. */
1564 if (TREE_CODE (format_tree) != CONST_DECL
1565 || !((objc_str && objc_string_ref_type_p (TREE_TYPE (format_tree)))
1566 || (*targetcm.string_object_ref_type_p)
1567 ((const_tree) TREE_TYPE (format_tree))))
1569 res->number_non_literal++;
1570 return;
1572 /* Skip to first argument to check. */
1573 while (arg_num + 1 < info->first_arg_num)
1575 if (params == 0)
1576 return;
1577 params = TREE_CHAIN (params);
1578 ++arg_num;
1580 /* So, we have a valid literal string object and one or more params.
1581 We need to use an external helper to parse the string into format
1582 info. For Objective-C variants we provide the resource within the
1583 objc tree, for target variants, via a hook. */
1584 if (objc_str)
1585 objc_check_format_arg (format_tree, params);
1586 else if (targetcm.check_string_object_format_arg)
1587 (*targetcm.check_string_object_format_arg) (format_tree, params);
1588 /* Else we can't handle it and retire quietly. */
1589 return;
1591 if (TREE_CODE (format_tree) == ARRAY_REF
1592 && tree_fits_shwi_p (TREE_OPERAND (format_tree, 1))
1593 && (offset += tree_to_shwi (TREE_OPERAND (format_tree, 1))) >= 0)
1594 format_tree = TREE_OPERAND (format_tree, 0);
1595 if (offset < 0)
1597 res->number_non_literal++;
1598 return;
1600 if (VAR_P (format_tree)
1601 && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
1602 && (array_init = decl_constant_value (format_tree)) != format_tree
1603 && TREE_CODE (array_init) == STRING_CST)
1605 /* Extract the string constant initializer. Note that this may include
1606 a trailing NUL character that is not in the array (e.g.
1607 const char a[3] = "foo";). */
1608 array_size = DECL_SIZE_UNIT (format_tree);
1609 format_tree = array_init;
1611 if (TREE_CODE (format_tree) != STRING_CST)
1613 res->number_non_literal++;
1614 return;
1616 if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree))) != char_type_node)
1618 res->number_wide++;
1619 return;
1621 format_chars = TREE_STRING_POINTER (format_tree);
1622 format_length = TREE_STRING_LENGTH (format_tree);
1623 if (array_size != 0)
1625 /* Variable length arrays can't be initialized. */
1626 gcc_assert (TREE_CODE (array_size) == INTEGER_CST);
1628 if (tree_fits_shwi_p (array_size))
1630 HOST_WIDE_INT array_size_value = tree_to_shwi (array_size);
1631 if (array_size_value > 0
1632 && array_size_value == (int) array_size_value
1633 && format_length > array_size_value)
1634 format_length = array_size_value;
1637 if (offset)
1639 if (offset >= format_length)
1641 res->number_non_literal++;
1642 return;
1644 format_chars += offset;
1645 format_length -= offset;
1647 if (format_length < 1 || format_chars[--format_length] != 0)
1649 res->number_unterminated++;
1650 return;
1652 if (format_length == 0)
1654 res->number_empty++;
1655 return;
1658 /* Skip to first argument to check. */
1659 while (arg_num + 1 < info->first_arg_num)
1661 if (params == 0)
1662 return;
1663 params = TREE_CHAIN (params);
1664 ++arg_num;
1666 /* Provisionally increment res->number_other; check_format_info_main
1667 will decrement it if it finds there are extra arguments, but this way
1668 need not adjust it for every return. */
1669 res->number_other++;
1670 object_allocator <format_wanted_type> fwt_pool ("format_wanted_type pool");
1671 check_format_info_main (res, info, format_chars, fmt_param_loc, format_tree,
1672 format_length, params, arg_num, fwt_pool);
1675 /* Support class for argument_parser and check_format_info_main.
1676 Tracks any flag characters that have been applied to the
1677 current argument. */
1679 class flag_chars_t
1681 public:
1682 flag_chars_t ();
1683 bool has_char_p (char ch) const;
1684 void add_char (char ch);
1685 void validate (const format_kind_info *fki,
1686 const format_char_info *fci,
1687 const format_flag_spec *flag_specs,
1688 const char * const format_chars,
1689 tree format_string_cst,
1690 location_t format_string_loc,
1691 const char * const orig_format_chars,
1692 char format_char);
1693 int get_alloc_flag (const format_kind_info *fki);
1694 int assignment_suppression_p (const format_kind_info *fki);
1696 private:
1697 char m_flag_chars[256];
1700 /* Support struct for argument_parser and check_format_info_main.
1701 Encapsulates any length modifier applied to the current argument. */
1703 struct length_modifier
1705 length_modifier ()
1706 : chars (NULL), val (FMT_LEN_none), std (STD_C89),
1707 scalar_identity_flag (0)
1711 length_modifier (const char *chars_,
1712 enum format_lengths val_,
1713 enum format_std_version std_,
1714 int scalar_identity_flag_)
1715 : chars (chars_), val (val_), std (std_),
1716 scalar_identity_flag (scalar_identity_flag_)
1720 const char *chars;
1721 enum format_lengths val;
1722 enum format_std_version std;
1723 int scalar_identity_flag;
1726 /* Parsing one argument within a format string. */
1728 class argument_parser
1730 public:
1731 argument_parser (function_format_info *info, const char *&format_chars,
1732 tree format_string_cst,
1733 const char * const orig_format_chars,
1734 location_t format_string_loc, flag_chars_t &flag_chars,
1735 int &has_operand_number, tree first_fillin_param,
1736 object_allocator <format_wanted_type> &fwt_pool_);
1738 bool read_any_dollar ();
1740 bool read_format_flags ();
1742 bool
1743 read_any_format_width (tree &params,
1744 unsigned HOST_WIDE_INT &arg_num);
1746 void
1747 read_any_format_left_precision ();
1749 bool
1750 read_any_format_precision (tree &params,
1751 unsigned HOST_WIDE_INT &arg_num);
1753 void handle_alloc_chars ();
1755 length_modifier read_any_length_modifier ();
1757 void read_any_other_modifier ();
1759 const format_char_info *find_format_char_info (char format_char);
1761 void
1762 validate_flag_pairs (const format_char_info *fci,
1763 char format_char);
1765 void
1766 give_y2k_warnings (const format_char_info *fci,
1767 char format_char);
1769 void parse_any_scan_set (const format_char_info *fci);
1771 bool handle_conversions (const format_char_info *fci,
1772 const length_modifier &len_modifier,
1773 tree &wanted_type,
1774 const char *&wanted_type_name,
1775 unsigned HOST_WIDE_INT &arg_num,
1776 tree &params,
1777 char format_char);
1779 bool
1780 check_argument_type (const format_char_info *fci,
1781 const length_modifier &len_modifier,
1782 tree &wanted_type,
1783 const char *&wanted_type_name,
1784 const bool suppressed,
1785 unsigned HOST_WIDE_INT &arg_num,
1786 tree &params,
1787 const int alloc_flag,
1788 const char * const format_start,
1789 const char * const type_start,
1790 location_t fmt_param_loc,
1791 char conversion_char);
1793 private:
1794 const function_format_info *const info;
1795 const format_kind_info * const fki;
1796 const format_flag_spec * const flag_specs;
1797 const char *start_of_this_format;
1798 const char *&format_chars;
1799 const tree format_string_cst;
1800 const char * const orig_format_chars;
1801 const location_t format_string_loc;
1802 object_allocator <format_wanted_type> &fwt_pool;
1803 flag_chars_t &flag_chars;
1804 int main_arg_num;
1805 tree main_arg_params;
1806 int &has_operand_number;
1807 const tree first_fillin_param;
1808 format_wanted_type width_wanted_type;
1809 format_wanted_type precision_wanted_type;
1810 public:
1811 format_wanted_type main_wanted_type;
1812 private:
1813 format_wanted_type *first_wanted_type;
1814 format_wanted_type *last_wanted_type;
1817 /* flag_chars_t's constructor. */
1819 flag_chars_t::flag_chars_t ()
1821 m_flag_chars[0] = 0;
1824 /* Has CH been seen as a flag within the current argument? */
1826 bool
1827 flag_chars_t::has_char_p (char ch) const
1829 return strchr (m_flag_chars, ch) != 0;
1832 /* Add CH to the flags seen within the current argument. */
1834 void
1835 flag_chars_t::add_char (char ch)
1837 int i = strlen (m_flag_chars);
1838 m_flag_chars[i++] = ch;
1839 m_flag_chars[i] = 0;
1842 /* Validate the individual flags used, removing any that are invalid. */
1844 void
1845 flag_chars_t::validate (const format_kind_info *fki,
1846 const format_char_info *fci,
1847 const format_flag_spec *flag_specs,
1848 const char * const format_chars,
1849 tree format_string_cst,
1850 location_t format_string_loc,
1851 const char * const orig_format_chars,
1852 char format_char)
1854 int i;
1855 int d = 0;
1856 for (i = 0; m_flag_chars[i] != 0; i++)
1858 const format_flag_spec *s = get_flag_spec (flag_specs,
1859 m_flag_chars[i], NULL);
1860 m_flag_chars[i - d] = m_flag_chars[i];
1861 if (m_flag_chars[i] == fki->length_code_char)
1862 continue;
1863 if (strchr (fci->flag_chars, m_flag_chars[i]) == 0)
1865 format_warning_at_char (format_string_loc, format_string_cst,
1866 format_chars - orig_format_chars,
1867 OPT_Wformat_,
1868 "%s used with %<%%%c%> %s format",
1869 _(s->name), format_char, fki->name);
1870 d++;
1871 continue;
1873 if (pedantic)
1875 const format_flag_spec *t;
1876 if (ADJ_STD (s->std) > C_STD_VER)
1877 warning_at (format_string_loc, OPT_Wformat_,
1878 "%s does not support %s",
1879 C_STD_NAME (s->std), _(s->long_name));
1880 t = get_flag_spec (flag_specs, m_flag_chars[i], fci->flags2);
1881 if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
1883 const char *long_name = (t->long_name != NULL
1884 ? t->long_name
1885 : s->long_name);
1886 if (ADJ_STD (t->std) > C_STD_VER)
1887 warning_at (format_string_loc, OPT_Wformat_,
1888 "%s does not support %s with"
1889 " the %<%%%c%> %s format",
1890 C_STD_NAME (t->std), _(long_name),
1891 format_char, fki->name);
1895 m_flag_chars[i - d] = 0;
1898 /* Determine if an assignment-allocation has been set, requiring
1899 an extra char ** for writing back a dynamically-allocated char *.
1900 This is for handling the optional 'm' character in scanf. */
1903 flag_chars_t::get_alloc_flag (const format_kind_info *fki)
1905 if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1906 && has_char_p ('a'))
1907 return 1;
1908 if (fki->alloc_char && has_char_p (fki->alloc_char))
1909 return 1;
1910 return 0;
1913 /* Determine if an assignment-suppression character was seen.
1914 ('*' in scanf, for discarding the converted input). */
1917 flag_chars_t::assignment_suppression_p (const format_kind_info *fki)
1919 if (fki->suppression_char
1920 && has_char_p (fki->suppression_char))
1921 return 1;
1922 return 0;
1925 /* Constructor for argument_parser. Initialize for parsing one
1926 argument within a format string. */
1928 argument_parser::
1929 argument_parser (function_format_info *info_, const char *&format_chars_,
1930 tree format_string_cst_,
1931 const char * const orig_format_chars_,
1932 location_t format_string_loc_,
1933 flag_chars_t &flag_chars_,
1934 int &has_operand_number_,
1935 tree first_fillin_param_,
1936 object_allocator <format_wanted_type> &fwt_pool_)
1937 : info (info_),
1938 fki (&format_types[info->format_type]),
1939 flag_specs (fki->flag_specs),
1940 start_of_this_format (format_chars_),
1941 format_chars (format_chars_),
1942 format_string_cst (format_string_cst_),
1943 orig_format_chars (orig_format_chars_),
1944 format_string_loc (format_string_loc_),
1945 fwt_pool (fwt_pool_),
1946 flag_chars (flag_chars_),
1947 main_arg_num (0),
1948 main_arg_params (NULL),
1949 has_operand_number (has_operand_number_),
1950 first_fillin_param (first_fillin_param_),
1951 first_wanted_type (NULL),
1952 last_wanted_type (NULL)
1956 /* Handle dollars at the start of format arguments, setting up main_arg_params
1957 and main_arg_num.
1959 Return true if format parsing is to continue, false otherwise. */
1961 bool
1962 argument_parser::read_any_dollar ()
1964 if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
1966 /* Possibly read a $ operand number at the start of the format.
1967 If one was previously used, one is required here. If one
1968 is not used here, we can't immediately conclude this is a
1969 format without them, since it could be printf %m or scanf %*. */
1970 int opnum;
1971 opnum = maybe_read_dollar_number (&format_chars, 0,
1972 first_fillin_param,
1973 &main_arg_params, fki);
1974 if (opnum == -1)
1975 return false;
1976 else if (opnum > 0)
1978 has_operand_number = 1;
1979 main_arg_num = opnum + info->first_arg_num - 1;
1982 else if (fki->flags & FMT_FLAG_USE_DOLLAR)
1984 if (avoid_dollar_number (format_chars))
1985 return false;
1987 return true;
1990 /* Read any format flags, but do not yet validate them beyond removing
1991 duplicates, since in general validation depends on the rest of
1992 the format.
1994 Return true if format parsing is to continue, false otherwise. */
1996 bool
1997 argument_parser::read_format_flags ()
1999 while (*format_chars != 0
2000 && strchr (fki->flag_chars, *format_chars) != 0)
2002 const format_flag_spec *s = get_flag_spec (flag_specs,
2003 *format_chars, NULL);
2004 if (flag_chars.has_char_p (*format_chars))
2006 format_warning_at_char (format_string_loc, format_string_cst,
2007 format_chars + 1 - orig_format_chars,
2008 OPT_Wformat_,
2009 "repeated %s in format", _(s->name));
2011 else
2012 flag_chars.add_char (*format_chars);
2014 if (s->skip_next_char)
2016 ++format_chars;
2017 if (*format_chars == 0)
2019 warning_at (format_string_loc, OPT_Wformat_,
2020 "missing fill character at end of strfmon format");
2021 return false;
2024 ++format_chars;
2027 return true;
2030 /* Read any format width, possibly * or *m$.
2032 Return true if format parsing is to continue, false otherwise. */
2034 bool
2035 argument_parser::
2036 read_any_format_width (tree &params,
2037 unsigned HOST_WIDE_INT &arg_num)
2039 if (!fki->width_char)
2040 return true;
2042 if (fki->width_type != NULL && *format_chars == '*')
2044 flag_chars.add_char (fki->width_char);
2045 /* "...a field width...may be indicated by an asterisk.
2046 In this case, an int argument supplies the field width..." */
2047 ++format_chars;
2048 if (has_operand_number != 0)
2050 int opnum;
2051 opnum = maybe_read_dollar_number (&format_chars,
2052 has_operand_number == 1,
2053 first_fillin_param,
2054 &params, fki);
2055 if (opnum == -1)
2056 return false;
2057 else if (opnum > 0)
2059 has_operand_number = 1;
2060 arg_num = opnum + info->first_arg_num - 1;
2062 else
2063 has_operand_number = 0;
2065 else
2067 if (avoid_dollar_number (format_chars))
2068 return false;
2070 if (info->first_arg_num != 0)
2072 tree cur_param;
2073 if (params == 0)
2074 cur_param = NULL;
2075 else
2077 cur_param = TREE_VALUE (params);
2078 if (has_operand_number <= 0)
2080 params = TREE_CHAIN (params);
2081 ++arg_num;
2084 width_wanted_type.wanted_type = *fki->width_type;
2085 width_wanted_type.wanted_type_name = NULL;
2086 width_wanted_type.pointer_count = 0;
2087 width_wanted_type.char_lenient_flag = 0;
2088 width_wanted_type.scalar_identity_flag = 0;
2089 width_wanted_type.writing_in_flag = 0;
2090 width_wanted_type.reading_from_flag = 0;
2091 width_wanted_type.kind = CF_KIND_FIELD_WIDTH;
2092 width_wanted_type.format_start = format_chars - 1;
2093 width_wanted_type.format_length = 1;
2094 width_wanted_type.param = cur_param;
2095 width_wanted_type.arg_num = arg_num;
2096 width_wanted_type.offset_loc =
2097 format_chars - orig_format_chars;
2098 width_wanted_type.next = NULL;
2099 if (last_wanted_type != 0)
2100 last_wanted_type->next = &width_wanted_type;
2101 if (first_wanted_type == 0)
2102 first_wanted_type = &width_wanted_type;
2103 last_wanted_type = &width_wanted_type;
2106 else
2108 /* Possibly read a numeric width. If the width is zero,
2109 we complain if appropriate. */
2110 int non_zero_width_char = FALSE;
2111 int found_width = FALSE;
2112 while (ISDIGIT (*format_chars))
2114 found_width = TRUE;
2115 if (*format_chars != '0')
2116 non_zero_width_char = TRUE;
2117 ++format_chars;
2119 if (found_width && !non_zero_width_char &&
2120 (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
2121 warning_at (format_string_loc, OPT_Wformat_,
2122 "zero width in %s format", fki->name);
2123 if (found_width)
2124 flag_chars.add_char (fki->width_char);
2127 return true;
2130 /* Read any format left precision (must be a number, not *). */
2131 void
2132 argument_parser::read_any_format_left_precision ()
2134 if (fki->left_precision_char == 0)
2135 return;
2136 if (*format_chars != '#')
2137 return;
2139 ++format_chars;
2140 flag_chars.add_char (fki->left_precision_char);
2141 if (!ISDIGIT (*format_chars))
2142 format_warning_at_char (format_string_loc, format_string_cst,
2143 format_chars - orig_format_chars,
2144 OPT_Wformat_,
2145 "empty left precision in %s format", fki->name);
2146 while (ISDIGIT (*format_chars))
2147 ++format_chars;
2150 /* Read any format precision, possibly * or *m$.
2152 Return true if format parsing is to continue, false otherwise. */
2154 bool
2155 argument_parser::
2156 read_any_format_precision (tree &params,
2157 unsigned HOST_WIDE_INT &arg_num)
2159 if (fki->precision_char == 0)
2160 return true;
2161 if (*format_chars != '.')
2162 return true;
2164 ++format_chars;
2165 flag_chars.add_char (fki->precision_char);
2166 if (fki->precision_type != NULL && *format_chars == '*')
2168 /* "...a...precision...may be indicated by an asterisk.
2169 In this case, an int argument supplies the...precision." */
2170 ++format_chars;
2171 if (has_operand_number != 0)
2173 int opnum;
2174 opnum = maybe_read_dollar_number (&format_chars,
2175 has_operand_number == 1,
2176 first_fillin_param,
2177 &params, fki);
2178 if (opnum == -1)
2179 return false;
2180 else if (opnum > 0)
2182 has_operand_number = 1;
2183 arg_num = opnum + info->first_arg_num - 1;
2185 else
2186 has_operand_number = 0;
2188 else
2190 if (avoid_dollar_number (format_chars))
2191 return false;
2193 if (info->first_arg_num != 0)
2195 tree cur_param;
2196 if (params == 0)
2197 cur_param = NULL;
2198 else
2200 cur_param = TREE_VALUE (params);
2201 if (has_operand_number <= 0)
2203 params = TREE_CHAIN (params);
2204 ++arg_num;
2207 precision_wanted_type.wanted_type = *fki->precision_type;
2208 precision_wanted_type.wanted_type_name = NULL;
2209 precision_wanted_type.pointer_count = 0;
2210 precision_wanted_type.char_lenient_flag = 0;
2211 precision_wanted_type.scalar_identity_flag = 0;
2212 precision_wanted_type.writing_in_flag = 0;
2213 precision_wanted_type.reading_from_flag = 0;
2214 precision_wanted_type.kind = CF_KIND_FIELD_PRECISION;
2215 precision_wanted_type.param = cur_param;
2216 precision_wanted_type.format_start = format_chars - 2;
2217 precision_wanted_type.format_length = 2;
2218 precision_wanted_type.arg_num = arg_num;
2219 precision_wanted_type.offset_loc =
2220 format_chars - orig_format_chars;
2221 precision_wanted_type.next = NULL;
2222 if (last_wanted_type != 0)
2223 last_wanted_type->next = &precision_wanted_type;
2224 if (first_wanted_type == 0)
2225 first_wanted_type = &precision_wanted_type;
2226 last_wanted_type = &precision_wanted_type;
2229 else
2231 if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
2232 && !ISDIGIT (*format_chars))
2233 format_warning_at_char (format_string_loc, format_string_cst,
2234 format_chars - orig_format_chars,
2235 OPT_Wformat_,
2236 "empty precision in %s format", fki->name);
2237 while (ISDIGIT (*format_chars))
2238 ++format_chars;
2241 return true;
2244 /* Parse any assignment-allocation flags, which request an extra
2245 char ** for writing back a dynamically-allocated char *.
2246 This is for handling the optional 'm' character in scanf,
2247 and, before C99, 'a' (for compatibility with a non-standard
2248 GNU libc extension). */
2250 void
2251 argument_parser::handle_alloc_chars ()
2253 if (fki->alloc_char && fki->alloc_char == *format_chars)
2255 flag_chars.add_char (fki->alloc_char);
2256 format_chars++;
2259 /* Handle the scanf allocation kludge. */
2260 if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
2262 if (*format_chars == 'a' && !flag_isoc99)
2264 if (format_chars[1] == 's' || format_chars[1] == 'S'
2265 || format_chars[1] == '[')
2267 /* 'a' is used as a flag. */
2268 flag_chars.add_char ('a');
2269 format_chars++;
2275 /* Look for length modifiers within the current format argument,
2276 returning a length_modifier instance describing it (or the
2277 default if one is not found).
2279 Issue warnings about non-standard modifiers. */
2281 length_modifier
2282 argument_parser::read_any_length_modifier ()
2284 length_modifier result;
2286 const format_length_info *fli = fki->length_char_specs;
2287 if (!fli)
2288 return result;
2290 while (fli->name != 0
2291 && strncmp (fli->name, format_chars, strlen (fli->name)))
2292 fli++;
2293 if (fli->name != 0)
2295 format_chars += strlen (fli->name);
2296 if (fli->double_name != 0 && fli->name[0] == *format_chars)
2298 format_chars++;
2299 result = length_modifier (fli->double_name, fli->double_index,
2300 fli->double_std, 0);
2302 else
2304 result = length_modifier (fli->name, fli->index, fli->std,
2305 fli->scalar_identity_flag);
2307 flag_chars.add_char (fki->length_code_char);
2309 if (pedantic)
2311 /* Warn if the length modifier is non-standard. */
2312 if (ADJ_STD (result.std) > C_STD_VER)
2313 warning_at (format_string_loc, OPT_Wformat_,
2314 "%s does not support the %qs %s length modifier",
2315 C_STD_NAME (result.std), result.chars,
2316 fki->name);
2319 return result;
2322 /* Read any other modifier (strftime E/O). */
2324 void
2325 argument_parser::read_any_other_modifier ()
2327 if (fki->modifier_chars == NULL)
2328 return;
2330 while (*format_chars != 0
2331 && strchr (fki->modifier_chars, *format_chars) != 0)
2333 if (flag_chars.has_char_p (*format_chars))
2335 const format_flag_spec *s = get_flag_spec (flag_specs,
2336 *format_chars, NULL);
2337 format_warning_at_char (format_string_loc, format_string_cst,
2338 format_chars - orig_format_chars,
2339 OPT_Wformat_,
2340 "repeated %s in format", _(s->name));
2342 else
2343 flag_chars.add_char (*format_chars);
2344 ++format_chars;
2348 /* Return the format_char_info corresponding to FORMAT_CHAR,
2349 potentially issuing a warning if the format char is
2350 not supported in the C standard version we are checking
2351 against.
2353 Issue a warning and return NULL if it is not found.
2355 Issue warnings about non-standard modifiers. */
2357 const format_char_info *
2358 argument_parser::find_format_char_info (char format_char)
2360 const format_char_info *fci = fki->conversion_specs;
2362 while (fci->format_chars != 0
2363 && strchr (fci->format_chars, format_char) == 0)
2364 ++fci;
2365 if (fci->format_chars == 0)
2367 format_warning_at_char (format_string_loc, format_string_cst,
2368 format_chars - orig_format_chars,
2369 OPT_Wformat_,
2370 "unknown conversion type character"
2371 " %qc in format",
2372 format_char);
2373 return NULL;
2376 if (pedantic)
2378 if (ADJ_STD (fci->std) > C_STD_VER)
2379 format_warning_at_char (format_string_loc, format_string_cst,
2380 format_chars - orig_format_chars,
2381 OPT_Wformat_,
2382 "%s does not support the %<%%%c%> %s format",
2383 C_STD_NAME (fci->std), format_char, fki->name);
2386 return fci;
2389 /* Validate the pairs of flags used.
2390 Issue warnings about incompatible combinations of flags. */
2392 void
2393 argument_parser::validate_flag_pairs (const format_char_info *fci,
2394 char format_char)
2396 const format_flag_pair * const bad_flag_pairs = fki->bad_flag_pairs;
2398 for (int i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
2400 const format_flag_spec *s, *t;
2401 if (!flag_chars.has_char_p (bad_flag_pairs[i].flag_char1))
2402 continue;
2403 if (!flag_chars.has_char_p (bad_flag_pairs[i].flag_char2))
2404 continue;
2405 if (bad_flag_pairs[i].predicate != 0
2406 && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
2407 continue;
2408 s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
2409 t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
2410 if (bad_flag_pairs[i].ignored)
2412 if (bad_flag_pairs[i].predicate != 0)
2413 warning_at (format_string_loc, OPT_Wformat_,
2414 "%s ignored with %s and %<%%%c%> %s format",
2415 _(s->name), _(t->name), format_char,
2416 fki->name);
2417 else
2418 warning_at (format_string_loc, OPT_Wformat_,
2419 "%s ignored with %s in %s format",
2420 _(s->name), _(t->name), fki->name);
2422 else
2424 if (bad_flag_pairs[i].predicate != 0)
2425 warning_at (format_string_loc, OPT_Wformat_,
2426 "use of %s and %s together with %<%%%c%> %s format",
2427 _(s->name), _(t->name), format_char,
2428 fki->name);
2429 else
2430 warning_at (format_string_loc, OPT_Wformat_,
2431 "use of %s and %s together in %s format",
2432 _(s->name), _(t->name), fki->name);
2437 /* Give Y2K warnings. */
2439 void
2440 argument_parser::give_y2k_warnings (const format_char_info *fci,
2441 char format_char)
2443 if (!warn_format_y2k)
2444 return;
2446 int y2k_level = 0;
2447 if (strchr (fci->flags2, '4') != 0)
2448 if (flag_chars.has_char_p ('E'))
2449 y2k_level = 3;
2450 else
2451 y2k_level = 2;
2452 else if (strchr (fci->flags2, '3') != 0)
2453 y2k_level = 3;
2454 else if (strchr (fci->flags2, '2') != 0)
2455 y2k_level = 2;
2456 if (y2k_level == 3)
2457 warning_at (format_string_loc, OPT_Wformat_y2k,
2458 "%<%%%c%> yields only last 2 digits of "
2459 "year in some locales", format_char);
2460 else if (y2k_level == 2)
2461 warning_at (format_string_loc, OPT_Wformat_y2k,
2462 "%<%%%c%> yields only last 2 digits of year",
2463 format_char);
2466 /* Parse any "scan sets" enclosed in square brackets, e.g.
2467 for scanf-style calls. */
2469 void
2470 argument_parser::parse_any_scan_set (const format_char_info *fci)
2472 if (strchr (fci->flags2, '[') == NULL)
2473 return;
2475 /* Skip over scan set, in case it happens to have '%' in it. */
2476 if (*format_chars == '^')
2477 ++format_chars;
2478 /* Find closing bracket; if one is hit immediately, then
2479 it's part of the scan set rather than a terminator. */
2480 if (*format_chars == ']')
2481 ++format_chars;
2482 while (*format_chars && *format_chars != ']')
2483 ++format_chars;
2484 if (*format_chars != ']')
2485 /* The end of the format string was reached. */
2486 format_warning_at_char (format_string_loc, format_string_cst,
2487 format_chars - orig_format_chars,
2488 OPT_Wformat_,
2489 "no closing %<]%> for %<%%[%> format");
2492 /* Return true if this argument is to be continued to be parsed,
2493 false to skip to next argument. */
2495 bool
2496 argument_parser::handle_conversions (const format_char_info *fci,
2497 const length_modifier &len_modifier,
2498 tree &wanted_type,
2499 const char *&wanted_type_name,
2500 unsigned HOST_WIDE_INT &arg_num,
2501 tree &params,
2502 char format_char)
2504 enum format_std_version wanted_type_std;
2506 if (!(fki->flags & (int) FMT_FLAG_ARG_CONVERT))
2507 return true;
2509 wanted_type = (fci->types[len_modifier.val].type
2510 ? *fci->types[len_modifier.val].type : 0);
2511 wanted_type_name = fci->types[len_modifier.val].name;
2512 wanted_type_std = fci->types[len_modifier.val].std;
2513 if (wanted_type == 0)
2515 format_warning_at_char (format_string_loc, format_string_cst,
2516 format_chars - orig_format_chars,
2517 OPT_Wformat_,
2518 "use of %qs length modifier with %qc type"
2519 " character has either no effect"
2520 " or undefined behavior",
2521 len_modifier.chars, format_char);
2522 /* Heuristic: skip one argument when an invalid length/type
2523 combination is encountered. */
2524 arg_num++;
2525 if (params != 0)
2526 params = TREE_CHAIN (params);
2527 return false;
2529 else if (pedantic
2530 /* Warn if non-standard, provided it is more non-standard
2531 than the length and type characters that may already
2532 have been warned for. */
2533 && ADJ_STD (wanted_type_std) > ADJ_STD (len_modifier.std)
2534 && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
2536 if (ADJ_STD (wanted_type_std) > C_STD_VER)
2537 format_warning_at_char (format_string_loc, format_string_cst,
2538 format_chars - orig_format_chars,
2539 OPT_Wformat_,
2540 "%s does not support the %<%%%s%c%> %s format",
2541 C_STD_NAME (wanted_type_std),
2542 len_modifier.chars,
2543 format_char, fki->name);
2546 return true;
2549 /* Check type of argument against desired type.
2551 Return true if format parsing is to continue, false otherwise. */
2553 bool
2554 argument_parser::
2555 check_argument_type (const format_char_info *fci,
2556 const length_modifier &len_modifier,
2557 tree &wanted_type,
2558 const char *&wanted_type_name,
2559 const bool suppressed,
2560 unsigned HOST_WIDE_INT &arg_num,
2561 tree &params,
2562 const int alloc_flag,
2563 const char * const format_start,
2564 const char * const type_start,
2565 location_t fmt_param_loc,
2566 char conversion_char)
2568 if (info->first_arg_num == 0)
2569 return true;
2571 if ((fci->pointer_count == 0 && wanted_type == void_type_node)
2572 || suppressed)
2574 if (main_arg_num != 0)
2576 if (suppressed)
2577 warning_at (format_string_loc, OPT_Wformat_,
2578 "operand number specified with "
2579 "suppressed assignment");
2580 else
2581 warning_at (format_string_loc, OPT_Wformat_,
2582 "operand number specified for format "
2583 "taking no argument");
2586 else
2588 format_wanted_type *wanted_type_ptr;
2590 if (main_arg_num != 0)
2592 arg_num = main_arg_num;
2593 params = main_arg_params;
2595 else
2597 ++arg_num;
2598 if (has_operand_number > 0)
2600 warning_at (format_string_loc, OPT_Wformat_,
2601 "missing $ operand number in format");
2602 return false;
2604 else
2605 has_operand_number = 0;
2608 wanted_type_ptr = &main_wanted_type;
2609 while (fci)
2611 tree cur_param;
2612 if (params == 0)
2613 cur_param = NULL;
2614 else
2616 cur_param = TREE_VALUE (params);
2617 params = TREE_CHAIN (params);
2620 wanted_type_ptr->wanted_type = wanted_type;
2621 wanted_type_ptr->wanted_type_name = wanted_type_name;
2622 wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag;
2623 wanted_type_ptr->char_lenient_flag = 0;
2624 if (strchr (fci->flags2, 'c') != 0)
2625 wanted_type_ptr->char_lenient_flag = 1;
2626 wanted_type_ptr->scalar_identity_flag = 0;
2627 if (len_modifier.scalar_identity_flag)
2628 wanted_type_ptr->scalar_identity_flag = 1;
2629 wanted_type_ptr->writing_in_flag = 0;
2630 wanted_type_ptr->reading_from_flag = 0;
2631 if (alloc_flag)
2632 wanted_type_ptr->writing_in_flag = 1;
2633 else
2635 if (strchr (fci->flags2, 'W') != 0)
2636 wanted_type_ptr->writing_in_flag = 1;
2637 if (strchr (fci->flags2, 'R') != 0)
2638 wanted_type_ptr->reading_from_flag = 1;
2640 wanted_type_ptr->kind = CF_KIND_FORMAT;
2641 wanted_type_ptr->param = cur_param;
2642 wanted_type_ptr->arg_num = arg_num;
2643 wanted_type_ptr->format_start = format_start;
2644 wanted_type_ptr->format_length = format_chars - format_start;
2645 wanted_type_ptr->offset_loc = format_chars - orig_format_chars;
2646 wanted_type_ptr->next = NULL;
2647 if (last_wanted_type != 0)
2648 last_wanted_type->next = wanted_type_ptr;
2649 if (first_wanted_type == 0)
2650 first_wanted_type = wanted_type_ptr;
2651 last_wanted_type = wanted_type_ptr;
2653 fci = fci->chain;
2654 if (fci)
2656 wanted_type_ptr = fwt_pool.allocate ();
2657 arg_num++;
2658 wanted_type = *fci->types[len_modifier.val].type;
2659 wanted_type_name = fci->types[len_modifier.val].name;
2664 if (first_wanted_type != 0)
2666 ptrdiff_t offset_to_format_start = (start_of_this_format - 1) - orig_format_chars;
2667 ptrdiff_t offset_to_format_end = (format_chars - 1) - orig_format_chars;
2668 /* By default, use the end of the range for the caret location. */
2669 substring_loc fmt_loc (fmt_param_loc, TREE_TYPE (format_string_cst),
2670 offset_to_format_end,
2671 offset_to_format_start, offset_to_format_end);
2672 ptrdiff_t offset_to_type_start = type_start - orig_format_chars;
2673 check_format_types (fmt_loc, first_wanted_type, fki,
2674 offset_to_type_start,
2675 conversion_char);
2678 return true;
2681 /* Do the main part of checking a call to a format function. FORMAT_CHARS
2682 is the NUL-terminated format string (which at this point may contain
2683 internal NUL characters); FORMAT_LENGTH is its length (excluding the
2684 terminating NUL character). ARG_NUM is one less than the number of
2685 the first format argument to check; PARAMS points to that format
2686 argument in the list of arguments. */
2688 static void
2689 check_format_info_main (format_check_results *res,
2690 function_format_info *info, const char *format_chars,
2691 location_t fmt_param_loc, tree format_string_cst,
2692 int format_length, tree params,
2693 unsigned HOST_WIDE_INT arg_num,
2694 object_allocator <format_wanted_type> &fwt_pool)
2696 const char * const orig_format_chars = format_chars;
2697 const tree first_fillin_param = params;
2699 const format_kind_info * const fki = &format_types[info->format_type];
2700 const format_flag_spec * const flag_specs = fki->flag_specs;
2701 const location_t format_string_loc = res->format_string_loc;
2703 /* -1 if no conversions taking an operand have been found; 0 if one has
2704 and it didn't use $; 1 if $ formats are in use. */
2705 int has_operand_number = -1;
2707 init_dollar_format_checking (info->first_arg_num, first_fillin_param);
2709 while (*format_chars != 0)
2711 if (*format_chars++ != '%')
2712 continue;
2713 if (*format_chars == 0)
2715 format_warning_at_char (format_string_loc, format_string_cst,
2716 format_chars - orig_format_chars,
2717 OPT_Wformat_,
2718 "spurious trailing %<%%%> in format");
2719 continue;
2721 if (*format_chars == '%')
2723 ++format_chars;
2724 continue;
2727 flag_chars_t flag_chars;
2728 argument_parser arg_parser (info, format_chars, format_string_cst,
2729 orig_format_chars, format_string_loc,
2730 flag_chars, has_operand_number,
2731 first_fillin_param, fwt_pool);
2733 if (!arg_parser.read_any_dollar ())
2734 return;
2736 if (!arg_parser.read_format_flags ())
2737 return;
2739 /* Read any format width, possibly * or *m$. */
2740 if (!arg_parser.read_any_format_width (params, arg_num))
2741 return;
2743 /* Read any format left precision (must be a number, not *). */
2744 arg_parser.read_any_format_left_precision ();
2746 /* Read any format precision, possibly * or *m$. */
2747 if (!arg_parser.read_any_format_precision (params, arg_num))
2748 return;
2750 const char *format_start = format_chars;
2752 arg_parser.handle_alloc_chars ();
2754 /* The rest of the conversion specification is the length modifier
2755 (if any), and the conversion specifier, so this is where the
2756 type information starts. If we need to issue a suggestion
2757 about a type mismatch, then we should preserve everything up
2758 to here. */
2759 const char *type_start = format_chars;
2761 /* Read any length modifier, if this kind of format has them. */
2762 const length_modifier len_modifier
2763 = arg_parser.read_any_length_modifier ();
2765 /* Read any modifier (strftime E/O). */
2766 arg_parser.read_any_other_modifier ();
2768 char format_char = *format_chars;
2769 if (format_char == 0
2770 || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
2771 && format_char == '%'))
2773 format_warning_at_char (format_string_loc, format_string_cst,
2774 format_chars - orig_format_chars,
2775 OPT_Wformat_,
2776 "conversion lacks type at end of format");
2777 continue;
2779 format_chars++;
2781 const format_char_info * const fci
2782 = arg_parser.find_format_char_info (format_char);
2783 if (!fci)
2784 continue;
2786 flag_chars.validate (fki, fci, flag_specs, format_chars,
2787 format_string_cst,
2788 format_string_loc, orig_format_chars, format_char);
2790 const int alloc_flag = flag_chars.get_alloc_flag (fki);
2791 const bool suppressed = flag_chars.assignment_suppression_p (fki);
2793 /* Validate the pairs of flags used. */
2794 arg_parser.validate_flag_pairs (fci, format_char);
2796 arg_parser.give_y2k_warnings (fci, format_char);
2798 arg_parser.parse_any_scan_set (fci);
2800 tree wanted_type = NULL;
2801 const char *wanted_type_name = NULL;
2803 if (!arg_parser.handle_conversions (fci, len_modifier,
2804 wanted_type, wanted_type_name,
2805 arg_num,
2806 params,
2807 format_char))
2808 continue;
2810 arg_parser.main_wanted_type.next = NULL;
2812 /* Finally. . .check type of argument against desired type! */
2813 if (!arg_parser.check_argument_type (fci, len_modifier,
2814 wanted_type, wanted_type_name,
2815 suppressed,
2816 arg_num, params,
2817 alloc_flag,
2818 format_start, type_start,
2819 fmt_param_loc,
2820 format_char))
2821 return;
2824 if (format_chars - orig_format_chars != format_length)
2825 format_warning_at_char (format_string_loc, format_string_cst,
2826 format_chars + 1 - orig_format_chars,
2827 OPT_Wformat_contains_nul,
2828 "embedded %<\\0%> in format");
2829 if (info->first_arg_num != 0 && params != 0
2830 && has_operand_number <= 0)
2832 res->number_other--;
2833 res->number_extra_args++;
2835 if (has_operand_number > 0)
2836 finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
2839 /* Check the argument types from a single format conversion (possibly
2840 including width and precision arguments).
2842 FMT_LOC is the location of the format conversion.
2844 TYPES is a singly-linked list expressing the parts of the format
2845 conversion that expect argument types, and the arguments they
2846 correspond to.
2848 OFFSET_TO_TYPE_START is the offset within the execution-charset encoded
2849 format string to where type information begins for the conversion
2850 (the length modifier and conversion specifier).
2852 CONVERSION_CHAR is the user-provided conversion specifier.
2854 For example, given:
2856 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2858 then FMT_LOC covers this range:
2860 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2861 ^^^^^^^^^
2863 and TYPES in this case is a three-entry singly-linked list consisting of:
2864 (1) the check for the field width here:
2865 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2866 ^ ^^^^
2867 against arg3, and
2868 (2) the check for the field precision here:
2869 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2870 ^^ ^^^^
2871 against arg4, and
2872 (3) the check for the length modifier and conversion char here:
2873 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2874 ^^^ ^^^^
2875 against arg5.
2877 OFFSET_TO_TYPE_START is 13, the offset to the "lld" within the
2878 STRING_CST:
2880 0000000000111111111122
2881 0123456789012345678901
2882 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2884 | ` CONVERSION_CHAR: 'd'
2885 type starts here. */
2887 static void
2888 check_format_types (const substring_loc &fmt_loc,
2889 format_wanted_type *types, const format_kind_info *fki,
2890 int offset_to_type_start,
2891 char conversion_char)
2893 for (; types != 0; types = types->next)
2895 tree cur_param;
2896 tree cur_type;
2897 tree orig_cur_type;
2898 tree wanted_type;
2899 int arg_num;
2900 int i;
2901 int char_type_flag;
2903 wanted_type = types->wanted_type;
2904 arg_num = types->arg_num;
2906 /* The following should not occur here. */
2907 gcc_assert (wanted_type);
2908 gcc_assert (wanted_type != void_type_node || types->pointer_count);
2910 if (types->pointer_count == 0)
2911 wanted_type = lang_hooks.types.type_promotes_to (wanted_type);
2913 wanted_type = TYPE_MAIN_VARIANT (wanted_type);
2915 cur_param = types->param;
2916 if (!cur_param)
2918 format_type_warning (fmt_loc, NULL, types, wanted_type, NULL, fki,
2919 offset_to_type_start, conversion_char);
2920 continue;
2923 cur_type = TREE_TYPE (cur_param);
2924 if (cur_type == error_mark_node)
2925 continue;
2926 orig_cur_type = cur_type;
2927 char_type_flag = 0;
2929 source_range param_range;
2930 source_range *param_range_ptr;
2931 if (CAN_HAVE_LOCATION_P (cur_param))
2933 param_range = EXPR_LOCATION_RANGE (cur_param);
2934 param_range_ptr = &param_range;
2936 else
2937 param_range_ptr = NULL;
2939 STRIP_NOPS (cur_param);
2941 /* Check the types of any additional pointer arguments
2942 that precede the "real" argument. */
2943 for (i = 0; i < types->pointer_count; ++i)
2945 if (TREE_CODE (cur_type) == POINTER_TYPE)
2947 cur_type = TREE_TYPE (cur_type);
2948 if (cur_type == error_mark_node)
2949 break;
2951 /* Check for writing through a NULL pointer. */
2952 if (types->writing_in_flag
2953 && i == 0
2954 && cur_param != 0
2955 && integer_zerop (cur_param))
2956 warning (OPT_Wformat_, "writing through null pointer "
2957 "(argument %d)", arg_num);
2959 /* Check for reading through a NULL pointer. */
2960 if (types->reading_from_flag
2961 && i == 0
2962 && cur_param != 0
2963 && integer_zerop (cur_param))
2964 warning (OPT_Wformat_, "reading through null pointer "
2965 "(argument %d)", arg_num);
2967 if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
2968 cur_param = TREE_OPERAND (cur_param, 0);
2969 else
2970 cur_param = 0;
2972 /* See if this is an attempt to write into a const type with
2973 scanf or with printf "%n". Note: the writing in happens
2974 at the first indirection only, if for example
2975 void * const * is passed to scanf %p; passing
2976 const void ** is simply passing an incompatible type. */
2977 if (types->writing_in_flag
2978 && i == 0
2979 && (TYPE_READONLY (cur_type)
2980 || (cur_param != 0
2981 && (CONSTANT_CLASS_P (cur_param)
2982 || (DECL_P (cur_param)
2983 && TREE_READONLY (cur_param))))))
2984 warning (OPT_Wformat_, "writing into constant object "
2985 "(argument %d)", arg_num);
2987 /* If there are extra type qualifiers beyond the first
2988 indirection, then this makes the types technically
2989 incompatible. */
2990 if (i > 0
2991 && pedantic
2992 && (TYPE_READONLY (cur_type)
2993 || TYPE_VOLATILE (cur_type)
2994 || TYPE_ATOMIC (cur_type)
2995 || TYPE_RESTRICT (cur_type)))
2996 warning (OPT_Wformat_, "extra type qualifiers in format "
2997 "argument (argument %d)",
2998 arg_num);
3001 else
3003 format_type_warning (fmt_loc, param_range_ptr,
3004 types, wanted_type, orig_cur_type, fki,
3005 offset_to_type_start, conversion_char);
3006 break;
3010 if (i < types->pointer_count)
3011 continue;
3013 cur_type = TYPE_MAIN_VARIANT (cur_type);
3015 /* Check whether the argument type is a character type. This leniency
3016 only applies to certain formats, flagged with 'c'. */
3017 if (types->char_lenient_flag)
3018 char_type_flag = (cur_type == char_type_node
3019 || cur_type == signed_char_type_node
3020 || cur_type == unsigned_char_type_node);
3022 /* Check the type of the "real" argument, if there's a type we want. */
3023 if (lang_hooks.types_compatible_p (wanted_type, cur_type))
3024 continue;
3025 /* If we want 'void *', allow any pointer type.
3026 (Anything else would already have got a warning.)
3027 With -Wpedantic, only allow pointers to void and to character
3028 types. */
3029 if (wanted_type == void_type_node
3030 && (!pedantic || (i == 1 && char_type_flag)))
3031 continue;
3032 /* Don't warn about differences merely in signedness, unless
3033 -Wpedantic. With -Wpedantic, warn if the type is a pointer
3034 target and not a character type, and for character types at
3035 a second level of indirection. */
3036 if (TREE_CODE (wanted_type) == INTEGER_TYPE
3037 && TREE_CODE (cur_type) == INTEGER_TYPE
3038 && ((!pedantic && !warn_format_signedness)
3039 || (i == 0 && !warn_format_signedness)
3040 || (i == 1 && char_type_flag))
3041 && (TYPE_UNSIGNED (wanted_type)
3042 ? wanted_type == c_common_unsigned_type (cur_type)
3043 : wanted_type == c_common_signed_type (cur_type)))
3044 continue;
3045 /* Don't warn about differences merely in signedness if we know
3046 that the current type is integer-promoted and its original type
3047 was unsigned such as that it is in the range of WANTED_TYPE. */
3048 if (TREE_CODE (wanted_type) == INTEGER_TYPE
3049 && TREE_CODE (cur_type) == INTEGER_TYPE
3050 && warn_format_signedness
3051 && TYPE_UNSIGNED (wanted_type)
3052 && cur_param != NULL_TREE
3053 && TREE_CODE (cur_param) == NOP_EXPR)
3055 tree t = TREE_TYPE (TREE_OPERAND (cur_param, 0));
3056 if (TYPE_UNSIGNED (t)
3057 && cur_type == lang_hooks.types.type_promotes_to (t))
3058 continue;
3060 /* Likewise, "signed char", "unsigned char" and "char" are
3061 equivalent but the above test won't consider them equivalent. */
3062 if (wanted_type == char_type_node
3063 && (!pedantic || i < 2)
3064 && char_type_flag)
3065 continue;
3066 if (types->scalar_identity_flag
3067 && (TREE_CODE (cur_type) == TREE_CODE (wanted_type)
3068 || (INTEGRAL_TYPE_P (cur_type)
3069 && INTEGRAL_TYPE_P (wanted_type)))
3070 && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type))
3071 continue;
3072 /* Now we have a type mismatch. */
3073 format_type_warning (fmt_loc, param_range_ptr, types,
3074 wanted_type, orig_cur_type, fki,
3075 offset_to_type_start, conversion_char);
3079 /* Given type TYPE, attempt to dereference the type N times
3080 (e.g. from ("int ***", 2) to "int *")
3082 Return the derefenced type, with any qualifiers
3083 such as "const" stripped from the result, or
3084 NULL if unsuccessful (e.g. TYPE is not a pointer type). */
3086 static tree
3087 deref_n_times (tree type, int n)
3089 gcc_assert (type);
3091 for (int i = n; i > 0; i--)
3093 if (TREE_CODE (type) != POINTER_TYPE)
3094 return NULL_TREE;
3095 type = TREE_TYPE (type);
3097 /* Strip off any "const" etc. */
3098 return build_qualified_type (type, 0);
3101 /* Lookup the format code for FORMAT_LEN within FLI,
3102 returning the string code for expressing it, or NULL
3103 if it is not found. */
3105 static const char *
3106 get_modifier_for_format_len (const format_length_info *fli,
3107 enum format_lengths format_len)
3109 for (; fli->name; fli++)
3111 if (fli->index == format_len)
3112 return fli->name;
3113 if (fli->double_index == format_len)
3114 return fli->double_name;
3116 return NULL;
3119 #if CHECKING_P
3121 namespace selftest {
3123 static void
3124 test_get_modifier_for_format_len ()
3126 ASSERT_STREQ ("h",
3127 get_modifier_for_format_len (printf_length_specs, FMT_LEN_h));
3128 ASSERT_STREQ ("hh",
3129 get_modifier_for_format_len (printf_length_specs, FMT_LEN_hh));
3130 ASSERT_STREQ ("L",
3131 get_modifier_for_format_len (printf_length_specs, FMT_LEN_L));
3132 ASSERT_EQ (NULL,
3133 get_modifier_for_format_len (printf_length_specs, FMT_LEN_none));
3136 } // namespace selftest
3138 #endif /* CHECKING_P */
3140 /* Determine if SPEC_TYPE and ARG_TYPE are sufficiently similar for a
3141 format_type_detail using SPEC_TYPE to be offered as a suggestion for
3142 Wformat type errors where the argument has type ARG_TYPE. */
3144 static bool
3145 matching_type_p (tree spec_type, tree arg_type)
3147 gcc_assert (spec_type);
3148 gcc_assert (arg_type);
3150 spec_type = TYPE_CANONICAL (spec_type);
3151 arg_type = TYPE_CANONICAL (arg_type);
3153 if (TREE_CODE (spec_type) == INTEGER_TYPE
3154 && TREE_CODE (arg_type) == INTEGER_TYPE
3155 && (TYPE_UNSIGNED (spec_type)
3156 ? spec_type == c_common_unsigned_type (arg_type)
3157 : spec_type == c_common_signed_type (arg_type)))
3158 return true;
3160 return spec_type == arg_type;
3163 /* Subroutine of get_format_for_type.
3165 Generate a string containing the length modifier and conversion specifier
3166 that should be used to format arguments of type ARG_TYPE within FKI
3167 (effectively the inverse of the checking code).
3169 If CONVERSION_CHAR is not zero (the first pass), the resulting suggestion
3170 is required to use it, for correcting bogus length modifiers.
3171 If CONVERSION_CHAR is zero (the second pass), then allow any suggestion
3172 that matches ARG_TYPE.
3174 If successful, returns a non-NULL string which should be freed
3175 by the caller.
3176 Otherwise, returns NULL. */
3178 static char *
3179 get_format_for_type_1 (const format_kind_info *fki, tree arg_type,
3180 char conversion_char)
3182 gcc_assert (arg_type);
3184 const format_char_info *spec;
3185 for (spec = &fki->conversion_specs[0];
3186 spec->format_chars;
3187 spec++)
3189 if (conversion_char)
3190 if (!strchr (spec->format_chars, conversion_char))
3191 continue;
3193 tree effective_arg_type = deref_n_times (arg_type,
3194 spec->pointer_count);
3195 if (!effective_arg_type)
3196 continue;
3197 for (int i = 0; i < FMT_LEN_MAX; i++)
3199 const format_type_detail *ftd = &spec->types[i];
3200 if (!ftd->type)
3201 continue;
3202 if (matching_type_p (*ftd->type, effective_arg_type))
3204 const char *len_modifier
3205 = get_modifier_for_format_len (fki->length_char_specs,
3206 (enum format_lengths)i);
3207 if (!len_modifier)
3208 len_modifier = "";
3210 if (conversion_char)
3211 /* We found a match, using the given conversion char - the
3212 length modifier was incorrect (or absent).
3213 Provide a suggestion using the conversion char with the
3214 correct length modifier for the type. */
3215 return xasprintf ("%s%c", len_modifier, conversion_char);
3216 else
3217 /* 2nd pass: no match was possible using the user-provided
3218 conversion char, but we do have a match without using it.
3219 Provide a suggestion using the first conversion char
3220 listed for the given type. */
3221 return xasprintf ("%s%c", len_modifier, spec->format_chars[0]);
3226 return NULL;
3229 /* Generate a string containing the length modifier and conversion specifier
3230 that should be used to format arguments of type ARG_TYPE within FKI
3231 (effectively the inverse of the checking code).
3233 If successful, returns a non-NULL string which should be freed
3234 by the caller.
3235 Otherwise, returns NULL. */
3237 static char *
3238 get_format_for_type (const format_kind_info *fki, tree arg_type,
3239 char conversion_char)
3241 gcc_assert (arg_type);
3242 gcc_assert (conversion_char);
3244 /* First pass: look for a format_char_info containing CONVERSION_CHAR
3245 If we find one, then presumably the length modifier was incorrect
3246 (or absent). */
3247 char *result = get_format_for_type_1 (fki, arg_type, conversion_char);
3248 if (result)
3249 return result;
3251 /* Second pass: we didn't find a match for CONVERSION_CHAR, so try
3252 matching just on the type. */
3253 return get_format_for_type_1 (fki, arg_type, '\0');
3256 /* Attempt to get a string for use as a replacement fix-it hint for the
3257 source range in FMT_LOC.
3259 Preserve all of the text within the range of FMT_LOC up to
3260 OFFSET_TO_TYPE_START, replacing the rest with an appropriate
3261 length modifier and conversion specifier for ARG_TYPE, attempting
3262 to keep the user-provided CONVERSION_CHAR if possible.
3264 For example, given a long vs long long mismatch for arg5 here:
3266 000000000111111111122222222223333333333|
3267 123456789012345678901234567890123456789` column numbers
3268 0000000000111111111122|
3269 0123456789012345678901` string offsets
3270 V~~~~~~~~ : range of FMT_LOC, from cols 23-31
3271 sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
3273 | ` CONVERSION_CHAR: 'd'
3274 type starts here
3276 where OFFSET_TO_TYPE_START is 13 (the offset to the "lld" within the
3277 STRING_CST), where the user provided:
3278 %-+*.*lld
3279 the result (assuming "long" argument 5) should be:
3280 %-+*.*ld
3282 If successful, returns a non-NULL string which should be freed
3283 by the caller.
3284 Otherwise, returns NULL. */
3286 static char *
3287 get_corrected_substring (const substring_loc &fmt_loc,
3288 format_wanted_type *type, tree arg_type,
3289 const format_kind_info *fki,
3290 int offset_to_type_start, char conversion_char)
3292 /* Attempt to provide hints for argument types, but not for field widths
3293 and precisions. */
3294 if (!arg_type)
3295 return NULL;
3296 if (type->kind != CF_KIND_FORMAT)
3297 return NULL;
3299 /* Locate the current code within the source range, rejecting
3300 any awkward cases where the format string occupies more than
3301 one line.
3302 Lookup the place where the type starts (including any length
3303 modifiers), getting it as the caret location. */
3304 substring_loc type_loc (fmt_loc);
3305 type_loc.set_caret_index (offset_to_type_start);
3307 location_t fmt_substring_loc;
3308 const char *err = type_loc.get_location (&fmt_substring_loc);
3309 if (err)
3310 return NULL;
3312 source_range fmt_substring_range
3313 = get_range_from_loc (line_table, fmt_substring_loc);
3315 expanded_location caret
3316 = expand_location_to_spelling_point (fmt_substring_loc);
3317 expanded_location start
3318 = expand_location_to_spelling_point (fmt_substring_range.m_start);
3319 expanded_location finish
3320 = expand_location_to_spelling_point (fmt_substring_range.m_finish);
3321 if (caret.file != start.file)
3322 return NULL;
3323 if (start.file != finish.file)
3324 return NULL;
3325 if (caret.line != start.line)
3326 return NULL;
3327 if (start.line != finish.line)
3328 return NULL;
3329 if (start.column > caret.column)
3330 return NULL;
3331 if (start.column > finish.column)
3332 return NULL;
3333 if (caret.column > finish.column)
3334 return NULL;
3336 int line_width;
3337 const char *line = location_get_source_line (start.file, start.line,
3338 &line_width);
3339 if (line == NULL)
3340 return NULL;
3342 /* If we got this far, then we have the line containing the
3343 existing conversion specification.
3345 Generate a trimmed copy, containing the prefix part of the conversion
3346 specification, up to the (but not including) the length modifier.
3347 In the above example, this would be "%-+*.*". */
3348 const char *current_content = line + start.column - 1;
3349 int length_up_to_type = caret.column - start.column;
3350 char *prefix = xstrndup (current_content, length_up_to_type);
3352 /* Now attempt to generate a suggestion for the rest of the specification
3353 (length modifier and conversion char), based on ARG_TYPE and
3354 CONVERSION_CHAR.
3355 In the above example, this would be "ld". */
3356 char *format_for_type = get_format_for_type (fki, arg_type, conversion_char);
3357 if (!format_for_type)
3359 free (prefix);
3360 return NULL;
3363 /* Success. Generate the resulting suggestion for the whole range of
3364 FMT_LOC by concatenating the two strings.
3365 In the above example, this would be "%-+*.*ld". */
3366 char *result = concat (prefix, format_for_type, NULL);
3367 free (format_for_type);
3368 free (prefix);
3369 return result;
3372 /* Give a warning about a format argument of different type from that expected.
3373 The range of the diagnostic is taken from WHOLE_FMT_LOC; the caret location
3374 is based on the location of the char at TYPE->offset_loc.
3375 If non-NULL, PARAM_RANGE is the source range of the
3376 relevant argument. WANTED_TYPE is the type the argument should have,
3377 possibly stripped of pointer dereferences. The description (such as "field
3378 precision"), the placement in the format string, a possibly more
3379 friendly name of WANTED_TYPE, and the number of pointer dereferences
3380 are taken from TYPE. ARG_TYPE is the type of the actual argument,
3381 or NULL if it is missing.
3383 OFFSET_TO_TYPE_START is the offset within the execution-charset encoded
3384 format string to where type information begins for the conversion
3385 (the length modifier and conversion specifier).
3386 CONVERSION_CHAR is the user-provided conversion specifier.
3388 For example, given a type mismatch for argument 5 here:
3390 00000000011111111112222222222333333333344444444445555555555|
3391 12345678901234567890123456789012345678901234567890123456789` column numbers
3392 0000000000111111111122|
3393 0123456789012345678901` offsets within STRING_CST
3394 V~~~~~~~~ : range of WHOLE_FMT_LOC, from cols 23-31
3395 sprintf (d, "before %-+*.*lld after", int_expr, int_expr, long_expr);
3396 ^ ^ ^~~~~~~~~
3397 | ` CONVERSION_CHAR: 'd' *PARAM_RANGE
3398 type starts here
3400 OFFSET_TO_TYPE_START is 13, the offset to the "lld" within the
3401 STRING_CST. */
3403 static void
3404 format_type_warning (const substring_loc &whole_fmt_loc,
3405 source_range *param_range,
3406 format_wanted_type *type,
3407 tree wanted_type, tree arg_type,
3408 const format_kind_info *fki,
3409 int offset_to_type_start,
3410 char conversion_char)
3412 enum format_specifier_kind kind = type->kind;
3413 const char *wanted_type_name = type->wanted_type_name;
3414 const char *format_start = type->format_start;
3415 int format_length = type->format_length;
3416 int pointer_count = type->pointer_count;
3417 int arg_num = type->arg_num;
3419 char *p;
3420 /* If ARG_TYPE is a typedef with a misleading name (for example,
3421 size_t but not the standard size_t expected by printf %zu), avoid
3422 printing the typedef name. */
3423 if (wanted_type_name
3424 && arg_type
3425 && TYPE_NAME (arg_type)
3426 && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL
3427 && DECL_NAME (TYPE_NAME (arg_type))
3428 && !strcmp (wanted_type_name,
3429 lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2)))
3430 arg_type = TYPE_MAIN_VARIANT (arg_type);
3431 /* The format type and name exclude any '*' for pointers, so those
3432 must be formatted manually. For all the types we currently have,
3433 this is adequate, but formats taking pointers to functions or
3434 arrays would require the full type to be built up in order to
3435 print it with %T. */
3436 p = (char *) alloca (pointer_count + 2);
3437 if (pointer_count == 0)
3438 p[0] = 0;
3439 else if (c_dialect_cxx ())
3441 memset (p, '*', pointer_count);
3442 p[pointer_count] = 0;
3444 else
3446 p[0] = ' ';
3447 memset (p + 1, '*', pointer_count);
3448 p[pointer_count + 1] = 0;
3451 /* WHOLE_FMT_LOC has the caret at the end of the range.
3452 Set the caret to be at the offset from TYPE. Subtract one
3453 from the offset for the same reason as in format_warning_at_char. */
3454 substring_loc fmt_loc (whole_fmt_loc);
3455 fmt_loc.set_caret_index (type->offset_loc - 1);
3457 /* Get a string for use as a replacement fix-it hint for the range in
3458 fmt_loc, or NULL. */
3459 char *corrected_substring
3460 = get_corrected_substring (fmt_loc, type, arg_type, fki,
3461 offset_to_type_start, conversion_char);
3463 if (wanted_type_name)
3465 if (arg_type)
3466 format_warning_at_substring
3467 (fmt_loc, param_range,
3468 corrected_substring, OPT_Wformat_,
3469 "%s %<%s%.*s%> expects argument of type %<%s%s%>, "
3470 "but argument %d has type %qT",
3471 gettext (kind_descriptions[kind]),
3472 (kind == CF_KIND_FORMAT ? "%" : ""),
3473 format_length, format_start,
3474 wanted_type_name, p, arg_num, arg_type);
3475 else
3476 format_warning_at_substring
3477 (fmt_loc, param_range,
3478 corrected_substring, OPT_Wformat_,
3479 "%s %<%s%.*s%> expects a matching %<%s%s%> argument",
3480 gettext (kind_descriptions[kind]),
3481 (kind == CF_KIND_FORMAT ? "%" : ""),
3482 format_length, format_start, wanted_type_name, p);
3484 else
3486 if (arg_type)
3487 format_warning_at_substring
3488 (fmt_loc, param_range,
3489 corrected_substring, OPT_Wformat_,
3490 "%s %<%s%.*s%> expects argument of type %<%T%s%>, "
3491 "but argument %d has type %qT",
3492 gettext (kind_descriptions[kind]),
3493 (kind == CF_KIND_FORMAT ? "%" : ""),
3494 format_length, format_start,
3495 wanted_type, p, arg_num, arg_type);
3496 else
3497 format_warning_at_substring
3498 (fmt_loc, param_range,
3499 corrected_substring, OPT_Wformat_,
3500 "%s %<%s%.*s%> expects a matching %<%T%s%> argument",
3501 gettext (kind_descriptions[kind]),
3502 (kind == CF_KIND_FORMAT ? "%" : ""),
3503 format_length, format_start, wanted_type, p);
3506 free (corrected_substring);
3510 /* Given a format_char_info array FCI, and a character C, this function
3511 returns the index into the conversion_specs where that specifier's
3512 data is located. The character must exist. */
3513 static unsigned int
3514 find_char_info_specifier_index (const format_char_info *fci, int c)
3516 unsigned i;
3518 for (i = 0; fci->format_chars; i++, fci++)
3519 if (strchr (fci->format_chars, c))
3520 return i;
3522 /* We shouldn't be looking for a non-existent specifier. */
3523 gcc_unreachable ();
3526 /* Given a format_length_info array FLI, and a character C, this
3527 function returns the index into the conversion_specs where that
3528 modifier's data is located. The character must exist. */
3529 static unsigned int
3530 find_length_info_modifier_index (const format_length_info *fli, int c)
3532 unsigned i;
3534 for (i = 0; fli->name; i++, fli++)
3535 if (strchr (fli->name, c))
3536 return i;
3538 /* We shouldn't be looking for a non-existent modifier. */
3539 gcc_unreachable ();
3542 /* Determine the type of HOST_WIDE_INT in the code being compiled for
3543 use in GCC's __asm_fprintf__ custom format attribute. You must
3544 have set dynamic_format_types before calling this function. */
3545 static void
3546 init_dynamic_asm_fprintf_info (void)
3548 static tree hwi;
3550 if (!hwi)
3552 format_length_info *new_asm_fprintf_length_specs;
3553 unsigned int i;
3555 /* Find the underlying type for HOST_WIDE_INT. For the %w
3556 length modifier to work, one must have issued: "typedef
3557 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
3558 prior to using that modifier. */
3559 hwi = maybe_get_identifier ("__gcc_host_wide_int__");
3560 if (!hwi)
3562 error ("%<__gcc_host_wide_int__%> is not defined as a type");
3563 return;
3565 hwi = identifier_global_value (hwi);
3566 if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
3568 error ("%<__gcc_host_wide_int__%> is not defined as a type");
3569 return;
3571 hwi = DECL_ORIGINAL_TYPE (hwi);
3572 gcc_assert (hwi);
3573 if (hwi != long_integer_type_node && hwi != long_long_integer_type_node)
3575 error ("%<__gcc_host_wide_int__%> is not defined as %<long%>"
3576 " or %<long long%>");
3577 return;
3580 /* Create a new (writable) copy of asm_fprintf_length_specs. */
3581 new_asm_fprintf_length_specs = (format_length_info *)
3582 xmemdup (asm_fprintf_length_specs,
3583 sizeof (asm_fprintf_length_specs),
3584 sizeof (asm_fprintf_length_specs));
3586 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
3587 i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
3588 if (hwi == long_integer_type_node)
3589 new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
3590 else if (hwi == long_long_integer_type_node)
3591 new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
3592 else
3593 gcc_unreachable ();
3595 /* Assign the new data for use. */
3596 dynamic_format_types[asm_fprintf_format_type].length_char_specs =
3597 new_asm_fprintf_length_specs;
3601 /* Determine the type of a "locus" in the code being compiled for use
3602 in GCC's __gcc_gfc__ custom format attribute. You must have set
3603 dynamic_format_types before calling this function. */
3604 static void
3605 init_dynamic_gfc_info (void)
3607 static tree locus;
3609 if (!locus)
3611 static format_char_info *gfc_fci;
3613 /* For the GCC __gcc_gfc__ custom format specifier to work, one
3614 must have declared 'locus' prior to using this attribute. If
3615 we haven't seen this declarations then you shouldn't use the
3616 specifier requiring that type. */
3617 if ((locus = maybe_get_identifier ("locus")))
3619 locus = identifier_global_value (locus);
3620 if (locus)
3622 if (TREE_CODE (locus) != TYPE_DECL
3623 || TREE_TYPE (locus) == error_mark_node)
3625 error ("%<locus%> is not defined as a type");
3626 locus = 0;
3628 else
3629 locus = TREE_TYPE (locus);
3633 /* Assign the new data for use. */
3635 /* Handle the __gcc_gfc__ format specifics. */
3636 if (!gfc_fci)
3637 dynamic_format_types[gcc_gfc_format_type].conversion_specs =
3638 gfc_fci = (format_char_info *)
3639 xmemdup (gcc_gfc_char_table,
3640 sizeof (gcc_gfc_char_table),
3641 sizeof (gcc_gfc_char_table));
3642 if (locus)
3644 const unsigned i = find_char_info_specifier_index (gfc_fci, 'L');
3645 gfc_fci[i].types[0].type = &locus;
3646 gfc_fci[i].pointer_count = 1;
3651 /* Determine the types of "tree" and "location_t" in the code being
3652 compiled for use in GCC's diagnostic custom format attributes. You
3653 must have set dynamic_format_types before calling this function. */
3654 static void
3655 init_dynamic_diag_info (void)
3657 static tree t, loc, hwi;
3659 if (!loc || !t || !hwi)
3661 static format_char_info *diag_fci, *tdiag_fci, *cdiag_fci, *cxxdiag_fci;
3662 static format_length_info *diag_ls;
3663 unsigned int i;
3665 /* For the GCC-diagnostics custom format specifiers to work, one
3666 must have declared 'tree' and/or 'location_t' prior to using
3667 those attributes. If we haven't seen these declarations then
3668 you shouldn't use the specifiers requiring these types.
3669 However we don't force a hard ICE because we may see only one
3670 or the other type. */
3671 if ((loc = maybe_get_identifier ("location_t")))
3673 loc = identifier_global_value (loc);
3674 if (loc)
3676 if (TREE_CODE (loc) != TYPE_DECL)
3678 error ("%<location_t%> is not defined as a type");
3679 loc = 0;
3681 else
3682 loc = TREE_TYPE (loc);
3686 /* We need to grab the underlying 'union tree_node' so peek into
3687 an extra type level. */
3688 if ((t = maybe_get_identifier ("tree")))
3690 t = identifier_global_value (t);
3691 if (t)
3693 if (TREE_CODE (t) != TYPE_DECL)
3695 error ("%<tree%> is not defined as a type");
3696 t = 0;
3698 else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
3700 error ("%<tree%> is not defined as a pointer type");
3701 t = 0;
3703 else
3704 t = TREE_TYPE (TREE_TYPE (t));
3708 /* Find the underlying type for HOST_WIDE_INT. For the %w
3709 length modifier to work, one must have issued: "typedef
3710 HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
3711 prior to using that modifier. */
3712 if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
3714 hwi = identifier_global_value (hwi);
3715 if (hwi)
3717 if (TREE_CODE (hwi) != TYPE_DECL)
3719 error ("%<__gcc_host_wide_int__%> is not defined as a type");
3720 hwi = 0;
3722 else
3724 hwi = DECL_ORIGINAL_TYPE (hwi);
3725 gcc_assert (hwi);
3726 if (hwi != long_integer_type_node
3727 && hwi != long_long_integer_type_node)
3729 error ("%<__gcc_host_wide_int__%> is not defined"
3730 " as %<long%> or %<long long%>");
3731 hwi = 0;
3737 /* Assign the new data for use. */
3739 /* All the GCC diag formats use the same length specs. */
3740 if (!diag_ls)
3741 dynamic_format_types[gcc_diag_format_type].length_char_specs =
3742 dynamic_format_types[gcc_tdiag_format_type].length_char_specs =
3743 dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
3744 dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
3745 diag_ls = (format_length_info *)
3746 xmemdup (gcc_diag_length_specs,
3747 sizeof (gcc_diag_length_specs),
3748 sizeof (gcc_diag_length_specs));
3749 if (hwi)
3751 /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
3752 i = find_length_info_modifier_index (diag_ls, 'w');
3753 if (hwi == long_integer_type_node)
3754 diag_ls[i].index = FMT_LEN_l;
3755 else if (hwi == long_long_integer_type_node)
3756 diag_ls[i].index = FMT_LEN_ll;
3757 else
3758 gcc_unreachable ();
3761 /* Handle the __gcc_diag__ format specifics. */
3762 if (!diag_fci)
3763 dynamic_format_types[gcc_diag_format_type].conversion_specs =
3764 diag_fci = (format_char_info *)
3765 xmemdup (gcc_diag_char_table,
3766 sizeof (gcc_diag_char_table),
3767 sizeof (gcc_diag_char_table));
3768 if (t)
3770 i = find_char_info_specifier_index (diag_fci, 'K');
3771 diag_fci[i].types[0].type = &t;
3772 diag_fci[i].pointer_count = 1;
3775 /* Handle the __gcc_tdiag__ format specifics. */
3776 if (!tdiag_fci)
3777 dynamic_format_types[gcc_tdiag_format_type].conversion_specs =
3778 tdiag_fci = (format_char_info *)
3779 xmemdup (gcc_tdiag_char_table,
3780 sizeof (gcc_tdiag_char_table),
3781 sizeof (gcc_tdiag_char_table));
3782 if (t)
3784 /* All specifiers taking a tree share the same struct. */
3785 i = find_char_info_specifier_index (tdiag_fci, 'D');
3786 tdiag_fci[i].types[0].type = &t;
3787 tdiag_fci[i].pointer_count = 1;
3788 i = find_char_info_specifier_index (tdiag_fci, 'K');
3789 tdiag_fci[i].types[0].type = &t;
3790 tdiag_fci[i].pointer_count = 1;
3793 /* Handle the __gcc_cdiag__ format specifics. */
3794 if (!cdiag_fci)
3795 dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
3796 cdiag_fci = (format_char_info *)
3797 xmemdup (gcc_cdiag_char_table,
3798 sizeof (gcc_cdiag_char_table),
3799 sizeof (gcc_cdiag_char_table));
3800 if (t)
3802 /* All specifiers taking a tree share the same struct. */
3803 i = find_char_info_specifier_index (cdiag_fci, 'D');
3804 cdiag_fci[i].types[0].type = &t;
3805 cdiag_fci[i].pointer_count = 1;
3806 i = find_char_info_specifier_index (cdiag_fci, 'K');
3807 cdiag_fci[i].types[0].type = &t;
3808 cdiag_fci[i].pointer_count = 1;
3811 /* Handle the __gcc_cxxdiag__ format specifics. */
3812 if (!cxxdiag_fci)
3813 dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
3814 cxxdiag_fci = (format_char_info *)
3815 xmemdup (gcc_cxxdiag_char_table,
3816 sizeof (gcc_cxxdiag_char_table),
3817 sizeof (gcc_cxxdiag_char_table));
3818 if (t)
3820 /* All specifiers taking a tree share the same struct. */
3821 i = find_char_info_specifier_index (cxxdiag_fci, 'D');
3822 cxxdiag_fci[i].types[0].type = &t;
3823 cxxdiag_fci[i].pointer_count = 1;
3824 i = find_char_info_specifier_index (cxxdiag_fci, 'K');
3825 cxxdiag_fci[i].types[0].type = &t;
3826 cxxdiag_fci[i].pointer_count = 1;
3831 #ifdef TARGET_FORMAT_TYPES
3832 extern const format_kind_info TARGET_FORMAT_TYPES[];
3833 #endif
3835 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
3836 extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[];
3837 #endif
3838 #ifdef TARGET_OVERRIDES_FORMAT_INIT
3839 extern void TARGET_OVERRIDES_FORMAT_INIT (void);
3840 #endif
3842 /* Attributes such as "printf" are equivalent to those such as
3843 "gnu_printf" unless this is overridden by a target. */
3844 static const target_ovr_attr gnu_target_overrides_format_attributes[] =
3846 { "gnu_printf", "printf" },
3847 { "gnu_scanf", "scanf" },
3848 { "gnu_strftime", "strftime" },
3849 { "gnu_strfmon", "strfmon" },
3850 { NULL, NULL }
3853 /* Translate to unified attribute name. This is used in decode_format_type and
3854 decode_format_attr. In attr_name the user specified argument is passed. It
3855 returns the unified format name from TARGET_OVERRIDES_FORMAT_ATTRIBUTES
3856 or the attr_name passed to this function, if there is no matching entry. */
3857 static const char *
3858 convert_format_name_to_system_name (const char *attr_name)
3860 int i;
3862 if (attr_name == NULL || *attr_name == 0
3863 || strncmp (attr_name, "gcc_", 4) == 0)
3864 return attr_name;
3865 #ifdef TARGET_OVERRIDES_FORMAT_INIT
3866 TARGET_OVERRIDES_FORMAT_INIT ();
3867 #endif
3869 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
3870 /* Check if format attribute is overridden by target. */
3871 if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL
3872 && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0)
3874 for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i)
3876 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src,
3877 attr_name))
3878 return attr_name;
3879 if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_dst,
3880 attr_name))
3881 return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src;
3884 #endif
3885 /* Otherwise default to gnu format. */
3886 for (i = 0;
3887 gnu_target_overrides_format_attributes[i].named_attr_src != NULL;
3888 ++i)
3890 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_src,
3891 attr_name))
3892 return attr_name;
3893 if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_dst,
3894 attr_name))
3895 return gnu_target_overrides_format_attributes[i].named_attr_src;
3898 return attr_name;
3901 /* Return true if TATTR_NAME and ATTR_NAME are the same format attribute,
3902 counting "name" and "__name__" as the same, false otherwise. */
3903 static bool
3904 cmp_attribs (const char *tattr_name, const char *attr_name)
3906 int alen = strlen (attr_name);
3907 int slen = (tattr_name ? strlen (tattr_name) : 0);
3908 if (alen > 4 && attr_name[0] == '_' && attr_name[1] == '_'
3909 && attr_name[alen - 1] == '_' && attr_name[alen - 2] == '_')
3911 attr_name += 2;
3912 alen -= 4;
3914 if (alen != slen || strncmp (tattr_name, attr_name, alen) != 0)
3915 return false;
3916 return true;
3919 /* Handle a "format" attribute; arguments as in
3920 struct attribute_spec.handler. */
3921 tree
3922 handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args,
3923 int flags, bool *no_add_attrs)
3925 tree type = *node;
3926 function_format_info info;
3928 #ifdef TARGET_FORMAT_TYPES
3929 /* If the target provides additional format types, we need to
3930 add them to FORMAT_TYPES at first use. */
3931 if (TARGET_FORMAT_TYPES != NULL && !dynamic_format_types)
3933 dynamic_format_types = XNEWVEC (format_kind_info,
3934 n_format_types + TARGET_N_FORMAT_TYPES);
3935 memcpy (dynamic_format_types, format_types_orig,
3936 sizeof (format_types_orig));
3937 memcpy (&dynamic_format_types[n_format_types], TARGET_FORMAT_TYPES,
3938 TARGET_N_FORMAT_TYPES * sizeof (dynamic_format_types[0]));
3940 format_types = dynamic_format_types;
3941 /* Provide a reference for the first potential external type. */
3942 first_target_format_type = n_format_types;
3943 n_format_types += TARGET_N_FORMAT_TYPES;
3945 #endif
3947 if (!decode_format_attr (args, &info, 0))
3949 *no_add_attrs = true;
3950 return NULL_TREE;
3953 if (prototype_p (type))
3955 if (!check_format_string (type, info.format_num, flags,
3956 no_add_attrs, info.format_type))
3957 return NULL_TREE;
3959 if (info.first_arg_num != 0)
3961 unsigned HOST_WIDE_INT arg_num = 1;
3962 function_args_iterator iter;
3963 tree arg_type;
3965 /* Verify that first_arg_num points to the last arg,
3966 the ... */
3967 FOREACH_FUNCTION_ARGS (type, arg_type, iter)
3968 arg_num++;
3970 if (arg_num != info.first_arg_num)
3972 if (!(flags & (int) ATTR_FLAG_BUILT_IN))
3973 error ("args to be formatted is not %<...%>");
3974 *no_add_attrs = true;
3975 return NULL_TREE;
3980 /* Check if this is a strftime variant. Just for this variant
3981 FMT_FLAG_ARG_CONVERT is not set. */
3982 if ((format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT) == 0
3983 && info.first_arg_num != 0)
3985 error ("strftime formats cannot format arguments");
3986 *no_add_attrs = true;
3987 return NULL_TREE;
3990 /* If this is a custom GCC-internal format type, we have to
3991 initialize certain bits at runtime. */
3992 if (info.format_type == asm_fprintf_format_type
3993 || info.format_type == gcc_gfc_format_type
3994 || info.format_type == gcc_diag_format_type
3995 || info.format_type == gcc_tdiag_format_type
3996 || info.format_type == gcc_cdiag_format_type
3997 || info.format_type == gcc_cxxdiag_format_type)
3999 /* Our first time through, we have to make sure that our
4000 format_type data is allocated dynamically and is modifiable. */
4001 if (!dynamic_format_types)
4002 format_types = dynamic_format_types = (format_kind_info *)
4003 xmemdup (format_types_orig, sizeof (format_types_orig),
4004 sizeof (format_types_orig));
4006 /* If this is format __asm_fprintf__, we have to initialize
4007 GCC's notion of HOST_WIDE_INT for checking %wd. */
4008 if (info.format_type == asm_fprintf_format_type)
4009 init_dynamic_asm_fprintf_info ();
4010 /* If this is format __gcc_gfc__, we have to initialize GCC's
4011 notion of 'locus' at runtime for %L. */
4012 else if (info.format_type == gcc_gfc_format_type)
4013 init_dynamic_gfc_info ();
4014 /* If this is one of the diagnostic attributes, then we have to
4015 initialize 'location_t' and 'tree' at runtime. */
4016 else if (info.format_type == gcc_diag_format_type
4017 || info.format_type == gcc_tdiag_format_type
4018 || info.format_type == gcc_cdiag_format_type
4019 || info.format_type == gcc_cxxdiag_format_type)
4020 init_dynamic_diag_info ();
4021 else
4022 gcc_unreachable ();
4025 return NULL_TREE;
4028 #if CHECKING_P
4030 namespace selftest {
4032 /* Selftests of location handling. */
4034 /* Get the format_kind_info with the given name. */
4036 static const format_kind_info *
4037 get_info (const char *name)
4039 int idx = decode_format_type (name);
4040 const format_kind_info *fki = &format_types[idx];
4041 ASSERT_STREQ (fki->name, name);
4042 return fki;
4045 /* Verify that get_format_for_type (FKI, TYPE, CONVERSION_CHAR)
4046 is EXPECTED_FORMAT. */
4048 static void
4049 assert_format_for_type_streq (const location &loc, const format_kind_info *fki,
4050 const char *expected_format, tree type,
4051 char conversion_char)
4053 gcc_assert (fki);
4054 gcc_assert (expected_format);
4055 gcc_assert (type);
4057 char *actual_format = get_format_for_type (fki, type, conversion_char);
4058 ASSERT_STREQ_AT (loc, expected_format, actual_format);
4059 free (actual_format);
4062 /* Selftests for get_format_for_type. */
4064 #define ASSERT_FORMAT_FOR_TYPE_STREQ(EXPECTED_FORMAT, TYPE, CONVERSION_CHAR) \
4065 assert_format_for_type_streq (SELFTEST_LOCATION, (fki), (EXPECTED_FORMAT), \
4066 (TYPE), (CONVERSION_CHAR))
4068 /* Selftest for get_format_for_type for "printf"-style functions. */
4070 static void
4071 test_get_format_for_type_printf ()
4073 const format_kind_info *fki = get_info ("gnu_printf");
4074 ASSERT_NE (fki, NULL);
4076 ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'i');
4077 ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'i');
4078 ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'o');
4079 ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'o');
4080 ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'x');
4081 ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'x');
4082 ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'X');
4083 ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'X');
4084 ASSERT_FORMAT_FOR_TYPE_STREQ ("d", integer_type_node, 'd');
4085 ASSERT_FORMAT_FOR_TYPE_STREQ ("i", integer_type_node, 'i');
4086 ASSERT_FORMAT_FOR_TYPE_STREQ ("o", integer_type_node, 'o');
4087 ASSERT_FORMAT_FOR_TYPE_STREQ ("x", integer_type_node, 'x');
4088 ASSERT_FORMAT_FOR_TYPE_STREQ ("X", integer_type_node, 'X');
4089 ASSERT_FORMAT_FOR_TYPE_STREQ ("d", unsigned_type_node, 'd');
4090 ASSERT_FORMAT_FOR_TYPE_STREQ ("i", unsigned_type_node, 'i');
4091 ASSERT_FORMAT_FOR_TYPE_STREQ ("o", unsigned_type_node, 'o');
4092 ASSERT_FORMAT_FOR_TYPE_STREQ ("x", unsigned_type_node, 'x');
4093 ASSERT_FORMAT_FOR_TYPE_STREQ ("X", unsigned_type_node, 'X');
4094 ASSERT_FORMAT_FOR_TYPE_STREQ ("ld", long_integer_type_node, 'd');
4095 ASSERT_FORMAT_FOR_TYPE_STREQ ("li", long_integer_type_node, 'i');
4096 ASSERT_FORMAT_FOR_TYPE_STREQ ("lx", long_integer_type_node, 'x');
4097 ASSERT_FORMAT_FOR_TYPE_STREQ ("lo", long_unsigned_type_node, 'o');
4098 ASSERT_FORMAT_FOR_TYPE_STREQ ("lx", long_unsigned_type_node, 'x');
4099 ASSERT_FORMAT_FOR_TYPE_STREQ ("lld", long_long_integer_type_node, 'd');
4100 ASSERT_FORMAT_FOR_TYPE_STREQ ("lli", long_long_integer_type_node, 'i');
4101 ASSERT_FORMAT_FOR_TYPE_STREQ ("llo", long_long_unsigned_type_node, 'o');
4102 ASSERT_FORMAT_FOR_TYPE_STREQ ("llx", long_long_unsigned_type_node, 'x');
4103 ASSERT_FORMAT_FOR_TYPE_STREQ ("s", build_pointer_type (char_type_node), 'i');
4106 /* Selftest for get_format_for_type for "scanf"-style functions. */
4108 static void
4109 test_get_format_for_type_scanf ()
4111 const format_kind_info *fki = get_info ("gnu_scanf");
4112 ASSERT_NE (fki, NULL);
4113 ASSERT_FORMAT_FOR_TYPE_STREQ ("d", build_pointer_type (integer_type_node), 'd');
4114 ASSERT_FORMAT_FOR_TYPE_STREQ ("u", build_pointer_type (unsigned_type_node), 'u');
4115 ASSERT_FORMAT_FOR_TYPE_STREQ ("ld",
4116 build_pointer_type (long_integer_type_node), 'd');
4117 ASSERT_FORMAT_FOR_TYPE_STREQ ("lu",
4118 build_pointer_type (long_unsigned_type_node), 'u');
4119 ASSERT_FORMAT_FOR_TYPE_STREQ
4120 ("lld", build_pointer_type (long_long_integer_type_node), 'd');
4121 ASSERT_FORMAT_FOR_TYPE_STREQ
4122 ("llu", build_pointer_type (long_long_unsigned_type_node), 'u');
4123 ASSERT_FORMAT_FOR_TYPE_STREQ ("e", build_pointer_type (float_type_node), 'e');
4124 ASSERT_FORMAT_FOR_TYPE_STREQ ("le", build_pointer_type (double_type_node), 'e');
4127 #undef ASSERT_FORMAT_FOR_TYPE_STREQ
4129 /* Run all of the selftests within this file. */
4131 void
4132 c_format_c_tests ()
4134 test_get_modifier_for_format_len ();
4135 test_get_format_for_type_printf ();
4136 test_get_format_for_type_scanf ();
4139 } // namespace selftest
4141 #endif /* CHECKING_P */