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