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