OSDN Git Service

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