OSDN Git Service

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