OSDN Git Service

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