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