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