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