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