OSDN Git Service

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