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