OSDN Git Service

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