OSDN Git Service

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