1 /* Check calls to formatted I/O functions (-Wformat).
2    Copyright (C) 1992-2019 Free Software Foundation, Inc.
3 
4    Extended for FRR's printfrr() with Linux kernel style extensions
5    Copyright (C) 2019-2020  David Lamparter, for NetDEF, Inc.
6 
7 This file is part of GCC.
8 
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13 
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING.GPLv3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22 
23 #include "gcc-common.h"
24 
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 //include "c-target.h"
30 #include "c-common.h"
31 #include "alloc-pool.h"
32 #include "stringpool.h"
33 #include "c-tree.h"
34 #include "c-objc.h"
35 #include "intl.h"
36 #include "langhooks.h"
37 #include "frr-format.h"
38 #include "diagnostic.h"
39 #include "substring-locations.h"
40 #include "selftest.h"
41 #include "selftest-diagnostic.h"
42 #ifndef FIRST_PSEUDO_REGISTER
43 #define FIRST_PSEUDO_REGISTER 0
44 #endif
45 #include "builtins.h"
46 #include "attribs.h"
47 #include "gcc-rich-location.h"
48 #include "c-pretty-print.h"
49 #include "c-pragma.h"
50 
51 extern struct cpp_reader *parse_in;
52 
53 #pragma GCC visibility push(hidden)
54 
55 /* Handle attributes associated with format checking.  */
56 
57 /* This must be in the same order as format_types, except for
58    format_type_error.  Target-specific format types do not have
59    matching enum values.  */
60 enum format_type { frr_printf_format_type,
61 		   format_type_error = -1};
62 
63 struct function_format_info
64 {
65   int format_type;			/* type of format (printf, scanf, etc.) */
66   unsigned HOST_WIDE_INT format_num;	/* number of format argument */
67   unsigned HOST_WIDE_INT first_arg_num;	/* number of first arg (zero for varargs) */
68 };
69 
70 static GTY(()) tree local_uint64_t_node;
71 static GTY(()) tree local_int64_t_node;
72 
73 static GTY(()) tree local_size_t_node;
74 static GTY(()) tree local_ssize_t_node;
75 static GTY(()) tree local_atomic_size_t_node;
76 static GTY(()) tree local_atomic_ssize_t_node;
77 static GTY(()) tree local_ptrdiff_t_node;
78 
79 static GTY(()) tree local_pid_t_node;
80 static GTY(()) tree local_uid_t_node;
81 static GTY(()) tree local_gid_t_node;
82 static GTY(()) tree local_time_t_node;
83 
84 static GTY(()) tree local_socklen_t_node;
85 static GTY(()) tree local_in_addr_t_node;
86 
87 static struct type_special {
88   tree *match;
89   tree *replace;
90   tree *cousin;
91 } special_types[] = {
92   { &local_atomic_size_t_node,	&local_size_t_node,	&local_ssize_t_node, },
93   { &local_atomic_ssize_t_node,	&local_ssize_t_node,	&local_size_t_node, },
94   { &local_size_t_node,		NULL,			&local_ssize_t_node, },
95   { &local_ssize_t_node,	NULL,			&local_size_t_node, },
96   { &local_uint64_t_node,	NULL,			&local_int64_t_node, },
97   { &local_int64_t_node,	NULL,			&local_uint64_t_node, },
98   { &local_pid_t_node,		NULL,			&local_pid_t_node, },
99   { &local_uid_t_node,		NULL,			&local_uid_t_node, },
100   { &local_gid_t_node,		NULL,			&local_gid_t_node, },
101   { &local_time_t_node,		NULL,			&local_time_t_node, },
102   { NULL,			NULL,			NULL, }
103 };
104 
105 static bool decode_format_attr (tree, function_format_info *, int);
106 static int decode_format_type (const char *);
107 
108 static bool check_format_string (tree argument,
109 				 unsigned HOST_WIDE_INT format_num,
110 				 int flags, bool *no_add_attrs,
111 				 int expected_format_type);
112 static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value,
113 			  int validated_p);
114 static const char *convert_format_name_to_system_name (const char *attr_name);
115 
116 static int first_target_format_type;
117 static const char *format_name (int format_num);
118 static int format_flags (int format_num);
119 
120 /* Emit a warning as per format_warning_va, but construct the substring_loc
121    for the character at offset (CHAR_IDX - 1) within a string constant
122    FORMAT_STRING_CST at FMT_STRING_LOC.  */
123 
124 ATTRIBUTE_GCC_DIAG (5,6)
125 static bool
format_warning_at_char(location_t fmt_string_loc,tree format_string_cst,int char_idx,int opt,const char * gmsgid,...)126 format_warning_at_char (location_t fmt_string_loc, tree format_string_cst,
127 			int char_idx, int opt, const char *gmsgid, ...)
128 {
129   va_list ap;
130   va_start (ap, gmsgid);
131   tree string_type = TREE_TYPE (format_string_cst);
132 
133   /* The callers are of the form:
134        format_warning (format_string_loc, format_string_cst,
135 		       format_chars - orig_format_chars,
136       where format_chars has already been incremented, so that
137       CHAR_IDX is one character beyond where the warning should
138       be emitted.  Fix it.  */
139   char_idx -= 1;
140 
141   substring_loc fmt_loc (fmt_string_loc, string_type, char_idx, char_idx,
142 			 char_idx);
143 #if BUILDING_GCC_VERSION >= 9000
144   format_string_diagnostic_t diag (fmt_loc, NULL, UNKNOWN_LOCATION, NULL,
145 				   NULL);
146   bool warned = diag.emit_warning_va (opt, gmsgid, &ap);
147 #else
148   bool warned = format_warning_va (fmt_loc, UNKNOWN_LOCATION, NULL,
149 				   opt, gmsgid, &ap);
150 #endif
151   va_end (ap);
152 
153   return warned;
154 }
155 
156 /* Check that we have a pointer to a string suitable for use as a format.
157    The default is to check for a char type.
158    For objective-c dialects, this is extended to include references to string
159    objects validated by objc_string_ref_type_p ().
160    Targets may also provide a string object type that can be used within c and
161    c++ and shared with their respective objective-c dialects. In this case the
162    reference to a format string is checked for validity via a hook.
163 
164    The function returns true if strref points to any string type valid for the
165    language dialect and target.  */
166 
167 static bool
valid_stringptr_type_p(tree strref)168 valid_stringptr_type_p (tree strref)
169 {
170   return (strref != NULL
171 	  && TREE_CODE (strref) == POINTER_TYPE
172 	  && (TYPE_MAIN_VARIANT (TREE_TYPE (strref)) == char_type_node
173 	      || objc_string_ref_type_p (strref)));
174 //	      || (*targetcm.string_object_ref_type_p) ((const_tree) strref)));
175 }
176 
177 /* Handle a "format_arg" attribute; arguments as in
178    struct attribute_spec.handler.  */
179 tree
handle_frr_format_arg_attribute(tree * node,tree ARG_UNUSED (name),tree args,int flags,bool * no_add_attrs)180 handle_frr_format_arg_attribute (tree *node, tree ARG_UNUSED (name),
181 			     tree args, int flags, bool *no_add_attrs)
182 {
183   tree type = *node;
184   tree format_num_expr = TREE_VALUE (args);
185   unsigned HOST_WIDE_INT format_num = 0;
186 
187   if (!get_constant (format_num_expr, &format_num, 0))
188     {
189       error ("format string has invalid operand number");
190       *no_add_attrs = true;
191       return NULL_TREE;
192     }
193 
194   if (prototype_p (type))
195     {
196       /* The format arg can be any string reference valid for the language and
197 	target.  We cannot be more specific in this case.  */
198       if (!check_format_string (type, format_num, flags, no_add_attrs, -1))
199 	return NULL_TREE;
200     }
201 
202   if (!valid_stringptr_type_p (TREE_TYPE (type)))
203     {
204       if (!(flags & (int) ATTR_FLAG_BUILT_IN))
205 	error ("function does not return string type");
206       *no_add_attrs = true;
207       return NULL_TREE;
208     }
209 
210   return NULL_TREE;
211 }
212 
213 /* Verify that the format_num argument is actually a string reference suitable,
214    for the language dialect and target (in case the format attribute is in
215    error).  When we know the specific reference type expected, this is also
216    checked.  */
217 static bool
check_format_string(tree fntype,unsigned HOST_WIDE_INT format_num,int flags,bool * no_add_attrs,int expected_format_type)218 check_format_string (tree fntype, unsigned HOST_WIDE_INT format_num,
219 		     int flags, bool *no_add_attrs, int expected_format_type)
220 {
221   unsigned HOST_WIDE_INT i;
222   bool is_target_sref, is_char_ref;
223   tree ref;
224   int fmt_flags;
225   function_args_iterator iter;
226 
227   i = 1;
228   FOREACH_FUNCTION_ARGS (fntype, ref, iter)
229     {
230       if (i == format_num)
231 	break;
232       i++;
233     }
234 
235   if (!ref
236       || !valid_stringptr_type_p (ref))
237     {
238       if (!(flags & (int) ATTR_FLAG_BUILT_IN))
239 	error ("format string argument is not a string type");
240       *no_add_attrs = true;
241       return false;
242     }
243 
244   /* We only know that we want a suitable string reference.  */
245   if (expected_format_type < 0)
246     return true;
247 
248   /* Now check that the arg matches the expected type.  */
249   is_char_ref =
250     (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) == char_type_node);
251 
252   fmt_flags = format_flags (expected_format_type);
253   is_target_sref = false;
254 
255   if (!(fmt_flags & FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL))
256     {
257       if (is_char_ref)
258 	return true; /* OK, we expected a char and found one.  */
259       else
260 	{
261 	    error ("found a %qT but the format argument should be a string",
262 		   ref);
263 	  *no_add_attrs = true;
264 	  return false;
265 	}
266     }
267 
268   /* We expect a string object type as the format arg.  */
269   if (is_char_ref)
270     {
271       error ("format argument should be a %qs reference but a string was found", format_name (expected_format_type));
272       *no_add_attrs = true;
273       return false;
274     }
275 
276   /* We will allow a target string ref to match only itself.  */
277   if (first_target_format_type
278       && expected_format_type >= first_target_format_type
279       && is_target_sref)
280     return true;
281   else
282     {
283       error ("format argument should be a %qs reference",
284 	      format_name (expected_format_type));
285       *no_add_attrs = true;
286       return false;
287     }
288 
289   gcc_unreachable ();
290 }
291 
292 /* Verify EXPR is a constant, and store its value.
293    If validated_p is true there should be no errors.
294    Returns true on success, false otherwise.  */
295 static bool
get_constant(tree expr,unsigned HOST_WIDE_INT * value,int validated_p)296 get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
297 {
298   if (!tree_fits_uhwi_p (expr))
299     {
300       gcc_assert (!validated_p);
301       return false;
302     }
303 
304   *value = TREE_INT_CST_LOW (expr);
305 
306   return true;
307 }
308 
309 /* Decode the arguments to a "format" attribute into a
310    function_format_info structure.  It is already known that the list
311    is of the right length.  If VALIDATED_P is true, then these
312    attributes have already been validated and must not be erroneous;
313    if false, it will give an error message.  Returns true if the
314    attributes are successfully decoded, false otherwise.  */
315 
316 static bool
decode_format_attr(tree args,function_format_info * info,int validated_p)317 decode_format_attr (tree args, function_format_info *info, int validated_p)
318 {
319   tree format_type_id = TREE_VALUE (args);
320   tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
321   tree first_arg_num_expr
322     = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
323 
324   if (TREE_CODE (format_type_id) != STRING_CST)
325     {
326       gcc_assert (!validated_p);
327       error ("unrecognized format specifier");
328       return false;
329     }
330   else
331     {
332       const char *p = TREE_STRING_POINTER (format_type_id);
333 
334       p = convert_format_name_to_system_name (p);
335 
336       info->format_type = decode_format_type (p);
337 
338       if (info->format_type == format_type_error)
339 	{
340 	  gcc_assert (!validated_p);
341 	  warning (OPT_Wformat_, "%qE is an unrecognized format function type",
342 		   format_type_id);
343 	  return false;
344 	}
345     }
346 
347   if (!get_constant (format_num_expr, &info->format_num, validated_p))
348     {
349       error ("format string has invalid operand number");
350       return false;
351     }
352 
353   if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
354     {
355       error ("%<...%> has invalid operand number");
356       return false;
357     }
358 
359   if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
360     {
361       gcc_assert (!validated_p);
362       error ("format string argument follows the arguments to be formatted");
363       return false;
364     }
365 
366   return true;
367 }
368 
369 /* Check a call to a format function against a parameter list.  */
370 
371 /* The C standard version C++ is treated as equivalent to
372    or inheriting from, for the purpose of format features supported.  */
373 #define CPLUSPLUS_STD_VER	(cxx_dialect < cxx11 ? STD_C94 : STD_C99)
374 /* The C standard version we are checking formats against when pedantic.  */
375 #define C_STD_VER		((int) (c_dialect_cxx ()		   \
376 				 ? CPLUSPLUS_STD_VER			   \
377 				 : (flag_isoc99				   \
378 				    ? STD_C99				   \
379 				    : (flag_isoc94 ? STD_C94 : STD_C89))))
380 /* The name to give to the standard version we are warning about when
381    pedantic.  FEATURE_VER is the version in which the feature warned out
382    appeared, which is higher than C_STD_VER.  */
383 #define C_STD_NAME(FEATURE_VER) (c_dialect_cxx ()		\
384 				 ? (cxx_dialect < cxx11 ? "ISO C++98" \
385 				    : "ISO C++11")		\
386 				 : ((FEATURE_VER) == STD_EXT	\
387 				    ? "ISO C"			\
388 				    : "ISO C90"))
389 /* Adjust a C standard version, which may be STD_C9L, to account for
390    -Wno-long-long.  Returns other standard versions unchanged.  */
391 #define ADJ_STD(VER)		((int) ((VER) == STD_C9L		      \
392 				       ? (warn_long_long ? STD_C99 : STD_C89) \
393 				       : (VER)))
394 
395 /* Enum describing the kind of specifiers present in the format and
396    requiring an argument.  */
397 enum format_specifier_kind {
398   CF_KIND_FORMAT,
399   CF_KIND_FIELD_WIDTH,
400   CF_KIND_FIELD_PRECISION
401 };
402 
403 static const char *kind_descriptions[] = {
404   N_("format"),
405   N_("field width specifier"),
406   N_("field precision specifier")
407 };
408 
409 /* Structure describing details of a type expected in format checking,
410    and the type to check against it.  */
411 struct format_wanted_type
412 {
413   /* The type wanted.  */
414   tree wanted_type;
415   /* The name of this type to use in diagnostics.  */
416   const char *wanted_type_name;
417   /* Should be type checked just for scalar width identity.  */
418   int scalar_identity_flag;
419   /* The level of indirection through pointers at which this type occurs.  */
420   int pointer_count;
421   /* Whether, when pointer_count is 1, to allow any character type when
422      pedantic, rather than just the character or void type specified.  */
423   int char_lenient_flag;
424   /* Whether the argument, dereferenced once, is written into and so the
425      argument must not be a pointer to a const-qualified type.  */
426   int writing_in_flag;
427   /* Whether the argument, dereferenced once, is read from and so
428      must not be a NULL pointer.  */
429   int reading_from_flag;
430   /* The kind of specifier that this type is used for.  */
431   enum format_specifier_kind kind;
432   /* The starting character of the specifier.  This never includes the
433      initial percent sign.  */
434   const char *format_start;
435   /* The length of the specifier.  */
436   int format_length;
437   /* The actual parameter to check against the wanted type.  */
438   tree param;
439   /* The argument number of that parameter.  */
440   int arg_num;
441   /* The offset location of this argument with respect to the format
442      string location.  */
443   unsigned int offset_loc;
444   /* The next type to check for this format conversion, or NULL if none.  */
445   struct format_wanted_type *next;
446 };
447 
448 /* Convenience macro for format_length_info meaning unused.  */
449 #define NO_FMT NULL, FMT_LEN_none, STD_C89
450 
451 static const format_length_info printf_length_specs[] =
452 {
453   { "h", FMT_LEN_h, STD_C89, "hh", FMT_LEN_hh, STD_C99, 0 },
454   { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C9L, 0 },
455   { "q", FMT_LEN_ll, STD_EXT, NO_FMT, 0 },
456   { "L", FMT_LEN_L, STD_C89, NO_FMT, 0 },
457   { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
458   { "Z", FMT_LEN_z, STD_EXT, NO_FMT, 0 },
459   { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
460   { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 },
461   { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 },
462   { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 },
463   { NO_FMT, NO_FMT, 0 }
464 };
465 
466 static const format_flag_spec printf_flag_specs[] =
467 {
468   { ' ',  0, 0, 0, N_("' ' flag"),        N_("the ' ' printf flag"),              STD_C89 },
469   { '+',  0, 0, 0, N_("'+' flag"),        N_("the '+' printf flag"),              STD_C89 },
470   { '#',  0, 0, 0, N_("'#' flag"),        N_("the '#' printf flag"),              STD_C89 },
471   { '0',  0, 0, 0, N_("'0' flag"),        N_("the '0' printf flag"),              STD_C89 },
472   { '-',  0, 0, 0, N_("'-' flag"),        N_("the '-' printf flag"),              STD_C89 },
473   { '\'', 0, 0, 0, N_("''' flag"),        N_("the ''' printf flag"),              STD_EXT },
474   { 'I',  0, 0, 0, N_("'I' flag"),        N_("the 'I' printf flag"),              STD_EXT },
475   { 'w',  0, 0, 0, N_("field width"),     N_("field width in printf format"),     STD_C89 },
476   { 'p',  0, 0, 0, N_("precision"),       N_("precision in printf format"),       STD_C89 },
477   { 'L',  0, 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
478   { 0, 0, 0, 0, NULL, NULL, STD_C89 }
479 };
480 
481 
482 static const format_flag_pair printf_flag_pairs[] =
483 {
484   { ' ', '+', 1, 0   },
485   { '0', '-', 1, 0   },
486   { '0', 'p', 1, 'i' },
487   { 0, 0, 0, 0 }
488 };
489 
490 #define ETAB_SZ 128
491 static kernel_ext_fmt ext_p[ETAB_SZ] = {
492   { }
493 };
494 static kernel_ext_fmt ext_d[ETAB_SZ] = {
495   { }
496 };
497 
498 static const format_char_info print_char_table[] =
499 {
500   /* C89 conversion specifiers.  */
501                       /* none,    hh,      h,       l,       ll,      L,       z,       t,       j,       H,       D,       DD     */
502   { "di",  0, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  TEX_S64, T99_SST, T99_PD,  T99_IM,  BADLEN,  BADLEN,  BADLEN },   "-wp0 +'I",  "i",  NULL, ext_d },
503   { "oxX", 0, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_U64, T99_ST,  T99_UPD, T99_UIM, BADLEN,  BADLEN,  BADLEN },   "-wp0#",     "i",  NULL, NULL },
504   { "u",   0, STD_C89, { T89_UI,  T99_UC,  T89_US,  T89_UL,  T9L_ULL, TEX_U64, T99_ST,  T99_UPD, T99_UIM, BADLEN,  BADLEN,  BADLEN },   "-wp0'I",    "i",  NULL, NULL },
505   { "fgG", 0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN,  TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "",   NULL, NULL },
506   { "eE",  0, STD_C89, { T89_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T89_LD,  BADLEN,  BADLEN,  BADLEN,  TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#I",  "",   NULL, NULL },
507   { "c",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  T94_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN },   "-w",        "",   NULL, NULL },
508   { "s",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  T94_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN },   "-wp",       "cR", NULL, NULL },
509   { "p",   1, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN },   "-wp",       "c",  NULL, ext_p },
510   { "n",   1, STD_C89, { T89_I,   T99_SC,  T89_S,   T89_L,   T9L_LL,  BADLEN,  T99_SST, T99_PD,  T99_IM,  BADLEN,  BADLEN,  BADLEN },   "",          "W",  NULL, NULL },
511   /* C99 conversion specifiers.  */
512   { "F",   0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN,  TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "",   NULL, NULL },
513   { "aA",  0, STD_C99, { T99_D,   BADLEN,  BADLEN,  T99_D,   BADLEN,  T99_LD,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN },   "-wp0 +#",   "",   NULL, NULL },
514   /* X/Open conversion specifiers.  */
515   { "C",   0, STD_EXT, { TEX_WI,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN },   "-w",        "",   NULL, NULL },
516   { "S",   1, STD_EXT, { TEX_W,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN },   "-wp",       "R",  NULL, NULL },
517   /* GNU conversion specifiers.  */
518   { "m",   0, STD_EXT, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN },   "-wp",       "",   NULL, NULL },
519   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL, NULL }
520 };
521 
522 /* This must be in the same order as enum format_type.  */
523 static const format_kind_info format_types_orig[] =
524 {
525   { "frr_printf",   printf_length_specs,  print_char_table, " +#0-'I", NULL,
526     printf_flag_specs, printf_flag_pairs,
527     FMT_FLAG_ARG_CONVERT|FMT_FLAG_DOLLAR_MULTIPLE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_EMPTY_PREC_OK,
528     'w', 0, 'p', 0, 'L', 0,
529     &integer_type_node, &integer_type_node
530   },
531 };
532 
533 /* This layer of indirection allows GCC to reassign format_types with
534    new data if necessary, while still allowing the original data to be
535    const.  */
536 static const format_kind_info *format_types = format_types_orig;
537 
538 static int n_format_types = ARRAY_SIZE (format_types_orig);
539 
540 /* Structure detailing the results of checking a format function call
541    where the format expression may be a conditional expression with
542    many leaves resulting from nested conditional expressions.  */
543 struct format_check_results
544 {
545   /* Number of leaves of the format argument that could not be checked
546      as they were not string literals.  */
547   int number_non_literal;
548   /* Number of leaves of the format argument that were null pointers or
549      string literals, but had extra format arguments.  */
550   int number_extra_args;
551   location_t extra_arg_loc;
552   /* Number of leaves of the format argument that were null pointers or
553      string literals, but had extra format arguments and used $ operand
554      numbers.  */
555   int number_dollar_extra_args;
556   /* Number of leaves of the format argument that were wide string
557      literals.  */
558   int number_wide;
559   /* Number of leaves of the format argument that are not array of "char".  */
560   int number_non_char;
561   /* Number of leaves of the format argument that were empty strings.  */
562   int number_empty;
563   /* Number of leaves of the format argument that were unterminated
564      strings.  */
565   int number_unterminated;
566   /* Number of leaves of the format argument that were not counted above.  */
567   int number_other;
568   /* Location of the format string.  */
569   location_t format_string_loc;
570 };
571 
572 struct format_check_context
573 {
574   format_check_results *res;
575   function_format_info *info;
576   tree params;
577   vec<location_t> *arglocs;
578 };
579 
580 /* Return the format name (as specified in the original table) for the format
581    type indicated by format_num.  */
582 static const char *
format_name(int format_num)583 format_name (int format_num)
584 {
585   if (format_num >= 0 && format_num < n_format_types)
586     return format_types[format_num].name;
587   gcc_unreachable ();
588 }
589 
590 /* Return the format flags (as specified in the original table) for the format
591    type indicated by format_num.  */
592 static int
format_flags(int format_num)593 format_flags (int format_num)
594 {
595   if (format_num >= 0 && format_num < n_format_types)
596     return format_types[format_num].flags;
597   gcc_unreachable ();
598 }
599 
600 static void check_format_info (function_format_info *, tree,
601 			       vec<location_t> *);
602 static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
603 static void check_format_info_main (format_check_results *,
604 				    function_format_info *, const char *,
605 				    location_t, tree,
606 				    int, tree,
607 				    unsigned HOST_WIDE_INT,
608 				    object_allocator<format_wanted_type> &,
609 				    vec<location_t> *);
610 
611 static void init_dollar_format_checking (int, tree);
612 static int maybe_read_dollar_number (const char **, int,
613 				     tree, tree *, const format_kind_info *);
614 static bool avoid_dollar_number (const char *);
615 static void finish_dollar_format_checking (format_check_results *, int);
616 
617 static const format_flag_spec *get_flag_spec (const format_flag_spec *,
618 					      int, const char *);
619 
620 static void check_format_types (const substring_loc &fmt_loc,
621 				format_wanted_type *,
622 				const format_kind_info *fki,
623 				int offset_to_type_start,
624 				char conversion_char,
625 				vec<location_t> *arglocs);
626 static void format_type_warning (const substring_loc &fmt_loc,
627 				 location_t param_loc,
628 				 format_wanted_type *, tree,
629 				 tree,
630 				 const format_kind_info *fki,
631 				 int offset_to_type_start,
632 				 char conversion_char,
633 				 const char *extra = NULL);
634 
635 static bool check_kef_type (const substring_loc &fmt_loc,
636 		const struct kernel_ext_fmt *kef,
637 		unsigned arg_num,
638 		tree cur_param,
639 		tree wanted_type,
640 		const format_kind_info *fki,
641 		int offset_to_type_start,
642 		char conversion_char,
643 		vec<location_t> *arglocs);
644 
645 /* Decode a format type from a string, returning the type, or
646    format_type_error if not valid, in which case the caller should print an
647    error message.  */
648 static int
decode_format_type(const char * s)649 decode_format_type (const char *s)
650 {
651   int i;
652   int slen;
653 
654   s = convert_format_name_to_system_name (s);
655   slen = strlen (s);
656   for (i = 0; i < n_format_types; i++)
657     {
658       int alen;
659       if (!strcmp (s, format_types[i].name))
660 	return i;
661       alen = strlen (format_types[i].name);
662       if (slen == alen + 4 && s[0] == '_' && s[1] == '_'
663 	  && s[slen - 1] == '_' && s[slen - 2] == '_'
664 	  && !strncmp (s + 2, format_types[i].name, alen))
665 	return i;
666     }
667   return format_type_error;
668 }
669 
670 
671 /* Check the argument list of a call to printf, scanf, etc.
672    ATTRS are the attributes on the function type.  There are NARGS argument
673    values in the array ARGARRAY.
674    Also, if -Wsuggest-attribute=format,
675    warn for calls to vprintf or vscanf in functions with no such format
676    attribute themselves.  */
677 
678 void
check_function_format(tree attrs,int nargs,tree * argarray,vec<location_t> * arglocs)679 check_function_format (tree attrs, int nargs, tree *argarray,
680 		       vec<location_t> *arglocs)
681 {
682   tree a;
683 
684   /* See if this function has any format attributes.  */
685   for (a = attrs; a; a = TREE_CHAIN (a))
686     {
687       if (is_attribute_p ("frr_format", TREE_PURPOSE (a)))
688 	{
689 	  /* Yup; check it.  */
690 	  function_format_info info;
691 	  decode_format_attr (TREE_VALUE (a), &info, /*validated=*/true);
692 	  if (warn_format)
693 	    {
694 	      /* FIXME: Rewrite all the internal functions in this file
695 		 to use the ARGARRAY directly instead of constructing this
696 		 temporary list.  */
697 	      tree params = NULL_TREE;
698 	      int i;
699 	      for (i = nargs - 1; i >= 0; i--)
700 		params = tree_cons (NULL_TREE, argarray[i], params);
701 	      check_format_info (&info, params, arglocs);
702 	    }
703 
704 	  /* Attempt to detect whether the current function might benefit
705 	     from the format attribute if the called function is decorated
706 	     with it.  Avoid using calls with string literal formats for
707 	     guidance since those are unlikely to be viable candidates.  */
708 	  if (warn_suggest_attribute_format
709 	      && current_function_decl != NULL_TREE
710 	      && info.first_arg_num == 0
711 	      && (format_types[info.format_type].flags
712 		  & (int) FMT_FLAG_ARG_CONVERT)
713 	      /* c_strlen will fail for a function parameter but succeed
714 		 for a literal or constant array.  */
715 	      && !c_strlen (argarray[info.format_num - 1], 1))
716 	    {
717 	      tree c;
718 	      for (c = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
719 		   c;
720 		   c = TREE_CHAIN (c))
721 		if (is_attribute_p ("frr_format", TREE_PURPOSE (c))
722 		    && (decode_format_type (IDENTIFIER_POINTER
723 					    (TREE_VALUE (TREE_VALUE (c))))
724 			== info.format_type))
725 		  break;
726 	      if (c == NULL_TREE)
727 		{
728 		  /* Check if the current function has a parameter to which
729 		     the format attribute could be attached; if not, it
730 		     can't be a candidate for a format attribute, despite
731 		     the vprintf-like or vscanf-like call.  */
732 		  tree args;
733 		  for (args = DECL_ARGUMENTS (current_function_decl);
734 		       args != 0;
735 		       args = DECL_CHAIN (args))
736 		    {
737 		      if (TREE_CODE (TREE_TYPE (args)) == POINTER_TYPE
738 			  && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args)))
739 			      == char_type_node))
740 			break;
741 		    }
742 		  if (args != 0)
743 		    warning (OPT_Wsuggest_attribute_format,
744 			     "function %qD might be a candidate for %qs %<frr_format%> attribute",
745 			     current_function_decl,
746 			     format_types[info.format_type].name);
747 		}
748 	    }
749 	}
750     }
751 }
752 
753 
754 /* Variables used by the checking of $ operand number formats.  */
755 static char *dollar_arguments_used = NULL;
756 static char *dollar_arguments_pointer_p = NULL;
757 static int dollar_arguments_alloc = 0;
758 static int dollar_arguments_count;
759 static int dollar_first_arg_num;
760 static int dollar_max_arg_used;
761 static int dollar_format_warned;
762 
763 /* Initialize the checking for a format string that may contain $
764    parameter number specifications; we will need to keep track of whether
765    each parameter has been used.  FIRST_ARG_NUM is the number of the first
766    argument that is a parameter to the format, or 0 for a vprintf-style
767    function; PARAMS is the list of arguments starting at this argument.  */
768 
769 static void
init_dollar_format_checking(int first_arg_num,tree params)770 init_dollar_format_checking (int first_arg_num, tree params)
771 {
772   tree oparams = params;
773 
774   dollar_first_arg_num = first_arg_num;
775   dollar_arguments_count = 0;
776   dollar_max_arg_used = 0;
777   dollar_format_warned = 0;
778   if (first_arg_num > 0)
779     {
780       while (params)
781 	{
782 	  dollar_arguments_count++;
783 	  params = TREE_CHAIN (params);
784 	}
785     }
786   if (dollar_arguments_alloc < dollar_arguments_count)
787     {
788       free (dollar_arguments_used);
789       free (dollar_arguments_pointer_p);
790       dollar_arguments_alloc = dollar_arguments_count;
791       dollar_arguments_used = XNEWVEC (char, dollar_arguments_alloc);
792       dollar_arguments_pointer_p = XNEWVEC (char, dollar_arguments_alloc);
793     }
794   if (dollar_arguments_alloc)
795     {
796       memset (dollar_arguments_used, 0, dollar_arguments_alloc);
797       if (first_arg_num > 0)
798 	{
799 	  int i = 0;
800 	  params = oparams;
801 	  while (params)
802 	    {
803 	      dollar_arguments_pointer_p[i] = (TREE_CODE (TREE_TYPE (TREE_VALUE (params)))
804 					       == POINTER_TYPE);
805 	      params = TREE_CHAIN (params);
806 	      i++;
807 	    }
808 	}
809     }
810 }
811 
812 
813 /* Look for a decimal number followed by a $ in *FORMAT.  If DOLLAR_NEEDED
814    is set, it is an error if one is not found; otherwise, it is OK.  If
815    such a number is found, check whether it is within range and mark that
816    numbered operand as being used for later checking.  Returns the operand
817    number if found and within range, zero if no such number was found and
818    this is OK, or -1 on error.  PARAMS points to the first operand of the
819    format; PARAM_PTR is made to point to the parameter referred to.  If
820    a $ format is found, *FORMAT is updated to point just after it.  */
821 
822 static int
maybe_read_dollar_number(const char ** format,int dollar_needed,tree params,tree * param_ptr,const format_kind_info * fki)823 maybe_read_dollar_number (const char **format,
824 			  int dollar_needed, tree params, tree *param_ptr,
825 			  const format_kind_info *fki)
826 {
827   int argnum;
828   int overflow_flag;
829   const char *fcp = *format;
830   if (!ISDIGIT (*fcp))
831     {
832       if (dollar_needed)
833 	{
834 	  warning (OPT_Wformat_, "missing $ operand number in format");
835 	  return -1;
836 	}
837       else
838 	return 0;
839     }
840   argnum = 0;
841   overflow_flag = 0;
842   while (ISDIGIT (*fcp))
843     {
844       int nargnum;
845       nargnum = 10 * argnum + (*fcp - '0');
846       if (nargnum < 0 || nargnum / 10 != argnum)
847 	overflow_flag = 1;
848       argnum = nargnum;
849       fcp++;
850     }
851   if (*fcp != '$')
852     {
853       if (dollar_needed)
854 	{
855 	  warning (OPT_Wformat_, "missing $ operand number in format");
856 	  return -1;
857 	}
858       else
859 	return 0;
860     }
861   *format = fcp + 1;
862   if (pedantic && !dollar_format_warned)
863     {
864       warning (OPT_Wformat_, "%s does not support %%n$ operand number formats",
865 	       C_STD_NAME (STD_EXT));
866       dollar_format_warned = 1;
867     }
868   if (overflow_flag || argnum == 0
869       || (dollar_first_arg_num && argnum > dollar_arguments_count))
870     {
871       warning (OPT_Wformat_, "operand number out of range in format");
872       return -1;
873     }
874   if (argnum > dollar_max_arg_used)
875     dollar_max_arg_used = argnum;
876   /* For vprintf-style functions we may need to allocate more memory to
877      track which arguments are used.  */
878   while (dollar_arguments_alloc < dollar_max_arg_used)
879     {
880       int nalloc;
881       nalloc = 2 * dollar_arguments_alloc + 16;
882       dollar_arguments_used = XRESIZEVEC (char, dollar_arguments_used,
883 					  nalloc);
884       dollar_arguments_pointer_p = XRESIZEVEC (char, dollar_arguments_pointer_p,
885 					       nalloc);
886       memset (dollar_arguments_used + dollar_arguments_alloc, 0,
887 	      nalloc - dollar_arguments_alloc);
888       dollar_arguments_alloc = nalloc;
889     }
890   if (!(fki->flags & (int) FMT_FLAG_DOLLAR_MULTIPLE)
891       && dollar_arguments_used[argnum - 1] == 1)
892     {
893       dollar_arguments_used[argnum - 1] = 2;
894       warning (OPT_Wformat_, "format argument %d used more than once in %s format",
895 	       argnum, fki->name);
896     }
897   else
898     dollar_arguments_used[argnum - 1] = 1;
899   if (dollar_first_arg_num)
900     {
901       int i;
902       *param_ptr = params;
903       for (i = 1; i < argnum && *param_ptr != 0; i++)
904 	*param_ptr = TREE_CHAIN (*param_ptr);
905 
906       /* This case shouldn't be caught here.  */
907       gcc_assert (*param_ptr);
908     }
909   else
910     *param_ptr = 0;
911   return argnum;
912 }
913 
914 /* Ensure that FORMAT does not start with a decimal number followed by
915    a $; give a diagnostic and return true if it does, false otherwise.  */
916 
917 static bool
avoid_dollar_number(const char * format)918 avoid_dollar_number (const char *format)
919 {
920   if (!ISDIGIT (*format))
921     return false;
922   while (ISDIGIT (*format))
923     format++;
924   if (*format == '$')
925     {
926       warning (OPT_Wformat_, "%<$%> operand number used after format without operand number");
927       return true;
928     }
929   return false;
930 }
931 
932 
933 /* Finish the checking for a format string that used $ operand number formats
934    instead of non-$ formats.  We check for unused operands before used ones
935    (a serious error, since the implementation of the format function
936    can't know what types to pass to va_arg to find the later arguments).
937    and for unused operands at the end of the format (if we know how many
938    arguments the format had, so not for vprintf).  If there were operand
939    numbers out of range on a non-vprintf-style format, we won't have reached
940    here.  If POINTER_GAP_OK, unused arguments are OK if all arguments are
941    pointers.  */
942 
943 static void
finish_dollar_format_checking(format_check_results * res,int pointer_gap_ok)944 finish_dollar_format_checking (format_check_results *res, int pointer_gap_ok)
945 {
946   int i;
947   bool found_pointer_gap = false;
948   for (i = 0; i < dollar_max_arg_used; i++)
949     {
950       if (!dollar_arguments_used[i])
951 	{
952 	  if (pointer_gap_ok && (dollar_first_arg_num == 0
953 				 || dollar_arguments_pointer_p[i]))
954 	    found_pointer_gap = true;
955 	  else
956 	    warning_at (res->format_string_loc, OPT_Wformat_,
957 			"format argument %d unused before used argument %d in %<$%>-style format",
958 			i + 1, dollar_max_arg_used);
959 	}
960     }
961   if (found_pointer_gap
962       || (dollar_first_arg_num
963 	  && dollar_max_arg_used < dollar_arguments_count))
964     {
965       res->number_other--;
966       res->number_dollar_extra_args++;
967     }
968 }
969 
970 
971 /* Retrieve the specification for a format flag.  SPEC contains the
972    specifications for format flags for the applicable kind of format.
973    FLAG is the flag in question.  If PREDICATES is NULL, the basic
974    spec for that flag must be retrieved and must exist.  If
975    PREDICATES is not NULL, it is a string listing possible predicates
976    for the spec entry; if an entry predicated on any of these is
977    found, it is returned, otherwise NULL is returned.  */
978 
979 static const format_flag_spec *
get_flag_spec(const format_flag_spec * spec,int flag,const char * predicates)980 get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
981 {
982   int i;
983   for (i = 0; spec[i].flag_char != 0; i++)
984     {
985       if (spec[i].flag_char != flag)
986 	continue;
987       if (predicates != NULL)
988 	{
989 	  if (spec[i].predicate != 0
990 	      && strchr (predicates, spec[i].predicate) != 0)
991 	    return &spec[i];
992 	}
993       else if (spec[i].predicate == 0)
994 	return &spec[i];
995     }
996   gcc_assert (predicates);
997   return NULL;
998 }
999 
1000 
1001 /* Check the argument list of a call to printf, scanf, etc.
1002    INFO points to the function_format_info structure.
1003    PARAMS is the list of argument values.  */
1004 
1005 static void
check_format_info(function_format_info * info,tree params,vec<location_t> * arglocs)1006 check_format_info (function_format_info *info, tree params,
1007 		   vec<location_t> *arglocs)
1008 {
1009   format_check_context format_ctx;
1010   unsigned HOST_WIDE_INT arg_num;
1011   tree format_tree;
1012   format_check_results res;
1013   /* Skip to format argument.  If the argument isn't available, there's
1014      no work for us to do; prototype checking will catch the problem.  */
1015   for (arg_num = 1; ; ++arg_num)
1016     {
1017       if (params == 0)
1018 	return;
1019       if (arg_num == info->format_num)
1020 	break;
1021       params = TREE_CHAIN (params);
1022     }
1023   format_tree = TREE_VALUE (params);
1024   params = TREE_CHAIN (params);
1025   if (format_tree == 0)
1026     return;
1027 
1028   res.number_non_literal = 0;
1029   res.number_extra_args = 0;
1030   res.extra_arg_loc = UNKNOWN_LOCATION;
1031   res.number_dollar_extra_args = 0;
1032   res.number_wide = 0;
1033   res.number_non_char = 0;
1034   res.number_empty = 0;
1035   res.number_unterminated = 0;
1036   res.number_other = 0;
1037   res.format_string_loc = input_location;
1038 
1039   format_ctx.res = &res;
1040   format_ctx.info = info;
1041   format_ctx.params = params;
1042   format_ctx.arglocs = arglocs;
1043 
1044   check_function_arguments_recurse (check_format_arg, &format_ctx,
1045 				    format_tree, arg_num);
1046 
1047   location_t loc = format_ctx.res->format_string_loc;
1048 
1049   if (res.number_non_literal > 0)
1050     {
1051       /* Functions taking a va_list normally pass a non-literal format
1052 	 string.  These functions typically are declared with
1053 	 first_arg_num == 0, so avoid warning in those cases.  */
1054       if (!(format_types[info->format_type].flags & (int) FMT_FLAG_ARG_CONVERT))
1055 	{
1056 	  /* For strftime-like formats, warn for not checking the format
1057 	     string; but there are no arguments to check.  */
1058 	  warning_at (loc, OPT_Wformat_nonliteral,
1059 		      "format not a string literal, format string not checked");
1060 	}
1061       else if (info->first_arg_num != 0)
1062 	{
1063 	  /* If there are no arguments for the format at all, we may have
1064 	     printf (foo) which is likely to be a security hole.  */
1065 	  while (arg_num + 1 < info->first_arg_num)
1066 	    {
1067 	      if (params == 0)
1068 		break;
1069 	      params = TREE_CHAIN (params);
1070 	      ++arg_num;
1071 	    }
1072 	  if (params == 0 && warn_format_security)
1073 	    warning_at (loc, OPT_Wformat_security,
1074 			"format not a string literal and no format arguments");
1075 	  else if (params == 0 && warn_format_nonliteral)
1076 	    warning_at (loc, OPT_Wformat_nonliteral,
1077 			"format not a string literal and no format arguments");
1078 	  else
1079 	    warning_at (loc, OPT_Wformat_nonliteral,
1080 			"format not a string literal, argument types not checked");
1081 	}
1082     }
1083 
1084   /* If there were extra arguments to the format, normally warn.  However,
1085      the standard does say extra arguments are ignored, so in the specific
1086      case where we have multiple leaves (conditional expressions or
1087      ngettext) allow extra arguments if at least one leaf didn't have extra
1088      arguments, but was otherwise OK (either non-literal or checked OK).
1089      If the format is an empty string, this should be counted similarly to the
1090      case of extra format arguments.  */
1091   if (res.number_extra_args > 0 && res.number_non_literal == 0
1092       && res.number_other == 0)
1093     {
1094       if (res.extra_arg_loc == UNKNOWN_LOCATION)
1095 	res.extra_arg_loc = loc;
1096       warning_at (res.extra_arg_loc, OPT_Wformat_extra_args,
1097 		  "too many arguments for format");
1098     }
1099   if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
1100       && res.number_other == 0)
1101     warning_at (loc, OPT_Wformat_extra_args, "unused arguments in %<$%>-style format");
1102   if (res.number_empty > 0 && res.number_non_literal == 0
1103       && res.number_other == 0)
1104     warning_at (loc, OPT_Wformat_zero_length, "zero-length %s format string",
1105 	     format_types[info->format_type].name);
1106 
1107   if (res.number_wide > 0)
1108     warning_at (loc, OPT_Wformat_, "format is a wide character string");
1109 
1110   if (res.number_non_char > 0)
1111     warning_at (loc, OPT_Wformat_,
1112 		"format string is not an array of type %qs", "char");
1113 
1114   if (res.number_unterminated > 0)
1115     warning_at (loc, OPT_Wformat_, "unterminated format string");
1116 }
1117 
1118 /* Callback from check_function_arguments_recurse to check a
1119    format string.  FORMAT_TREE is the format parameter.  ARG_NUM
1120    is the number of the format argument.  CTX points to a
1121    format_check_context.  */
1122 
1123 static void
check_format_arg(void * ctx,tree format_tree,unsigned HOST_WIDE_INT arg_num)1124 check_format_arg (void *ctx, tree format_tree,
1125 		  unsigned HOST_WIDE_INT arg_num)
1126 {
1127   format_check_context *format_ctx = (format_check_context *) ctx;
1128   format_check_results *res = format_ctx->res;
1129   function_format_info *info = format_ctx->info;
1130   tree params = format_ctx->params;
1131   vec<location_t> *arglocs = format_ctx->arglocs;
1132 
1133   int format_length;
1134   HOST_WIDE_INT offset;
1135   const char *format_chars;
1136   tree array_size = 0;
1137   tree array_init;
1138 
1139   location_t fmt_param_loc = EXPR_LOC_OR_LOC (format_tree, input_location);
1140 
1141   /* Pull out a constant value if the front end didn't, and handle location
1142      wrappers.  */
1143   format_tree = fold_for_warn (format_tree);
1144   STRIP_NOPS (format_tree);
1145 
1146   if (integer_zerop (format_tree))
1147     {
1148       /* Skip to first argument to check, so we can see if this format
1149 	 has any arguments (it shouldn't).  */
1150       while (arg_num + 1 < info->first_arg_num)
1151 	{
1152 	  if (params == 0)
1153 	    return;
1154 	  params = TREE_CHAIN (params);
1155 	  ++arg_num;
1156 	}
1157 
1158       if (params == 0)
1159 	res->number_other++;
1160       else
1161 	{
1162 	  if (res->number_extra_args == 0)
1163 	    res->extra_arg_loc = EXPR_LOC_OR_LOC (TREE_VALUE (params),
1164 						  input_location);
1165 	  res->number_extra_args++;
1166 	}
1167       return;
1168     }
1169 
1170   offset = 0;
1171   if (TREE_CODE (format_tree) == POINTER_PLUS_EXPR)
1172     {
1173       tree arg0, arg1;
1174 
1175       arg0 = TREE_OPERAND (format_tree, 0);
1176       arg1 = TREE_OPERAND (format_tree, 1);
1177       STRIP_NOPS (arg0);
1178       STRIP_NOPS (arg1);
1179       if (TREE_CODE (arg1) == INTEGER_CST)
1180 	format_tree = arg0;
1181       else
1182 	{
1183 	  res->number_non_literal++;
1184 	  return;
1185 	}
1186       /* POINTER_PLUS_EXPR offsets are to be interpreted signed.  */
1187       if (!cst_and_fits_in_hwi (arg1))
1188 	{
1189 	  res->number_non_literal++;
1190 	  return;
1191 	}
1192       offset = int_cst_value (arg1);
1193     }
1194   if (TREE_CODE (format_tree) != ADDR_EXPR)
1195     {
1196       res->number_non_literal++;
1197       return;
1198     }
1199   res->format_string_loc = EXPR_LOC_OR_LOC (format_tree, input_location);
1200   format_tree = TREE_OPERAND (format_tree, 0);
1201   if (format_types[info->format_type].flags
1202       & (int) FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL)
1203     {
1204       /* We cannot examine this string here - but we can check that it is
1205 	 a valid type.  */
1206       if (TREE_CODE (format_tree) != CONST_DECL)
1207 	{
1208 	  res->number_non_literal++;
1209 	  return;
1210 	}
1211       /* Skip to first argument to check.  */
1212       while (arg_num + 1 < info->first_arg_num)
1213 	{
1214 	  if (params == 0)
1215 	    return;
1216 	  params = TREE_CHAIN (params);
1217 	  ++arg_num;
1218 	}
1219       return;
1220     }
1221   if (TREE_CODE (format_tree) == ARRAY_REF
1222       && tree_fits_shwi_p (TREE_OPERAND (format_tree, 1))
1223       && (offset += tree_to_shwi (TREE_OPERAND (format_tree, 1))) >= 0)
1224     format_tree = TREE_OPERAND (format_tree, 0);
1225   if (offset < 0)
1226     {
1227       res->number_non_literal++;
1228       return;
1229     }
1230   if (VAR_P (format_tree)
1231       && TREE_CODE (TREE_TYPE (format_tree)) == ARRAY_TYPE
1232       && (array_init = decl_constant_value (format_tree)) != format_tree
1233       && TREE_CODE (array_init) == STRING_CST)
1234     {
1235       /* Extract the string constant initializer.  Note that this may include
1236 	 a trailing NUL character that is not in the array (e.g.
1237 	 const char a[3] = "foo";).  */
1238       array_size = DECL_SIZE_UNIT (format_tree);
1239       format_tree = array_init;
1240     }
1241   if (TREE_CODE (format_tree) != STRING_CST)
1242     {
1243       res->number_non_literal++;
1244       return;
1245     }
1246   tree underlying_type
1247     = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (format_tree)));
1248   if (underlying_type != char_type_node)
1249     {
1250       if (underlying_type == char16_type_node
1251 	  || underlying_type == char32_type_node
1252 	  || underlying_type == wchar_type_node)
1253 	res->number_wide++;
1254       else
1255 	res->number_non_char++;
1256       return;
1257     }
1258   format_chars = TREE_STRING_POINTER (format_tree);
1259   format_length = TREE_STRING_LENGTH (format_tree);
1260   if (array_size != 0)
1261     {
1262       /* Variable length arrays can't be initialized.  */
1263       gcc_assert (TREE_CODE (array_size) == INTEGER_CST);
1264 
1265       if (tree_fits_shwi_p (array_size))
1266 	{
1267 	  HOST_WIDE_INT array_size_value = tree_to_shwi (array_size);
1268 	  if (array_size_value > 0
1269 	      && array_size_value == (int) array_size_value
1270 	      && format_length > array_size_value)
1271 	    format_length = array_size_value;
1272 	}
1273     }
1274   if (offset)
1275     {
1276       if (offset >= format_length)
1277 	{
1278 	  res->number_non_literal++;
1279 	  return;
1280 	}
1281       format_chars += offset;
1282       format_length -= offset;
1283     }
1284   if (format_length < 1 || format_chars[--format_length] != 0)
1285     {
1286       res->number_unterminated++;
1287       return;
1288     }
1289   if (format_length == 0)
1290     {
1291       res->number_empty++;
1292       return;
1293     }
1294 
1295   /* Skip to first argument to check.  */
1296   while (arg_num + 1 < info->first_arg_num)
1297     {
1298       if (params == 0)
1299 	return;
1300       params = TREE_CHAIN (params);
1301       ++arg_num;
1302     }
1303   /* Provisionally increment res->number_other; check_format_info_main
1304      will decrement it if it finds there are extra arguments, but this way
1305      need not adjust it for every return.  */
1306   res->number_other++;
1307   object_allocator <format_wanted_type> fwt_pool ("format_wanted_type pool");
1308   check_format_info_main (res, info, format_chars, fmt_param_loc, format_tree,
1309 			  format_length, params, arg_num, fwt_pool, arglocs);
1310 }
1311 
1312 /* Support class for argument_parser and check_format_info_main.
1313    Tracks any flag characters that have been applied to the
1314    current argument.  */
1315 
1316 class flag_chars_t
1317 {
1318  public:
1319   flag_chars_t ();
1320   bool has_char_p (char ch) const;
1321   void add_char (char ch);
1322   void validate (const format_kind_info *fki,
1323 		 const format_char_info *fci,
1324 		 const format_flag_spec *flag_specs,
1325 		 const char * const format_chars,
1326 		 tree format_string_cst,
1327 		 location_t format_string_loc,
1328 		 const char * const orig_format_chars,
1329 		 char format_char,
1330 		 bool quoted);
1331   int get_alloc_flag (const format_kind_info *fki);
1332   int assignment_suppression_p (const format_kind_info *fki);
1333 
1334  private:
1335   char m_flag_chars[256];
1336 };
1337 
1338 /* Support struct for argument_parser and check_format_info_main.
1339    Encapsulates any length modifier applied to the current argument.  */
1340 
1341 struct length_modifier
1342 {
length_modifierlength_modifier1343   length_modifier ()
1344   : chars (NULL), val (FMT_LEN_none), std (STD_C89),
1345     scalar_identity_flag (0)
1346   {
1347   }
1348 
length_modifierlength_modifier1349   length_modifier (const char *chars_,
1350 		   enum format_lengths val_,
1351 		   enum format_std_version std_,
1352 		   int scalar_identity_flag_)
1353   : chars (chars_), val (val_), std (std_),
1354     scalar_identity_flag (scalar_identity_flag_)
1355   {
1356   }
1357 
1358   const char *chars;
1359   enum format_lengths val;
1360   enum format_std_version std;
1361   int scalar_identity_flag;
1362 };
1363 
1364 /* Parsing one argument within a format string.  */
1365 
1366 class argument_parser
1367 {
1368  public:
1369   argument_parser (function_format_info *info, const char *&format_chars,
1370 		   tree format_string_cst,
1371 		   const char * const orig_format_chars,
1372 		   location_t format_string_loc, flag_chars_t &flag_chars,
1373 		   int &has_operand_number, tree first_fillin_param,
1374 		   object_allocator <format_wanted_type> &fwt_pool_,
1375 		   vec<location_t> *arglocs);
1376 
1377   bool read_any_dollar ();
1378 
1379   bool read_format_flags ();
1380 
1381   bool
1382   read_any_format_width (tree &params,
1383 			 unsigned HOST_WIDE_INT &arg_num);
1384 
1385   void
1386   read_any_format_left_precision ();
1387 
1388   bool
1389   read_any_format_precision (tree &params,
1390 			     unsigned HOST_WIDE_INT &arg_num);
1391 
1392   void handle_alloc_chars ();
1393 
1394   length_modifier read_any_length_modifier ();
1395 
1396   void read_any_other_modifier ();
1397 
1398   const format_char_info *find_format_char_info (char format_char);
1399 
1400   void
1401   validate_flag_pairs (const format_char_info *fci,
1402 		       char format_char);
1403 
1404   void
1405   give_y2k_warnings (const format_char_info *fci,
1406 		     char format_char);
1407 
1408   void parse_any_scan_set (const format_char_info *fci);
1409 
1410   bool handle_conversions (const format_char_info *fci,
1411 			   const length_modifier &len_modifier,
1412 			   tree &wanted_type,
1413 			   const char *&wanted_type_name,
1414 			   unsigned HOST_WIDE_INT &arg_num,
1415 			   tree &params,
1416 			   char format_char);
1417 
1418   bool
1419   check_argument_type (const format_char_info *fci,
1420 		       const struct kernel_ext_fmt *kef,
1421 		       const length_modifier &len_modifier,
1422 		       tree &wanted_type,
1423 		       const char *&wanted_type_name,
1424 		       const bool suppressed,
1425 		       unsigned HOST_WIDE_INT &arg_num,
1426 		       tree &params,
1427 		       const int alloc_flag,
1428 		       const char * const format_start,
1429 		       const char * const type_start,
1430 		       location_t fmt_param_loc,
1431 		       char conversion_char);
1432 
1433  private:
1434   const function_format_info *const info;
1435   const format_kind_info * const fki;
1436   const format_flag_spec * const flag_specs;
1437   const char *start_of_this_format;
1438   const char *&format_chars;
1439   const tree format_string_cst;
1440   const char * const orig_format_chars;
1441   const location_t format_string_loc;
1442   object_allocator <format_wanted_type> &fwt_pool;
1443   flag_chars_t &flag_chars;
1444   int main_arg_num;
1445   tree main_arg_params;
1446   int &has_operand_number;
1447   const tree first_fillin_param;
1448   format_wanted_type width_wanted_type;
1449   format_wanted_type precision_wanted_type;
1450  public:
1451   format_wanted_type main_wanted_type;
1452  private:
1453   format_wanted_type *first_wanted_type;
1454   format_wanted_type *last_wanted_type;
1455   vec<location_t> *arglocs;
1456 };
1457 
1458 /* flag_chars_t's constructor.  */
1459 
flag_chars_t()1460 flag_chars_t::flag_chars_t ()
1461 {
1462   m_flag_chars[0] = 0;
1463 }
1464 
1465 /* Has CH been seen as a flag within the current argument?  */
1466 
1467 bool
has_char_p(char ch)1468 flag_chars_t::has_char_p (char ch) const
1469 {
1470   return strchr (m_flag_chars, ch) != 0;
1471 }
1472 
1473 /* Add CH to the flags seen within the current argument.  */
1474 
1475 void
add_char(char ch)1476 flag_chars_t::add_char (char ch)
1477 {
1478   int i = strlen (m_flag_chars);
1479   m_flag_chars[i++] = ch;
1480   m_flag_chars[i] = 0;
1481 }
1482 
1483 /* Validate the individual flags used, removing any that are invalid.  */
1484 
1485 void
validate(const format_kind_info * fki,const format_char_info * fci,const format_flag_spec * flag_specs,const char * const format_chars,tree format_string_cst,location_t format_string_loc,const char * const orig_format_chars,char format_char,bool quoted)1486 flag_chars_t::validate (const format_kind_info *fki,
1487 			const format_char_info *fci,
1488 			const format_flag_spec *flag_specs,
1489 			const char * const format_chars,
1490 			tree format_string_cst,
1491 			location_t format_string_loc,
1492 			const char * const orig_format_chars,
1493 			char format_char,
1494 			bool quoted)
1495 {
1496   int i;
1497   int d = 0;
1498   bool quotflag = false;
1499 
1500   for (i = 0; m_flag_chars[i] != 0; i++)
1501     {
1502       const format_flag_spec *s = get_flag_spec (flag_specs,
1503 						 m_flag_chars[i], NULL);
1504       m_flag_chars[i - d] = m_flag_chars[i];
1505       if (m_flag_chars[i] == fki->length_code_char)
1506 	continue;
1507 
1508       /* Remember if a quoting flag is seen.  */
1509       quotflag |= s->quoting;
1510 
1511       if (strchr (fci->flag_chars, m_flag_chars[i]) == 0)
1512 	{
1513 	  format_warning_at_char (format_string_loc, format_string_cst,
1514 				  format_chars - orig_format_chars,
1515 				  OPT_Wformat_,
1516 				  "%s used with %<%%%c%> %s format",
1517 				  _(s->name), format_char, fki->name);
1518 	  d++;
1519 	  continue;
1520 	}
1521       if (pedantic)
1522 	{
1523 	  const format_flag_spec *t;
1524 	  if (ADJ_STD (s->std) > C_STD_VER)
1525 	    warning_at (format_string_loc, OPT_Wformat_,
1526 			"%s does not support %s",
1527 			C_STD_NAME (s->std), _(s->long_name));
1528 	  t = get_flag_spec (flag_specs, m_flag_chars[i], fci->flags2);
1529 	  if (t != NULL && ADJ_STD (t->std) > ADJ_STD (s->std))
1530 	    {
1531 	      const char *long_name = (t->long_name != NULL
1532 				       ? t->long_name
1533 				       : s->long_name);
1534 	      if (ADJ_STD (t->std) > C_STD_VER)
1535 		warning_at (format_string_loc, OPT_Wformat_,
1536 			    "%s does not support %s with the %<%%%c%> %s format",
1537 			    C_STD_NAME (t->std), _(long_name),
1538 			    format_char, fki->name);
1539 	    }
1540 	}
1541 
1542       /* Detect quoting directives used within a quoted sequence, such
1543 	 as GCC's "%<...%qE".  */
1544       if (quoted && s->quoting)
1545 	{
1546 	  format_warning_at_char (format_string_loc, format_string_cst,
1547 				  format_chars - orig_format_chars - 1,
1548 				  OPT_Wformat_,
1549 				  "%s used within a quoted sequence",
1550 				  _(s->name));
1551 	}
1552     }
1553   m_flag_chars[i - d] = 0;
1554 
1555   if (!quoted
1556       && !quotflag
1557       && strchr (fci->flags2, '\''))
1558     {
1559       format_warning_at_char (format_string_loc, format_string_cst,
1560 			      format_chars - orig_format_chars,
1561 			      OPT_Wformat_,
1562 			      "%qc conversion used unquoted",
1563 			      format_char);
1564     }
1565 }
1566 
1567 /* Determine if an assignment-allocation has been set, requiring
1568    an extra char ** for writing back a dynamically-allocated char *.
1569    This is for handling the optional 'm' character in scanf.  */
1570 
1571 int
get_alloc_flag(const format_kind_info * fki)1572 flag_chars_t::get_alloc_flag (const format_kind_info *fki)
1573 {
1574   if ((fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1575       && has_char_p ('a'))
1576     return 1;
1577   if (fki->alloc_char && has_char_p (fki->alloc_char))
1578     return 1;
1579   return 0;
1580 }
1581 
1582 /* Determine if an assignment-suppression character was seen.
1583    ('*' in scanf, for discarding the converted input).  */
1584 
1585 int
assignment_suppression_p(const format_kind_info * fki)1586 flag_chars_t::assignment_suppression_p (const format_kind_info *fki)
1587 {
1588   if (fki->suppression_char
1589       && has_char_p (fki->suppression_char))
1590     return 1;
1591   return 0;
1592 }
1593 
1594 /* Constructor for argument_parser.  Initialize for parsing one
1595    argument within a format string.  */
1596 
1597 argument_parser::
argument_parser(function_format_info * info_,const char * & format_chars_,tree format_string_cst_,const char * const orig_format_chars_,location_t format_string_loc_,flag_chars_t & flag_chars_,int & has_operand_number_,tree first_fillin_param_,object_allocator<format_wanted_type> & fwt_pool_,vec<location_t> * arglocs_)1598 argument_parser (function_format_info *info_, const char *&format_chars_,
1599 		 tree format_string_cst_,
1600 		 const char * const orig_format_chars_,
1601 		 location_t format_string_loc_,
1602 		 flag_chars_t &flag_chars_,
1603 		 int &has_operand_number_,
1604 		 tree first_fillin_param_,
1605 		 object_allocator <format_wanted_type> &fwt_pool_,
1606 		 vec<location_t> *arglocs_)
1607 : info (info_),
1608   fki (&format_types[info->format_type]),
1609   flag_specs (fki->flag_specs),
1610   start_of_this_format (format_chars_),
1611   format_chars (format_chars_),
1612   format_string_cst (format_string_cst_),
1613   orig_format_chars (orig_format_chars_),
1614   format_string_loc (format_string_loc_),
1615   fwt_pool (fwt_pool_),
1616   flag_chars (flag_chars_),
1617   main_arg_num (0),
1618   main_arg_params (NULL),
1619   has_operand_number (has_operand_number_),
1620   first_fillin_param (first_fillin_param_),
1621   first_wanted_type (NULL),
1622   last_wanted_type (NULL),
1623   arglocs (arglocs_)
1624 {
1625 }
1626 
1627 /* Handle dollars at the start of format arguments, setting up main_arg_params
1628    and main_arg_num.
1629 
1630    Return true if format parsing is to continue, false otherwise.  */
1631 
1632 bool
read_any_dollar()1633 argument_parser::read_any_dollar ()
1634 {
1635   if ((fki->flags & (int) FMT_FLAG_USE_DOLLAR) && has_operand_number != 0)
1636     {
1637       /* Possibly read a $ operand number at the start of the format.
1638 	 If one was previously used, one is required here.  If one
1639 	 is not used here, we can't immediately conclude this is a
1640 	 format without them, since it could be printf %m or scanf %*.  */
1641       int opnum;
1642       opnum = maybe_read_dollar_number (&format_chars, 0,
1643 					first_fillin_param,
1644 					&main_arg_params, fki);
1645       if (opnum == -1)
1646 	return false;
1647       else if (opnum > 0)
1648 	{
1649 	  has_operand_number = 1;
1650 	  main_arg_num = opnum + info->first_arg_num - 1;
1651 	}
1652     }
1653   else if (fki->flags & FMT_FLAG_USE_DOLLAR)
1654     {
1655       if (avoid_dollar_number (format_chars))
1656 	return false;
1657     }
1658   return true;
1659 }
1660 
1661 /* Read any format flags, but do not yet validate them beyond removing
1662    duplicates, since in general validation depends on the rest of
1663    the format.
1664 
1665    Return true if format parsing is to continue, false otherwise.  */
1666 
1667 bool
read_format_flags()1668 argument_parser::read_format_flags ()
1669 {
1670   while (*format_chars != 0
1671 	 && strchr (fki->flag_chars, *format_chars) != 0)
1672     {
1673       const format_flag_spec *s = get_flag_spec (flag_specs,
1674 						 *format_chars, NULL);
1675       if (flag_chars.has_char_p (*format_chars))
1676 	{
1677 	  format_warning_at_char (format_string_loc, format_string_cst,
1678 				  format_chars + 1 - orig_format_chars,
1679 				  OPT_Wformat_,
1680 				  "repeated %s in format", _(s->name));
1681 	}
1682       else
1683 	flag_chars.add_char (*format_chars);
1684 
1685       if (s->skip_next_char)
1686 	{
1687 	  ++format_chars;
1688 	  if (*format_chars == 0)
1689 	    {
1690 	      warning_at (format_string_loc, OPT_Wformat_,
1691 			  "missing fill character at end of strfmon format");
1692 	      return false;
1693 	    }
1694 	}
1695       ++format_chars;
1696     }
1697 
1698   return true;
1699 }
1700 
1701 /* Read any format width, possibly * or *m$.
1702 
1703    Return true if format parsing is to continue, false otherwise.  */
1704 
1705 bool
1706 argument_parser::
read_any_format_width(tree & params,unsigned HOST_WIDE_INT & arg_num)1707 read_any_format_width (tree &params,
1708 		       unsigned HOST_WIDE_INT &arg_num)
1709 {
1710   if (!fki->width_char)
1711     return true;
1712 
1713   if (fki->width_type != NULL && *format_chars == '*')
1714     {
1715       flag_chars.add_char (fki->width_char);
1716       /* "...a field width...may be indicated by an asterisk.
1717 	 In this case, an int argument supplies the field width..."  */
1718       ++format_chars;
1719       if (has_operand_number != 0)
1720 	{
1721 	  int opnum;
1722 	  opnum = maybe_read_dollar_number (&format_chars,
1723 					    has_operand_number == 1,
1724 					    first_fillin_param,
1725 					    &params, fki);
1726 	  if (opnum == -1)
1727 	    return false;
1728 	  else if (opnum > 0)
1729 	    {
1730 	      has_operand_number = 1;
1731 	      arg_num = opnum + info->first_arg_num - 1;
1732 	    }
1733 	  else
1734 	    has_operand_number = 0;
1735 	}
1736       else
1737 	{
1738 	  if (avoid_dollar_number (format_chars))
1739 	    return false;
1740 	}
1741       if (info->first_arg_num != 0)
1742 	{
1743 	  tree cur_param;
1744 	  if (params == 0)
1745 	    cur_param = NULL;
1746 	  else
1747 	    {
1748 	      cur_param = TREE_VALUE (params);
1749 	      if (has_operand_number <= 0)
1750 		{
1751 		  params = TREE_CHAIN (params);
1752 		  ++arg_num;
1753 		}
1754 	    }
1755 	  width_wanted_type.wanted_type = *fki->width_type;
1756 	  width_wanted_type.wanted_type_name = NULL;
1757 	  width_wanted_type.pointer_count = 0;
1758 	  width_wanted_type.char_lenient_flag = 0;
1759 	  width_wanted_type.scalar_identity_flag = 0;
1760 	  width_wanted_type.writing_in_flag = 0;
1761 	  width_wanted_type.reading_from_flag = 0;
1762 	  width_wanted_type.kind = CF_KIND_FIELD_WIDTH;
1763 	  width_wanted_type.format_start = format_chars - 1;
1764 	  width_wanted_type.format_length = 1;
1765 	  width_wanted_type.param = cur_param;
1766 	  width_wanted_type.arg_num = arg_num;
1767 	  width_wanted_type.offset_loc =
1768 	    format_chars - orig_format_chars;
1769 	  width_wanted_type.next = NULL;
1770 	  if (last_wanted_type != 0)
1771 	    last_wanted_type->next = &width_wanted_type;
1772 	  if (first_wanted_type == 0)
1773 	    first_wanted_type = &width_wanted_type;
1774 	  last_wanted_type = &width_wanted_type;
1775 	}
1776     }
1777   else
1778     {
1779       /* Possibly read a numeric width.  If the width is zero,
1780 	 we complain if appropriate.  */
1781       int non_zero_width_char = FALSE;
1782       int found_width = FALSE;
1783       while (ISDIGIT (*format_chars))
1784 	{
1785 	  found_width = TRUE;
1786 	  if (*format_chars != '0')
1787 	    non_zero_width_char = TRUE;
1788 	  ++format_chars;
1789 	}
1790       if (found_width && !non_zero_width_char &&
1791 	  (fki->flags & (int) FMT_FLAG_ZERO_WIDTH_BAD))
1792 	warning_at (format_string_loc, OPT_Wformat_,
1793 		    "zero width in %s format", fki->name);
1794       if (found_width)
1795 	flag_chars.add_char (fki->width_char);
1796     }
1797 
1798   return true;
1799 }
1800 
1801 /* Read any format left precision (must be a number, not *).  */
1802 void
read_any_format_left_precision()1803 argument_parser::read_any_format_left_precision ()
1804 {
1805   if (fki->left_precision_char == 0)
1806     return;
1807   if (*format_chars != '#')
1808     return;
1809 
1810   ++format_chars;
1811   flag_chars.add_char (fki->left_precision_char);
1812   if (!ISDIGIT (*format_chars))
1813     format_warning_at_char (format_string_loc, format_string_cst,
1814 			    format_chars - orig_format_chars,
1815 			    OPT_Wformat_,
1816 			    "empty left precision in %s format", fki->name);
1817   while (ISDIGIT (*format_chars))
1818     ++format_chars;
1819 }
1820 
1821 /* Read any format precision, possibly * or *m$.
1822 
1823    Return true if format parsing is to continue, false otherwise.  */
1824 
1825 bool
1826 argument_parser::
read_any_format_precision(tree & params,unsigned HOST_WIDE_INT & arg_num)1827 read_any_format_precision (tree &params,
1828 			   unsigned HOST_WIDE_INT &arg_num)
1829 {
1830   if (fki->precision_char == 0)
1831     return true;
1832   if (*format_chars != '.')
1833     return true;
1834 
1835   ++format_chars;
1836   flag_chars.add_char (fki->precision_char);
1837   if (fki->precision_type != NULL && *format_chars == '*')
1838     {
1839       /* "...a...precision...may be indicated by an asterisk.
1840 	 In this case, an int argument supplies the...precision."  */
1841       ++format_chars;
1842       if (has_operand_number != 0)
1843 	{
1844 	  int opnum;
1845 	  opnum = maybe_read_dollar_number (&format_chars,
1846 					    has_operand_number == 1,
1847 					    first_fillin_param,
1848 					    &params, fki);
1849 	  if (opnum == -1)
1850 	    return false;
1851 	  else if (opnum > 0)
1852 	    {
1853 	      has_operand_number = 1;
1854 	      arg_num = opnum + info->first_arg_num - 1;
1855 	    }
1856 	  else
1857 	    has_operand_number = 0;
1858 	}
1859       else
1860 	{
1861 	  if (avoid_dollar_number (format_chars))
1862 	    return false;
1863 	}
1864       if (info->first_arg_num != 0)
1865 	{
1866 	  tree cur_param;
1867 	  if (params == 0)
1868 	    cur_param = NULL;
1869 	  else
1870 	    {
1871 	      cur_param = TREE_VALUE (params);
1872 	      if (has_operand_number <= 0)
1873 		{
1874 		  params = TREE_CHAIN (params);
1875 		  ++arg_num;
1876 		}
1877 	    }
1878 	  precision_wanted_type.wanted_type = *fki->precision_type;
1879 	  precision_wanted_type.wanted_type_name = NULL;
1880 	  precision_wanted_type.pointer_count = 0;
1881 	  precision_wanted_type.char_lenient_flag = 0;
1882 	  precision_wanted_type.scalar_identity_flag = 0;
1883 	  precision_wanted_type.writing_in_flag = 0;
1884 	  precision_wanted_type.reading_from_flag = 0;
1885 	  precision_wanted_type.kind = CF_KIND_FIELD_PRECISION;
1886 	  precision_wanted_type.param = cur_param;
1887 	  precision_wanted_type.format_start = format_chars - 2;
1888 	  precision_wanted_type.format_length = 2;
1889 	  precision_wanted_type.arg_num = arg_num;
1890 	  precision_wanted_type.offset_loc =
1891 	    format_chars - orig_format_chars;
1892 	  precision_wanted_type.next = NULL;
1893 	  if (last_wanted_type != 0)
1894 	    last_wanted_type->next = &precision_wanted_type;
1895 	  if (first_wanted_type == 0)
1896 	    first_wanted_type = &precision_wanted_type;
1897 	  last_wanted_type = &precision_wanted_type;
1898 	}
1899     }
1900   else
1901     {
1902       if (!(fki->flags & (int) FMT_FLAG_EMPTY_PREC_OK)
1903 	  && !ISDIGIT (*format_chars))
1904 	format_warning_at_char (format_string_loc, format_string_cst,
1905 				format_chars - orig_format_chars,
1906 				OPT_Wformat_,
1907 				"empty precision in %s format", fki->name);
1908       while (ISDIGIT (*format_chars))
1909 	++format_chars;
1910     }
1911 
1912   return true;
1913 }
1914 
1915 /* Parse any assignment-allocation flags, which request an extra
1916    char ** for writing back a dynamically-allocated char *.
1917    This is for handling the optional 'm' character in scanf,
1918    and, before C99, 'a' (for compatibility with a non-standard
1919    GNU libc extension).  */
1920 
1921 void
handle_alloc_chars()1922 argument_parser::handle_alloc_chars ()
1923 {
1924   if (fki->alloc_char && fki->alloc_char == *format_chars)
1925     {
1926       flag_chars.add_char (fki->alloc_char);
1927       format_chars++;
1928     }
1929 
1930   /* Handle the scanf allocation kludge.  */
1931   if (fki->flags & (int) FMT_FLAG_SCANF_A_KLUDGE)
1932     {
1933       if (*format_chars == 'a' && !flag_isoc99)
1934 	{
1935 	  if (format_chars[1] == 's' || format_chars[1] == 'S'
1936 	      || format_chars[1] == '[')
1937 	    {
1938 	      /* 'a' is used as a flag.  */
1939 	      flag_chars.add_char ('a');
1940 	      format_chars++;
1941 	    }
1942 	}
1943     }
1944 }
1945 
1946 /* Look for length modifiers within the current format argument,
1947    returning a length_modifier instance describing it (or the
1948    default if one is not found).
1949 
1950    Issue warnings about non-standard modifiers.  */
1951 
1952 length_modifier
read_any_length_modifier()1953 argument_parser::read_any_length_modifier ()
1954 {
1955   length_modifier result;
1956 
1957   const format_length_info *fli = fki->length_char_specs;
1958   if (!fli)
1959     return result;
1960 
1961   while (fli->name != 0
1962 	 && strncmp (fli->name, format_chars, strlen (fli->name)))
1963     fli++;
1964   if (fli->name != 0)
1965     {
1966       format_chars += strlen (fli->name);
1967       if (fli->double_name != 0 && fli->name[0] == *format_chars)
1968 	{
1969 	  format_chars++;
1970 	  result = length_modifier (fli->double_name, fli->double_index,
1971 				    fli->double_std, 0);
1972 	}
1973       else
1974 	{
1975 	  result = length_modifier (fli->name, fli->index, fli->std,
1976 				    fli->scalar_identity_flag);
1977 	}
1978       flag_chars.add_char (fki->length_code_char);
1979     }
1980   if (pedantic)
1981     {
1982       /* Warn if the length modifier is non-standard.  */
1983       if (ADJ_STD (result.std) > C_STD_VER)
1984 	warning_at (format_string_loc, OPT_Wformat_,
1985 		    "%s does not support the %qs %s length modifier",
1986 		    C_STD_NAME (result.std), result.chars,
1987 		    fki->name);
1988     }
1989 
1990   return result;
1991 }
1992 
1993 /* Read any other modifier (strftime E/O).  */
1994 
1995 void
read_any_other_modifier()1996 argument_parser::read_any_other_modifier ()
1997 {
1998   if (fki->modifier_chars == NULL)
1999     return;
2000 
2001   while (*format_chars != 0
2002 	 && strchr (fki->modifier_chars, *format_chars) != 0)
2003     {
2004       if (flag_chars.has_char_p (*format_chars))
2005 	{
2006 	  const format_flag_spec *s = get_flag_spec (flag_specs,
2007 						     *format_chars, NULL);
2008 	  format_warning_at_char (format_string_loc, format_string_cst,
2009 				  format_chars - orig_format_chars,
2010 				  OPT_Wformat_,
2011 				  "repeated %s in format", _(s->name));
2012 	}
2013       else
2014 	flag_chars.add_char (*format_chars);
2015       ++format_chars;
2016     }
2017 }
2018 
2019 /* Return the format_char_info corresponding to FORMAT_CHAR,
2020    potentially issuing a warning if the format char is
2021    not supported in the C standard version we are checking
2022    against.
2023 
2024    Issue a warning and return NULL if it is not found.
2025 
2026    Issue warnings about non-standard modifiers.  */
2027 
2028 const format_char_info *
find_format_char_info(char format_char)2029 argument_parser::find_format_char_info (char format_char)
2030 {
2031   const format_char_info *fci = fki->conversion_specs;
2032 
2033   while (fci->format_chars != 0
2034 	 && strchr (fci->format_chars, format_char) == 0)
2035     ++fci;
2036   if (fci->format_chars == 0)
2037     {
2038       format_warning_at_char (format_string_loc, format_string_cst,
2039 			      format_chars - orig_format_chars,
2040 			      OPT_Wformat_,
2041 			      "unknown conversion type character %qc in format",
2042 			      format_char);
2043       return NULL;
2044     }
2045 
2046   if (pedantic)
2047     {
2048       if (ADJ_STD (fci->std) > C_STD_VER)
2049 	format_warning_at_char (format_string_loc, format_string_cst,
2050 				format_chars - orig_format_chars,
2051 				OPT_Wformat_,
2052 				"%s does not support the %<%%%c%> %s format",
2053 				C_STD_NAME (fci->std), format_char, fki->name);
2054     }
2055 
2056   return fci;
2057 }
2058 
2059 /* Validate the pairs of flags used.
2060    Issue warnings about incompatible combinations of flags.  */
2061 
2062 void
validate_flag_pairs(const format_char_info * fci,char format_char)2063 argument_parser::validate_flag_pairs (const format_char_info *fci,
2064 				      char format_char)
2065 {
2066   const format_flag_pair * const bad_flag_pairs = fki->bad_flag_pairs;
2067 
2068   for (int i = 0; bad_flag_pairs[i].flag_char1 != 0; i++)
2069     {
2070       const format_flag_spec *s, *t;
2071       if (!flag_chars.has_char_p (bad_flag_pairs[i].flag_char1))
2072 	continue;
2073       if (!flag_chars.has_char_p (bad_flag_pairs[i].flag_char2))
2074 	continue;
2075       if (bad_flag_pairs[i].predicate != 0
2076 	  && strchr (fci->flags2, bad_flag_pairs[i].predicate) == 0)
2077 	continue;
2078       s = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char1, NULL);
2079       t = get_flag_spec (flag_specs, bad_flag_pairs[i].flag_char2, NULL);
2080       if (bad_flag_pairs[i].ignored)
2081 	{
2082 	  if (bad_flag_pairs[i].predicate != 0)
2083 	    warning_at (format_string_loc, OPT_Wformat_,
2084 			"%s ignored with %s and %<%%%c%> %s format",
2085 			_(s->name), _(t->name), format_char,
2086 			fki->name);
2087 	  else
2088 	    warning_at (format_string_loc, OPT_Wformat_,
2089 			"%s ignored with %s in %s format",
2090 			_(s->name), _(t->name), fki->name);
2091 	}
2092       else
2093 	{
2094 	  if (bad_flag_pairs[i].predicate != 0)
2095 	    warning_at (format_string_loc, OPT_Wformat_,
2096 			"use of %s and %s together with %<%%%c%> %s format",
2097 			_(s->name), _(t->name), format_char,
2098 			fki->name);
2099 	  else
2100 	    warning_at (format_string_loc, OPT_Wformat_,
2101 			"use of %s and %s together in %s format",
2102 			_(s->name), _(t->name), fki->name);
2103 	}
2104     }
2105 }
2106 
2107 /* Give Y2K warnings.  */
2108 
2109 void
give_y2k_warnings(const format_char_info * fci,char format_char)2110 argument_parser::give_y2k_warnings (const format_char_info *fci,
2111 				    char format_char)
2112 {
2113   if (!warn_format_y2k)
2114     return;
2115 
2116   int y2k_level = 0;
2117   if (strchr (fci->flags2, '4') != 0)
2118     if (flag_chars.has_char_p ('E'))
2119       y2k_level = 3;
2120     else
2121       y2k_level = 2;
2122   else if (strchr (fci->flags2, '3') != 0)
2123     y2k_level = 3;
2124   else if (strchr (fci->flags2, '2') != 0)
2125     y2k_level = 2;
2126   if (y2k_level == 3)
2127     warning_at (format_string_loc, OPT_Wformat_y2k,
2128 		"%<%%%c%> yields only last 2 digits of year in some locales", format_char);
2129   else if (y2k_level == 2)
2130     warning_at (format_string_loc, OPT_Wformat_y2k,
2131 		"%<%%%c%> yields only last 2 digits of year",
2132 		format_char);
2133 }
2134 
2135 /* Parse any "scan sets" enclosed in square brackets, e.g.
2136    for scanf-style calls.  */
2137 
2138 void
parse_any_scan_set(const format_char_info * fci)2139 argument_parser::parse_any_scan_set (const format_char_info *fci)
2140 {
2141   if (strchr (fci->flags2, '[') == NULL)
2142     return;
2143 
2144   /* Skip over scan set, in case it happens to have '%' in it.  */
2145   if (*format_chars == '^')
2146     ++format_chars;
2147   /* Find closing bracket; if one is hit immediately, then
2148      it's part of the scan set rather than a terminator.  */
2149   if (*format_chars == ']')
2150     ++format_chars;
2151   while (*format_chars && *format_chars != ']')
2152     ++format_chars;
2153   if (*format_chars != ']')
2154     /* The end of the format string was reached.  */
2155     format_warning_at_char (format_string_loc, format_string_cst,
2156 			    format_chars - orig_format_chars,
2157 			    OPT_Wformat_,
2158 			    "no closing %<]%> for %<%%[%> format");
2159 }
2160 
2161 /* Return true if this argument is to be continued to be parsed,
2162    false to skip to next argument.  */
2163 
2164 bool
handle_conversions(const format_char_info * fci,const length_modifier & len_modifier,tree & wanted_type,const char * & wanted_type_name,unsigned HOST_WIDE_INT & arg_num,tree & params,char format_char)2165 argument_parser::handle_conversions (const format_char_info *fci,
2166 				     const length_modifier &len_modifier,
2167 				     tree &wanted_type,
2168 				     const char *&wanted_type_name,
2169 				     unsigned HOST_WIDE_INT &arg_num,
2170 				     tree &params,
2171 				     char format_char)
2172 {
2173   enum format_std_version wanted_type_std;
2174 
2175   if (!(fki->flags & (int) FMT_FLAG_ARG_CONVERT))
2176     return true;
2177 
2178   wanted_type = (fci->types[len_modifier.val].type
2179 		 ? *fci->types[len_modifier.val].type : 0);
2180   wanted_type_name = fci->types[len_modifier.val].name;
2181   wanted_type_std = fci->types[len_modifier.val].std;
2182   if (wanted_type == 0)
2183     {
2184       format_warning_at_char (format_string_loc, format_string_cst,
2185 			      format_chars - orig_format_chars,
2186 			      OPT_Wformat_,
2187 			      "use of %qs length modifier with %qc type character has either no effect or undefined behavior",
2188 			      len_modifier.chars, format_char);
2189       /* Heuristic: skip one argument when an invalid length/type
2190 	 combination is encountered.  */
2191       arg_num++;
2192       if (params != 0)
2193 	params = TREE_CHAIN (params);
2194       return false;
2195     }
2196   else if (pedantic
2197 	   /* Warn if non-standard, provided it is more non-standard
2198 	      than the length and type characters that may already
2199 	      have been warned for.  */
2200 	   && ADJ_STD (wanted_type_std) > ADJ_STD (len_modifier.std)
2201 	   && ADJ_STD (wanted_type_std) > ADJ_STD (fci->std))
2202     {
2203       if (ADJ_STD (wanted_type_std) > C_STD_VER)
2204 	format_warning_at_char (format_string_loc, format_string_cst,
2205 				format_chars - orig_format_chars,
2206 				OPT_Wformat_,
2207 				"%s does not support the %<%%%s%c%> %s format",
2208 				C_STD_NAME (wanted_type_std),
2209 				len_modifier.chars,
2210 				format_char, fki->name);
2211     }
2212 
2213   return true;
2214 }
2215 
2216 /* Check type of argument against desired type.
2217 
2218    Return true if format parsing is to continue, false otherwise.  */
2219 
2220 bool
2221 argument_parser::
check_argument_type(const format_char_info * fci,const struct kernel_ext_fmt * kef,const length_modifier & len_modifier,tree & wanted_type,const char * & wanted_type_name,const bool suppressed,unsigned HOST_WIDE_INT & arg_num,tree & params,const int alloc_flag,const char * const format_start,const char * const type_start,location_t fmt_param_loc,char conversion_char)2222 check_argument_type (const format_char_info *fci,
2223 		     const struct kernel_ext_fmt *kef,
2224 		     const length_modifier &len_modifier,
2225 		     tree &wanted_type,
2226 		     const char *&wanted_type_name,
2227 		     const bool suppressed,
2228 		     unsigned HOST_WIDE_INT &arg_num,
2229 		     tree &params,
2230 		     const int alloc_flag,
2231 		     const char * const format_start,
2232 		     const char * const type_start,
2233 		     location_t fmt_param_loc,
2234 		     char conversion_char)
2235 {
2236   if (info->first_arg_num == 0)
2237     return true;
2238 
2239   if ((fci->pointer_count == 0 && wanted_type == void_type_node)
2240       || suppressed)
2241     {
2242       if (main_arg_num != 0)
2243 	{
2244 	  if (suppressed)
2245 	    warning_at (format_string_loc, OPT_Wformat_,
2246 			"operand number specified with suppressed assignment");
2247 	  else
2248 	    warning_at (format_string_loc, OPT_Wformat_,
2249 			"operand number specified for format taking no argument");
2250 	}
2251     }
2252   else
2253     {
2254       format_wanted_type *wanted_type_ptr;
2255 
2256       if (main_arg_num != 0)
2257 	{
2258 	  arg_num = main_arg_num;
2259 	  params = main_arg_params;
2260 	}
2261       else
2262 	{
2263 	  ++arg_num;
2264 	  if (has_operand_number > 0)
2265 	    {
2266 	      warning_at (format_string_loc, OPT_Wformat_,
2267 			  "missing $ operand number in format");
2268 	      return false;
2269 	    }
2270 	  else
2271 	    has_operand_number = 0;
2272 	}
2273 
2274       wanted_type_ptr = &main_wanted_type;
2275       while (fci)
2276 	{
2277 	  tree cur_param;
2278 	  if (params == 0)
2279 	    cur_param = NULL;
2280 	  else
2281 	    {
2282 	      cur_param = TREE_VALUE (params);
2283 	      params = TREE_CHAIN (params);
2284 	    }
2285 
2286 	  wanted_type_ptr->wanted_type = wanted_type;
2287 	  wanted_type_ptr->wanted_type_name = wanted_type_name;
2288 	  wanted_type_ptr->pointer_count = fci->pointer_count + alloc_flag;
2289 	  wanted_type_ptr->char_lenient_flag = 0;
2290 	  if (strchr (fci->flags2, 'c') != 0)
2291 	    wanted_type_ptr->char_lenient_flag = 1;
2292 	  wanted_type_ptr->scalar_identity_flag = 0;
2293 	  if (len_modifier.scalar_identity_flag)
2294 	    wanted_type_ptr->scalar_identity_flag = 1;
2295 	  wanted_type_ptr->writing_in_flag = 0;
2296 	  wanted_type_ptr->reading_from_flag = 0;
2297 	  if (alloc_flag)
2298 	    wanted_type_ptr->writing_in_flag = 1;
2299 	  else
2300 	    {
2301 	      if (strchr (fci->flags2, 'W') != 0)
2302 		wanted_type_ptr->writing_in_flag = 1;
2303 	      if (strchr (fci->flags2, 'R') != 0)
2304 		wanted_type_ptr->reading_from_flag = 1;
2305 	    }
2306 	  wanted_type_ptr->kind = CF_KIND_FORMAT;
2307 	  wanted_type_ptr->param = cur_param;
2308 	  wanted_type_ptr->arg_num = arg_num;
2309 	  wanted_type_ptr->format_start = format_start;
2310 	  wanted_type_ptr->format_length = format_chars - format_start;
2311 	  wanted_type_ptr->offset_loc = format_chars - orig_format_chars;
2312 	  wanted_type_ptr->next = NULL;
2313 	  if (last_wanted_type != 0)
2314 	    last_wanted_type->next = wanted_type_ptr;
2315 	  if (first_wanted_type == 0)
2316 	    first_wanted_type = wanted_type_ptr;
2317 	  last_wanted_type = wanted_type_ptr;
2318 
2319 	  fci = fci->chain;
2320 	  if (fci)
2321 	    {
2322 	      wanted_type_ptr = fwt_pool.allocate ();
2323 	      arg_num++;
2324 	      wanted_type = *fci->types[len_modifier.val].type;
2325 	      wanted_type_name = fci->types[len_modifier.val].name;
2326 	    }
2327 	}
2328     }
2329 
2330   if (first_wanted_type != 0)
2331     {
2332       ptrdiff_t offset_to_format_start = (start_of_this_format - 1) - orig_format_chars;
2333       ptrdiff_t offset_to_format_end = (format_chars - 1) - orig_format_chars;
2334       /* By default, use the end of the range for the caret location.  */
2335       substring_loc fmt_loc (fmt_param_loc, TREE_TYPE (format_string_cst),
2336 			     offset_to_format_end,
2337 			     offset_to_format_start, offset_to_format_end);
2338       ptrdiff_t offset_to_type_start = type_start - orig_format_chars;
2339       check_format_types (fmt_loc, first_wanted_type, fki,
2340 			  offset_to_type_start,
2341 			  conversion_char, arglocs);
2342 
2343       /* note printf extension type checks are *additional* - %p must always
2344        * be pointer compatible, %d always int compatible.
2345        */
2346       if (!kef)
2347 	return true;
2348 
2349       const struct kernel_ext_fmt *kef_now;
2350       bool success;
2351 
2352       for (kef_now = kef; kef_now->suffix && !strcmp (kef->suffix, kef_now->suffix); kef_now++)
2353 	{
2354 	  success = check_kef_type (fmt_loc, kef_now,
2355 	      first_wanted_type->arg_num,
2356 	      first_wanted_type->param,
2357 	      kef_now->type, fki, offset_to_type_start, conversion_char, arglocs);
2358 
2359 	  if (success)
2360 	    return true;
2361 	}
2362 
2363       location_t param_loc;
2364 
2365       if (EXPR_HAS_LOCATION (first_wanted_type->param))
2366 	param_loc = EXPR_LOCATION (first_wanted_type->param);
2367       else if (arglocs)
2368 	{
2369 	  /* arg_num is 1-based.  */
2370 	  gcc_assert (first_wanted_type->arg_num > 0);
2371 	  param_loc = (*arglocs)[first_wanted_type->arg_num - 1];
2372 	}
2373 
2374       format_type_warning (fmt_loc, param_loc, first_wanted_type,
2375 			   kef->type, TREE_TYPE (first_wanted_type->param),
2376 			   fki, offset_to_type_start, conversion_char);
2377     }
2378 
2379   return true;
2380 }
2381 
2382 /* Do the main part of checking a call to a format function.  FORMAT_CHARS
2383    is the NUL-terminated format string (which at this point may contain
2384    internal NUL characters); FORMAT_LENGTH is its length (excluding the
2385    terminating NUL character).  ARG_NUM is one less than the number of
2386    the first format argument to check; PARAMS points to that format
2387    argument in the list of arguments.  */
2388 
2389 static void
check_format_info_main(format_check_results * res,function_format_info * info,const char * format_chars,location_t fmt_param_loc,tree format_string_cst,int format_length,tree params,unsigned HOST_WIDE_INT arg_num,object_allocator<format_wanted_type> & fwt_pool,vec<location_t> * arglocs)2390 check_format_info_main (format_check_results *res,
2391 			function_format_info *info, const char *format_chars,
2392 			location_t fmt_param_loc, tree format_string_cst,
2393 			int format_length, tree params,
2394 			unsigned HOST_WIDE_INT arg_num,
2395 			object_allocator <format_wanted_type> &fwt_pool,
2396 			vec<location_t> *arglocs)
2397 {
2398   const char * const orig_format_chars = format_chars;
2399   const tree first_fillin_param = params;
2400 
2401   const format_kind_info * const fki = &format_types[info->format_type];
2402   const format_flag_spec * const flag_specs = fki->flag_specs;
2403   const location_t format_string_loc = res->format_string_loc;
2404 
2405   /* -1 if no conversions taking an operand have been found; 0 if one has
2406      and it didn't use $; 1 if $ formats are in use.  */
2407   int has_operand_number = -1;
2408 
2409   /* Vector of pointers to opening quoting directives (like GCC "%<").  */
2410   auto_vec<const char*> quotdirs;
2411 
2412   /* Pointers to the most recent color directives (like GCC's "%r or %R").
2413      A starting color directive much be terminated before the end of
2414      the format string.  A terminating directive makes no sense without
2415      a prior starting directive.  */
2416   const char *color_begin = NULL;
2417   const char *color_end = NULL;
2418 
2419   init_dollar_format_checking (info->first_arg_num, first_fillin_param);
2420 
2421   while (*format_chars != 0)
2422     {
2423       if (*format_chars++ != '%')
2424 	continue;
2425       if (*format_chars == 0)
2426 	{
2427 	  format_warning_at_char (format_string_loc, format_string_cst,
2428 				  format_chars - orig_format_chars,
2429 				  OPT_Wformat_,
2430 				  "spurious trailing %<%%%> in format");
2431 	  continue;
2432 	}
2433       if (*format_chars == '%')
2434 	{
2435 	  ++format_chars;
2436 	  continue;
2437 	}
2438 
2439       flag_chars_t flag_chars;
2440       argument_parser arg_parser (info, format_chars, format_string_cst,
2441 				  orig_format_chars, format_string_loc,
2442 				  flag_chars, has_operand_number,
2443 				  first_fillin_param, fwt_pool, arglocs);
2444 
2445       if (!arg_parser.read_any_dollar ())
2446 	return;
2447 
2448       if (!arg_parser.read_format_flags ())
2449 	return;
2450 
2451       /* Read any format width, possibly * or *m$.  */
2452       if (!arg_parser.read_any_format_width (params, arg_num))
2453 	return;
2454 
2455       /* Read any format left precision (must be a number, not *).  */
2456       arg_parser.read_any_format_left_precision ();
2457 
2458       /* Read any format precision, possibly * or *m$.  */
2459       if (!arg_parser.read_any_format_precision (params, arg_num))
2460 	return;
2461 
2462       const char *format_start = format_chars;
2463 
2464       arg_parser.handle_alloc_chars ();
2465 
2466       /* The rest of the conversion specification is the length modifier
2467 	 (if any), and the conversion specifier, so this is where the
2468 	 type information starts.  If we need to issue a suggestion
2469 	 about a type mismatch, then we should preserve everything up
2470 	 to here. */
2471       const char *type_start = format_chars;
2472 
2473       /* Read any length modifier, if this kind of format has them.  */
2474       const length_modifier len_modifier
2475 	= arg_parser.read_any_length_modifier ();
2476 
2477       /* Read any modifier (strftime E/O).  */
2478       arg_parser.read_any_other_modifier ();
2479 
2480       char format_char = *format_chars;
2481       if (format_char == 0
2482 	  || (!(fki->flags & (int) FMT_FLAG_FANCY_PERCENT_OK)
2483 	      && format_char == '%'))
2484 	{
2485 	  format_warning_at_char (format_string_loc, format_string_cst,
2486 			     format_chars - orig_format_chars,
2487 			     OPT_Wformat_,
2488 			     "conversion lacks type at end of format");
2489 	  continue;
2490 	}
2491       format_chars++;
2492 
2493       const format_char_info * const fci
2494 	= arg_parser.find_format_char_info (format_char);
2495       if (!fci)
2496 	continue;
2497 
2498       struct kernel_ext_fmt *etab = fci->kernel_ext;
2499 
2500       if (etab && format_chars[0] >= 'A' && format_chars[0] <= 'Z')
2501         {
2502           struct kernel_ext_fmt *etab_end = etab + ETAB_SZ;
2503 
2504           for (; etab < etab_end && etab->suffix; etab++)
2505             {
2506               if (!strncmp (etab->suffix, format_chars, strlen (etab->suffix)))
2507                 break;
2508             }
2509 
2510           if (!etab->suffix || etab == etab_end)
2511             {
2512 	      format_warning_at_char (format_string_loc, format_string_cst,
2513 				      format_chars - orig_format_chars + 1,
2514 				      OPT_Wformat_,
2515 				      "unrecognized printf extension suffix");
2516               etab = NULL;
2517             }
2518 	  else
2519 	    {
2520 	      format_chars += strlen (etab->suffix);
2521 	    }
2522         }
2523       else
2524 	etab = NULL;
2525 
2526       flag_chars.validate (fki, fci, flag_specs, format_chars,
2527 			   format_string_cst,
2528 			   format_string_loc, orig_format_chars, format_char,
2529 			   quotdirs.length () > 0);
2530 
2531       const int alloc_flag = flag_chars.get_alloc_flag (fki);
2532       const bool suppressed = flag_chars.assignment_suppression_p (fki);
2533 
2534       /* Diagnose nested or unmatched quoting directives such as GCC's
2535 	 "%<...%<" and "%>...%>".  */
2536       bool quot_begin_p = strchr (fci->flags2, '<');
2537       bool quot_end_p = strchr (fci->flags2, '>');
2538 
2539       if (quot_begin_p && !quot_end_p)
2540 	{
2541 	  if (quotdirs.length ())
2542 	    format_warning_at_char (format_string_loc, format_string_cst,
2543 				    format_chars - orig_format_chars,
2544 				    OPT_Wformat_,
2545 				    "nested quoting directive");
2546 	  quotdirs.safe_push (format_chars);
2547 	}
2548       else if (!quot_begin_p && quot_end_p)
2549 	{
2550 	  if (quotdirs.length ())
2551 	    quotdirs.pop ();
2552 	  else
2553 	    format_warning_at_char (format_string_loc, format_string_cst,
2554 				    format_chars - orig_format_chars,
2555 				    OPT_Wformat_,
2556 				    "unmatched quoting directive");
2557 	}
2558 
2559       bool color_begin_p = strchr (fci->flags2, '/');
2560       if (color_begin_p)
2561 	{
2562 	  color_begin = format_chars;
2563 	  color_end = NULL;
2564 	}
2565       else if (strchr (fci->flags2, '\\'))
2566 	{
2567 	  if (color_end)
2568 	    format_warning_at_char (format_string_loc, format_string_cst,
2569 				    format_chars - orig_format_chars,
2570 				    OPT_Wformat_,
2571 				    "%qc directive redundant after prior occurence of the same", format_char);
2572 	  else if (!color_begin)
2573 	    format_warning_at_char (format_string_loc, format_string_cst,
2574 				    format_chars - orig_format_chars,
2575 				    OPT_Wformat_,
2576 				    "unmatched color reset directive");
2577 	  color_end = format_chars;
2578 	}
2579 
2580       /* Diagnose directives that shouldn't appear in a quoted sequence.
2581 	 (They are denoted by a double quote in FLAGS2.)  */
2582       if (quotdirs.length ())
2583 	{
2584 	  if (strchr (fci->flags2, '"'))
2585 	    format_warning_at_char (format_string_loc, format_string_cst,
2586 				    format_chars - orig_format_chars,
2587 				    OPT_Wformat_,
2588 				    "%qc conversion used within a quoted sequence",
2589 				    format_char);
2590 	}
2591 
2592       /* Validate the pairs of flags used.  */
2593       arg_parser.validate_flag_pairs (fci, format_char);
2594 
2595       arg_parser.give_y2k_warnings (fci, format_char);
2596 
2597       arg_parser.parse_any_scan_set (fci);
2598 
2599       tree wanted_type = NULL;
2600       const char *wanted_type_name = NULL;
2601 
2602       if (!arg_parser.handle_conversions (fci, len_modifier,
2603 					  wanted_type, wanted_type_name,
2604 					  arg_num,
2605 					  params,
2606 					  format_char))
2607 	continue;
2608 
2609       arg_parser.main_wanted_type.next = NULL;
2610 
2611       /* Finally. . .check type of argument against desired type!  */
2612       if (!arg_parser.check_argument_type (fci, etab, len_modifier,
2613 					   wanted_type, wanted_type_name,
2614 					   suppressed,
2615 					   arg_num, params,
2616 					   alloc_flag,
2617 					   format_start, type_start,
2618 					   fmt_param_loc,
2619 					   format_char))
2620 	return;
2621     }
2622 
2623   if (format_chars - orig_format_chars != format_length)
2624     format_warning_at_char (format_string_loc, format_string_cst,
2625 			    format_chars + 1 - orig_format_chars,
2626 			    OPT_Wformat_contains_nul,
2627 			    "embedded %<\\0%> in format");
2628   if (info->first_arg_num != 0 && params != 0
2629       && has_operand_number <= 0)
2630     {
2631       res->number_other--;
2632       res->number_extra_args++;
2633     }
2634   if (has_operand_number > 0)
2635     finish_dollar_format_checking (res, fki->flags & (int) FMT_FLAG_DOLLAR_GAP_POINTER_OK);
2636 
2637   if (quotdirs.length ())
2638     format_warning_at_char (format_string_loc, format_string_cst,
2639 			    quotdirs.pop () - orig_format_chars,
2640 			    OPT_Wformat_, "unterminated quoting directive");
2641   if (color_begin && !color_end)
2642     format_warning_at_char (format_string_loc, format_string_cst,
2643 			    color_begin - orig_format_chars,
2644 			    OPT_Wformat_, "unterminated color directive");
2645 }
2646 
2647 /* Check the argument types from a single format conversion (possibly
2648    including width and precision arguments).
2649 
2650    FMT_LOC is the location of the format conversion.
2651 
2652    TYPES is a singly-linked list expressing the parts of the format
2653    conversion that expect argument types, and the arguments they
2654    correspond to.
2655 
2656    OFFSET_TO_TYPE_START is the offset within the execution-charset encoded
2657    format string to where type information begins for the conversion
2658    (the length modifier and conversion specifier).
2659 
2660    CONVERSION_CHAR is the user-provided conversion specifier.
2661 
2662    For example, given:
2663 
2664      sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2665 
2666    then FMT_LOC covers this range:
2667 
2668      sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2669                          ^^^^^^^^^
2670 
2671    and TYPES in this case is a three-entry singly-linked list consisting of:
2672    (1) the check for the field width here:
2673          sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2674                                 ^              ^^^^
2675        against arg3, and
2676    (2) the check for the field precision here:
2677          sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2678                                  ^^                  ^^^^
2679        against arg4, and
2680    (3) the check for the length modifier and conversion char here:
2681          sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2682                                    ^^^                     ^^^^
2683        against arg5.
2684 
2685    OFFSET_TO_TYPE_START is 13, the offset to the "lld" within the
2686    STRING_CST:
2687 
2688                   0000000000111111111122
2689                   0123456789012345678901
2690      sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
2691                                ^ ^
2692                                | ` CONVERSION_CHAR: 'd'
2693                                type starts here.  */
2694 tree type_normalize (tree type, tree *cousin, tree target = NULL)
2695 {
2696   while (1)
2697     {
2698       if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == POINTER_TYPE)
2699 	return type;
2700       if (target)
2701 	/* Strip off any "const" etc.  */
2702         type = build_qualified_type (type, 0);
2703       if (TREE_CODE (TYPE_NAME (type)) != TYPE_DECL)
2704 	return type;
2705 
2706       if (target && (type == target || TYPE_NAME (type) == target))
2707 	return target;
2708 
2709       struct type_special *t;
2710       for (t = special_types; t->match; t++)
2711         {
2712 	  if (!*t->match)
2713 	    continue;
2714 	  if (TYPE_NAME (type) != *t->match)
2715 	    continue;
2716 	  if (t->cousin && *t->cousin)
2717 	    *cousin = *t->cousin;
2718 	  if (t->replace)
2719 	    return *t->replace ? *t->replace : type;
2720 	  return type;
2721         }
2722 
2723       tree orig = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
2724       if (!orig)
2725 	return type;
2726 
2727       type = orig;
2728     }
2729   return type;
2730 }
2731 
2732 static void
check_format_types(const substring_loc & fmt_loc,format_wanted_type * types,const format_kind_info * fki,int offset_to_type_start,char conversion_char,vec<location_t> * arglocs)2733 check_format_types (const substring_loc &fmt_loc,
2734 		    format_wanted_type *types, const format_kind_info *fki,
2735 		    int offset_to_type_start,
2736 		    char conversion_char,
2737 		    vec<location_t> *arglocs)
2738 {
2739   for (; types != 0; types = types->next)
2740     {
2741       tree cur_param;
2742       tree cur_type;
2743       tree cur_type_cousin = NULL;
2744       tree orig_cur_type;
2745       tree wanted_type;
2746       int arg_num;
2747       int i;
2748       int char_type_flag;
2749 
2750       wanted_type = types->wanted_type;
2751       arg_num = types->arg_num;
2752 
2753       /* The following should not occur here.  */
2754       gcc_assert (wanted_type);
2755       gcc_assert (wanted_type != void_type_node || types->pointer_count);
2756 
2757       if (types->pointer_count == 0)
2758 	wanted_type = lang_hooks.types.type_promotes_to (wanted_type);
2759 
2760       switch (TREE_CODE (wanted_type))
2761         {
2762 	  case IDENTIFIER_NODE:
2763 	    break;
2764 	  case TYPE_DECL:
2765 	    wanted_type = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (wanted_type));
2766 	    break;
2767 	  default:
2768 	    wanted_type = TYPE_MAIN_VARIANT (wanted_type);
2769 	    break;
2770         }
2771 
2772       cur_param = types->param;
2773       if (!cur_param)
2774         {
2775 	  format_type_warning (fmt_loc, UNKNOWN_LOCATION, types, wanted_type,
2776 			       NULL, fki, offset_to_type_start,
2777 			       conversion_char);
2778           continue;
2779         }
2780 
2781       cur_type = TREE_TYPE (cur_param);
2782       if (cur_type == error_mark_node)
2783 	continue;
2784       orig_cur_type = cur_type;
2785       char_type_flag = 0;
2786 
2787       location_t param_loc = UNKNOWN_LOCATION;
2788       if (EXPR_HAS_LOCATION (cur_param))
2789 	param_loc = EXPR_LOCATION (cur_param);
2790       else if (arglocs)
2791 	{
2792 	  /* arg_num is 1-based.  */
2793 	  gcc_assert (types->arg_num > 0);
2794 	  param_loc = (*arglocs)[types->arg_num - 1];
2795 	}
2796 
2797       STRIP_NOPS (cur_param);
2798 
2799       /* Check the types of any additional pointer arguments
2800 	 that precede the "real" argument.  */
2801       for (i = 0; i < types->pointer_count; ++i)
2802 	{
2803 	  if (TREE_CODE (cur_type) == POINTER_TYPE)
2804 	    {
2805 	      cur_type = TREE_TYPE (cur_type);
2806 	      if (cur_type == error_mark_node)
2807 		break;
2808 
2809 	      /* Check for writing through a NULL pointer.  */
2810 	      if (types->writing_in_flag
2811 		  && i == 0
2812 		  && cur_param != 0
2813 		  && integer_zerop (cur_param))
2814 		warning (OPT_Wformat_, "writing through null pointer (argument %d)", arg_num);
2815 
2816 	      /* Check for reading through a NULL pointer.  */
2817 	      if (types->reading_from_flag
2818 		  && i == 0
2819 		  && cur_param != 0
2820 		  && integer_zerop (cur_param))
2821 		warning (OPT_Wformat_, "reading through null pointer (argument %d)", arg_num);
2822 
2823 	      if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
2824 		cur_param = TREE_OPERAND (cur_param, 0);
2825 	      else
2826 		cur_param = 0;
2827 
2828 	      /* See if this is an attempt to write into a const type with
2829 		 scanf or with printf "%n".  Note: the writing in happens
2830 		 at the first indirection only, if for example
2831 		 void * const * is passed to scanf %p; passing
2832 		 const void ** is simply passing an incompatible type.  */
2833 	      if (types->writing_in_flag
2834 		  && i == 0
2835 		  && (TYPE_READONLY (cur_type)
2836 		      || (cur_param != 0
2837 			  && (CONSTANT_CLASS_P (cur_param)
2838 			      || (DECL_P (cur_param)
2839 				  && TREE_READONLY (cur_param))))))
2840 		warning (OPT_Wformat_, "writing into constant object (argument %d)", arg_num);
2841 
2842 	      /* If there are extra type qualifiers beyond the first
2843 		 indirection, then this makes the types technically
2844 		 incompatible.  */
2845 	      if (i > 0
2846 		  && pedantic
2847 		  && (TYPE_READONLY (cur_type)
2848 		      || TYPE_VOLATILE (cur_type)
2849 		      || TYPE_ATOMIC (cur_type)
2850 		      || TYPE_RESTRICT (cur_type)))
2851 		warning (OPT_Wformat_, "extra type qualifiers in format argument (argument %d)",
2852 			 arg_num);
2853 
2854 	    }
2855 	  else
2856 	    {
2857 	      format_type_warning (fmt_loc, param_loc,
2858 				   types, wanted_type, orig_cur_type, fki,
2859 				   offset_to_type_start, conversion_char);
2860 	      break;
2861 	    }
2862 	}
2863 
2864       if (i < types->pointer_count)
2865 	continue;
2866 
2867       cur_type = type_normalize (cur_type, &cur_type_cousin);
2868 
2869       /* Check whether the argument type is a character type.  This leniency
2870 	 only applies to certain formats, flagged with 'c'.  */
2871       if (types->char_lenient_flag)
2872 	char_type_flag = (cur_type == char_type_node
2873 			  || cur_type == signed_char_type_node
2874 			  || cur_type == unsigned_char_type_node);
2875 
2876       int compat = lang_hooks.types_compatible_p (wanted_type, cur_type);
2877       /* Check the type of the "real" argument, if there's a type we want.  */
2878       if ((TREE_CODE (wanted_type) != INTEGER_TYPE || types->pointer_count)
2879 	  && compat)
2880 	continue;
2881       if (TREE_CODE (wanted_type) == INTEGER_TYPE && !types->pointer_count
2882 	  && compat)
2883         {
2884 compat_inner:
2885 	  if (TREE_CODE (cur_param) == INTEGER_CST)
2886 	    continue;
2887 
2888 	  if (TREE_CODE (types->wanted_type) == TYPE_DECL
2889 	      && TREE_CODE (cur_type) == TYPE_DECL)
2890 	    {
2891 	      if (types->wanted_type == cur_type)
2892 		continue;
2893 	      format_type_warning (fmt_loc, param_loc, types,
2894 				   wanted_type, orig_cur_type, fki,
2895 				   offset_to_type_start, conversion_char,
2896 				   " (strict match required [A])");
2897 	      continue;
2898 	    }
2899 	  else if (TREE_CODE (types->wanted_type) == TYPE_DECL)
2900 	    {
2901 	      if (types->wanted_type == TYPE_NAME(cur_type))
2902 		continue;
2903 	      format_type_warning (fmt_loc, param_loc, types,
2904 				   wanted_type, orig_cur_type, fki,
2905 				   offset_to_type_start, conversion_char,
2906 				   " (strict match required [B])");
2907 	      continue;
2908 	    }
2909 	  else if (wanted_type == cur_type)
2910 	    continue;
2911 	  else if (cur_type_cousin)
2912 	    {
2913 	      format_type_warning (fmt_loc, param_loc, types,
2914 				   wanted_type, orig_cur_type, fki,
2915 				   offset_to_type_start, conversion_char,
2916 				   " (strict match required [C])");
2917 	    }
2918 
2919 	  /*
2920 	  format_type_warning (fmt_loc, param_loc, types,
2921 			       wanted_type, orig_cur_type, fki,
2922 			       offset_to_type_start, conversion_char,
2923 			       " (ultra-pedantic mode)");
2924 	  */
2925 	  continue;
2926         }
2927 
2928       /* If we want 'void *', allow any pointer type.
2929 	 (Anything else would already have got a warning.)
2930 	 With -Wpedantic, only allow pointers to void and to character
2931 	 types.  */
2932       if (wanted_type == void_type_node
2933 	  && (!pedantic || (i == 1 && char_type_flag)))
2934 	continue;
2935       /* Don't warn about differences merely in signedness, unless
2936 	 -Wpedantic.  With -Wpedantic, warn if the type is a pointer
2937 	 target and not a character type, and for character types at
2938 	 a second level of indirection.  */
2939       if (TREE_CODE (wanted_type) == INTEGER_TYPE
2940 	  && TREE_CODE (cur_type) == INTEGER_TYPE
2941 	  && ((!pedantic && !warn_format_signedness)
2942 	      || (i == 0 && !warn_format_signedness)
2943 	      || (i == 1 && char_type_flag))
2944 	  && (TYPE_UNSIGNED (wanted_type)
2945 	      ? wanted_type == c_common_unsigned_type (cur_type)
2946 	      : wanted_type == c_common_signed_type (cur_type)))
2947         {
2948 	  if (cur_type_cousin)
2949 	    {
2950 	      if (TREE_CODE (types->wanted_type) == TYPE_DECL
2951 		  && TREE_CODE (cur_type_cousin) == TYPE_DECL)
2952 		{
2953 		  if (types->wanted_type == cur_type_cousin)
2954 		    continue;
2955 		  format_type_warning (fmt_loc, param_loc, types,
2956 				       wanted_type, orig_cur_type, fki,
2957 				       offset_to_type_start, conversion_char,
2958 				       " (strict match required [X])");
2959 		  continue;
2960 		}
2961 	      else if (TREE_CODE (types->wanted_type) == TYPE_DECL)
2962 		{
2963 		  if (types->wanted_type == TYPE_NAME(cur_type_cousin))
2964 		    continue;
2965 		  format_type_warning (fmt_loc, param_loc, types,
2966 				       wanted_type, orig_cur_type, fki,
2967 				       offset_to_type_start, conversion_char,
2968 				       " (strict match required [Y])");
2969 		  continue;
2970 		}
2971 	      else if (wanted_type == cur_type_cousin)
2972 		continue;
2973 	      else
2974 	        {
2975 		  format_type_warning (fmt_loc, param_loc, types,
2976 				       wanted_type, orig_cur_type, fki,
2977 				       offset_to_type_start, conversion_char,
2978 				       " (strict match required [Z])");
2979 		}
2980 	    }
2981 
2982 	  goto compat_inner;
2983 	}
2984       /* Don't warn about differences merely in signedness if we know
2985 	 that the current type is integer-promoted and its original type
2986 	 was unsigned such as that it is in the range of WANTED_TYPE.  */
2987       if (TREE_CODE (wanted_type) == INTEGER_TYPE
2988 	  && TREE_CODE (cur_type) == INTEGER_TYPE
2989 	  && warn_format_signedness
2990 	  && TYPE_UNSIGNED (wanted_type)
2991 	  && cur_param != NULL_TREE
2992 	  && TREE_CODE (cur_param) == NOP_EXPR)
2993 	{
2994 	  tree t = TREE_TYPE (TREE_OPERAND (cur_param, 0));
2995 	  if (TYPE_UNSIGNED (t)
2996 	      && cur_type == lang_hooks.types.type_promotes_to (t))
2997 	    continue;
2998 	}
2999       /* Likewise, "signed char", "unsigned char" and "char" are
3000 	 equivalent but the above test won't consider them equivalent.  */
3001       if (wanted_type == char_type_node
3002 	  && (!pedantic || i < 2)
3003 	  && char_type_flag)
3004 	continue;
3005       if (types->scalar_identity_flag
3006 	  && (TREE_CODE (cur_type) == TREE_CODE (wanted_type)
3007 	      || (INTEGRAL_TYPE_P (cur_type)
3008 		  && INTEGRAL_TYPE_P (wanted_type)))
3009 	  && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type))
3010 	continue;
3011       /* Now we have a type mismatch.  */
3012       format_type_warning (fmt_loc, param_loc, types,
3013 			   wanted_type, orig_cur_type, fki,
3014 			   offset_to_type_start, conversion_char);
3015     }
3016 }
3017 
3018 static bool
check_kef_type(const substring_loc & fmt_loc,const struct kernel_ext_fmt * kef,unsigned arg_num,tree cur_param,tree wanted_type,const format_kind_info * fki,int offset_to_type_start,char conversion_char,vec<location_t> * arglocs)3019 check_kef_type (const substring_loc &fmt_loc,
3020 		const struct kernel_ext_fmt *kef,
3021 		unsigned arg_num,
3022 		tree cur_param,
3023 		tree wanted_type,
3024 		const format_kind_info *fki,
3025 		int offset_to_type_start,
3026 		char conversion_char,
3027 		vec<location_t> *arglocs)
3028 {
3029   tree cur_type;
3030   bool ok = true;
3031   int i;
3032 
3033   /* The following should not occur here.  */
3034   gcc_assert (wanted_type);
3035   gcc_assert (wanted_type != void_type_node || kef->ptrlevel);
3036 
3037   if (TREE_CODE (wanted_type) == TYPE_DECL)
3038     wanted_type = DECL_ORIGINAL_TYPE (wanted_type);
3039 
3040   if (!cur_param)
3041     return false;
3042 
3043   cur_type = TREE_TYPE (cur_param);
3044   if (cur_type == error_mark_node)
3045     return false;
3046 
3047   location_t param_loc = UNKNOWN_LOCATION;
3048   if (EXPR_HAS_LOCATION (cur_param))
3049     param_loc = EXPR_LOCATION (cur_param);
3050   else if (arglocs)
3051     {
3052       /* arg_num is 1-based.  */
3053       gcc_assert (arg_num > 0);
3054       param_loc = (*arglocs)[arg_num - 1];
3055     }
3056   (void)param_loc;
3057 
3058   STRIP_NOPS (cur_param);
3059 
3060   /* Check the types of any additional pointer arguments
3061      that precede the "real" argument.  */
3062   for (i = 0; i < kef->ptrlevel; ++i)
3063     {
3064       if (TREE_CODE (cur_type) == POINTER_TYPE)
3065 	{
3066 	  cur_type = TREE_TYPE (cur_type);
3067 	  if (cur_type == error_mark_node)
3068 	    break;
3069 
3070 	  if (cur_param != 0 && TREE_CODE (cur_param) == ADDR_EXPR)
3071 	    cur_param = TREE_OPERAND (cur_param, 0);
3072 	  else
3073 	    cur_param = 0;
3074 
3075 	  /* If there are extra type qualifiers beyond the first
3076 	     indirection, then this makes the types technically
3077 	     incompatible.  */
3078 	  if (i > 0
3079 	      && pedantic
3080 	      && (TYPE_READONLY (cur_type)
3081 		  || TYPE_VOLATILE (cur_type)
3082 		  || TYPE_ATOMIC (cur_type)
3083 		  || TYPE_RESTRICT (cur_type)))
3084 	    warning (OPT_Wformat_, "extra type qualifiers in format argument (argument %d)",
3085 		     arg_num);
3086 
3087 	}
3088       else
3089 	{
3090 	  ok = false;
3091 	  break;
3092 	}
3093     }
3094 
3095   if (i < kef->ptrlevel)
3096     return ok;
3097 
3098   int compat = lang_hooks.types_compatible_p (wanted_type, cur_type);
3099 
3100   if (!compat)
3101     return false;
3102 
3103   tree cousin;
3104   tree normal_type;
3105 
3106   normal_type = type_normalize (cur_type, &cousin, wanted_type);
3107 
3108   return normal_type == wanted_type;
3109 }
3110 
3111 
3112 /* Given type TYPE, attempt to dereference the type N times
3113    (e.g. from ("int ***", 2) to "int *")
3114 
3115    Return the derefenced type, with any qualifiers
3116    such as "const" stripped from the result, or
3117    NULL if unsuccessful (e.g. TYPE is not a pointer type).  */
3118 
3119 static tree
deref_n_times(tree type,int n)3120 deref_n_times (tree type, int n)
3121 {
3122   gcc_assert (type);
3123 
3124   for (int i = n; i > 0; i--)
3125     {
3126       if (TREE_CODE (type) != POINTER_TYPE)
3127 	return NULL_TREE;
3128       type = TREE_TYPE (type);
3129     }
3130   /* Strip off any "const" etc.  */
3131   return build_qualified_type (type, 0);
3132 }
3133 
3134 /* Lookup the format code for FORMAT_LEN within FLI,
3135    returning the string code for expressing it, or NULL
3136    if it is not found.  */
3137 
3138 static const char *
get_modifier_for_format_len(const format_length_info * fli,enum format_lengths format_len)3139 get_modifier_for_format_len (const format_length_info *fli,
3140 			     enum format_lengths format_len)
3141 {
3142   for (; fli->name; fli++)
3143     {
3144       if (fli->index == format_len)
3145 	return fli->name;
3146       if (fli->double_index == format_len)
3147 	return fli->double_name;
3148     }
3149   return NULL;
3150 }
3151 
3152 #if CHECKING_P
3153 
3154 namespace selftest {
3155 
3156 static void
test_get_modifier_for_format_len()3157 test_get_modifier_for_format_len ()
3158 {
3159   ASSERT_STREQ ("h",
3160 		get_modifier_for_format_len (printf_length_specs, FMT_LEN_h));
3161   ASSERT_STREQ ("hh",
3162 		get_modifier_for_format_len (printf_length_specs, FMT_LEN_hh));
3163   ASSERT_STREQ ("L",
3164 		get_modifier_for_format_len (printf_length_specs, FMT_LEN_L));
3165   ASSERT_EQ (NULL,
3166 	     get_modifier_for_format_len (printf_length_specs, FMT_LEN_none));
3167 }
3168 
3169 } // namespace selftest
3170 
3171 #endif /* CHECKING_P */
3172 
3173 /* Determine if SPEC_TYPE and ARG_TYPE are sufficiently similar for a
3174    format_type_detail using SPEC_TYPE to be offered as a suggestion for
3175    Wformat type errors where the argument has type ARG_TYPE.  */
3176 
3177 static bool
matching_type_p(tree spec_type,tree arg_type)3178 matching_type_p (tree spec_type, tree arg_type)
3179 {
3180   gcc_assert (spec_type);
3181   gcc_assert (arg_type);
3182 
3183   /* If any of the types requires structural equality, we can't compare
3184      their canonical types.  */
3185   if (TYPE_STRUCTURAL_EQUALITY_P (spec_type)
3186       || TYPE_STRUCTURAL_EQUALITY_P (arg_type))
3187     return false;
3188 
3189   spec_type = TYPE_CANONICAL (spec_type);
3190   arg_type = TYPE_CANONICAL (arg_type);
3191 
3192   if (TREE_CODE (spec_type) == INTEGER_TYPE
3193       && TREE_CODE (arg_type) == INTEGER_TYPE
3194       && (TYPE_UNSIGNED (spec_type)
3195 	  ? spec_type == c_common_unsigned_type (arg_type)
3196 	  : spec_type == c_common_signed_type (arg_type)))
3197     return true;
3198 
3199   return spec_type == arg_type;
3200 }
3201 
3202 /* Subroutine of get_format_for_type.
3203 
3204    Generate a string containing the length modifier and conversion specifier
3205    that should be used to format arguments of type ARG_TYPE within FKI
3206    (effectively the inverse of the checking code).
3207 
3208    If CONVERSION_CHAR is not zero (the first pass), the resulting suggestion
3209    is required to use it, for correcting bogus length modifiers.
3210    If CONVERSION_CHAR is zero (the second pass), then allow any suggestion
3211    that matches ARG_TYPE.
3212 
3213    If successful, returns a non-NULL string which should be freed
3214    by the caller.
3215    Otherwise, returns NULL.  */
3216 
3217 static char *
get_format_for_type_1(const format_kind_info * fki,tree arg_type,char conversion_char)3218 get_format_for_type_1 (const format_kind_info *fki, tree arg_type,
3219 		       char conversion_char)
3220 {
3221   gcc_assert (arg_type);
3222 
3223   const format_char_info *spec;
3224   for (spec = &fki->conversion_specs[0];
3225        spec->format_chars;
3226        spec++)
3227     {
3228       if (conversion_char)
3229 	if (!strchr (spec->format_chars, conversion_char))
3230 	  continue;
3231 
3232       tree effective_arg_type = deref_n_times (arg_type,
3233 					       spec->pointer_count);
3234       if (!effective_arg_type)
3235 	continue;
3236       for (int i = 0; i < FMT_LEN_MAX; i++)
3237 	{
3238 	  const format_type_detail *ftd = &spec->types[i];
3239 	  if (!ftd->type)
3240 	    continue;
3241 	  if (matching_type_p (*ftd->type, effective_arg_type))
3242 	    {
3243 	      const char *len_modifier
3244 		= get_modifier_for_format_len (fki->length_char_specs,
3245 					       (enum format_lengths)i);
3246 	      if (!len_modifier)
3247 		len_modifier = "";
3248 
3249 	      if (conversion_char)
3250 		/* We found a match, using the given conversion char - the
3251 		   length modifier was incorrect (or absent).
3252 		   Provide a suggestion using the conversion char with the
3253 		   correct length modifier for the type.  */
3254 		return xasprintf ("%s%c", len_modifier, conversion_char);
3255 	      else
3256 		/* 2nd pass: no match was possible using the user-provided
3257 		   conversion char, but we do have a match without using it.
3258 		   Provide a suggestion using the first conversion char
3259 		   listed for the given type.  */
3260 		return xasprintf ("%s%c", len_modifier, spec->format_chars[0]);
3261 	    }
3262 	}
3263    }
3264 
3265   return NULL;
3266 }
3267 
3268 /* Generate a string containing the length modifier and conversion specifier
3269    that should be used to format arguments of type ARG_TYPE within FKI
3270    (effectively the inverse of the checking code).
3271 
3272    If successful, returns a non-NULL string which should be freed
3273    by the caller.
3274    Otherwise, returns NULL.  */
3275 
3276 static char *
get_format_for_type(const format_kind_info * fki,tree arg_type,char conversion_char)3277 get_format_for_type (const format_kind_info *fki, tree arg_type,
3278 		     char conversion_char)
3279 {
3280   gcc_assert (arg_type);
3281   gcc_assert (conversion_char);
3282 
3283   /* First pass: look for a format_char_info containing CONVERSION_CHAR
3284      If we find one, then presumably the length modifier was incorrect
3285      (or absent).  */
3286   char *result = get_format_for_type_1 (fki, arg_type, conversion_char);
3287   if (result)
3288     return result;
3289 
3290   /* Second pass: we didn't find a match for CONVERSION_CHAR, so try
3291      matching just on the type. */
3292   return get_format_for_type_1 (fki, arg_type, '\0');
3293 }
3294 
3295 /* Attempt to get a string for use as a replacement fix-it hint for the
3296    source range in FMT_LOC.
3297 
3298    Preserve all of the text within the range of FMT_LOC up to
3299    OFFSET_TO_TYPE_START, replacing the rest with an appropriate
3300    length modifier and conversion specifier for ARG_TYPE, attempting
3301    to keep the user-provided CONVERSION_CHAR if possible.
3302 
3303    For example, given a long vs long long mismatch for arg5 here:
3304 
3305     000000000111111111122222222223333333333|
3306     123456789012345678901234567890123456789` column numbers
3307                    0000000000111111111122|
3308                    0123456789012345678901` string offsets
3309                           V~~~~~~~~ : range of FMT_LOC, from cols 23-31
3310       sprintf (d, "before %-+*.*lld after", arg3, arg4, arg5);
3311                                 ^ ^
3312                                 | ` CONVERSION_CHAR: 'd'
3313                                 type starts here
3314 
3315    where OFFSET_TO_TYPE_START is 13 (the offset to the "lld" within the
3316    STRING_CST), where the user provided:
3317      %-+*.*lld
3318    the result (assuming "long" argument 5) should be:
3319      %-+*.*ld
3320 
3321    If successful, returns a non-NULL string which should be freed
3322    by the caller.
3323    Otherwise, returns NULL.  */
3324 
3325 static char *
get_corrected_substring(const substring_loc & fmt_loc,format_wanted_type * type,tree arg_type,const format_kind_info * fki,int offset_to_type_start,char conversion_char)3326 get_corrected_substring (const substring_loc &fmt_loc,
3327 			 format_wanted_type *type, tree arg_type,
3328 			 const format_kind_info *fki,
3329 			 int offset_to_type_start, char conversion_char)
3330 {
3331   /* Attempt to provide hints for argument types, but not for field widths
3332      and precisions.  */
3333   if (!arg_type)
3334     return NULL;
3335   if (type->kind != CF_KIND_FORMAT)
3336     return NULL;
3337 
3338   /* Locate the current code within the source range, rejecting
3339      any awkward cases where the format string occupies more than
3340      one line.
3341      Lookup the place where the type starts (including any length
3342      modifiers), getting it as the caret location.  */
3343   substring_loc type_loc (fmt_loc);
3344   type_loc.set_caret_index (offset_to_type_start);
3345 
3346   location_t fmt_substring_loc;
3347   const char *err = type_loc.get_location (&fmt_substring_loc);
3348   if (err)
3349     return NULL;
3350 
3351   source_range fmt_substring_range
3352     = get_range_from_loc (line_table, fmt_substring_loc);
3353 
3354   expanded_location caret
3355     = expand_location_to_spelling_point (fmt_substring_loc);
3356   expanded_location start
3357     = expand_location_to_spelling_point (fmt_substring_range.m_start);
3358   expanded_location finish
3359     = expand_location_to_spelling_point (fmt_substring_range.m_finish);
3360   if (caret.file != start.file)
3361     return NULL;
3362   if (start.file != finish.file)
3363     return NULL;
3364   if (caret.line != start.line)
3365     return NULL;
3366   if (start.line != finish.line)
3367     return NULL;
3368   if (start.column > caret.column)
3369     return NULL;
3370   if (start.column > finish.column)
3371     return NULL;
3372   if (caret.column > finish.column)
3373     return NULL;
3374 
3375 #if BUILDING_GCC_VERSION >= 9000
3376   char_span line = location_get_source_line (start.file, start.line);
3377   if (!line)
3378     return NULL;
3379 
3380   /* If we got this far, then we have the line containing the
3381      existing conversion specification.
3382 
3383      Generate a trimmed copy, containing the prefix part of the conversion
3384      specification, up to the (but not including) the length modifier.
3385      In the above example, this would be "%-+*.*".  */
3386   int length_up_to_type = caret.column - start.column;
3387   char_span prefix_span = line.subspan (start.column - 1, length_up_to_type);
3388   char *prefix = prefix_span.xstrdup ();
3389 #else
3390   char *prefix = NULL;
3391 #endif
3392 
3393   /* Now attempt to generate a suggestion for the rest of the specification
3394      (length modifier and conversion char), based on ARG_TYPE and
3395      CONVERSION_CHAR.
3396      In the above example, this would be "ld".  */
3397   char *format_for_type = get_format_for_type (fki, arg_type, conversion_char);
3398   if (!format_for_type)
3399     {
3400       free (prefix);
3401       return NULL;
3402     }
3403 
3404   /* Success.  Generate the resulting suggestion for the whole range of
3405      FMT_LOC by concatenating the two strings.
3406      In the above example, this would be "%-+*.*ld".  */
3407   char *result = concat (prefix, format_for_type, NULL);
3408   free (format_for_type);
3409   free (prefix);
3410   return result;
3411 }
3412 
3413 /* Helper class for adding zero or more trailing '*' to types.
3414 
3415    The format type and name exclude any '*' for pointers, so those
3416    must be formatted manually.  For all the types we currently have,
3417    this is adequate, but formats taking pointers to functions or
3418    arrays would require the full type to be built up in order to
3419    print it with %T.  */
3420 
3421 class indirection_suffix
3422 {
3423  public:
indirection_suffix(int pointer_count)3424   indirection_suffix (int pointer_count) : m_pointer_count (pointer_count) {}
3425 
3426   /* Determine the size of the buffer (including NUL-terminator).  */
3427 
get_buffer_size()3428   size_t get_buffer_size () const
3429   {
3430     return m_pointer_count + 2;
3431   }
3432 
3433   /* Write the '*' to DST and add a NUL-terminator.  */
3434 
fill_buffer(char * dst)3435   void fill_buffer (char *dst) const
3436   {
3437     if (m_pointer_count == 0)
3438       dst[0] = 0;
3439     else if (c_dialect_cxx ())
3440       {
3441 	memset (dst, '*', m_pointer_count);
3442 	dst[m_pointer_count] = 0;
3443       }
3444     else
3445       {
3446 	dst[0] = ' ';
3447 	memset (dst + 1, '*', m_pointer_count);
3448 	dst[m_pointer_count + 1] = 0;
3449       }
3450   }
3451 
3452  private:
3453   int m_pointer_count;
3454 };
3455 
3456 #if BUILDING_GCC_VERSION >= 9000
3457 /* not exported by GCC... need a local copy :( */
3458 class frr_range_label_for_type_mismatch : public range_label
3459 {
3460  public:
frr_range_label_for_type_mismatch(tree labelled_type,tree other_type)3461   frr_range_label_for_type_mismatch (tree labelled_type, tree other_type)
3462   : m_labelled_type (labelled_type), m_other_type (other_type)
3463   {
3464   }
3465 
3466   label_text get_text (unsigned range_idx) const OVERRIDE;
3467 
3468  protected:
3469   tree m_labelled_type;
3470   tree m_other_type;
3471 };
3472 
3473 /* Print T to CPP.  */
3474 
3475 static void
print_type(c_pretty_printer * cpp,tree t,bool * quoted)3476 print_type (c_pretty_printer *cpp, tree t, bool *quoted)
3477 {
3478   gcc_assert (TYPE_P (t));
3479   struct obstack *ob = pp_buffer (cpp)->obstack;
3480   char *p = (char *) obstack_base (ob);
3481   /* Remember the end of the initial dump.  */
3482   int len = obstack_object_size (ob);
3483 
3484   tree name = TYPE_NAME (t);
3485   if (name && TREE_CODE (name) == TYPE_DECL && DECL_NAME (name))
3486     pp_identifier (cpp, lang_hooks.decl_printable_name (name, 2));
3487   else
3488     cpp->type_id (t);
3489 
3490   /* If we're printing a type that involves typedefs, also print the
3491      stripped version.  But sometimes the stripped version looks
3492      exactly the same, so we don't want it after all.  To avoid
3493      printing it in that case, we play ugly obstack games.  */
3494   if (TYPE_CANONICAL (t) && t != TYPE_CANONICAL (t))
3495     {
3496       c_pretty_printer cpp2;
3497       /* Print the stripped version into a temporary printer.  */
3498       cpp2.type_id (TYPE_CANONICAL (t));
3499       struct obstack *ob2 = cpp2.buffer->obstack;
3500       /* Get the stripped version from the temporary printer.  */
3501       const char *aka = (char *) obstack_base (ob2);
3502       int aka_len = obstack_object_size (ob2);
3503       int type1_len = obstack_object_size (ob) - len;
3504 
3505       /* If they are identical, bail out.  */
3506       if (aka_len == type1_len && memcmp (p + len, aka, aka_len) == 0)
3507 	return;
3508 
3509       /* They're not, print the stripped version now.  */
3510       if (*quoted)
3511 	pp_end_quote (cpp, pp_show_color (cpp));
3512       pp_c_whitespace (cpp);
3513       pp_left_brace (cpp);
3514       pp_c_ws_string (cpp, _("aka"));
3515       pp_c_whitespace (cpp);
3516       if (*quoted)
3517 	pp_begin_quote (cpp, pp_show_color (cpp));
3518       cpp->type_id (TYPE_CANONICAL (t));
3519       if (*quoted)
3520 	pp_end_quote (cpp, pp_show_color (cpp));
3521       pp_right_brace (cpp);
3522       /* No further closing quotes are needed.  */
3523       *quoted = false;
3524     }
3525 }
3526 
3527 /* C-specific implementation of range_label::get_text () vfunc for
3528    range_label_for_type_mismatch.  */
3529 #if BUILDING_GCC_VERSION >= 10000
3530 #define label_borrow(text) label_text::borrow(text)
3531 #define label_take(text)   label_text::take(text)
3532 #else
3533 #define label_borrow(text) label_text((char *)text, false)
3534 #define label_take(text)   label_text(text, true)
3535 #endif
3536 
3537 label_text
get_text(unsigned)3538 frr_range_label_for_type_mismatch::get_text (unsigned /*range_idx*/) const
3539 {
3540   if (m_labelled_type == NULL_TREE)
3541     return label_borrow("(null tree)");
3542 
3543   c_pretty_printer cpp;
3544   bool quoted = false;
3545   print_type (&cpp, m_labelled_type, &quoted);
3546   return label_take(xstrdup (pp_formatted_text (&cpp)));
3547 }
3548 
3549 #define range_label_for_type_mismatch frr_range_label_for_type_mismatch
3550 #endif
3551 
3552 /* Subclass of range_label for labelling the range in the format string
3553    with the type in question, adding trailing '*' for pointer_count.  */
3554 
3555 class range_label_for_format_type_mismatch
3556   : public range_label_for_type_mismatch
3557 {
3558  public:
range_label_for_format_type_mismatch(tree labelled_type,tree other_type,int pointer_count)3559   range_label_for_format_type_mismatch (tree labelled_type, tree other_type,
3560 					int pointer_count)
3561   : range_label_for_type_mismatch (labelled_type, other_type),
3562     m_pointer_count (pointer_count)
3563   {
3564   }
3565 
get_text(unsigned range_idx)3566   label_text get_text (unsigned range_idx) const FINAL OVERRIDE
3567   {
3568     label_text text = range_label_for_type_mismatch::get_text (range_idx);
3569     if (text.m_buffer == NULL)
3570       return text;
3571 
3572     indirection_suffix suffix (m_pointer_count);
3573     char *p = (char *) alloca (suffix.get_buffer_size ());
3574     suffix.fill_buffer (p);
3575 
3576     char *result = concat (text.m_buffer, p, NULL);
3577     text.maybe_free ();
3578     return label_take(result);
3579   }
3580 
3581  private:
3582   int m_pointer_count;
3583 };
3584 
3585 /* Give a warning about a format argument of different type from that expected.
3586    The range of the diagnostic is taken from WHOLE_FMT_LOC; the caret location
3587    is based on the location of the char at TYPE->offset_loc.
3588    PARAM_LOC is the location of the relevant argument, or UNKNOWN_LOCATION
3589    if this is unavailable.
3590    WANTED_TYPE is the type the argument should have,
3591    possibly stripped of pointer dereferences.  The description (such as "field
3592    precision"), the placement in the format string, a possibly more
3593    friendly name of WANTED_TYPE, and the number of pointer dereferences
3594    are taken from TYPE.  ARG_TYPE is the type of the actual argument,
3595    or NULL if it is missing.
3596 
3597    OFFSET_TO_TYPE_START is the offset within the execution-charset encoded
3598    format string to where type information begins for the conversion
3599    (the length modifier and conversion specifier).
3600    CONVERSION_CHAR is the user-provided conversion specifier.
3601 
3602    For example, given a type mismatch for argument 5 here:
3603 
3604     00000000011111111112222222222333333333344444444445555555555|
3605     12345678901234567890123456789012345678901234567890123456789` column numbers
3606                    0000000000111111111122|
3607                    0123456789012345678901` offsets within STRING_CST
3608                           V~~~~~~~~ : range of WHOLE_FMT_LOC, from cols 23-31
3609       sprintf (d, "before %-+*.*lld after", int_expr, int_expr, long_expr);
3610                                 ^ ^                             ^~~~~~~~~
3611                                 | ` CONVERSION_CHAR: 'd'        PARAM_LOC
3612                                 type starts here
3613 
3614    OFFSET_TO_TYPE_START is 13, the offset to the "lld" within the
3615    STRING_CST.  */
3616 
3617 static void
format_type_warning(const substring_loc & whole_fmt_loc,location_t param_loc,format_wanted_type * type,tree wanted_type,tree arg_type,const format_kind_info * fki,int offset_to_type_start,char conversion_char,const char * extra)3618 format_type_warning (const substring_loc &whole_fmt_loc,
3619 		     location_t param_loc,
3620 		     format_wanted_type *type,
3621 		     tree wanted_type, tree arg_type,
3622 		     const format_kind_info *fki,
3623 		     int offset_to_type_start,
3624 		     char conversion_char,
3625 		     const char *extra)
3626 {
3627   enum format_specifier_kind kind = type->kind;
3628   const char *wanted_type_name = type->wanted_type_name;
3629   const char *format_start = type->format_start;
3630   int format_length = type->format_length;
3631   int pointer_count = type->pointer_count;
3632   int arg_num = type->arg_num;
3633 
3634   if (!extra)
3635     extra = "";
3636 
3637   /* If ARG_TYPE is a typedef with a misleading name (for example,
3638      size_t but not the standard size_t expected by printf %zu), avoid
3639      printing the typedef name.  */
3640   if (wanted_type_name
3641       && arg_type
3642       && TYPE_NAME (arg_type)
3643       && TREE_CODE (TYPE_NAME (arg_type)) == TYPE_DECL
3644       && DECL_NAME (TYPE_NAME (arg_type))
3645       && !strcmp (wanted_type_name,
3646 		  lang_hooks.decl_printable_name (TYPE_NAME (arg_type), 2)))
3647     arg_type = TYPE_MAIN_VARIANT (arg_type);
3648 
3649   indirection_suffix suffix (pointer_count);
3650   char *p = (char *) alloca (suffix.get_buffer_size ());
3651   suffix.fill_buffer (p);
3652 
3653   /* WHOLE_FMT_LOC has the caret at the end of the range.
3654      Set the caret to be at the offset from TYPE.  Subtract one
3655      from the offset for the same reason as in format_warning_at_char.  */
3656   substring_loc fmt_loc (whole_fmt_loc);
3657   fmt_loc.set_caret_index (type->offset_loc - 1);
3658 
3659 #if BUILDING_GCC_VERSION >= 9000
3660   range_label_for_format_type_mismatch fmt_label (wanted_type, arg_type,
3661 						  pointer_count);
3662   range_label_for_type_mismatch param_label (arg_type, wanted_type);
3663 
3664   /* Get a string for use as a replacement fix-it hint for the range in
3665      fmt_loc, or NULL.  */
3666   char *corrected_substring
3667     = get_corrected_substring (fmt_loc, type, arg_type, fki,
3668 			       offset_to_type_start, conversion_char);
3669   format_string_diagnostic_t diag (fmt_loc, &fmt_label, param_loc, &param_label,
3670 				   corrected_substring);
3671 # define format_warning_at_substring(a,b,c,d,e,...) \
3672 	diag.emit_warning(__VA_ARGS__)
3673 #else
3674 # define format_warning_at_substring(a,b,c,d,...) \
3675 	format_warning_at_substring(a,c,__VA_ARGS__)
3676   /* Get a string for use as a replacement fix-it hint for the range in
3677      fmt_loc, or NULL.  */
3678   char *corrected_substring
3679     = get_corrected_substring (fmt_loc, type, arg_type, fki,
3680 			       offset_to_type_start, conversion_char);
3681 
3682 #endif
3683 
3684   if (wanted_type_name)
3685     {
3686       if (arg_type)
3687 	format_warning_at_substring
3688 	  (fmt_loc, &fmt_label, param_loc, &param_label,
3689 	   corrected_substring, OPT_Wformat_,
3690 	   "%s %<%s%.*s%> expects argument of type %<%s%s%>, but argument %d has type %qT%s",
3691 	   gettext (kind_descriptions[kind]),
3692 	   (kind == CF_KIND_FORMAT ? "%" : ""),
3693 	   format_length, format_start,
3694 	   wanted_type_name, p, arg_num, arg_type, extra);
3695       else
3696 	format_warning_at_substring
3697 	  (fmt_loc, &fmt_label, param_loc, &param_label,
3698 	   corrected_substring, OPT_Wformat_,
3699 	   "%s %<%s%.*s%> expects a matching %<%s%s%> argument%s",
3700 	   gettext (kind_descriptions[kind]),
3701 	   (kind == CF_KIND_FORMAT ? "%" : ""),
3702 	   format_length, format_start, wanted_type_name, p, extra);
3703     }
3704   else
3705     {
3706       if (arg_type)
3707 	format_warning_at_substring
3708 	  (fmt_loc, &fmt_label, param_loc, &param_label,
3709 	   corrected_substring, OPT_Wformat_,
3710 	   "%s %<%s%.*s%> expects argument of type %<%T%s%>, but argument %d has type %qT%s",
3711 	   gettext (kind_descriptions[kind]),
3712 	   (kind == CF_KIND_FORMAT ? "%" : ""),
3713 	   format_length, format_start,
3714 	   wanted_type, p, arg_num, arg_type, extra);
3715       else
3716 	format_warning_at_substring
3717 	  (fmt_loc, &fmt_label, param_loc, &param_label,
3718 	   corrected_substring, OPT_Wformat_,
3719 	   "%s %<%s%.*s%> expects a matching %<%T%s%> argument%s",
3720 	   gettext (kind_descriptions[kind]),
3721 	   (kind == CF_KIND_FORMAT ? "%" : ""),
3722 	   format_length, format_start, wanted_type, p, extra);
3723     }
3724 
3725   free (corrected_substring);
3726 }
3727 
3728 
3729 #if 0
3730 /* Given a format_char_info array FCI, and a character C, this function
3731    returns the index into the conversion_specs where that specifier's
3732    data is located.  The character must exist.  */
3733 static unsigned int
3734 find_char_info_specifier_index (const format_char_info *fci, int c)
3735 {
3736   unsigned i;
3737 
3738   for (i = 0; fci->format_chars; i++, fci++)
3739     if (strchr (fci->format_chars, c))
3740       return i;
3741 
3742   /* We shouldn't be looking for a non-existent specifier.  */
3743   gcc_unreachable ();
3744 }
3745 
3746 /* Given a format_length_info array FLI, and a character C, this
3747    function returns the index into the conversion_specs where that
3748    modifier's data is located.  The character must exist.  */
3749 static unsigned int
3750 find_length_info_modifier_index (const format_length_info *fli, int c)
3751 {
3752   unsigned i;
3753 
3754   for (i = 0; fli->name; i++, fli++)
3755     if (strchr (fli->name, c))
3756       return i;
3757 
3758   /* We shouldn't be looking for a non-existent modifier.  */
3759   gcc_unreachable ();
3760 }
3761 #endif
3762 
3763 #ifdef TARGET_FORMAT_TYPES
3764 extern const format_kind_info TARGET_FORMAT_TYPES[];
3765 #endif
3766 
3767 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
3768 extern const target_ovr_attr TARGET_OVERRIDES_FORMAT_ATTRIBUTES[];
3769 #endif
3770 #ifdef TARGET_OVERRIDES_FORMAT_INIT
3771   extern void TARGET_OVERRIDES_FORMAT_INIT (void);
3772 #endif
3773 
3774 /* Attributes such as "printf" are equivalent to those such as
3775    "gnu_printf" unless this is overridden by a target.  */
3776 static const target_ovr_attr gnu_target_overrides_format_attributes[] =
3777 {
3778   { NULL,           NULL }
3779 };
3780 
3781 /* Translate to unified attribute name. This is used in decode_format_type and
3782    decode_format_attr. In attr_name the user specified argument is passed. It
3783    returns the unified format name from TARGET_OVERRIDES_FORMAT_ATTRIBUTES
3784    or the attr_name passed to this function, if there is no matching entry.  */
3785 static const char *
convert_format_name_to_system_name(const char * attr_name)3786 convert_format_name_to_system_name (const char *attr_name)
3787 {
3788   int i;
3789 
3790   if (attr_name == NULL || *attr_name == 0
3791       || strncmp (attr_name, "gcc_", 4) == 0)
3792     return attr_name;
3793 #ifdef TARGET_OVERRIDES_FORMAT_INIT
3794   TARGET_OVERRIDES_FORMAT_INIT ();
3795 #endif
3796 
3797 #ifdef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
3798   /* Check if format attribute is overridden by target.  */
3799   if (TARGET_OVERRIDES_FORMAT_ATTRIBUTES != NULL
3800       && TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT > 0)
3801     {
3802       for (i = 0; i < TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT; ++i)
3803         {
3804           if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src,
3805 			   attr_name))
3806             return attr_name;
3807           if (cmp_attribs (TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_dst,
3808 			   attr_name))
3809             return TARGET_OVERRIDES_FORMAT_ATTRIBUTES[i].named_attr_src;
3810         }
3811     }
3812 #endif
3813   /* Otherwise default to gnu format.  */
3814   for (i = 0;
3815        gnu_target_overrides_format_attributes[i].named_attr_src != NULL;
3816        ++i)
3817     {
3818       if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_src,
3819 		       attr_name))
3820         return attr_name;
3821       if (cmp_attribs (gnu_target_overrides_format_attributes[i].named_attr_dst,
3822 		       attr_name))
3823         return gnu_target_overrides_format_attributes[i].named_attr_src;
3824     }
3825 
3826   return attr_name;
3827 }
3828 
3829 /* Handle a "format" attribute; arguments as in
3830    struct attribute_spec.handler.  */
3831 tree
handle_frr_format_attribute(tree * node,tree ARG_UNUSED (name),tree args,int flags,bool * no_add_attrs)3832 handle_frr_format_attribute (tree *node, tree ARG_UNUSED (name), tree args,
3833 			 int flags, bool *no_add_attrs)
3834 {
3835   tree type = *node;
3836   function_format_info info;
3837 
3838   /* Canonicalize name of format function.  */
3839   if (TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
3840     TREE_VALUE (args) = canonicalize_attr_name (TREE_VALUE (args));
3841 
3842   if (!decode_format_attr (args, &info, 0))
3843     {
3844       *no_add_attrs = true;
3845       return NULL_TREE;
3846     }
3847 
3848   if (prototype_p (type))
3849     {
3850       if (!check_format_string (type, info.format_num, flags,
3851 				no_add_attrs, info.format_type))
3852 	return NULL_TREE;
3853 
3854       if (info.first_arg_num != 0)
3855 	{
3856 	  unsigned HOST_WIDE_INT arg_num = 1;
3857 	  function_args_iterator iter;
3858 	  tree arg_type;
3859 
3860 	  /* Verify that first_arg_num points to the last arg,
3861 	     the ...  */
3862 	  FOREACH_FUNCTION_ARGS (type, arg_type, iter)
3863 	    arg_num++;
3864 
3865 	  if (arg_num != info.first_arg_num)
3866 	    {
3867 	      if (!(flags & (int) ATTR_FLAG_BUILT_IN))
3868 		error ("arguments to be formatted is not %<...%>");
3869 	      *no_add_attrs = true;
3870 	      return NULL_TREE;
3871 	    }
3872 	}
3873     }
3874 
3875   /* Check if this is a strftime variant. Just for this variant
3876      FMT_FLAG_ARG_CONVERT is not set.  */
3877   if ((format_types[info.format_type].flags & (int) FMT_FLAG_ARG_CONVERT) == 0
3878       && info.first_arg_num != 0)
3879     {
3880       error ("strftime formats cannot format arguments");
3881       *no_add_attrs = true;
3882       return NULL_TREE;
3883     }
3884 
3885   return NULL_TREE;
3886 }
3887 
3888 #if CHECKING_P
3889 
3890 namespace selftest {
3891 
3892 /* Selftests of location handling.  */
3893 
3894 /* Get the format_kind_info with the given name.  */
3895 
3896 static const format_kind_info *
get_info(const char * name)3897 get_info (const char *name)
3898 {
3899   int idx = decode_format_type (name);
3900   const format_kind_info *fki = &format_types[idx];
3901   ASSERT_STREQ (fki->name, name);
3902   return fki;
3903 }
3904 
3905 /* Verify that get_format_for_type (FKI, TYPE, CONVERSION_CHAR)
3906    is EXPECTED_FORMAT.  */
3907 
3908 static void
assert_format_for_type_streq(const location & loc,const format_kind_info * fki,const char * expected_format,tree type,char conversion_char)3909 assert_format_for_type_streq (const location &loc, const format_kind_info *fki,
3910 			      const char *expected_format, tree type,
3911 			      char conversion_char)
3912 {
3913   gcc_assert (fki);
3914   gcc_assert (expected_format);
3915   gcc_assert (type);
3916 
3917   char *actual_format = get_format_for_type (fki, type, conversion_char);
3918   ASSERT_STREQ_AT (loc, expected_format, actual_format);
3919   free (actual_format);
3920 }
3921 
3922 /* Selftests for get_format_for_type.  */
3923 
3924 #define ASSERT_FORMAT_FOR_TYPE_STREQ(EXPECTED_FORMAT, TYPE, CONVERSION_CHAR) \
3925   assert_format_for_type_streq (SELFTEST_LOCATION, (fki), (EXPECTED_FORMAT), \
3926 				(TYPE), (CONVERSION_CHAR))
3927 
3928 /* Selftest for get_format_for_type for "printf"-style functions.  */
3929 
3930 static void
test_get_format_for_type_printf()3931 test_get_format_for_type_printf ()
3932 {
3933   const format_kind_info *fki = get_info ("gnu_printf");
3934   ASSERT_NE (fki, NULL);
3935 
3936   ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'i');
3937   ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'i');
3938   ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'o');
3939   ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'o');
3940   ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'x');
3941   ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'x');
3942   ASSERT_FORMAT_FOR_TYPE_STREQ ("f", double_type_node, 'X');
3943   ASSERT_FORMAT_FOR_TYPE_STREQ ("Lf", long_double_type_node, 'X');
3944   ASSERT_FORMAT_FOR_TYPE_STREQ ("d", integer_type_node, 'd');
3945   ASSERT_FORMAT_FOR_TYPE_STREQ ("i", integer_type_node, 'i');
3946   ASSERT_FORMAT_FOR_TYPE_STREQ ("o", integer_type_node, 'o');
3947   ASSERT_FORMAT_FOR_TYPE_STREQ ("x", integer_type_node, 'x');
3948   ASSERT_FORMAT_FOR_TYPE_STREQ ("X", integer_type_node, 'X');
3949   ASSERT_FORMAT_FOR_TYPE_STREQ ("d", unsigned_type_node, 'd');
3950   ASSERT_FORMAT_FOR_TYPE_STREQ ("i", unsigned_type_node, 'i');
3951   ASSERT_FORMAT_FOR_TYPE_STREQ ("o", unsigned_type_node, 'o');
3952   ASSERT_FORMAT_FOR_TYPE_STREQ ("x", unsigned_type_node, 'x');
3953   ASSERT_FORMAT_FOR_TYPE_STREQ ("X", unsigned_type_node, 'X');
3954   ASSERT_FORMAT_FOR_TYPE_STREQ ("ld", long_integer_type_node, 'd');
3955   ASSERT_FORMAT_FOR_TYPE_STREQ ("li", long_integer_type_node, 'i');
3956   ASSERT_FORMAT_FOR_TYPE_STREQ ("lx", long_integer_type_node, 'x');
3957   ASSERT_FORMAT_FOR_TYPE_STREQ ("lo", long_unsigned_type_node, 'o');
3958   ASSERT_FORMAT_FOR_TYPE_STREQ ("lx", long_unsigned_type_node, 'x');
3959   ASSERT_FORMAT_FOR_TYPE_STREQ ("lld", long_long_integer_type_node, 'd');
3960   ASSERT_FORMAT_FOR_TYPE_STREQ ("lli", long_long_integer_type_node, 'i');
3961   ASSERT_FORMAT_FOR_TYPE_STREQ ("llo", long_long_unsigned_type_node, 'o');
3962   ASSERT_FORMAT_FOR_TYPE_STREQ ("llx", long_long_unsigned_type_node, 'x');
3963   ASSERT_FORMAT_FOR_TYPE_STREQ ("s", build_pointer_type (char_type_node), 'i');
3964 }
3965 
3966 /* Selftest for get_format_for_type for "scanf"-style functions.  */
3967 
3968 static void
test_get_format_for_type_scanf()3969 test_get_format_for_type_scanf ()
3970 {
3971   const format_kind_info *fki = get_info ("gnu_scanf");
3972   ASSERT_NE (fki, NULL);
3973   ASSERT_FORMAT_FOR_TYPE_STREQ ("d", build_pointer_type (integer_type_node), 'd');
3974   ASSERT_FORMAT_FOR_TYPE_STREQ ("u", build_pointer_type (unsigned_type_node), 'u');
3975   ASSERT_FORMAT_FOR_TYPE_STREQ ("ld",
3976 				build_pointer_type (long_integer_type_node), 'd');
3977   ASSERT_FORMAT_FOR_TYPE_STREQ ("lu",
3978 				build_pointer_type (long_unsigned_type_node), 'u');
3979   ASSERT_FORMAT_FOR_TYPE_STREQ
3980     ("lld", build_pointer_type (long_long_integer_type_node), 'd');
3981   ASSERT_FORMAT_FOR_TYPE_STREQ
3982     ("llu", build_pointer_type (long_long_unsigned_type_node), 'u');
3983   ASSERT_FORMAT_FOR_TYPE_STREQ ("e", build_pointer_type (float_type_node), 'e');
3984   ASSERT_FORMAT_FOR_TYPE_STREQ ("le", build_pointer_type (double_type_node), 'e');
3985 }
3986 
3987 #undef ASSERT_FORMAT_FOR_TYPE_STREQ
3988 
3989 /* Exercise the type-printing label code, to give some coverage
3990    under "make selftest-valgrind" (in particular, to ensure that
3991    the label-printing machinery doesn't leak).  */
3992 
3993 static void
test_type_mismatch_range_labels()3994 test_type_mismatch_range_labels ()
3995 {
3996   /* Create a tempfile and write some text to it.
3997      ....................0000000001 11111111 12 22222222
3998      ....................1234567890 12345678 90 12345678.  */
3999   const char *content = "  printf (\"msg: %i\\n\", msg);\n";
4000   temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
4001   line_table_test ltt;
4002 
4003   linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);
4004 
4005   location_t c17 = linemap_position_for_column (line_table, 17);
4006   ASSERT_EQ (LOCATION_COLUMN (c17), 17);
4007   location_t c18 = linemap_position_for_column (line_table, 18);
4008   location_t c24 = linemap_position_for_column (line_table, 24);
4009   location_t c26 = linemap_position_for_column (line_table, 26);
4010 
4011   /* Don't attempt to run the tests if column data might be unavailable.  */
4012   if (c26 > LINE_MAP_MAX_LOCATION_WITH_COLS)
4013     return;
4014 
4015   location_t fmt = make_location (c18, c17, c18);
4016   ASSERT_EQ (LOCATION_COLUMN (fmt), 18);
4017 
4018   location_t param = make_location (c24, c24, c26);
4019   ASSERT_EQ (LOCATION_COLUMN (param), 24);
4020 
4021   range_label_for_format_type_mismatch fmt_label (char_type_node,
4022 						  integer_type_node, 1);
4023   range_label_for_type_mismatch param_label (integer_type_node,
4024 					     char_type_node);
4025   gcc_rich_location richloc (fmt, &fmt_label);
4026   richloc.add_range (param, SHOW_RANGE_WITHOUT_CARET, &param_label);
4027 
4028   test_diagnostic_context dc;
4029   diagnostic_show_locus (&dc, &richloc, DK_ERROR);
4030   if (c_dialect_cxx ())
4031     /* "char*", without a space.  */
4032     ASSERT_STREQ ("\n"
4033 		  "   printf (\"msg: %i\\n\", msg);\n"
4034 		  "                 ~^     ~~~\n"
4035 		  "                  |     |\n"
4036 		  "                  char* int\n",
4037 		  pp_formatted_text (dc.printer));
4038   else
4039     /* "char *", with a space.  */
4040     ASSERT_STREQ ("\n"
4041 		  "   printf (\"msg: %i\\n\", msg);\n"
4042 		  "                 ~^     ~~~\n"
4043 		  "                  |     |\n"
4044 		  "                  |     int\n"
4045 		  "                  char *\n",
4046 		  pp_formatted_text (dc.printer));
4047 }
4048 
4049 /* Run all of the selftests within this file.  */
4050 
4051 void
c_format_c_tests()4052 c_format_c_tests ()
4053 {
4054   test_get_modifier_for_format_len ();
4055   test_get_format_for_type_printf ();
4056   test_get_format_for_type_scanf ();
4057   test_type_mismatch_range_labels ();
4058 }
4059 
4060 } // namespace selftest
4061 
4062 #endif /* CHECKING_P */
4063 
4064 // include "gt-c-family-c-format.h"
4065 
4066 static const struct attribute_spec frr_format_attribute_table[] =
4067 {
4068   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
4069        affects_type_identity, handler, exclude } */
4070   { "frr_format",             3, 3, false, true,  true, false,
4071 			      handle_frr_format_attribute, NULL },
4072   { "frr_format_arg",         1, 1, false, true,  true, false,
4073 			      handle_frr_format_arg_attribute, NULL },
4074   { NULL,                     0, 0, false, false, false, false, NULL, NULL }
4075 };
4076 
4077 static void
register_attributes(void * event_data,void * data)4078 register_attributes (void *event_data, void *data)
4079 {
4080   // warning (0, G_("Callback to register attributes"));
4081   register_attribute (frr_format_attribute_table);
4082 }
4083 
4084 tree
cb_walk_tree_fn(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)4085 cb_walk_tree_fn (tree * tp, int * walk_subtrees, void * data ATTRIBUTE_UNUSED)
4086 {
4087   if (TREE_CODE (*tp) != CALL_EXPR)
4088     return NULL_TREE;
4089 
4090   tree call_expr = *tp;
4091 
4092   int nargs = call_expr_nargs(call_expr);
4093   tree fn = CALL_EXPR_FN(call_expr);
4094 
4095   if (!fn || TREE_CODE (fn) != ADDR_EXPR)
4096     return NULL_TREE;
4097 
4098   tree fndecl = TREE_OPERAND (fn, 0);
4099   if (TREE_CODE (fndecl) != FUNCTION_DECL)
4100     return NULL_TREE;
4101 
4102 #if 0
4103   warning (0, G_("function call to %s, %d args"),
4104            IDENTIFIER_POINTER (DECL_NAME (fndecl)),
4105 	   nargs);
4106 #endif
4107 
4108   tree *fargs = (tree *) alloca (nargs * sizeof (tree));
4109 
4110   for (int j = 0; j < nargs; j++)
4111     {
4112       tree arg = CALL_EXPR_ARG(call_expr, j);
4113 
4114       /* For -Wformat undo the implicit passing by hidden reference
4115 	 done by convert_arg_to_ellipsis.  */
4116       if (TREE_CODE (arg) == ADDR_EXPR
4117 	  && TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
4118 	fargs[j] = TREE_OPERAND (arg, 0);
4119       else
4120 	fargs[j] = arg;
4121     }
4122 
4123   check_function_format (TYPE_ATTRIBUTES (TREE_TYPE (fndecl)), nargs, fargs, NULL);
4124   return NULL_TREE;
4125 }
4126 
4127 static void
setup_type(const char * name,tree * dst)4128 setup_type (const char *name, tree *dst)
4129 {
4130   tree tmp;
4131 
4132   if (*dst && *dst != void_type_node)
4133     return;
4134 
4135   *dst = maybe_get_identifier (name);
4136   if (!*dst)
4137     return;
4138 
4139   tmp = identifier_global_value (*dst);
4140   if (tmp && TREE_CODE (tmp) != TYPE_DECL)
4141     {
4142       warning (0, "%qs is not defined as a type", name);
4143       *dst = NULL;
4144       return;
4145     }
4146   if (tmp && TREE_CODE (tmp) == TYPE_DECL)
4147     *dst = tmp;
4148   else
4149     *dst = NULL;
4150 }
4151 
4152 static void
handle_finish_parse(void * event_data,void * data)4153 handle_finish_parse (void *event_data, void *data)
4154 {
4155   tree fndecl = (tree) event_data;
4156   gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
4157 
4158   setup_type ("uint64_t", &local_uint64_t_node);
4159   setup_type ("int64_t", &local_int64_t_node);
4160 
4161   setup_type ("size_t", &local_size_t_node);
4162   setup_type ("ssize_t", &local_ssize_t_node);
4163   setup_type ("atomic_size_t", &local_atomic_size_t_node);
4164   setup_type ("atomic_ssize_t", &local_atomic_ssize_t_node);
4165   setup_type ("ptrdiff_t", &local_ptrdiff_t_node);
4166 
4167   setup_type ("pid_t", &local_pid_t_node);
4168   setup_type ("uid_t", &local_uid_t_node);
4169   setup_type ("gid_t", &local_gid_t_node);
4170   setup_type ("time_t", &local_time_t_node);
4171 
4172   setup_type ("socklen_t", &local_socklen_t_node);
4173   setup_type ("in_addr_t", &local_in_addr_t_node);
4174 
4175   const format_char_info *fci;
4176 
4177   for (fci = print_char_table; fci->format_chars; fci++)
4178     {
4179       if (!fci->kernel_ext)
4180 	continue;
4181 
4182       struct kernel_ext_fmt *etab = fci->kernel_ext;
4183       struct kernel_ext_fmt *etab_end = etab + ETAB_SZ;
4184 
4185       for (; etab->suffix && etab < etab_end; etab++)
4186         {
4187 	  tree identifier, node;
4188 
4189           if (etab->type && etab->type != void_type_node)
4190 	    continue;
4191 
4192 	  identifier = maybe_get_identifier (etab->type_str);
4193 
4194 	  if (!identifier || identifier == error_mark_node)
4195 	    continue;
4196 
4197 	  if (etab->type_code)
4198 	    {
4199 	      node = identifier_global_tag (identifier);
4200 	      if (!node)
4201 	        continue;
4202 
4203 	      if (node->base.code != etab->type_code)
4204 	        {
4205 		  if (!etab->warned)
4206 		    {
4207 		      warning (0, "%qs tag category (struct/union/enum) mismatch", etab->type_str);
4208 		      etab->warned = true;
4209 		    }
4210 		  continue;
4211 	        }
4212 	    }
4213 	  else
4214 	    {
4215 	      node = identifier_global_value (identifier);
4216 	      if (!node)
4217 	        continue;
4218 
4219 	      if (TREE_CODE (node) != TYPE_DECL)
4220 		{
4221 		  if (!etab->warned)
4222 		    {
4223 		      warning (0, "%qs is defined as a non-type", etab->type_str);
4224 		      etab->warned = true;
4225 		    }
4226 		  continue;
4227 		}
4228 	      node = TREE_TYPE (node);
4229 	    }
4230 
4231 	  etab->type = node;
4232         }
4233     }
4234 
4235   walk_tree (&DECL_SAVED_TREE (fndecl), cb_walk_tree_fn, NULL, NULL);
4236 }
4237 
4238 static void
handle_pragma_printfrr_ext(cpp_reader * dummy)4239 handle_pragma_printfrr_ext (cpp_reader *dummy)
4240 {
4241   tree token = 0;
4242   location_t loc;
4243   enum cpp_ttype ttype;
4244 
4245   ttype = pragma_lex (&token, &loc);
4246   if (ttype != CPP_STRING)
4247     {
4248       error_at (loc, "%<#pragma FRR printfrr_ext%> requires string argument");
4249       return;
4250     }
4251 
4252   const char *s = TREE_STRING_POINTER (token);
4253 
4254   if (s[0] != '%')
4255     {
4256       error_at (loc, "%<#pragma FRR printfrr_ext%>: invalid format string, needs to start with '%%'");
4257       return;
4258     }
4259 
4260   switch (s[1])
4261     {
4262       case 'p':
4263       case 'd':
4264       case 'i':
4265         break;
4266       default:
4267         error_at (loc, "%<#pragma FRR printfrr_ext%>: invalid format string, needs to be %%p, %%d or %%i");
4268         return;
4269     }
4270 
4271   const format_char_info *fci;
4272 
4273   for (fci = print_char_table; fci->format_chars; fci++)
4274     if (strchr (fci->format_chars, s[1]))
4275       break;
4276 
4277   gcc_assert (fci->format_chars);
4278   gcc_assert (fci->kernel_ext);
4279 
4280   struct kernel_ext_fmt *etab = fci->kernel_ext;
4281   struct kernel_ext_fmt *etab_end = etab + ETAB_SZ;
4282 
4283   switch (s[2])
4284     {
4285       case 'A' ... 'Z':
4286         break;
4287 
4288       default:
4289         error_at (loc, "%<#pragma FRR printfrr_ext%>: invalid format string, suffix must start with an uppercase letter");
4290         return;
4291     }
4292 
4293   /* -2 -- need to keep the sentinel at the end */
4294   if (etab[ETAB_SZ - 2].suffix)
4295     {
4296       error_at (loc, "%<#pragma FRR printfrr_ext%>: out of space for format suffixes");
4297       return;
4298     }
4299 
4300   for (; etab->suffix && etab < etab_end; etab++)
4301     {
4302       if (!strcmp(s + 2, etab->suffix))
4303         {
4304           memmove (etab + 1, etab, (etab_end - etab - 1) * sizeof (*etab));
4305 
4306           if (0)
4307             {
4308               warning_at (loc, OPT_Wformat_,
4309                           "%<#pragma FRR printfrr_ext%>: duplicate printf format suffix %qs", s);
4310               warning_at (etab->origin_loc, OPT_Wformat_,
4311                           "%<#pragma FRR printfrr_ext%>: previous definition was here");
4312               return;
4313             }
4314 
4315           break;
4316         }
4317 
4318       if (!strncmp(s + 2, etab->suffix, MIN(strlen(s + 2), strlen(etab->suffix))))
4319         {
4320           warning_at (loc, OPT_Wformat_,
4321                       "%<#pragma FRR printfrr_ext%>: overlapping printf format suffix %qs", s);
4322           warning_at (etab->origin_loc, OPT_Wformat_,
4323                       "%<#pragma FRR printfrr_ext%>: previous definition for %<%%%c%s%> was here", s[1], etab->suffix);
4324           return;
4325         }
4326     }
4327 
4328   gcc_assert (etab < etab_end);
4329 
4330   memset (etab, 0, sizeof (*etab));
4331   etab->suffix = xstrdup(s + 2);
4332   etab->origin_loc = loc;
4333   etab->type = void_type_node;
4334 
4335   ttype = pragma_lex (&token, &loc);
4336   if (ttype != CPP_OPEN_PAREN)
4337     {
4338       error_at (loc, "%<#pragma FRR printfrr_ext%> expected %<(%>");
4339       goto out_drop;
4340     }
4341 
4342   ttype = pragma_lex (&token, &loc);
4343 
4344   /* qualifiers */
4345   if (ttype == CPP_NAME && !strcmp (IDENTIFIER_POINTER (token), "const"))
4346     {
4347       etab->t_const = true;
4348       ttype = pragma_lex (&token, &loc);
4349     }
4350 
4351   /* tagged types */
4352   if (ttype == CPP_NAME && !strcmp (IDENTIFIER_POINTER (token), "struct"))
4353     {
4354       etab->type_code = RECORD_TYPE;
4355       ttype = pragma_lex (&token, &loc);
4356     }
4357   else if (ttype == CPP_NAME && !strcmp (IDENTIFIER_POINTER (token), "union"))
4358     {
4359       etab->type_code = UNION_TYPE;
4360       ttype = pragma_lex (&token, &loc);
4361     }
4362   else if (ttype == CPP_NAME && !strcmp (IDENTIFIER_POINTER (token), "enum"))
4363     {
4364       etab->type_code = ENUMERAL_TYPE;
4365       ttype = pragma_lex (&token, &loc);
4366     }
4367 
4368   /* type name */
4369   if (ttype != CPP_NAME)
4370     {
4371       error_at (loc, "%<#pragma FRR printfrr_ext%>: expected typename identifier");
4372       goto out_drop;
4373     }
4374 
4375   etab->type_str = xstrdup (IDENTIFIER_POINTER (token));
4376 
4377   while ((ttype = pragma_lex (&token, &loc)) != CPP_CLOSE_PAREN)
4378     {
4379       switch (ttype) {
4380       case CPP_NAME:
4381         error_at (loc, "%<#pragma FRR printfrr_ext%>: unexpected identifier.  Note the only supported qualifier is %<const%>");
4382         goto out_drop;
4383 
4384       case CPP_MULT:
4385         etab->ptrlevel++;
4386         break;
4387 
4388       case CPP_EOF:
4389         error_at (loc, "%<#pragma FRR printfrr_ext%>: premature end of line, missing %<)%>");
4390         goto out_drop;
4391 
4392       default:
4393         error_at (loc, "%<#pragma FRR printfrr_ext%>: unsupported token");
4394         goto out_drop;
4395       }
4396     }
4397 
4398   ttype = pragma_lex (&token, &loc);
4399   if (ttype != CPP_EOF)
4400     warning_at (loc, OPT_Wformat_,
4401                 "%<#pragma FRR printfrr_ext%>: garbage at end of line");
4402 
4403   return;
4404 
4405 out_drop:
4406   memset (etab, 0, sizeof (*etab));
4407 }
4408 
4409 static void
register_pragma_printfrr_ext(void * event_data,void * data)4410 register_pragma_printfrr_ext (void *event_data, void *data)
4411 {
4412   c_register_pragma_with_expansion ("FRR", "printfrr_ext", handle_pragma_printfrr_ext);
4413 }
4414 
4415 static void
define_vars(void * gcc_data,void * user_data)4416 define_vars (void *gcc_data, void *user_data)
4417 {
4418   cpp_define (parse_in, "_FRR_ATTRIBUTE_PRINTFRR=0x10000");
4419 }
4420 
4421 #ifndef __visible
4422 #define __visible __attribute__((visibility("default")))
4423 #endif
4424 
4425 __visible int plugin_is_GPL_compatible;
4426 
4427 __visible int
plugin_init(struct plugin_name_args * plugin_info,struct plugin_gcc_version * version)4428 plugin_init (struct plugin_name_args *plugin_info,
4429              struct plugin_gcc_version *version)
4430 {
4431   const char *plugin_name = plugin_info->base_name;
4432 
4433   if (!plugin_default_version_check(version, &gcc_version))
4434     {
4435       error(G_("incompatible gcc/plugin versions"));
4436       return 1;
4437     }
4438 
4439   memset (ext_p, 0, sizeof (ext_p));
4440   memset (ext_d, 0, sizeof (ext_d));
4441 
4442   register_callback (plugin_name, PLUGIN_FINISH_PARSE_FUNCTION, handle_finish_parse, NULL);
4443   register_callback (plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL);
4444   register_callback (plugin_name, PLUGIN_START_UNIT, define_vars, NULL);
4445   register_callback (plugin_name, PLUGIN_PRAGMAS, register_pragma_printfrr_ext, NULL);
4446   return 0;
4447 }
4448