1/* Pass to detect and issue warnings for invalid accesses, including
2 invalid or mismatched allocation/deallocation calls.
3
4 Copyright (C) 2020-2024 Free Software Foundation, Inc.
5 Contributed by Martin Sebor <msebor@redhat.com>.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
22
23#define INCLUDE_STRING
24#include "config.h"
25#include "system.h"
26#include "coretypes.h"
27#include "backend.h"
28#include "tree.h"
29#include "gimple.h"
30#include "tree-pass.h"
31#include "builtins.h"
32#include "diagnostic.h"
33#include "ssa.h"
34#include "gimple-pretty-print.h"
35#include "gimple-ssa-warn-access.h"
36#include "gimple-ssa-warn-restrict.h"
37#include "diagnostic-core.h"
38#include "fold-const.h"
39#include "gimple-iterator.h"
40#include "gimple-fold.h"
41#include "langhooks.h"
42#include "memmodel.h"
43#include "target.h"
44#include "tree-dfa.h"
45#include "tree-ssa.h"
46#include "tree-cfg.h"
47#include "tree-object-size.h"
48#include "tree-ssa-strlen.h"
49#include "calls.h"
50#include "cfganal.h"
51#include "intl.h"
52#include "gimple-range.h"
53#include "stringpool.h"
54#include "attribs.h"
55#include "demangle.h"
56#include "attr-fnspec.h"
57#include "pointer-query.h"
58
59/* Return true if tree node X has an associated location. */
60
61static inline location_t
62has_location (const_tree x)
63{
64 if (DECL_P (x))
65 return DECL_SOURCE_LOCATION (x) != UNKNOWN_LOCATION;
66
67 if (EXPR_P (x))
68 return EXPR_HAS_LOCATION (x);
69
70 return false;
71}
72
73/* Return the associated location of STMT. */
74
75static inline location_t
76get_location (const gimple *stmt)
77{
78 return gimple_location (g: stmt);
79}
80
81/* Return the associated location of tree node X. */
82
83static inline location_t
84get_location (tree x)
85{
86 if (DECL_P (x))
87 return DECL_SOURCE_LOCATION (x);
88
89 if (EXPR_P (x))
90 return EXPR_LOCATION (x);
91
92 return UNKNOWN_LOCATION;
93}
94
95/* Overload of the nascent tree function for GIMPLE STMT. */
96
97static inline tree
98get_callee_fndecl (const gimple *stmt)
99{
100 return gimple_call_fndecl (gs: stmt);
101}
102
103static inline unsigned
104call_nargs (const gimple *stmt)
105{
106 return gimple_call_num_args (gs: stmt);
107}
108
109static inline unsigned
110call_nargs (const_tree expr)
111{
112 return call_expr_nargs (expr);
113}
114
115
116static inline tree
117call_arg (const gimple *stmt, unsigned argno)
118{
119 return gimple_call_arg (gs: stmt, index: argno);
120}
121
122static inline tree
123call_arg (tree expr, unsigned argno)
124{
125 return CALL_EXPR_ARG (expr, argno);
126}
127
128/* For a call EXPR at LOC to a function FNAME that expects a string
129 in the argument ARG, issue a diagnostic due to it being a called
130 with an argument that is a character array with no terminating
131 NUL. SIZE is the EXACT size of the array, and BNDRNG the number
132 of characters in which the NUL is expected. Either EXPR or FNAME
133 may be null but noth both. SIZE may be null when BNDRNG is null. */
134
135template <class GimpleOrTree>
136static void
137warn_string_no_nul (location_t loc, GimpleOrTree expr, const char *fname,
138 tree arg, tree decl, tree size, bool exact,
139 const wide_int bndrng[2] /* = NULL */)
140{
141 const opt_code opt = OPT_Wstringop_overread;
142 if ((expr && warning_suppressed_p (expr, opt))
143 || warning_suppressed_p (arg, opt))
144 return;
145
146 loc = expansion_point_location_if_in_system_header (loc);
147 bool warned;
148
149 /* Format the bound range as a string to keep the number of messages
150 from exploding. */
151 char bndstr[80];
152 *bndstr = 0;
153 if (bndrng)
154 {
155 if (bndrng[0] == bndrng[1])
156 sprintf (s: bndstr, format: "%llu", (unsigned long long) bndrng[0].to_uhwi ());
157 else
158 sprintf (s: bndstr, format: "[%llu, %llu]",
159 (unsigned long long) bndrng[0].to_uhwi (),
160 (unsigned long long) bndrng[1].to_uhwi ());
161 }
162
163 auto_diagnostic_group d;
164
165 const tree maxobjsize = max_object_size ();
166 const wide_int maxsiz = wi::to_wide (t: maxobjsize);
167 if (expr)
168 {
169 tree func = get_callee_fndecl (expr);
170 if (bndrng)
171 {
172 if (wi::ltu_p (x: maxsiz, y: bndrng[0]))
173 warned = warning_at (loc, opt,
174 "%qD specified bound %s exceeds "
175 "maximum object size %E",
176 func, bndstr, maxobjsize);
177 else
178 {
179 bool maybe = wi::to_wide (t: size) == bndrng[0];
180 warned = warning_at (loc, opt,
181 exact
182 ? G_("%qD specified bound %s exceeds "
183 "the size %E of unterminated array")
184 : (maybe
185 ? G_("%qD specified bound %s may "
186 "exceed the size of at most %E "
187 "of unterminated array")
188 : G_("%qD specified bound %s exceeds "
189 "the size of at most %E "
190 "of unterminated array")),
191 func, bndstr, size);
192 }
193 }
194 else
195 warned = warning_at (loc, opt,
196 "%qD argument missing terminating nul",
197 func);
198 }
199 else
200 {
201 if (bndrng)
202 {
203 if (wi::ltu_p (x: maxsiz, y: bndrng[0]))
204 warned = warning_at (loc, opt,
205 "%qs specified bound %s exceeds "
206 "maximum object size %E",
207 fname, bndstr, maxobjsize);
208 else
209 {
210 bool maybe = wi::to_wide (t: size) == bndrng[0];
211 warned = warning_at (loc, opt,
212 exact
213 ? G_("%qs specified bound %s exceeds "
214 "the size %E of unterminated array")
215 : (maybe
216 ? G_("%qs specified bound %s may "
217 "exceed the size of at most %E "
218 "of unterminated array")
219 : G_("%qs specified bound %s exceeds "
220 "the size of at most %E "
221 "of unterminated array")),
222 fname, bndstr, size);
223 }
224 }
225 else
226 warned = warning_at (loc, opt,
227 "%qs argument missing terminating nul",
228 fname);
229 }
230
231 if (warned)
232 {
233 inform (get_location (x: decl),
234 "referenced argument declared here");
235 suppress_warning (arg, opt);
236 if (expr)
237 suppress_warning (expr, opt);
238 }
239}
240
241void
242warn_string_no_nul (location_t loc, gimple *stmt, const char *fname,
243 tree arg, tree decl, tree size /* = NULL_TREE */,
244 bool exact /* = false */,
245 const wide_int bndrng[2] /* = NULL */)
246{
247 return warn_string_no_nul<gimple *> (loc, expr: stmt, fname,
248 arg, decl, size, exact, bndrng);
249}
250
251void
252warn_string_no_nul (location_t loc, tree expr, const char *fname,
253 tree arg, tree decl, tree size /* = NULL_TREE */,
254 bool exact /* = false */,
255 const wide_int bndrng[2] /* = NULL */)
256{
257 return warn_string_no_nul<tree> (loc, expr, fname,
258 arg, decl, size, exact, bndrng);
259}
260
261/* If EXP refers to an unterminated constant character array return
262 the declaration of the object of which the array is a member or
263 element and if SIZE is not null, set *SIZE to the size of
264 the unterminated array and set *EXACT if the size is exact or
265 clear it otherwise. Otherwise return null. */
266
267tree
268unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */)
269{
270 /* C_STRLEN will return NULL and set DECL in the info
271 structure if EXP references a unterminated array. */
272 c_strlen_data lendata = { };
273 tree len = c_strlen (exp, 1, &lendata);
274 if (len || !lendata.minlen || !lendata.decl)
275 return NULL_TREE;
276
277 if (!size)
278 return lendata.decl;
279
280 len = lendata.minlen;
281 if (lendata.off)
282 {
283 /* Constant offsets are already accounted for in LENDATA.MINLEN,
284 but not in a SSA_NAME + CST expression. */
285 if (TREE_CODE (lendata.off) == INTEGER_CST)
286 *exact = true;
287 else if (TREE_CODE (lendata.off) == PLUS_EXPR
288 && TREE_CODE (TREE_OPERAND (lendata.off, 1)) == INTEGER_CST)
289 {
290 /* Subtract the offset from the size of the array. */
291 *exact = false;
292 tree temp = TREE_OPERAND (lendata.off, 1);
293 temp = fold_convert (ssizetype, temp);
294 len = fold_build2 (MINUS_EXPR, ssizetype, len, temp);
295 }
296 else
297 *exact = false;
298 }
299 else
300 *exact = true;
301
302 *size = len;
303 return lendata.decl;
304}
305
306/* For a call EXPR (which may be null) that expects a string argument
307 SRC as an argument, returns false if SRC is a character array with
308 no terminating NUL. When nonnull, BOUND is the number of characters
309 in which to expect the terminating NUL. When EXPR is nonnull also
310 issues a warning. */
311
312template <class GimpleOrTree>
313static bool
314check_nul_terminated_array (GimpleOrTree expr, tree src, tree bound)
315{
316 /* The constant size of the array SRC points to. The actual size
317 may be less of EXACT is true, but not more. */
318 tree size;
319 /* True if SRC involves a non-constant offset into the array. */
320 bool exact;
321 /* The unterminated constant array SRC points to. */
322 tree nonstr = unterminated_array (exp: src, size: &size, exact: &exact);
323 if (!nonstr)
324 return true;
325
326 /* NONSTR refers to the non-nul terminated constant array and SIZE
327 is the constant size of the array in bytes. EXACT is true when
328 SIZE is exact. */
329
330 wide_int bndrng[2];
331 if (bound)
332 {
333 Value_Range r (TREE_TYPE (bound));
334
335 get_range_query (cfun)->range_of_expr (r, expr: bound);
336
337 if (r.undefined_p () || r.varying_p ())
338 return true;
339
340 bndrng[0] = r.lower_bound ();
341 bndrng[1] = r.upper_bound ();
342
343 if (exact)
344 {
345 if (wi::leu_p (x: bndrng[0], y: wi::to_wide (t: size)))
346 return true;
347 }
348 else if (wi::lt_p (x: bndrng[0], y: wi::to_wide (t: size), sgn: UNSIGNED))
349 return true;
350 }
351
352 if (expr)
353 warn_string_no_nul (get_location (expr), expr, NULL, src, nonstr,
354 size, exact, bound ? bndrng : NULL);
355
356 return false;
357}
358
359bool
360check_nul_terminated_array (gimple *stmt, tree src, tree bound /* = NULL_TREE */)
361{
362 return check_nul_terminated_array<gimple *>(expr: stmt, src, bound);
363}
364
365bool
366check_nul_terminated_array (tree expr, tree src, tree bound /* = NULL_TREE */)
367{
368 return check_nul_terminated_array<tree>(expr, src, bound);
369}
370
371/* Warn about passing a non-string array/pointer to a built-in function
372 that expects a nul-terminated string argument. Returns true if
373 a warning has been issued.*/
374
375template <class GimpleOrTree>
376static bool
377maybe_warn_nonstring_arg (tree fndecl, GimpleOrTree exp)
378{
379 if (!fndecl || !fndecl_built_in_p (node: fndecl, klass: BUILT_IN_NORMAL))
380 return false;
381
382 if (!warn_stringop_overread
383 || warning_suppressed_p (exp, OPT_Wstringop_overread))
384 return false;
385
386 /* Avoid clearly invalid calls (more checking done below). */
387 unsigned nargs = call_nargs (exp);
388 if (!nargs)
389 return false;
390
391 /* The bound argument to a bounded string function like strncpy. */
392 tree bound = NULL_TREE;
393
394 /* The longest known or possible string argument to one of the comparison
395 functions. If the length is less than the bound it is used instead.
396 Since the length is only used for warning and not for code generation
397 disable strict mode in the calls to get_range_strlen below. */
398 tree maxlen = NULL_TREE;
399
400 /* It's safe to call "bounded" string functions with a non-string
401 argument since the functions provide an explicit bound for this
402 purpose. The exception is strncat where the bound may refer to
403 either the destination or the source. */
404 int fncode = DECL_FUNCTION_CODE (decl: fndecl);
405 switch (fncode)
406 {
407 case BUILT_IN_STRCMP:
408 case BUILT_IN_STRNCMP:
409 case BUILT_IN_STRNCASECMP:
410 {
411 /* For these, if one argument refers to one or more of a set
412 of string constants or arrays of known size, determine
413 the range of their known or possible lengths and use it
414 conservatively as the bound for the unbounded function,
415 and to adjust the range of the bound of the bounded ones. */
416 for (unsigned argno = 0;
417 argno < MIN (nargs, 2)
418 && !(maxlen && TREE_CODE (maxlen) == INTEGER_CST); argno++)
419 {
420 tree arg = call_arg (exp, argno);
421 if (!get_attr_nonstring_decl (arg))
422 {
423 c_strlen_data lendata = { };
424 /* Set MAXBOUND to an arbitrary non-null non-integer
425 node as a request to have it set to the length of
426 the longest string in a PHI. */
427 lendata.maxbound = arg;
428 get_range_strlen (arg, &lendata, /* eltsize = */ 1);
429 maxlen = lendata.maxbound;
430 }
431 }
432 }
433 /* Fall through. */
434
435 case BUILT_IN_STRNCAT:
436 case BUILT_IN_STPNCPY:
437 case BUILT_IN_STRNCPY:
438 if (nargs > 2)
439 bound = call_arg (exp, 2);
440 break;
441
442 case BUILT_IN_STRNDUP:
443 if (nargs < 2)
444 return false;
445 bound = call_arg (exp, 1);
446 break;
447
448 case BUILT_IN_STRNLEN:
449 {
450 tree arg = call_arg (exp, 0);
451 if (!get_attr_nonstring_decl (arg))
452 {
453 c_strlen_data lendata = { };
454 /* Set MAXBOUND to an arbitrary non-null non-integer
455 node as a request to have it set to the length of
456 the longest string in a PHI. */
457 lendata.maxbound = arg;
458 get_range_strlen (arg, &lendata, /* eltsize = */ 1);
459 maxlen = lendata.maxbound;
460 }
461 if (nargs > 1)
462 bound = call_arg (exp, 1);
463 break;
464 }
465
466 default:
467 break;
468 }
469
470 /* Determine the range of the bound argument (if specified). */
471 tree bndrng[2] = { NULL_TREE, NULL_TREE };
472 if (bound)
473 {
474 STRIP_NOPS (bound);
475 get_size_range (bound, bndrng);
476 }
477
478 location_t loc = get_location (exp);
479
480 if (bndrng[0])
481 {
482 /* Diagnose excessive bound prior to the adjustment below and
483 regardless of attribute nonstring. */
484 tree maxobjsize = max_object_size ();
485 if (tree_int_cst_lt (t1: maxobjsize, t2: bndrng[0]))
486 {
487 bool warned = false;
488 if (tree_int_cst_equal (bndrng[0], bndrng[1]))
489 warned = warning_at (loc, OPT_Wstringop_overread,
490 "%qD specified bound %E "
491 "exceeds maximum object size %E",
492 fndecl, bndrng[0], maxobjsize);
493 else
494 warned = warning_at (loc, OPT_Wstringop_overread,
495 "%qD specified bound [%E, %E] "
496 "exceeds maximum object size %E",
497 fndecl, bndrng[0], bndrng[1],
498 maxobjsize);
499 if (warned)
500 suppress_warning (exp, OPT_Wstringop_overread);
501
502 return warned;
503 }
504 }
505
506 if (maxlen && !integer_all_onesp (maxlen))
507 {
508 /* Add one for the nul. */
509 maxlen = const_binop (PLUS_EXPR, TREE_TYPE (maxlen), maxlen,
510 size_one_node);
511
512 if (!bndrng[0])
513 {
514 /* Conservatively use the upper bound of the lengths for
515 both the lower and the upper bound of the operation. */
516 bndrng[0] = maxlen;
517 bndrng[1] = maxlen;
518 bound = void_type_node;
519 }
520 else if (maxlen)
521 {
522 /* Replace the bound on the operation with the upper bound
523 of the length of the string if the latter is smaller. */
524 if (tree_int_cst_lt (t1: maxlen, t2: bndrng[0]))
525 bndrng[0] = maxlen;
526 else if (tree_int_cst_lt (t1: maxlen, t2: bndrng[1]))
527 bndrng[1] = maxlen;
528 }
529 }
530
531 bool any_arg_warned = false;
532 /* Iterate over the built-in function's formal arguments and check
533 each const char* against the actual argument. If the actual
534 argument is declared attribute non-string issue a warning unless
535 the argument's maximum length is bounded. */
536 function_args_iterator it;
537 function_args_iter_init (&it, TREE_TYPE (fndecl));
538
539 for (unsigned argno = 0; ; ++argno, function_args_iter_next (i: &it))
540 {
541 /* Avoid iterating past the declared argument in a call
542 to function declared without a prototype. */
543 if (argno >= nargs)
544 break;
545
546 tree argtype = function_args_iter_cond (i: &it);
547 if (!argtype)
548 break;
549
550 if (TREE_CODE (argtype) != POINTER_TYPE)
551 continue;
552
553 argtype = TREE_TYPE (argtype);
554
555 if (TREE_CODE (argtype) != INTEGER_TYPE
556 || !TYPE_READONLY (argtype))
557 continue;
558
559 argtype = TYPE_MAIN_VARIANT (argtype);
560 if (argtype != char_type_node)
561 continue;
562
563 tree callarg = call_arg (exp, argno);
564 if (TREE_CODE (callarg) == ADDR_EXPR)
565 callarg = TREE_OPERAND (callarg, 0);
566
567 /* See if the destination is declared with attribute "nonstring". */
568 tree decl = get_attr_nonstring_decl (callarg);
569 if (!decl)
570 continue;
571
572 /* The maximum number of array elements accessed. */
573 offset_int wibnd = 0;
574
575 if (argno && fncode == BUILT_IN_STRNCAT)
576 {
577 /* See if the bound in strncat is derived from the length
578 of the strlen of the destination (as it's expected to be).
579 If so, reset BOUND and FNCODE to trigger a warning. */
580 tree dstarg = call_arg (exp, 0);
581 if (is_strlen_related_p (dstarg, bound))
582 {
583 /* The bound applies to the destination, not to the source,
584 so reset these to trigger a warning without mentioning
585 the bound. */
586 bound = NULL;
587 fncode = 0;
588 }
589 else if (bndrng[1])
590 /* Use the upper bound of the range for strncat. */
591 wibnd = wi::to_offset (t: bndrng[1]);
592 }
593 else if (bndrng[0])
594 /* Use the lower bound of the range for functions other than
595 strncat. */
596 wibnd = wi::to_offset (t: bndrng[0]);
597
598 /* Determine the size of the argument array if it is one. */
599 offset_int asize = wibnd;
600 bool known_size = false;
601 tree type = TREE_TYPE (decl);
602
603 /* Determine the array size. For arrays of unknown bound and
604 pointers reset BOUND to trigger the appropriate warning. */
605 if (TREE_CODE (type) == ARRAY_TYPE)
606 {
607 if (tree arrbnd = TYPE_DOMAIN (type))
608 {
609 if ((arrbnd = TYPE_MAX_VALUE (arrbnd)))
610 {
611 asize = wi::to_offset (t: arrbnd) + 1;
612 known_size = true;
613 }
614 }
615 else if (bound == void_type_node)
616 bound = NULL_TREE;
617 }
618 else if (bound == void_type_node)
619 bound = NULL_TREE;
620
621 /* In a call to strncat with a bound in a range whose lower but
622 not upper bound is less than the array size, reset ASIZE to
623 be the same as the bound and the other variable to trigger
624 the appropriate warning below. */
625 if (fncode == BUILT_IN_STRNCAT
626 && bndrng[0] != bndrng[1]
627 && wi::ltu_p (x: wi::to_offset (t: bndrng[0]), y: asize)
628 && (!known_size
629 || wi::ltu_p (x: asize, y: wibnd)))
630 {
631 asize = wibnd;
632 bound = NULL_TREE;
633 fncode = 0;
634 }
635
636 bool warned = false;
637
638 auto_diagnostic_group d;
639 if (wi::ltu_p (x: asize, y: wibnd))
640 {
641 if (bndrng[0] == bndrng[1])
642 warned = warning_at (loc, OPT_Wstringop_overread,
643 "%qD argument %i declared attribute "
644 "%<nonstring%> is smaller than the specified "
645 "bound %wu",
646 fndecl, argno + 1, wibnd.to_uhwi ());
647 else if (wi::ltu_p (x: asize, y: wi::to_offset (t: bndrng[0])))
648 warned = warning_at (loc, OPT_Wstringop_overread,
649 "%qD argument %i declared attribute "
650 "%<nonstring%> is smaller than "
651 "the specified bound [%E, %E]",
652 fndecl, argno + 1, bndrng[0], bndrng[1]);
653 else
654 warned = warning_at (loc, OPT_Wstringop_overread,
655 "%qD argument %i declared attribute "
656 "%<nonstring%> may be smaller than "
657 "the specified bound [%E, %E]",
658 fndecl, argno + 1, bndrng[0], bndrng[1]);
659 }
660 else if (fncode == BUILT_IN_STRNCAT)
661 ; /* Avoid warning for calls to strncat() when the bound
662 is equal to the size of the non-string argument. */
663 else if (!bound)
664 warned = warning_at (loc, OPT_Wstringop_overread,
665 "%qD argument %i declared attribute %<nonstring%>",
666 fndecl, argno + 1);
667
668 if (warned)
669 {
670 inform (DECL_SOURCE_LOCATION (decl),
671 "argument %qD declared here", decl);
672 any_arg_warned = true;
673 }
674 }
675
676 if (any_arg_warned)
677 suppress_warning (exp, OPT_Wstringop_overread);
678
679 return any_arg_warned;
680}
681
682bool
683maybe_warn_nonstring_arg (tree fndecl, gimple *stmt)
684{
685 return maybe_warn_nonstring_arg<gimple *>(fndecl, exp: stmt);
686}
687
688
689bool
690maybe_warn_nonstring_arg (tree fndecl, tree expr)
691{
692 return maybe_warn_nonstring_arg<tree>(fndecl, exp: expr);
693}
694
695/* Issue a warning OPT for a bounded call EXP with a bound in RANGE
696 accessing an object with SIZE. */
697
698template <class GimpleOrTree>
699static bool
700maybe_warn_for_bound (opt_code opt, location_t loc, GimpleOrTree exp, tree func,
701 tree bndrng[2], tree size, const access_data *pad)
702{
703 if (!bndrng[0] || warning_suppressed_p (exp, opt))
704 return false;
705
706 tree maxobjsize = max_object_size ();
707
708 bool warned = false;
709
710 if (opt == OPT_Wstringop_overread)
711 {
712 bool maybe = pad && pad->src.phi ();
713 if (maybe)
714 {
715 /* Issue a "maybe" warning only if the PHI refers to objects
716 at least one of which has more space remaining than the bound.
717 Otherwise, if the bound is greater, use the definitive form. */
718 offset_int remmax = pad->src.size_remaining ();
719 if (remmax < wi::to_offset (t: bndrng[0]))
720 maybe = false;
721 }
722
723 auto_diagnostic_group d;
724 if (tree_int_cst_lt (t1: maxobjsize, t2: bndrng[0]))
725 {
726 if (bndrng[0] == bndrng[1])
727 warned = (func
728 ? warning_at (loc, opt,
729 (maybe
730 ? G_("%qD specified bound %E may "
731 "exceed maximum object size %E")
732 : G_("%qD specified bound %E "
733 "exceeds maximum object size %E")),
734 func, bndrng[0], maxobjsize)
735 : warning_at (loc, opt,
736 (maybe
737 ? G_("specified bound %E may "
738 "exceed maximum object size %E")
739 : G_("specified bound %E "
740 "exceeds maximum object size %E")),
741 bndrng[0], maxobjsize));
742 else
743 warned = (func
744 ? warning_at (loc, opt,
745 (maybe
746 ? G_("%qD specified bound [%E, %E] may "
747 "exceed maximum object size %E")
748 : G_("%qD specified bound [%E, %E] "
749 "exceeds maximum object size %E")),
750 func,
751 bndrng[0], bndrng[1], maxobjsize)
752 : warning_at (loc, opt,
753 (maybe
754 ? G_("specified bound [%E, %E] may "
755 "exceed maximum object size %E")
756 : G_("specified bound [%E, %E] "
757 "exceeds maximum object size %E")),
758 bndrng[0], bndrng[1], maxobjsize));
759 }
760 else if (!size || tree_int_cst_le (t1: bndrng[0], t2: size))
761 return false;
762 else if (tree_int_cst_equal (bndrng[0], bndrng[1]))
763 warned = (func
764 ? warning_at (loc, opt,
765 (maybe
766 ? G_("%qD specified bound %E may exceed "
767 "source size %E")
768 : G_("%qD specified bound %E exceeds "
769 "source size %E")),
770 func, bndrng[0], size)
771 : warning_at (loc, opt,
772 (maybe
773 ? G_("specified bound %E may exceed "
774 "source size %E")
775 : G_("specified bound %E exceeds "
776 "source size %E")),
777 bndrng[0], size));
778 else
779 warned = (func
780 ? warning_at (loc, opt,
781 (maybe
782 ? G_("%qD specified bound [%E, %E] may "
783 "exceed source size %E")
784 : G_("%qD specified bound [%E, %E] exceeds "
785 "source size %E")),
786 func, bndrng[0], bndrng[1], size)
787 : warning_at (loc, opt,
788 (maybe
789 ? G_("specified bound [%E, %E] may exceed "
790 "source size %E")
791 : G_("specified bound [%E, %E] exceeds "
792 "source size %E")),
793 bndrng[0], bndrng[1], size));
794 if (warned)
795 {
796 if (pad && pad->src.ref
797 && has_location (x: pad->src.ref))
798 inform (get_location (x: pad->src.ref),
799 "source object allocated here");
800 suppress_warning (exp, opt);
801 }
802
803 return warned;
804 }
805
806 bool maybe = pad && pad->dst.phi ();
807 if (maybe)
808 {
809 /* Issue a "maybe" warning only if the PHI refers to objects
810 at least one of which has more space remaining than the bound.
811 Otherwise, if the bound is greater, use the definitive form. */
812 offset_int remmax = pad->dst.size_remaining ();
813 if (remmax < wi::to_offset (t: bndrng[0]))
814 maybe = false;
815 }
816 if (tree_int_cst_lt (t1: maxobjsize, t2: bndrng[0]))
817 {
818 if (bndrng[0] == bndrng[1])
819 warned = (func
820 ? warning_at (loc, opt,
821 (maybe
822 ? G_("%qD specified size %E may "
823 "exceed maximum object size %E")
824 : G_("%qD specified size %E "
825 "exceeds maximum object size %E")),
826 func, bndrng[0], maxobjsize)
827 : warning_at (loc, opt,
828 (maybe
829 ? G_("specified size %E may exceed "
830 "maximum object size %E")
831 : G_("specified size %E exceeds "
832 "maximum object size %E")),
833 bndrng[0], maxobjsize));
834 else
835 warned = (func
836 ? warning_at (loc, opt,
837 (maybe
838 ? G_("%qD specified size between %E and %E "
839 "may exceed maximum object size %E")
840 : G_("%qD specified size between %E and %E "
841 "exceeds maximum object size %E")),
842 func, bndrng[0], bndrng[1], maxobjsize)
843 : warning_at (loc, opt,
844 (maybe
845 ? G_("specified size between %E and %E "
846 "may exceed maximum object size %E")
847 : G_("specified size between %E and %E "
848 "exceeds maximum object size %E")),
849 bndrng[0], bndrng[1], maxobjsize));
850 }
851 else if (!size || tree_int_cst_le (t1: bndrng[0], t2: size))
852 return false;
853 else if (tree_int_cst_equal (bndrng[0], bndrng[1]))
854 warned = (func
855 ? warning_at (loc, opt,
856 (maybe
857 ? G_("%qD specified bound %E may exceed "
858 "destination size %E")
859 : G_("%qD specified bound %E exceeds "
860 "destination size %E")),
861 func, bndrng[0], size)
862 : warning_at (loc, opt,
863 (maybe
864 ? G_("specified bound %E may exceed "
865 "destination size %E")
866 : G_("specified bound %E exceeds "
867 "destination size %E")),
868 bndrng[0], size));
869 else
870 warned = (func
871 ? warning_at (loc, opt,
872 (maybe
873 ? G_("%qD specified bound [%E, %E] may exceed "
874 "destination size %E")
875 : G_("%qD specified bound [%E, %E] exceeds "
876 "destination size %E")),
877 func, bndrng[0], bndrng[1], size)
878 : warning_at (loc, opt,
879 (maybe
880 ? G_("specified bound [%E, %E] exceeds "
881 "destination size %E")
882 : G_("specified bound [%E, %E] exceeds "
883 "destination size %E")),
884 bndrng[0], bndrng[1], size));
885
886 if (warned)
887 {
888 if (pad && pad->dst.ref
889 && has_location (x: pad->dst.ref))
890 inform (get_location (x: pad->dst.ref),
891 "destination object allocated here");
892 suppress_warning (exp, opt);
893 }
894
895 return warned;
896}
897
898bool
899maybe_warn_for_bound (opt_code opt, location_t loc, gimple *stmt, tree func,
900 tree bndrng[2], tree size,
901 const access_data *pad /* = NULL */)
902{
903 return maybe_warn_for_bound<gimple *> (opt, loc, exp: stmt, func, bndrng, size,
904 pad);
905}
906
907bool
908maybe_warn_for_bound (opt_code opt, location_t loc, tree expr, tree func,
909 tree bndrng[2], tree size,
910 const access_data *pad /* = NULL */)
911{
912 return maybe_warn_for_bound<tree> (opt, loc, exp: expr, func, bndrng, size, pad);
913}
914
915/* For an expression EXP issue an access warning controlled by option OPT
916 with access to a region SIZE bytes in size in the RANGE of sizes.
917 WRITE is true for a write access, READ for a read access, neither for
918 call that may or may not perform an access but for which the range
919 is expected to valid.
920 Returns true when a warning has been issued. */
921
922template <class GimpleOrTree>
923static bool
924warn_for_access (location_t loc, tree func, GimpleOrTree exp, int opt,
925 tree range[2], tree size, bool write, bool read, bool maybe)
926{
927 bool warned = false;
928
929 if (write && read)
930 {
931 if (tree_int_cst_equal (range[0], range[1]))
932 warned = (func
933 ? warning_n (loc, opt, tree_to_uhwi (range[0]),
934 (maybe
935 ? G_("%qD may access %E byte in a region "
936 "of size %E")
937 : G_("%qD accessing %E byte in a region "
938 "of size %E")),
939 (maybe
940 ? G_ ("%qD may access %E bytes in a region "
941 "of size %E")
942 : G_ ("%qD accessing %E bytes in a region "
943 "of size %E")),
944 func, range[0], size)
945 : warning_n (loc, opt, tree_to_uhwi (range[0]),
946 (maybe
947 ? G_("may access %E byte in a region "
948 "of size %E")
949 : G_("accessing %E byte in a region "
950 "of size %E")),
951 (maybe
952 ? G_("may access %E bytes in a region "
953 "of size %E")
954 : G_("accessing %E bytes in a region "
955 "of size %E")),
956 range[0], size));
957 else if (tree_int_cst_sign_bit (range[1]))
958 {
959 /* Avoid printing the upper bound if it's invalid. */
960 warned = (func
961 ? warning_at (loc, opt,
962 (maybe
963 ? G_("%qD may access %E or more bytes "
964 "in a region of size %E")
965 : G_("%qD accessing %E or more bytes "
966 "in a region of size %E")),
967 func, range[0], size)
968 : warning_at (loc, opt,
969 (maybe
970 ? G_("may access %E or more bytes "
971 "in a region of size %E")
972 : G_("accessing %E or more bytes "
973 "in a region of size %E")),
974 range[0], size));
975 }
976 else
977 warned = (func
978 ? warning_at (loc, opt,
979 (maybe
980 ? G_("%qD may access between %E and %E "
981 "bytes in a region of size %E")
982 : G_("%qD accessing between %E and %E "
983 "bytes in a region of size %E")),
984 func, range[0], range[1], size)
985 : warning_at (loc, opt,
986 (maybe
987 ? G_("may access between %E and %E bytes "
988 "in a region of size %E")
989 : G_("accessing between %E and %E bytes "
990 "in a region of size %E")),
991 range[0], range[1], size));
992 return warned;
993 }
994
995 if (write)
996 {
997 if (tree_int_cst_equal (range[0], range[1]))
998 warned = (func
999 ? warning_n (loc, opt, tree_to_uhwi (range[0]),
1000 (maybe
1001 ? G_("%qD may write %E byte into a region "
1002 "of size %E")
1003 : G_("%qD writing %E byte into a region "
1004 "of size %E overflows the destination")),
1005 (maybe
1006 ? G_("%qD may write %E bytes into a region "
1007 "of size %E")
1008 : G_("%qD writing %E bytes into a region "
1009 "of size %E overflows the destination")),
1010 func, range[0], size)
1011 : warning_n (loc, opt, tree_to_uhwi (range[0]),
1012 (maybe
1013 ? G_("may write %E byte into a region "
1014 "of size %E")
1015 : G_("writing %E byte into a region "
1016 "of size %E overflows the destination")),
1017 (maybe
1018 ? G_("may write %E bytes into a region "
1019 "of size %E")
1020 : G_("writing %E bytes into a region "
1021 "of size %E overflows the destination")),
1022 range[0], size));
1023 else if (tree_int_cst_sign_bit (range[1]))
1024 {
1025 /* Avoid printing the upper bound if it's invalid. */
1026 warned = (func
1027 ? warning_at (loc, opt,
1028 (maybe
1029 ? G_("%qD may write %E or more bytes "
1030 "into a region of size %E")
1031 : G_("%qD writing %E or more bytes "
1032 "into a region of size %E overflows "
1033 "the destination")),
1034 func, range[0], size)
1035 : warning_at (loc, opt,
1036 (maybe
1037 ? G_("may write %E or more bytes into "
1038 "a region of size %E")
1039 : G_("writing %E or more bytes into "
1040 "a region of size %E overflows "
1041 "the destination")),
1042 range[0], size));
1043 }
1044 else
1045 warned = (func
1046 ? warning_at (loc, opt,
1047 (maybe
1048 ? G_("%qD may write between %E and %E bytes "
1049 "into a region of size %E")
1050 : G_("%qD writing between %E and %E bytes "
1051 "into a region of size %E overflows "
1052 "the destination")),
1053 func, range[0], range[1], size)
1054 : warning_at (loc, opt,
1055 (maybe
1056 ? G_("may write between %E and %E bytes "
1057 "into a region of size %E")
1058 : G_("writing between %E and %E bytes "
1059 "into a region of size %E overflows "
1060 "the destination")),
1061 range[0], range[1], size));
1062 return warned;
1063 }
1064
1065 if (read)
1066 {
1067 if (tree_int_cst_equal (range[0], range[1]))
1068 warned = (func
1069 ? warning_n (loc, OPT_Wstringop_overread,
1070 tree_to_uhwi (range[0]),
1071 (maybe
1072 ? G_("%qD may read %E byte from a region "
1073 "of size %E")
1074 : G_("%qD reading %E byte from a region "
1075 "of size %E")),
1076 (maybe
1077 ? G_("%qD may read %E bytes from a region "
1078 "of size %E")
1079 : G_("%qD reading %E bytes from a region "
1080 "of size %E")),
1081 func, range[0], size)
1082 : warning_n (loc, OPT_Wstringop_overread,
1083 tree_to_uhwi (range[0]),
1084 (maybe
1085 ? G_("may read %E byte from a region "
1086 "of size %E")
1087 : G_("reading %E byte from a region "
1088 "of size %E")),
1089 (maybe
1090 ? G_("may read %E bytes from a region "
1091 "of size %E")
1092 : G_("reading %E bytes from a region "
1093 "of size %E")),
1094 range[0], size));
1095 else if (tree_int_cst_sign_bit (range[1]))
1096 {
1097 /* Avoid printing the upper bound if it's invalid. */
1098 warned = (func
1099 ? warning_at (loc, OPT_Wstringop_overread,
1100 (maybe
1101 ? G_("%qD may read %E or more bytes "
1102 "from a region of size %E")
1103 : G_("%qD reading %E or more bytes "
1104 "from a region of size %E")),
1105 func, range[0], size)
1106 : warning_at (loc, OPT_Wstringop_overread,
1107 (maybe
1108 ? G_("may read %E or more bytes "
1109 "from a region of size %E")
1110 : G_("reading %E or more bytes "
1111 "from a region of size %E")),
1112 range[0], size));
1113 }
1114 else
1115 warned = (func
1116 ? warning_at (loc, OPT_Wstringop_overread,
1117 (maybe
1118 ? G_("%qD may read between %E and %E bytes "
1119 "from a region of size %E")
1120 : G_("%qD reading between %E and %E bytes "
1121 "from a region of size %E")),
1122 func, range[0], range[1], size)
1123 : warning_at (loc, opt,
1124 (maybe
1125 ? G_("may read between %E and %E bytes "
1126 "from a region of size %E")
1127 : G_("reading between %E and %E bytes "
1128 "from a region of size %E")),
1129 range[0], range[1], size));
1130
1131 if (warned)
1132 suppress_warning (exp, OPT_Wstringop_overread);
1133
1134 return warned;
1135 }
1136
1137 if (tree_int_cst_equal (range[0], range[1])
1138 || tree_int_cst_sign_bit (range[1]))
1139 warned = (func
1140 ? warning_n (loc, OPT_Wstringop_overread,
1141 tree_to_uhwi (range[0]),
1142 "%qD expecting %E byte in a region of size %E",
1143 "%qD expecting %E bytes in a region of size %E",
1144 func, range[0], size)
1145 : warning_n (loc, OPT_Wstringop_overread,
1146 tree_to_uhwi (range[0]),
1147 "expecting %E byte in a region of size %E",
1148 "expecting %E bytes in a region of size %E",
1149 range[0], size));
1150 else if (tree_int_cst_sign_bit (range[1]))
1151 {
1152 /* Avoid printing the upper bound if it's invalid. */
1153 warned = (func
1154 ? warning_at (loc, OPT_Wstringop_overread,
1155 "%qD expecting %E or more bytes in a region "
1156 "of size %E",
1157 func, range[0], size)
1158 : warning_at (loc, OPT_Wstringop_overread,
1159 "expecting %E or more bytes in a region "
1160 "of size %E",
1161 range[0], size));
1162 }
1163 else
1164 warned = (func
1165 ? warning_at (loc, OPT_Wstringop_overread,
1166 "%qD expecting between %E and %E bytes in "
1167 "a region of size %E",
1168 func, range[0], range[1], size)
1169 : warning_at (loc, OPT_Wstringop_overread,
1170 "expecting between %E and %E bytes in "
1171 "a region of size %E",
1172 range[0], range[1], size));
1173
1174 if (warned)
1175 suppress_warning (exp, OPT_Wstringop_overread);
1176
1177 return warned;
1178}
1179
1180static bool
1181warn_for_access (location_t loc, tree func, gimple *stmt, int opt,
1182 tree range[2], tree size, bool write, bool read, bool maybe)
1183{
1184 return warn_for_access<gimple *>(loc, func, exp: stmt, opt, range, size,
1185 write, read, maybe);
1186}
1187
1188static bool
1189warn_for_access (location_t loc, tree func, tree expr, int opt,
1190 tree range[2], tree size, bool write, bool read, bool maybe)
1191{
1192 return warn_for_access<tree>(loc, func, exp: expr, opt, range, size,
1193 write, read, maybe);
1194}
1195
1196/* Helper to set RANGE to the range of BOUND if it's nonnull, bounded
1197 by BNDRNG if nonnull and valid. */
1198
1199static void
1200get_size_range (range_query *query, tree bound, gimple *stmt, tree range[2],
1201 int flags, const offset_int bndrng[2])
1202{
1203 if (bound)
1204 get_size_range (query, bound, stmt, range, flags);
1205
1206 if (!bndrng || (bndrng[0] == 0 && bndrng[1] == HOST_WIDE_INT_M1U))
1207 return;
1208
1209 if (range[0] && TREE_CODE (range[0]) == INTEGER_CST)
1210 {
1211 offset_int r[] =
1212 { wi::to_offset (t: range[0]), wi::to_offset (t: range[1]) };
1213 if (r[0] < bndrng[0])
1214 range[0] = wide_int_to_tree (sizetype, cst: bndrng[0]);
1215 if (bndrng[1] < r[1])
1216 range[1] = wide_int_to_tree (sizetype, cst: bndrng[1]);
1217 }
1218 else
1219 {
1220 range[0] = wide_int_to_tree (sizetype, cst: bndrng[0]);
1221 range[1] = wide_int_to_tree (sizetype, cst: bndrng[1]);
1222 }
1223}
1224
1225/* Try to verify that the sizes and lengths of the arguments to a string
1226 manipulation function given by EXP are within valid bounds and that
1227 the operation does not lead to buffer overflow or read past the end.
1228 Arguments other than EXP may be null. When non-null, the arguments
1229 have the following meaning:
1230 DST is the destination of a copy call or NULL otherwise.
1231 SRC is the source of a copy call or NULL otherwise.
1232 DSTWRITE is the number of bytes written into the destination obtained
1233 from the user-supplied size argument to the function (such as in
1234 memcpy(DST, SRCs, DSTWRITE) or strncpy(DST, DRC, DSTWRITE).
1235 MAXREAD is the user-supplied bound on the length of the source sequence
1236 (such as in strncat(d, s, N). It specifies the upper limit on the number
1237 of bytes to write. If NULL, it's taken to be the same as DSTWRITE.
1238 SRCSTR is the source string (such as in strcpy(DST, SRC)) when the
1239 expression EXP is a string function call (as opposed to a memory call
1240 like memcpy). As an exception, SRCSTR can also be an integer denoting
1241 the precomputed size of the source string or object (for functions like
1242 memcpy).
1243 DSTSIZE is the size of the destination object.
1244
1245 When DSTWRITE is null LEN is checked to verify that it doesn't exceed
1246 SIZE_MAX.
1247
1248 WRITE is true for write accesses, READ is true for reads. Both are
1249 false for simple size checks in calls to functions that neither read
1250 from nor write to the region.
1251
1252 When nonnull, PAD points to a more detailed description of the access.
1253
1254 If the call is successfully verified as safe return true, otherwise
1255 return false. */
1256
1257template <class GimpleOrTree>
1258static bool
1259check_access (GimpleOrTree exp, tree dstwrite,
1260 tree maxread, tree srcstr, tree dstsize,
1261 access_mode mode, const access_data *pad,
1262 range_query *rvals)
1263{
1264 /* The size of the largest object is half the address space, or
1265 PTRDIFF_MAX. (This is way too permissive.) */
1266 tree maxobjsize = max_object_size ();
1267
1268 /* Either an approximate/minimum the length of the source string for
1269 string functions or the size of the source object for raw memory
1270 functions. */
1271 tree slen = NULL_TREE;
1272
1273 /* The range of the access in bytes; first set to the write access
1274 for functions that write and then read for those that also (or
1275 just) read. */
1276 tree range[2] = { NULL_TREE, NULL_TREE };
1277
1278 /* Set to true when the exact number of bytes written by a string
1279 function like strcpy is not known and the only thing that is
1280 known is that it must be at least one (for the terminating nul). */
1281 bool at_least_one = false;
1282 if (srcstr)
1283 {
1284 /* SRCSTR is normally a pointer to string but as a special case
1285 it can be an integer denoting the length of a string. */
1286 if (POINTER_TYPE_P (TREE_TYPE (srcstr)))
1287 {
1288 if (!check_nul_terminated_array (exp, srcstr, maxread))
1289 /* Return if the array is not nul-terminated and a warning
1290 has been issued. */
1291 return false;
1292
1293 /* Try to determine the range of lengths the source string
1294 refers to. If it can be determined and is less than
1295 the upper bound given by MAXREAD add one to it for
1296 the terminating nul. Otherwise, set it to one for
1297 the same reason, or to MAXREAD as appropriate. */
1298 c_strlen_data lendata = { };
1299 get_range_strlen (srcstr, &lendata, /* eltsize = */ 1);
1300 range[0] = lendata.minlen;
1301 range[1] = lendata.maxbound ? lendata.maxbound : lendata.maxlen;
1302 if (range[0]
1303 && TREE_CODE (range[0]) == INTEGER_CST
1304 && TREE_CODE (range[1]) == INTEGER_CST
1305 && (!maxread || TREE_CODE (maxread) == INTEGER_CST))
1306 {
1307 if (maxread && tree_int_cst_le (t1: maxread, t2: range[0]))
1308 range[0] = range[1] = maxread;
1309 else
1310 range[0] = fold_build2 (PLUS_EXPR, size_type_node,
1311 range[0], size_one_node);
1312
1313 if (maxread && tree_int_cst_le (t1: maxread, t2: range[1]))
1314 range[1] = maxread;
1315 else if (!integer_all_onesp (range[1]))
1316 range[1] = fold_build2 (PLUS_EXPR, size_type_node,
1317 range[1], size_one_node);
1318
1319 slen = range[0];
1320 }
1321 else
1322 {
1323 at_least_one = true;
1324 slen = size_one_node;
1325 }
1326 }
1327 else
1328 slen = srcstr;
1329 }
1330
1331 if (!dstwrite && !maxread)
1332 {
1333 /* When the only available piece of data is the object size
1334 there is nothing to do. */
1335 if (!slen)
1336 return true;
1337
1338 /* Otherwise, when the length of the source sequence is known
1339 (as with strlen), set DSTWRITE to it. */
1340 if (!range[0])
1341 dstwrite = slen;
1342 }
1343
1344 if (!dstsize)
1345 dstsize = maxobjsize;
1346
1347 /* Set RANGE to that of DSTWRITE if non-null, bounded by PAD->DST_BNDRNG
1348 if valid. */
1349 gimple *stmt = pad ? pad->stmt : nullptr;
1350 get_size_range (query: rvals, bound: dstwrite, stmt, range,
1351 /* If the destination has known zero size prefer a zero
1352 size range to avoid false positives if that's a
1353 possibility. */
1354 flags: integer_zerop (dstsize) ? SR_ALLOW_ZERO : 0,
1355 bndrng: pad ? pad->dst_bndrng : NULL);
1356
1357 tree func = get_callee_fndecl (exp);
1358 /* Read vs write access by built-ins can be determined from the const
1359 qualifiers on the pointer argument. In the absence of attribute
1360 access, non-const qualified pointer arguments to user-defined
1361 functions are assumed to both read and write the objects. */
1362 const bool builtin = func ? fndecl_built_in_p (node: func) : false;
1363
1364 /* First check the number of bytes to be written against the maximum
1365 object size. */
1366 if (range[0]
1367 && TREE_CODE (range[0]) == INTEGER_CST
1368 && tree_int_cst_lt (t1: maxobjsize, t2: range[0]))
1369 {
1370 location_t loc = get_location (exp);
1371 maybe_warn_for_bound (OPT_Wstringop_overflow_, loc, exp, func, range,
1372 NULL_TREE, pad);
1373 return false;
1374 }
1375
1376 /* The number of bytes to write is "exact" if DSTWRITE is non-null,
1377 constant, and in range of unsigned HOST_WIDE_INT. */
1378 bool exactwrite = dstwrite && tree_fits_uhwi_p (dstwrite);
1379
1380 /* Next check the number of bytes to be written against the destination
1381 object size. */
1382 if (range[0] || !exactwrite || integer_all_onesp (dstwrite))
1383 {
1384 if (range[0]
1385 && TREE_CODE (range[0]) == INTEGER_CST
1386 && ((tree_fits_uhwi_p (dstsize)
1387 && tree_int_cst_lt (t1: dstsize, t2: range[0]))
1388 || (dstwrite
1389 && tree_fits_uhwi_p (dstwrite)
1390 && tree_int_cst_lt (t1: dstwrite, t2: range[0]))))
1391 {
1392 const opt_code opt = OPT_Wstringop_overflow_;
1393 if (warning_suppressed_p (exp, opt)
1394 || (pad && pad->dst.ref
1395 && warning_suppressed_p (pad->dst.ref, opt)))
1396 return false;
1397
1398 auto_diagnostic_group d;
1399 location_t loc = get_location (exp);
1400 bool warned = false;
1401 if (dstwrite == slen && at_least_one)
1402 {
1403 /* This is a call to strcpy with a destination of 0 size
1404 and a source of unknown length. The call will write
1405 at least one byte past the end of the destination. */
1406 warned = (func
1407 ? warning_at (loc, opt,
1408 "%qD writing %E or more bytes into "
1409 "a region of size %E overflows "
1410 "the destination",
1411 func, range[0], dstsize)
1412 : warning_at (loc, opt,
1413 "writing %E or more bytes into "
1414 "a region of size %E overflows "
1415 "the destination",
1416 range[0], dstsize));
1417 }
1418 else
1419 {
1420 const bool read
1421 = mode == access_read_only || mode == access_read_write;
1422 const bool write
1423 = mode == access_write_only || mode == access_read_write;
1424 const bool maybe = pad && pad->dst.parmarray;
1425 warned = warn_for_access (loc, func, exp,
1426 OPT_Wstringop_overflow_,
1427 range, dstsize,
1428 write, read && !builtin, maybe);
1429 }
1430
1431 if (warned)
1432 {
1433 suppress_warning (exp, OPT_Wstringop_overflow_);
1434 if (pad)
1435 pad->dst.inform_access (pad->mode);
1436 }
1437
1438 /* Return error when an overflow has been detected. */
1439 return false;
1440 }
1441 }
1442
1443 /* Check the maximum length of the source sequence against the size
1444 of the destination object if known, or against the maximum size
1445 of an object. */
1446 if (maxread)
1447 {
1448 /* Set RANGE to that of MAXREAD, bounded by PAD->SRC_BNDRNG if
1449 PAD is nonnull and BNDRNG is valid. */
1450 get_size_range (query: rvals, bound: maxread, stmt, range, flags: 0,
1451 bndrng: pad ? pad->src_bndrng : NULL);
1452
1453 location_t loc = get_location (exp);
1454 tree size = dstsize;
1455 if (pad && pad->mode == access_read_only)
1456 size = wide_int_to_tree (sizetype, cst: pad->src.size_remaining ());
1457
1458 if (range[0] && maxread && tree_fits_uhwi_p (size))
1459 {
1460 if (tree_int_cst_lt (t1: maxobjsize, t2: range[0]))
1461 {
1462 maybe_warn_for_bound (OPT_Wstringop_overread, loc, exp, func,
1463 range, size, pad);
1464 return false;
1465 }
1466
1467 if (size != maxobjsize && tree_int_cst_lt (t1: size, t2: range[0]))
1468 {
1469 opt_code opt = (dstwrite || mode != access_read_only
1470 ? OPT_Wstringop_overflow_
1471 : OPT_Wstringop_overread);
1472 maybe_warn_for_bound (opt, loc, exp, func, range, size, pad);
1473 return false;
1474 }
1475 }
1476
1477 maybe_warn_nonstring_arg (func, exp);
1478 }
1479
1480 /* Check for reading past the end of SRC. */
1481 bool overread = (slen
1482 && slen == srcstr
1483 && dstwrite
1484 && range[0]
1485 && TREE_CODE (slen) == INTEGER_CST
1486 && tree_int_cst_lt (t1: slen, t2: range[0]));
1487 /* If none is determined try to get a better answer based on the details
1488 in PAD. */
1489 if (!overread
1490 && pad
1491 && pad->src.sizrng[1] >= 0
1492 && pad->src.offrng[0] >= 0
1493 && (pad->src.offrng[1] < 0
1494 || pad->src.offrng[0] <= pad->src.offrng[1]))
1495 {
1496 /* Set RANGE to that of MAXREAD, bounded by PAD->SRC_BNDRNG if
1497 PAD is nonnull and BNDRNG is valid. */
1498 get_size_range (query: rvals, bound: maxread, stmt, range, flags: 0,
1499 bndrng: pad ? pad->src_bndrng : NULL);
1500 /* Set OVERREAD for reads starting just past the end of an object. */
1501 overread = pad->src.sizrng[1] - pad->src.offrng[0] < pad->src_bndrng[0];
1502 range[0] = wide_int_to_tree (sizetype, cst: pad->src_bndrng[0]);
1503 slen = size_zero_node;
1504 }
1505
1506 if (overread)
1507 {
1508 const opt_code opt = OPT_Wstringop_overread;
1509 if (warning_suppressed_p (exp, opt)
1510 || (srcstr && warning_suppressed_p (srcstr, opt))
1511 || (pad && pad->src.ref
1512 && warning_suppressed_p (pad->src.ref, opt)))
1513 return false;
1514
1515 location_t loc = get_location (exp);
1516 const bool read
1517 = mode == access_read_only || mode == access_read_write;
1518 const bool maybe = pad && pad->dst.parmarray;
1519 auto_diagnostic_group d;
1520 if (warn_for_access (loc, func, exp, opt, range, slen, false, read,
1521 maybe))
1522 {
1523 suppress_warning (exp, opt);
1524 if (pad)
1525 pad->src.inform_access (access_read_only);
1526 }
1527 return false;
1528 }
1529
1530 return true;
1531}
1532
1533static bool
1534check_access (gimple *stmt, tree dstwrite,
1535 tree maxread, tree srcstr, tree dstsize,
1536 access_mode mode, const access_data *pad,
1537 range_query *rvals)
1538{
1539 return check_access<gimple *> (exp: stmt, dstwrite, maxread, srcstr, dstsize,
1540 mode, pad, rvals);
1541}
1542
1543bool
1544check_access (tree expr, tree dstwrite,
1545 tree maxread, tree srcstr, tree dstsize,
1546 access_mode mode, const access_data *pad /* = NULL */)
1547{
1548 return check_access<tree> (exp: expr, dstwrite, maxread, srcstr, dstsize,
1549 mode, pad, rvals: nullptr);
1550}
1551
1552/* Return true if STMT is a call to an allocation function. Unless
1553 ALL_ALLOC is set, consider only functions that return dynamically
1554 allocated objects. Otherwise return true even for all forms of
1555 alloca (including VLA). */
1556
1557static bool
1558fndecl_alloc_p (tree fndecl, bool all_alloc)
1559{
1560 if (!fndecl)
1561 return false;
1562
1563 /* A call to operator new isn't recognized as one to a built-in. */
1564 if (DECL_IS_OPERATOR_NEW_P (fndecl))
1565 return true;
1566
1567 if (fndecl_built_in_p (node: fndecl, klass: BUILT_IN_NORMAL))
1568 {
1569 switch (DECL_FUNCTION_CODE (decl: fndecl))
1570 {
1571 case BUILT_IN_ALLOCA:
1572 case BUILT_IN_ALLOCA_WITH_ALIGN:
1573 return all_alloc;
1574 case BUILT_IN_ALIGNED_ALLOC:
1575 case BUILT_IN_CALLOC:
1576 case BUILT_IN_GOMP_ALLOC:
1577 case BUILT_IN_GOMP_REALLOC:
1578 case BUILT_IN_MALLOC:
1579 case BUILT_IN_REALLOC:
1580 case BUILT_IN_STRDUP:
1581 case BUILT_IN_STRNDUP:
1582 return true;
1583 default:
1584 break;
1585 }
1586 }
1587
1588 /* A function is considered an allocation function if it's declared
1589 with attribute malloc with an argument naming its associated
1590 deallocation function. */
1591 tree attrs = DECL_ATTRIBUTES (fndecl);
1592 if (!attrs)
1593 return false;
1594
1595 for (tree allocs = attrs;
1596 (allocs = lookup_attribute (attr_name: "malloc", list: allocs));
1597 allocs = TREE_CHAIN (allocs))
1598 {
1599 tree args = TREE_VALUE (allocs);
1600 if (!args)
1601 continue;
1602
1603 if (TREE_VALUE (args))
1604 return true;
1605 }
1606
1607 return false;
1608}
1609
1610/* Return true if STMT is a call to an allocation function. A wrapper
1611 around fndecl_alloc_p. */
1612
1613static bool
1614gimple_call_alloc_p (gimple *stmt, bool all_alloc = false)
1615{
1616 return fndecl_alloc_p (fndecl: gimple_call_fndecl (gs: stmt), all_alloc);
1617}
1618
1619/* Return true if DELC doesn't refer to an operator delete that's
1620 suitable to call with a pointer returned from the operator new
1621 described by NEWC. */
1622
1623static bool
1624new_delete_mismatch_p (const demangle_component &newc,
1625 const demangle_component &delc)
1626{
1627 if (newc.type != delc.type)
1628 return true;
1629
1630 switch (newc.type)
1631 {
1632 case DEMANGLE_COMPONENT_NAME:
1633 {
1634 int len = newc.u.s_name.len;
1635 const char *news = newc.u.s_name.s;
1636 const char *dels = delc.u.s_name.s;
1637 if (len != delc.u.s_name.len || memcmp (s1: news, s2: dels, n: len))
1638 return true;
1639
1640 if (news[len] == 'n')
1641 {
1642 if (news[len + 1] == 'a')
1643 return dels[len] != 'd' || dels[len + 1] != 'a';
1644 if (news[len + 1] == 'w')
1645 return dels[len] != 'd' || dels[len + 1] != 'l';
1646 }
1647 return false;
1648 }
1649
1650 case DEMANGLE_COMPONENT_OPERATOR:
1651 /* Operator mismatches are handled above. */
1652 return false;
1653
1654 case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
1655 if (newc.u.s_extended_operator.args != delc.u.s_extended_operator.args)
1656 return true;
1657 return new_delete_mismatch_p (newc: *newc.u.s_extended_operator.name,
1658 delc: *delc.u.s_extended_operator.name);
1659
1660 case DEMANGLE_COMPONENT_FIXED_TYPE:
1661 if (newc.u.s_fixed.accum != delc.u.s_fixed.accum
1662 || newc.u.s_fixed.sat != delc.u.s_fixed.sat)
1663 return true;
1664 return new_delete_mismatch_p (newc: *newc.u.s_fixed.length,
1665 delc: *delc.u.s_fixed.length);
1666
1667 case DEMANGLE_COMPONENT_CTOR:
1668 if (newc.u.s_ctor.kind != delc.u.s_ctor.kind)
1669 return true;
1670 return new_delete_mismatch_p (newc: *newc.u.s_ctor.name,
1671 delc: *delc.u.s_ctor.name);
1672
1673 case DEMANGLE_COMPONENT_DTOR:
1674 if (newc.u.s_dtor.kind != delc.u.s_dtor.kind)
1675 return true;
1676 return new_delete_mismatch_p (newc: *newc.u.s_dtor.name,
1677 delc: *delc.u.s_dtor.name);
1678
1679 case DEMANGLE_COMPONENT_BUILTIN_TYPE:
1680 {
1681 /* The demangler API provides no better way to compare built-in
1682 types except to by comparing their demangled names. */
1683 size_t nsz, dsz;
1684 demangle_component *pnc = const_cast<demangle_component *>(&newc);
1685 demangle_component *pdc = const_cast<demangle_component *>(&delc);
1686 char *nts = cplus_demangle_print (options: 0, tree: pnc, estimated_length: 16, p_allocated_size: &nsz);
1687 char *dts = cplus_demangle_print (options: 0, tree: pdc, estimated_length: 16, p_allocated_size: &dsz);
1688 if (!nts != !dts)
1689 return true;
1690 bool mismatch = strcmp (s1: nts, s2: dts);
1691 free (ptr: nts);
1692 free (ptr: dts);
1693 return mismatch;
1694 }
1695
1696 case DEMANGLE_COMPONENT_SUB_STD:
1697 if (newc.u.s_string.len != delc.u.s_string.len)
1698 return true;
1699 return memcmp (s1: newc.u.s_string.string, s2: delc.u.s_string.string,
1700 n: newc.u.s_string.len);
1701
1702 case DEMANGLE_COMPONENT_FUNCTION_PARAM:
1703 case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
1704 case DEMANGLE_COMPONENT_UNNAMED_TYPE:
1705 return newc.u.s_number.number != delc.u.s_number.number;
1706
1707 case DEMANGLE_COMPONENT_CHARACTER:
1708 return newc.u.s_character.character != delc.u.s_character.character;
1709
1710 case DEMANGLE_COMPONENT_DEFAULT_ARG:
1711 case DEMANGLE_COMPONENT_LAMBDA:
1712 if (newc.u.s_unary_num.num != delc.u.s_unary_num.num)
1713 return true;
1714 return new_delete_mismatch_p (newc: *newc.u.s_unary_num.sub,
1715 delc: *delc.u.s_unary_num.sub);
1716 default:
1717 break;
1718 }
1719
1720 if (!newc.u.s_binary.left != !delc.u.s_binary.left)
1721 return true;
1722
1723 if (!newc.u.s_binary.left)
1724 return false;
1725
1726 if (new_delete_mismatch_p (newc: *newc.u.s_binary.left, delc: *delc.u.s_binary.left)
1727 || !newc.u.s_binary.right != !delc.u.s_binary.right)
1728 return true;
1729
1730 if (newc.u.s_binary.right)
1731 return new_delete_mismatch_p (newc: *newc.u.s_binary.right,
1732 delc: *delc.u.s_binary.right);
1733 return false;
1734}
1735
1736/* Return true if DELETE_DECL is an operator delete that's not suitable
1737 to call with a pointer returned from NEW_DECL. */
1738
1739static bool
1740new_delete_mismatch_p (tree new_decl, tree delete_decl)
1741{
1742 tree new_name = DECL_ASSEMBLER_NAME (new_decl);
1743 tree delete_name = DECL_ASSEMBLER_NAME (delete_decl);
1744
1745 /* valid_new_delete_pair_p() returns a conservative result (currently
1746 it only handles global operators). A true result is reliable but
1747 a false result doesn't necessarily mean the operators don't match
1748 unless CERTAIN is set. */
1749 bool certain;
1750 if (valid_new_delete_pair_p (new_name, delete_name, &certain))
1751 return false;
1752 /* CERTAIN is set when the negative result is certain. */
1753 if (certain)
1754 return true;
1755
1756 /* For anything not handled by valid_new_delete_pair_p() such as member
1757 operators compare the individual demangled components of the mangled
1758 name. */
1759 const char *new_str = IDENTIFIER_POINTER (new_name);
1760 const char *del_str = IDENTIFIER_POINTER (delete_name);
1761
1762 void *np = NULL, *dp = NULL;
1763 demangle_component *ndc = cplus_demangle_v3_components (mangled: new_str, options: 0, mem: &np);
1764 demangle_component *ddc = cplus_demangle_v3_components (mangled: del_str, options: 0, mem: &dp);
1765 bool mismatch = new_delete_mismatch_p (newc: *ndc, delc: *ddc);
1766 free (ptr: np);
1767 free (ptr: dp);
1768 return mismatch;
1769}
1770
1771/* ALLOC_DECL and DEALLOC_DECL are pair of allocation and deallocation
1772 functions. Return true if the latter is suitable to deallocate objects
1773 allocated by calls to the former. */
1774
1775static bool
1776matching_alloc_calls_p (tree alloc_decl, tree dealloc_decl)
1777{
1778 /* Set to alloc_kind_t::builtin if ALLOC_DECL is associated with
1779 a built-in deallocator. */
1780 enum class alloc_kind_t { none, builtin, user }
1781 alloc_dealloc_kind = alloc_kind_t::none;
1782
1783 if (DECL_IS_OPERATOR_NEW_P (alloc_decl))
1784 {
1785 if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl))
1786 /* Return true iff both functions are of the same array or
1787 singleton form and false otherwise. */
1788 return !new_delete_mismatch_p (new_decl: alloc_decl, delete_decl: dealloc_decl);
1789
1790 /* Return false for deallocation functions that are known not
1791 to match. */
1792 if (fndecl_built_in_p (node: dealloc_decl, name1: BUILT_IN_FREE, names: BUILT_IN_REALLOC))
1793 return false;
1794 /* Otherwise proceed below to check the deallocation function's
1795 "*dealloc" attributes to look for one that mentions this operator
1796 new. */
1797 }
1798 else if (fndecl_built_in_p (node: alloc_decl, klass: BUILT_IN_NORMAL))
1799 {
1800 switch (DECL_FUNCTION_CODE (decl: alloc_decl))
1801 {
1802 case BUILT_IN_ALLOCA:
1803 case BUILT_IN_ALLOCA_WITH_ALIGN:
1804 return false;
1805
1806 case BUILT_IN_GOMP_ALLOC:
1807 case BUILT_IN_GOMP_REALLOC:
1808 if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl))
1809 return false;
1810
1811 if (fndecl_built_in_p (node: dealloc_decl, name1: BUILT_IN_GOMP_FREE,
1812 names: BUILT_IN_GOMP_REALLOC))
1813 return true;
1814
1815 alloc_dealloc_kind = alloc_kind_t::builtin;
1816 break;
1817
1818 case BUILT_IN_ALIGNED_ALLOC:
1819 case BUILT_IN_CALLOC:
1820 case BUILT_IN_MALLOC:
1821 case BUILT_IN_REALLOC:
1822 case BUILT_IN_STRDUP:
1823 case BUILT_IN_STRNDUP:
1824 if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl))
1825 return false;
1826
1827 if (fndecl_built_in_p (node: dealloc_decl, name1: BUILT_IN_FREE,
1828 names: BUILT_IN_REALLOC))
1829 return true;
1830
1831 alloc_dealloc_kind = alloc_kind_t::builtin;
1832 break;
1833
1834 default:
1835 break;
1836 }
1837 }
1838
1839 /* Set if DEALLOC_DECL both allocates and deallocates. */
1840 alloc_kind_t realloc_kind = alloc_kind_t::none;
1841
1842 if (fndecl_built_in_p (node: dealloc_decl, klass: BUILT_IN_NORMAL))
1843 {
1844 built_in_function dealloc_code = DECL_FUNCTION_CODE (decl: dealloc_decl);
1845 if (dealloc_code == BUILT_IN_REALLOC
1846 || dealloc_code == BUILT_IN_GOMP_REALLOC)
1847 realloc_kind = alloc_kind_t::builtin;
1848
1849 for (tree amats = DECL_ATTRIBUTES (alloc_decl);
1850 (amats = lookup_attribute (attr_name: "malloc", list: amats));
1851 amats = TREE_CHAIN (amats))
1852 {
1853 tree args = TREE_VALUE (amats);
1854 if (!args)
1855 continue;
1856
1857 tree fndecl = TREE_VALUE (args);
1858 if (!fndecl || !DECL_P (fndecl))
1859 continue;
1860
1861 if (fndecl_built_in_p (node: fndecl, klass: BUILT_IN_NORMAL)
1862 && dealloc_code == DECL_FUNCTION_CODE (decl: fndecl))
1863 return true;
1864 }
1865 }
1866
1867 const bool alloc_builtin = fndecl_built_in_p (node: alloc_decl, klass: BUILT_IN_NORMAL);
1868 alloc_kind_t realloc_dealloc_kind = alloc_kind_t::none;
1869
1870 /* If DEALLOC_DECL has an internal "*dealloc" attribute scan the list
1871 of its associated allocation functions for ALLOC_DECL.
1872 If the corresponding ALLOC_DECL is found they're a matching pair,
1873 otherwise they're not.
1874 With DDATS set to the Deallocator's *Dealloc ATtributes... */
1875 for (tree ddats = DECL_ATTRIBUTES (dealloc_decl);
1876 (ddats = lookup_attribute (attr_name: "*dealloc", list: ddats));
1877 ddats = TREE_CHAIN (ddats))
1878 {
1879 tree args = TREE_VALUE (ddats);
1880 if (!args)
1881 continue;
1882
1883 tree alloc = TREE_VALUE (args);
1884 if (!alloc)
1885 continue;
1886
1887 if (alloc == DECL_NAME (dealloc_decl))
1888 realloc_kind = alloc_kind_t::user;
1889
1890 if (DECL_P (alloc))
1891 {
1892 gcc_checking_assert (fndecl_built_in_p (alloc, BUILT_IN_NORMAL));
1893
1894 switch (DECL_FUNCTION_CODE (decl: alloc))
1895 {
1896 case BUILT_IN_ALIGNED_ALLOC:
1897 case BUILT_IN_CALLOC:
1898 case BUILT_IN_GOMP_ALLOC:
1899 case BUILT_IN_GOMP_REALLOC:
1900 case BUILT_IN_MALLOC:
1901 case BUILT_IN_REALLOC:
1902 case BUILT_IN_STRDUP:
1903 case BUILT_IN_STRNDUP:
1904 realloc_dealloc_kind = alloc_kind_t::builtin;
1905 break;
1906 default:
1907 break;
1908 }
1909
1910 if (!alloc_builtin)
1911 continue;
1912
1913 if (DECL_FUNCTION_CODE (decl: alloc) != DECL_FUNCTION_CODE (decl: alloc_decl))
1914 continue;
1915
1916 return true;
1917 }
1918
1919 if (alloc == DECL_NAME (alloc_decl))
1920 return true;
1921 }
1922
1923 if (realloc_kind == alloc_kind_t::none)
1924 return false;
1925
1926 hash_set<tree> common_deallocs;
1927 /* Special handling for deallocators. Iterate over both the allocator's
1928 and the reallocator's associated deallocator functions looking for
1929 the first one in common. If one is found, the de/reallocator is
1930 a match for the allocator even though the latter isn't directly
1931 associated with the former. This simplifies declarations in system
1932 headers.
1933 With AMATS set to the Allocator's Malloc ATtributes,
1934 and RMATS set to Reallocator's Malloc ATtributes... */
1935 for (tree amats = DECL_ATTRIBUTES (alloc_decl),
1936 rmats = DECL_ATTRIBUTES (dealloc_decl);
1937 (amats = lookup_attribute (attr_name: "malloc", list: amats))
1938 || (rmats = lookup_attribute (attr_name: "malloc", list: rmats));
1939 amats = amats ? TREE_CHAIN (amats) : NULL_TREE,
1940 rmats = rmats ? TREE_CHAIN (rmats) : NULL_TREE)
1941 {
1942 if (tree args = amats ? TREE_VALUE (amats) : NULL_TREE)
1943 if (tree adealloc = TREE_VALUE (args))
1944 {
1945 if (DECL_P (adealloc)
1946 && fndecl_built_in_p (node: adealloc, klass: BUILT_IN_NORMAL))
1947 {
1948 built_in_function fncode = DECL_FUNCTION_CODE (decl: adealloc);
1949 if (fncode == BUILT_IN_FREE || fncode == BUILT_IN_REALLOC)
1950 {
1951 if (realloc_kind == alloc_kind_t::builtin)
1952 return true;
1953 alloc_dealloc_kind = alloc_kind_t::builtin;
1954 }
1955 continue;
1956 }
1957
1958 common_deallocs.add (k: adealloc);
1959 }
1960
1961 if (tree args = rmats ? TREE_VALUE (rmats) : NULL_TREE)
1962 if (tree ddealloc = TREE_VALUE (args))
1963 {
1964 if (DECL_P (ddealloc)
1965 && fndecl_built_in_p (node: ddealloc, klass: BUILT_IN_NORMAL))
1966 {
1967 built_in_function fncode = DECL_FUNCTION_CODE (decl: ddealloc);
1968 if (fncode == BUILT_IN_FREE || fncode == BUILT_IN_REALLOC)
1969 {
1970 if (alloc_dealloc_kind == alloc_kind_t::builtin)
1971 return true;
1972 realloc_dealloc_kind = alloc_kind_t::builtin;
1973 }
1974 continue;
1975 }
1976
1977 if (common_deallocs.add (k: ddealloc))
1978 return true;
1979 }
1980 }
1981
1982 /* Succeed only if ALLOC_DECL and the reallocator DEALLOC_DECL share
1983 a built-in deallocator. */
1984 return (alloc_dealloc_kind == alloc_kind_t::builtin
1985 && realloc_dealloc_kind == alloc_kind_t::builtin);
1986}
1987
1988/* Return true if DEALLOC_DECL is a function suitable to deallocate
1989 objects allocated by the ALLOC call. */
1990
1991static bool
1992matching_alloc_calls_p (gimple *alloc, tree dealloc_decl)
1993{
1994 tree alloc_decl = gimple_call_fndecl (gs: alloc);
1995 if (!alloc_decl)
1996 return true;
1997
1998 return matching_alloc_calls_p (alloc_decl, dealloc_decl);
1999}
2000
2001/* Diagnose a call EXP to deallocate a pointer referenced by AREF if it
2002 includes a nonzero offset. Such a pointer cannot refer to the beginning
2003 of an allocated object. A negative offset may refer to it only if
2004 the target pointer is unknown. */
2005
2006static bool
2007warn_dealloc_offset (location_t loc, gimple *call, const access_ref &aref)
2008{
2009 if (aref.deref || aref.offrng[0] <= 0 || aref.offrng[1] <= 0)
2010 return false;
2011
2012 tree dealloc_decl = gimple_call_fndecl (gs: call);
2013 if (!dealloc_decl)
2014 return false;
2015
2016 if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl)
2017 && !DECL_IS_REPLACEABLE_OPERATOR (dealloc_decl))
2018 {
2019 /* A call to a user-defined operator delete with a pointer plus offset
2020 may be valid if it's returned from an unknown function (i.e., one
2021 that's not operator new). */
2022 if (TREE_CODE (aref.ref) == SSA_NAME)
2023 {
2024 gimple *def_stmt = SSA_NAME_DEF_STMT (aref.ref);
2025 if (is_gimple_call (gs: def_stmt))
2026 {
2027 tree alloc_decl = gimple_call_fndecl (gs: def_stmt);
2028 if (!alloc_decl || !DECL_IS_OPERATOR_NEW_P (alloc_decl))
2029 return false;
2030 }
2031 }
2032 }
2033
2034 char offstr[80];
2035 offstr[0] = '\0';
2036 if (wi::fits_shwi_p (x: aref.offrng[0]))
2037 {
2038 if (aref.offrng[0] == aref.offrng[1]
2039 || !wi::fits_shwi_p (x: aref.offrng[1]))
2040 sprintf (s: offstr, format: " %lli",
2041 (long long)aref.offrng[0].to_shwi ());
2042 else
2043 sprintf (s: offstr, format: " [%lli, %lli]",
2044 (long long)aref.offrng[0].to_shwi (),
2045 (long long)aref.offrng[1].to_shwi ());
2046 }
2047
2048 auto_diagnostic_group d;
2049 if (!warning_at (loc, OPT_Wfree_nonheap_object,
2050 "%qD called on pointer %qE with nonzero offset%s",
2051 dealloc_decl, aref.ref, offstr))
2052 return false;
2053
2054 if (DECL_P (aref.ref))
2055 inform (get_location (x: aref.ref), "declared here");
2056 else if (TREE_CODE (aref.ref) == SSA_NAME)
2057 {
2058 gimple *def_stmt = SSA_NAME_DEF_STMT (aref.ref);
2059 if (is_gimple_call (gs: def_stmt))
2060 {
2061 location_t def_loc = get_location (stmt: def_stmt);
2062 tree alloc_decl = gimple_call_fndecl (gs: def_stmt);
2063 if (alloc_decl)
2064 inform (def_loc,
2065 "returned from %qD", alloc_decl);
2066 else if (tree alloc_fntype = gimple_call_fntype (gs: def_stmt))
2067 inform (def_loc,
2068 "returned from %qT", alloc_fntype);
2069 else
2070 inform (def_loc, "obtained here");
2071 }
2072 }
2073
2074 return true;
2075}
2076
2077namespace {
2078
2079const pass_data pass_data_waccess = {
2080 .type: GIMPLE_PASS,
2081 .name: "waccess",
2082 .optinfo_flags: OPTGROUP_NONE,
2083 .tv_id: TV_WARN_ACCESS, /* timer variable */
2084 PROP_cfg, /* properties_required */
2085 .properties_provided: 0, /* properties_provided */
2086 .properties_destroyed: 0, /* properties_destroyed */
2087 .todo_flags_start: 0, /* properties_start */
2088 .todo_flags_finish: 0, /* properties_finish */
2089};
2090
2091/* Pass to detect invalid accesses. */
2092class pass_waccess : public gimple_opt_pass
2093{
2094 public:
2095 pass_waccess (gcc::context *);
2096
2097 ~pass_waccess ();
2098
2099 opt_pass *clone () final override;
2100
2101 bool gate (function *) final override;
2102
2103 void set_pass_param (unsigned, bool) final override;
2104
2105 unsigned int execute (function *) final override;
2106
2107private:
2108 /* Not copyable or assignable. */
2109 pass_waccess (pass_waccess &) = delete;
2110 void operator= (pass_waccess &) = delete;
2111
2112 /* Check a call to an atomic built-in function. */
2113 bool check_atomic_builtin (gcall *);
2114
2115 /* Check a call to a built-in function. */
2116 bool check_builtin (gcall *);
2117
2118 /* Check a call to an ordinary function for invalid accesses. */
2119 bool check_call_access (gcall *);
2120
2121 /* Check a non-call statement. */
2122 void check_stmt (gimple *);
2123
2124 /* Check statements in a basic block. */
2125 void check_block (basic_block);
2126
2127 /* Check a call to a function. */
2128 void check_call (gcall *);
2129
2130 /* Check a call to the named built-in function. */
2131 void check_alloca (gcall *);
2132 void check_alloc_size_call (gcall *);
2133 void check_strcat (gcall *);
2134 void check_strncat (gcall *);
2135 void check_stxcpy (gcall *);
2136 void check_stxncpy (gcall *);
2137 void check_strncmp (gcall *);
2138 void check_memop_access (gimple *, tree, tree, tree);
2139 void check_read_access (gimple *, tree, tree = NULL_TREE, int = 1);
2140
2141 void maybe_check_dealloc_call (gcall *);
2142 void maybe_check_access_sizes (rdwr_map *, tree, tree, gimple *);
2143 bool maybe_warn_memmodel (gimple *, tree, tree, const unsigned char *);
2144 void check_atomic_memmodel (gimple *, tree, tree, const unsigned char *);
2145
2146 /* Check for uses of indeterminate pointers. */
2147 void check_pointer_uses (gimple *, tree, tree = NULL_TREE, bool = false);
2148
2149 /* Return the argument that a call returns. */
2150 tree gimple_call_return_arg (gcall *);
2151
2152 /* Check a call for uses of a dangling pointer arguments. */
2153 void check_call_dangling (gcall *);
2154
2155 /* Check uses of a dangling pointer or those derived from it. */
2156 void check_dangling_uses (tree, tree, bool = false, bool = false);
2157 void check_dangling_uses ();
2158 void check_dangling_stores ();
2159 bool check_dangling_stores (basic_block, hash_set<tree> &);
2160
2161 void warn_invalid_pointer (tree, gimple *, gimple *, tree, bool, bool = false);
2162
2163 /* Return true if use follows an invalidating statement. */
2164 bool use_after_inval_p (gimple *, gimple *, bool = false);
2165
2166 /* A pointer_query object to store information about pointers and
2167 their targets in. */
2168 pointer_query m_ptr_qry;
2169 /* Mapping from DECLs and their clobber statements in the function. */
2170 hash_map<tree, gimple *> m_clobbers;
2171 /* A bit is set for each basic block whose statements have been assigned
2172 valid UIDs. */
2173 bitmap m_bb_uids_set;
2174 /* The current function. */
2175 function *m_func;
2176 /* True to run checks for uses of dangling pointers. */
2177 bool m_check_dangling_p;
2178 /* True to run checks early on in the optimization pipeline. */
2179 bool m_early_checks_p;
2180};
2181
2182/* Construct the pass. */
2183
2184pass_waccess::pass_waccess (gcc::context *ctxt)
2185 : gimple_opt_pass (pass_data_waccess, ctxt),
2186 m_ptr_qry (NULL),
2187 m_clobbers (),
2188 m_bb_uids_set (),
2189 m_func (),
2190 m_check_dangling_p (),
2191 m_early_checks_p ()
2192{
2193}
2194
2195/* Return a copy of the pass with RUN_NUMBER one greater than THIS. */
2196
2197opt_pass*
2198pass_waccess::clone ()
2199{
2200 return new pass_waccess (m_ctxt);
2201}
2202
2203/* Release pointer_query cache. */
2204
2205pass_waccess::~pass_waccess ()
2206{
2207 m_ptr_qry.flush_cache ();
2208}
2209
2210void
2211pass_waccess::set_pass_param (unsigned int n, bool early)
2212{
2213 gcc_assert (n == 0);
2214
2215 m_early_checks_p = early;
2216}
2217
2218/* Return true when any checks performed by the pass are enabled. */
2219
2220bool
2221pass_waccess::gate (function *)
2222{
2223 return (warn_free_nonheap_object
2224 || warn_mismatched_alloc
2225 || warn_mismatched_new_delete);
2226}
2227
2228/* Initialize ALLOC_OBJECT_SIZE_LIMIT based on the -Walloc-size-larger-than=
2229 setting if the option is specified, or to the maximum object size if it
2230 is not. Return the initialized value. */
2231
2232static tree
2233alloc_max_size (void)
2234{
2235 HOST_WIDE_INT limit = warn_alloc_size_limit;
2236 if (limit == HOST_WIDE_INT_MAX)
2237 limit = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
2238
2239 return build_int_cst (size_type_node, limit);
2240}
2241
2242/* Diagnose a call EXP to function FN decorated with attribute alloc_size
2243 whose argument numbers given by IDX with values given by ARGS exceed
2244 the maximum object size or cause an unsigned overflow (wrapping) when
2245 multiplied. FN is null when EXP is a call via a function pointer.
2246 When ARGS[0] is null the function does nothing. ARGS[1] may be null
2247 for functions like malloc, and non-null for those like calloc that
2248 are decorated with a two-argument attribute alloc_size. */
2249
2250void
2251maybe_warn_alloc_args_overflow (gimple *stmt, const tree args[2],
2252 const int idx[2])
2253{
2254 /* The range each of the (up to) two arguments is known to be in. */
2255 tree argrange[2][2] = { { NULL_TREE, NULL_TREE }, { NULL_TREE, NULL_TREE } };
2256
2257 /* Maximum object size set by -Walloc-size-larger-than= or SIZE_MAX / 2. */
2258 tree maxobjsize = alloc_max_size ();
2259
2260 location_t loc = get_location (stmt);
2261
2262 tree fn = gimple_call_fndecl (gs: stmt);
2263 tree fntype = fn ? TREE_TYPE (fn) : gimple_call_fntype (gs: stmt);
2264 bool warned = false;
2265
2266 /* Validate each argument individually. */
2267 for (unsigned i = 0; i != 2 && args[i]; ++i)
2268 {
2269 if (TREE_CODE (args[i]) == INTEGER_CST)
2270 {
2271 argrange[i][0] = args[i];
2272 argrange[i][1] = args[i];
2273
2274 if (tree_int_cst_lt (t1: args[i], integer_zero_node))
2275 {
2276 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2277 "argument %i value %qE is negative",
2278 idx[i] + 1, args[i]);
2279 }
2280 else if (integer_zerop (args[i]))
2281 {
2282 /* Avoid issuing -Walloc-zero for allocation functions other
2283 than __builtin_alloca that are declared with attribute
2284 returns_nonnull because there's no portability risk. This
2285 avoids warning for such calls to libiberty's xmalloc and
2286 friends.
2287 Also avoid issuing the warning for calls to function named
2288 "alloca". */
2289 if (fn && fndecl_built_in_p (node: fn, name1: BUILT_IN_ALLOCA)
2290 ? IDENTIFIER_LENGTH (DECL_NAME (fn)) != 6
2291 : !lookup_attribute (attr_name: "returns_nonnull",
2292 TYPE_ATTRIBUTES (fntype)))
2293 warned = warning_at (loc, OPT_Walloc_zero,
2294 "argument %i value is zero",
2295 idx[i] + 1);
2296 }
2297 else if (tree_int_cst_lt (t1: maxobjsize, t2: args[i]))
2298 {
2299 /* G++ emits calls to ::operator new[](SIZE_MAX) in C++98
2300 mode and with -fno-exceptions as a way to indicate array
2301 size overflow. There's no good way to detect C++98 here
2302 so avoid diagnosing these calls for all C++ modes. */
2303 if (i == 0
2304 && fn
2305 && !args[1]
2306 && lang_GNU_CXX ()
2307 && DECL_IS_OPERATOR_NEW_P (fn)
2308 && integer_all_onesp (args[i]))
2309 continue;
2310
2311 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2312 "argument %i value %qE exceeds "
2313 "maximum object size %E",
2314 idx[i] + 1, args[i], maxobjsize);
2315 }
2316 }
2317 else if (TREE_CODE (args[i]) == SSA_NAME
2318 && get_size_range (args[i], argrange[i]))
2319 {
2320 /* Verify that the argument's range is not negative (including
2321 upper bound of zero). */
2322 if (tree_int_cst_lt (t1: argrange[i][0], integer_zero_node)
2323 && tree_int_cst_le (t1: argrange[i][1], integer_zero_node))
2324 {
2325 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2326 "argument %i range [%E, %E] is negative",
2327 idx[i] + 1,
2328 argrange[i][0], argrange[i][1]);
2329 }
2330 else if (tree_int_cst_lt (t1: maxobjsize, t2: argrange[i][0]))
2331 {
2332 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2333 "argument %i range [%E, %E] exceeds "
2334 "maximum object size %E",
2335 idx[i] + 1,
2336 argrange[i][0], argrange[i][1],
2337 maxobjsize);
2338 }
2339 }
2340 }
2341
2342 if (!argrange[0][0])
2343 return;
2344
2345 /* For a two-argument alloc_size, validate the product of the two
2346 arguments if both of their values or ranges are known. */
2347 if (!warned && tree_fits_uhwi_p (argrange[0][0])
2348 && argrange[1][0] && tree_fits_uhwi_p (argrange[1][0])
2349 && !integer_onep (argrange[0][0])
2350 && !integer_onep (argrange[1][0]))
2351 {
2352 /* Check for overflow in the product of a function decorated with
2353 attribute alloc_size (X, Y). */
2354 unsigned szprec = TYPE_PRECISION (size_type_node);
2355 wide_int x = wi::to_wide (t: argrange[0][0], prec: szprec);
2356 wide_int y = wi::to_wide (t: argrange[1][0], prec: szprec);
2357
2358 wi::overflow_type vflow;
2359 wide_int prod = wi::umul (x, y, overflow: &vflow);
2360
2361 if (vflow)
2362 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2363 "product %<%E * %E%> of arguments %i and %i "
2364 "exceeds %<SIZE_MAX%>",
2365 argrange[0][0], argrange[1][0],
2366 idx[0] + 1, idx[1] + 1);
2367 else if (wi::ltu_p (x: wi::to_wide (t: maxobjsize, prec: szprec), y: prod))
2368 warned = warning_at (loc, OPT_Walloc_size_larger_than_,
2369 "product %<%E * %E%> of arguments %i and %i "
2370 "exceeds maximum object size %E",
2371 argrange[0][0], argrange[1][0],
2372 idx[0] + 1, idx[1] + 1,
2373 maxobjsize);
2374
2375 if (warned)
2376 {
2377 /* Print the full range of each of the two arguments to make
2378 it clear when it is, in fact, in a range and not constant. */
2379 if (argrange[0][0] != argrange [0][1])
2380 inform (loc, "argument %i in the range [%E, %E]",
2381 idx[0] + 1, argrange[0][0], argrange[0][1]);
2382 if (argrange[1][0] != argrange [1][1])
2383 inform (loc, "argument %i in the range [%E, %E]",
2384 idx[1] + 1, argrange[1][0], argrange[1][1]);
2385 }
2386 }
2387
2388 if (warned && fn)
2389 {
2390 location_t fnloc = DECL_SOURCE_LOCATION (fn);
2391
2392 if (DECL_IS_UNDECLARED_BUILTIN (fn))
2393 inform (loc,
2394 "in a call to built-in allocation function %qD", fn);
2395 else
2396 inform (fnloc,
2397 "in a call to allocation function %qD declared here", fn);
2398 }
2399}
2400
2401/* Check a call to an alloca function for an excessive size. */
2402
2403void
2404pass_waccess::check_alloca (gcall *stmt)
2405{
2406 if (m_early_checks_p)
2407 return;
2408
2409 if ((warn_vla_limit >= HOST_WIDE_INT_MAX
2410 && warn_alloc_size_limit < warn_vla_limit)
2411 || (warn_alloca_limit >= HOST_WIDE_INT_MAX
2412 && warn_alloc_size_limit < warn_alloca_limit))
2413 {
2414 /* -Walloca-larger-than and -Wvla-larger-than settings of less
2415 than HWI_MAX override the more general -Walloc-size-larger-than
2416 so unless either of the former options is smaller than the last
2417 one (which would imply that the call was already checked), check
2418 the alloca arguments for overflow. */
2419 const tree alloc_args[] = { call_arg (stmt, argno: 0), NULL_TREE };
2420 const int idx[] = { 0, -1 };
2421 maybe_warn_alloc_args_overflow (stmt, args: alloc_args, idx);
2422 }
2423}
2424
2425/* Check a call to an allocation function for an excessive size. */
2426
2427void
2428pass_waccess::check_alloc_size_call (gcall *stmt)
2429{
2430 if (m_early_checks_p)
2431 return;
2432
2433 if (gimple_call_num_args (gs: stmt) < 1)
2434 /* Avoid invalid calls to functions without a prototype. */
2435 return;
2436
2437 tree fndecl = gimple_call_fndecl (gs: stmt);
2438 if (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
2439 {
2440 /* Alloca is handled separately. */
2441 switch (DECL_FUNCTION_CODE (decl: fndecl))
2442 {
2443 case BUILT_IN_ALLOCA:
2444 case BUILT_IN_ALLOCA_WITH_ALIGN:
2445 case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
2446 return;
2447 default:
2448 break;
2449 }
2450 }
2451
2452 tree fntype = gimple_call_fntype (gs: stmt);
2453 tree fntypeattrs = TYPE_ATTRIBUTES (fntype);
2454
2455 tree alloc_size = lookup_attribute (attr_name: "alloc_size", list: fntypeattrs);
2456 if (!alloc_size)
2457 return;
2458
2459 /* Extract attribute alloc_size from the type of the called expression
2460 (which could be a function or a function pointer) and if set, store
2461 the indices of the corresponding arguments in ALLOC_IDX, and then
2462 the actual argument(s) at those indices in ALLOC_ARGS. */
2463 int idx[2] = { -1, -1 };
2464 tree alloc_args[] = { NULL_TREE, NULL_TREE };
2465 unsigned nargs = gimple_call_num_args (gs: stmt);
2466
2467 tree args = TREE_VALUE (alloc_size);
2468 idx[0] = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1;
2469 /* Avoid invalid calls to functions without a prototype. */
2470 if ((unsigned) idx[0] >= nargs)
2471 return;
2472 alloc_args[0] = call_arg (stmt, argno: idx[0]);
2473 if (TREE_CHAIN (args))
2474 {
2475 idx[1] = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1;
2476 if ((unsigned) idx[1] >= nargs)
2477 return;
2478 alloc_args[1] = call_arg (stmt, argno: idx[1]);
2479 }
2480
2481 maybe_warn_alloc_args_overflow (stmt, args: alloc_args, idx);
2482}
2483
2484/* Check a call STMT to strcat() for overflow and warn if it does. */
2485
2486void
2487pass_waccess::check_strcat (gcall *stmt)
2488{
2489 if (m_early_checks_p)
2490 return;
2491
2492 if (!warn_stringop_overflow && !warn_stringop_overread)
2493 return;
2494
2495 tree dest = call_arg (stmt, argno: 0);
2496 tree src = call_arg (stmt, argno: 1);
2497
2498 /* There is no way here to determine the length of the string in
2499 the destination to which the SRC string is being appended so
2500 just diagnose cases when the source string is longer than
2501 the destination object. */
2502 access_data data (m_ptr_qry.rvals, stmt, access_read_write, NULL_TREE,
2503 true, NULL_TREE, true);
2504 const int ost = warn_stringop_overflow ? warn_stringop_overflow - 1 : 1;
2505 compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
2506 tree destsize = compute_objsize (dest, stmt, ost, &data.dst, &m_ptr_qry);
2507
2508 check_access (exp: stmt, /*dstwrite=*/NULL_TREE, /*maxread=*/NULL_TREE,
2509 srcstr: src, dstsize: destsize, mode: data.mode, pad: &data, rvals: m_ptr_qry.rvals);
2510}
2511
2512/* Check a call STMT to strcat() for overflow and warn if it does. */
2513
2514void
2515pass_waccess::check_strncat (gcall *stmt)
2516{
2517 if (m_early_checks_p)
2518 return;
2519
2520 if (!warn_stringop_overflow && !warn_stringop_overread)
2521 return;
2522
2523 tree dest = call_arg (stmt, argno: 0);
2524 tree src = call_arg (stmt, argno: 1);
2525 /* The upper bound on the number of bytes to write. */
2526 tree maxread = call_arg (stmt, argno: 2);
2527
2528 /* Detect unterminated source (only). */
2529 if (!check_nul_terminated_array (expr: stmt, src, bound: maxread))
2530 return;
2531
2532 /* The length of the source sequence. */
2533 tree slen = c_strlen (src, 1);
2534
2535 /* Try to determine the range of lengths that the source expression
2536 refers to. Since the lengths are only used for warning and not
2537 for code generation disable strict mode below. */
2538 tree maxlen = slen;
2539 if (!maxlen)
2540 {
2541 c_strlen_data lendata = { };
2542 get_range_strlen (src, &lendata, /* eltsize = */ 1);
2543 maxlen = lendata.maxbound;
2544 }
2545
2546 access_data data (m_ptr_qry.rvals, stmt, access_read_write);
2547 /* Try to verify that the destination is big enough for the shortest
2548 string. First try to determine the size of the destination object
2549 into which the source is being copied. */
2550 const int ost = warn_stringop_overflow - 1;
2551 tree destsize = compute_objsize (dest, stmt, ost, &data.dst, &m_ptr_qry);
2552
2553 /* Add one for the terminating nul. */
2554 tree srclen = (maxlen
2555 ? fold_build2 (PLUS_EXPR, size_type_node, maxlen,
2556 size_one_node)
2557 : NULL_TREE);
2558
2559 /* The strncat function copies at most MAXREAD bytes and always appends
2560 the terminating nul so the specified upper bound should never be equal
2561 to (or greater than) the size of the destination. */
2562 if (tree_fits_uhwi_p (maxread) && tree_fits_uhwi_p (destsize)
2563 && tree_int_cst_equal (destsize, maxread))
2564 {
2565 location_t loc = get_location (stmt);
2566 warning_at (loc, OPT_Wstringop_overflow_,
2567 "%qD specified bound %E equals destination size",
2568 get_callee_fndecl (stmt), maxread);
2569
2570 return;
2571 }
2572
2573 if (!srclen
2574 || (maxread && tree_fits_uhwi_p (maxread)
2575 && tree_fits_uhwi_p (srclen)
2576 && tree_int_cst_lt (t1: maxread, t2: srclen)))
2577 srclen = maxread;
2578
2579 check_access (exp: stmt, /*dstwrite=*/NULL_TREE, maxread, srcstr: srclen,
2580 dstsize: destsize, mode: data.mode, pad: &data, rvals: m_ptr_qry.rvals);
2581}
2582
2583/* Check a call STMT to stpcpy() or strcpy() for overflow and warn
2584 if it does. */
2585
2586void
2587pass_waccess::check_stxcpy (gcall *stmt)
2588{
2589 if (m_early_checks_p)
2590 return;
2591
2592 tree dst = call_arg (stmt, argno: 0);
2593 tree src = call_arg (stmt, argno: 1);
2594
2595 tree size;
2596 bool exact;
2597 if (tree nonstr = unterminated_array (exp: src, size: &size, exact: &exact))
2598 {
2599 /* NONSTR refers to the non-nul terminated constant array. */
2600 warn_string_no_nul (loc: get_location (stmt), stmt, NULL, arg: src, decl: nonstr,
2601 size, exact);
2602 return;
2603 }
2604
2605 if (warn_stringop_overflow)
2606 {
2607 access_data data (m_ptr_qry.rvals, stmt, access_read_write, NULL_TREE,
2608 true, NULL_TREE, true);
2609 const int ost = warn_stringop_overflow ? warn_stringop_overflow - 1 : 1;
2610 compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
2611 tree dstsize = compute_objsize (dst, stmt, ost, &data.dst, &m_ptr_qry);
2612 check_access (exp: stmt, /*dstwrite=*/ NULL_TREE,
2613 /*maxread=*/ NULL_TREE, /*srcstr=*/ src,
2614 dstsize, mode: data.mode, pad: &data, rvals: m_ptr_qry.rvals);
2615 }
2616
2617 /* Check to see if the argument was declared attribute nonstring
2618 and if so, issue a warning since at this point it's not known
2619 to be nul-terminated. */
2620 tree fndecl = get_callee_fndecl (stmt);
2621 maybe_warn_nonstring_arg (fndecl, exp: stmt);
2622}
2623
2624/* Check a call STMT to stpncpy() or strncpy() for overflow and warn
2625 if it does. */
2626
2627void
2628pass_waccess::check_stxncpy (gcall *stmt)
2629{
2630 if (m_early_checks_p || !warn_stringop_overflow)
2631 return;
2632
2633 tree dst = call_arg (stmt, argno: 0);
2634 tree src = call_arg (stmt, argno: 1);
2635 /* The number of bytes to write (not the maximum). */
2636 tree len = call_arg (stmt, argno: 2);
2637
2638 access_data data (m_ptr_qry.rvals, stmt, access_read_write, len, true, len,
2639 true);
2640 const int ost = warn_stringop_overflow ? warn_stringop_overflow - 1 : 1;
2641 compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
2642 tree dstsize = compute_objsize (dst, stmt, ost, &data.dst, &m_ptr_qry);
2643
2644 check_access (exp: stmt, /*dstwrite=*/len, /*maxread=*/len, srcstr: src, dstsize,
2645 mode: data.mode, pad: &data, rvals: m_ptr_qry.rvals);
2646}
2647
2648/* Check a call STMT to stpncpy() or strncpy() for overflow and warn
2649 if it does. */
2650
2651void
2652pass_waccess::check_strncmp (gcall *stmt)
2653{
2654 if (m_early_checks_p || !warn_stringop_overread)
2655 return;
2656
2657 tree arg1 = call_arg (stmt, argno: 0);
2658 tree arg2 = call_arg (stmt, argno: 1);
2659 tree bound = call_arg (stmt, argno: 2);
2660
2661 /* First check each argument separately, considering the bound. */
2662 if (!check_nul_terminated_array (expr: stmt, src: arg1, bound)
2663 || !check_nul_terminated_array (expr: stmt, src: arg2, bound))
2664 return;
2665
2666 /* A strncmp read from each argument is constrained not just by
2667 the bound but also by the length of the shorter string. Specifying
2668 a bound that's larger than the size of either array makes no sense
2669 and is likely a bug. When the length of neither of the two strings
2670 is known but the sizes of both of the arrays they are stored in is,
2671 issue a warning if the bound is larger than the size of
2672 the larger of the two arrays. */
2673
2674 c_strlen_data lendata1{ }, lendata2{ };
2675 tree len1 = c_strlen (arg1, 1, &lendata1);
2676 tree len2 = c_strlen (arg2, 1, &lendata2);
2677
2678 if (len1 && TREE_CODE (len1) != INTEGER_CST)
2679 len1 = NULL_TREE;
2680 if (len2 && TREE_CODE (len2) != INTEGER_CST)
2681 len2 = NULL_TREE;
2682
2683 if (len1 && len2)
2684 /* If the length of both arguments was computed they must both be
2685 nul-terminated and no further checking is necessary regardless
2686 of the bound. */
2687 return;
2688
2689 /* Check to see if the argument was declared with attribute nonstring
2690 and if so, issue a warning since at this point it's not known to be
2691 nul-terminated. */
2692 if (maybe_warn_nonstring_arg (fndecl: get_callee_fndecl (stmt), exp: stmt))
2693 return;
2694
2695 access_data adata1 (m_ptr_qry.rvals, stmt, access_read_only, NULL_TREE, false,
2696 bound, true);
2697 access_data adata2 (m_ptr_qry.rvals, stmt, access_read_only, NULL_TREE, false,
2698 bound, true);
2699
2700 /* Determine the range of the bound first and bail if it fails; it's
2701 cheaper than computing the size of the objects. */
2702 tree bndrng[2] = { NULL_TREE, NULL_TREE };
2703 get_size_range (query: m_ptr_qry.rvals, bound, stmt, range: bndrng, flags: 0, bndrng: adata1.src_bndrng);
2704 if (!bndrng[0] || integer_zerop (bndrng[0]))
2705 return;
2706
2707 if (len1 && tree_int_cst_lt (t1: len1, t2: bndrng[0]))
2708 bndrng[0] = len1;
2709 if (len2 && tree_int_cst_lt (t1: len2, t2: bndrng[0]))
2710 bndrng[0] = len2;
2711
2712 /* compute_objsize almost never fails (and ultimately should never
2713 fail). Don't bother to handle the rare case when it does. */
2714 if (!compute_objsize (arg1, stmt, 1, &adata1.src, &m_ptr_qry)
2715 || !compute_objsize (arg2, stmt, 1, &adata2.src, &m_ptr_qry))
2716 return;
2717
2718 /* Compute the size of the remaining space in each array after
2719 subtracting any offset into it. */
2720 offset_int rem1 = adata1.src.size_remaining ();
2721 offset_int rem2 = adata2.src.size_remaining ();
2722
2723 /* Cap REM1 and REM2 at the other if the other's argument is known
2724 to be an unterminated array, either because there's no space
2725 left in it after adding its offset or because it's constant and
2726 has no nul. */
2727 if (rem1 == 0 || (rem1 < rem2 && lendata1.decl))
2728 rem2 = rem1;
2729 else if (rem2 == 0 || (rem2 < rem1 && lendata2.decl))
2730 rem1 = rem2;
2731
2732 /* Point PAD at the array to reference in the note if a warning
2733 is issued. */
2734 access_data *pad = len1 ? &adata2 : &adata1;
2735 offset_int maxrem = wi::max (x: rem1, y: rem2, sgn: UNSIGNED);
2736 if (lendata1.decl || lendata2.decl
2737 || maxrem < wi::to_offset (t: bndrng[0]))
2738 {
2739 /* Warn when either argument isn't nul-terminated or the maximum
2740 remaining space in the two arrays is less than the bound. */
2741 tree func = get_callee_fndecl (stmt);
2742 location_t loc = gimple_location (g: stmt);
2743 maybe_warn_for_bound (opt: OPT_Wstringop_overread, loc, exp: stmt, func,
2744 bndrng, size: wide_int_to_tree (sizetype, cst: maxrem),
2745 pad);
2746 }
2747}
2748
2749/* Determine and check the sizes of the source and the destination
2750 of calls to __builtin_{bzero,memcpy,mempcpy,memset} calls. STMT is
2751 the call statement, DEST is the destination argument, SRC is the source
2752 argument or null, and SIZE is the number of bytes being accessed. Use
2753 Object Size type-0 regardless of the OPT_Wstringop_overflow_ setting.
2754 Return true on success (no overflow or invalid sizes), false otherwise. */
2755
2756void
2757pass_waccess::check_memop_access (gimple *stmt, tree dest, tree src, tree size)
2758{
2759 if (m_early_checks_p)
2760 return;
2761
2762 /* For functions like memset and memcpy that operate on raw memory
2763 try to determine the size of the largest source and destination
2764 object using type-0 Object Size regardless of the object size
2765 type specified by the option. */
2766 access_data data (m_ptr_qry.rvals, stmt, access_read_write);
2767 tree srcsize
2768 = src ? compute_objsize (src, stmt, 0, &data.src, &m_ptr_qry) : NULL_TREE;
2769 tree dstsize = compute_objsize (dest, stmt, 0, &data.dst, &m_ptr_qry);
2770
2771 check_access (stmt, dstwrite: size, /*maxread=*/NULL_TREE, srcstr: srcsize, dstsize,
2772 mode: data.mode, pad: &data, rvals: m_ptr_qry.rvals);
2773}
2774
2775/* A convenience wrapper for check_access to check access by a read-only
2776 function like puts or strcmp. */
2777
2778void
2779pass_waccess::check_read_access (gimple *stmt, tree src,
2780 tree bound /* = NULL_TREE */,
2781 int ost /* = 1 */)
2782{
2783 if (m_early_checks_p || !warn_stringop_overread)
2784 return;
2785
2786 if (bound && !useless_type_conversion_p (size_type_node, TREE_TYPE (bound)))
2787 bound = fold_convert (size_type_node, bound);
2788
2789 tree fndecl = get_callee_fndecl (stmt);
2790 maybe_warn_nonstring_arg (fndecl, stmt);
2791
2792 access_data data (m_ptr_qry.rvals, stmt, access_read_only, NULL_TREE,
2793 false, bound, true);
2794 compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
2795 check_access (stmt, /*dstwrite=*/ NULL_TREE, /*maxread=*/ bound,
2796 /*srcstr=*/ src, /*dstsize=*/ NULL_TREE, mode: data.mode,
2797 pad: &data, rvals: m_ptr_qry.rvals);
2798}
2799
2800/* Return true if memory model ORD is constant in the context of STMT and
2801 set *CSTVAL to the constant value. Otherwise return false. Warn for
2802 invalid ORD. */
2803
2804bool
2805memmodel_to_uhwi (tree ord, gimple *stmt, unsigned HOST_WIDE_INT *cstval)
2806{
2807 unsigned HOST_WIDE_INT val;
2808
2809 if (TREE_CODE (ord) == INTEGER_CST)
2810 {
2811 if (!tree_fits_uhwi_p (ord))
2812 return false;
2813 val = tree_to_uhwi (ord);
2814 }
2815 else
2816 {
2817 /* Use the range query to determine constant values in the absence
2818 of constant propagation (such as at -O0). */
2819 Value_Range rng (TREE_TYPE (ord));
2820 if (!get_range_query (cfun)->range_of_expr (r&: rng, expr: ord, stmt)
2821 || !rng.singleton_p (result: &ord))
2822 return false;
2823
2824 wide_int lob = rng.lower_bound ();
2825 if (!wi::fits_uhwi_p (x: lob))
2826 return false;
2827
2828 val = lob.to_shwi ();
2829 }
2830
2831 if (targetm.memmodel_check)
2832 /* This might warn for an invalid VAL but return a conservatively
2833 valid result. */
2834 val = targetm.memmodel_check (val);
2835 else if (val & ~MEMMODEL_MASK)
2836 {
2837 tree fndecl = gimple_call_fndecl (gs: stmt);
2838 location_t loc = gimple_location (g: stmt);
2839 loc = expansion_point_location_if_in_system_header (loc);
2840
2841 warning_at (loc, OPT_Winvalid_memory_model,
2842 "unknown architecture specifier in memory model "
2843 "%wi for %qD", val, fndecl);
2844 return false;
2845 }
2846
2847 *cstval = val;
2848
2849 return true;
2850}
2851
2852/* Valid memory model for each set of atomic built-in functions. */
2853
2854struct memmodel_pair
2855{
2856 memmodel modval;
2857 const char* modname;
2858
2859#define MEMMODEL_PAIR(val, str) \
2860 { MEMMODEL_ ## val, "memory_order_" str }
2861};
2862
2863/* Valid memory models in the order of increasing strength. */
2864
2865static const memmodel_pair memory_models[] =
2866 { MEMMODEL_PAIR (RELAXED, "relaxed"),
2867 MEMMODEL_PAIR (SEQ_CST, "seq_cst"),
2868 MEMMODEL_PAIR (ACQUIRE, "acquire"),
2869 MEMMODEL_PAIR (CONSUME, "consume"),
2870 MEMMODEL_PAIR (RELEASE, "release"),
2871 MEMMODEL_PAIR (ACQ_REL, "acq_rel")
2872 };
2873
2874/* Return the name of the memory model VAL. */
2875
2876static const char*
2877memmodel_name (unsigned HOST_WIDE_INT val)
2878{
2879 val = memmodel_base (val);
2880
2881 for (unsigned i = 0; i != ARRAY_SIZE (memory_models); ++i)
2882 {
2883 if (val == memory_models[i].modval)
2884 return memory_models[i].modname;
2885 }
2886 return NULL;
2887}
2888
2889/* Indices of valid MEMORY_MODELS above for corresponding atomic operations. */
2890static const unsigned char load_models[] = { 0, 1, 2, 3, UCHAR_MAX };
2891static const unsigned char store_models[] = { 0, 1, 4, UCHAR_MAX };
2892static const unsigned char xchg_models[] = { 0, 1, 3, 4, 5, UCHAR_MAX };
2893static const unsigned char flag_clr_models[] = { 0, 1, 4, UCHAR_MAX };
2894static const unsigned char all_models[] = { 0, 1, 2, 3, 4, 5, UCHAR_MAX };
2895
2896/* Check the success memory model argument ORD_SUCS to the call STMT to
2897 an atomic function and warn if it's invalid. If nonnull, also check
2898 the failure memory model ORD_FAIL and warn if it's invalid. Return
2899 true if a warning has been issued. */
2900
2901bool
2902pass_waccess::maybe_warn_memmodel (gimple *stmt, tree ord_sucs,
2903 tree ord_fail, const unsigned char *valid)
2904{
2905 unsigned HOST_WIDE_INT sucs, fail = 0;
2906 if (!memmodel_to_uhwi (ord: ord_sucs, stmt, cstval: &sucs)
2907 || (ord_fail && !memmodel_to_uhwi (ord: ord_fail, stmt, cstval: &fail)))
2908 return false;
2909
2910 bool is_valid = false;
2911 if (valid)
2912 for (unsigned i = 0; valid[i] != UCHAR_MAX; ++i)
2913 {
2914 memmodel model = memory_models[valid[i]].modval;
2915 if (memmodel_base (val: sucs) == model)
2916 {
2917 is_valid = true;
2918 break;
2919 }
2920 }
2921 else
2922 is_valid = true;
2923
2924 tree fndecl = gimple_call_fndecl (gs: stmt);
2925 location_t loc = gimple_location (g: stmt);
2926 loc = expansion_point_location_if_in_system_header (loc);
2927
2928 if (!is_valid)
2929 {
2930 bool warned = false;
2931 auto_diagnostic_group d;
2932 if (const char *modname = memmodel_name (val: sucs))
2933 warned = warning_at (loc, OPT_Winvalid_memory_model,
2934 "invalid memory model %qs for %qD",
2935 modname, fndecl);
2936 else
2937 warned = warning_at (loc, OPT_Winvalid_memory_model,
2938 "invalid memory model %wi for %qD",
2939 sucs, fndecl);
2940
2941 if (!warned)
2942 return false;
2943
2944 /* Print a note with the valid memory models. */
2945 pretty_printer pp;
2946 pp_show_color (&pp) = pp_show_color (global_dc->printer);
2947 for (unsigned i = 0; valid[i] != UCHAR_MAX; ++i)
2948 {
2949 const char *modname = memory_models[valid[i]].modname;
2950 pp_printf (&pp, "%s%qs", i ? ", " : "", modname);
2951 }
2952
2953 inform (loc, "valid models are %s", pp_formatted_text (&pp));
2954 return true;
2955 }
2956
2957 if (!ord_fail)
2958 return false;
2959
2960 if (fail == MEMMODEL_RELEASE || fail == MEMMODEL_ACQ_REL)
2961 if (const char *failname = memmodel_name (val: fail))
2962 {
2963 /* If both memory model arguments are valid but their combination
2964 is not, use their names in the warning. */
2965 auto_diagnostic_group d;
2966 if (!warning_at (loc, OPT_Winvalid_memory_model,
2967 "invalid failure memory model %qs for %qD",
2968 failname, fndecl))
2969 return false;
2970
2971 inform (loc,
2972 "valid failure models are %qs, %qs, %qs, %qs",
2973 "memory_order_relaxed", "memory_order_seq_cst",
2974 "memory_order_acquire", "memory_order_consume");
2975 return true;
2976 }
2977
2978 if (memmodel_base (val: fail) <= memmodel_base (val: sucs))
2979 return false;
2980
2981 if (const char *sucsname = memmodel_name (val: sucs))
2982 if (const char *failname = memmodel_name (val: fail))
2983 {
2984 /* If both memory model arguments are valid but their combination
2985 is not, use their names in the warning. */
2986 auto_diagnostic_group d;
2987 if (!warning_at (loc, OPT_Winvalid_memory_model,
2988 "failure memory model %qs cannot be stronger "
2989 "than success memory model %qs for %qD",
2990 failname, sucsname, fndecl))
2991 return false;
2992
2993 /* Print a note with the valid failure memory models which are
2994 those with a value less than or equal to the success mode. */
2995 char buf[120];
2996 *buf = '\0';
2997 for (unsigned i = 0;
2998 memory_models[i].modval <= memmodel_base (val: sucs); ++i)
2999 {
3000 if (*buf)
3001 strcat (dest: buf, src: ", ");
3002
3003 const char *modname = memory_models[valid[i]].modname;
3004 sprintf (s: buf + strlen (s: buf), format: "'%s'", modname);
3005 }
3006
3007 inform (loc, "valid models are %s", buf);
3008 return true;
3009 }
3010
3011 /* If either memory model argument value is invalid use the numerical
3012 value of both in the message. */
3013 return warning_at (loc, OPT_Winvalid_memory_model,
3014 "failure memory model %wi cannot be stronger "
3015 "than success memory model %wi for %qD",
3016 fail, sucs, fndecl);
3017}
3018
3019/* Wrapper for the above. */
3020
3021void
3022pass_waccess::check_atomic_memmodel (gimple *stmt, tree ord_sucs,
3023 tree ord_fail, const unsigned char *valid)
3024{
3025 if (warning_suppressed_p (stmt, OPT_Winvalid_memory_model))
3026 return;
3027
3028 if (!maybe_warn_memmodel (stmt, ord_sucs, ord_fail, valid))
3029 return;
3030
3031 suppress_warning (stmt, OPT_Winvalid_memory_model);
3032}
3033
3034/* Check a call STMT to an atomic or sync built-in. */
3035
3036bool
3037pass_waccess::check_atomic_builtin (gcall *stmt)
3038{
3039 tree callee = gimple_call_fndecl (gs: stmt);
3040 if (!callee)
3041 return false;
3042
3043 /* The size in bytes of the access by the function, and the number
3044 of the second argument to check (if any). */
3045 unsigned bytes = 0, arg2 = UINT_MAX;
3046 unsigned sucs_arg = UINT_MAX, fail_arg = UINT_MAX;
3047 /* Points to the array of indices of valid memory models. */
3048 const unsigned char *pvalid_models = NULL;
3049
3050 switch (DECL_FUNCTION_CODE (decl: callee))
3051 {
3052#define BUILTIN_ACCESS_SIZE_FNSPEC(N) \
3053 BUILT_IN_SYNC_FETCH_AND_ADD_ ## N: \
3054 case BUILT_IN_SYNC_FETCH_AND_SUB_ ## N: \
3055 case BUILT_IN_SYNC_FETCH_AND_OR_ ## N: \
3056 case BUILT_IN_SYNC_FETCH_AND_AND_ ## N: \
3057 case BUILT_IN_SYNC_FETCH_AND_XOR_ ## N: \
3058 case BUILT_IN_SYNC_FETCH_AND_NAND_ ## N: \
3059 case BUILT_IN_SYNC_ADD_AND_FETCH_ ## N: \
3060 case BUILT_IN_SYNC_SUB_AND_FETCH_ ## N: \
3061 case BUILT_IN_SYNC_OR_AND_FETCH_ ## N: \
3062 case BUILT_IN_SYNC_AND_AND_FETCH_ ## N: \
3063 case BUILT_IN_SYNC_XOR_AND_FETCH_ ## N: \
3064 case BUILT_IN_SYNC_NAND_AND_FETCH_ ## N: \
3065 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_ ## N: \
3066 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_ ## N: \
3067 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_ ## N: \
3068 case BUILT_IN_SYNC_LOCK_RELEASE_ ## N: \
3069 bytes = N; \
3070 break; \
3071 case BUILT_IN_ATOMIC_LOAD_ ## N: \
3072 pvalid_models = load_models; \
3073 sucs_arg = 1; \
3074 /* FALLTHROUGH */ \
3075 case BUILT_IN_ATOMIC_STORE_ ## N: \
3076 if (!pvalid_models) \
3077 pvalid_models = store_models; \
3078 /* FALLTHROUGH */ \
3079 case BUILT_IN_ATOMIC_ADD_FETCH_ ## N: \
3080 case BUILT_IN_ATOMIC_SUB_FETCH_ ## N: \
3081 case BUILT_IN_ATOMIC_AND_FETCH_ ## N: \
3082 case BUILT_IN_ATOMIC_NAND_FETCH_ ## N: \
3083 case BUILT_IN_ATOMIC_XOR_FETCH_ ## N: \
3084 case BUILT_IN_ATOMIC_OR_FETCH_ ## N: \
3085 case BUILT_IN_ATOMIC_FETCH_ADD_ ## N: \
3086 case BUILT_IN_ATOMIC_FETCH_SUB_ ## N: \
3087 case BUILT_IN_ATOMIC_FETCH_AND_ ## N: \
3088 case BUILT_IN_ATOMIC_FETCH_NAND_ ## N: \
3089 case BUILT_IN_ATOMIC_FETCH_OR_ ## N: \
3090 case BUILT_IN_ATOMIC_FETCH_XOR_ ## N: \
3091 bytes = N; \
3092 if (sucs_arg == UINT_MAX) \
3093 sucs_arg = 2; \
3094 if (!pvalid_models) \
3095 pvalid_models = all_models; \
3096 break; \
3097 case BUILT_IN_ATOMIC_EXCHANGE_ ## N: \
3098 bytes = N; \
3099 sucs_arg = 3; \
3100 pvalid_models = xchg_models; \
3101 break; \
3102 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_ ## N: \
3103 bytes = N; \
3104 sucs_arg = 4; \
3105 fail_arg = 5; \
3106 pvalid_models = all_models; \
3107 arg2 = 1
3108
3109 case BUILTIN_ACCESS_SIZE_FNSPEC (1);
3110 break;
3111 case BUILTIN_ACCESS_SIZE_FNSPEC (2);
3112 break;
3113 case BUILTIN_ACCESS_SIZE_FNSPEC (4);
3114 break;
3115 case BUILTIN_ACCESS_SIZE_FNSPEC (8);
3116 break;
3117 case BUILTIN_ACCESS_SIZE_FNSPEC (16);
3118 break;
3119
3120 case BUILT_IN_ATOMIC_CLEAR:
3121 sucs_arg = 1;
3122 pvalid_models = flag_clr_models;
3123 break;
3124
3125 default:
3126 return false;
3127 }
3128
3129 unsigned nargs = gimple_call_num_args (gs: stmt);
3130 if (sucs_arg < nargs)
3131 {
3132 tree ord_sucs = gimple_call_arg (gs: stmt, index: sucs_arg);
3133 tree ord_fail = NULL_TREE;
3134 if (fail_arg < nargs)
3135 ord_fail = gimple_call_arg (gs: stmt, index: fail_arg);
3136 check_atomic_memmodel (stmt, ord_sucs, ord_fail, valid: pvalid_models);
3137 }
3138
3139 if (!bytes)
3140 return true;
3141
3142 tree size = build_int_cstu (sizetype, bytes);
3143 tree dst = gimple_call_arg (gs: stmt, index: 0);
3144 check_memop_access (stmt, dest: dst, NULL_TREE, size);
3145
3146 if (arg2 != UINT_MAX)
3147 {
3148 tree dst = gimple_call_arg (gs: stmt, index: arg2);
3149 check_memop_access (stmt, dest: dst, NULL_TREE, size);
3150 }
3151
3152 return true;
3153}
3154
3155/* Check call STMT to a built-in function for invalid accesses. Return
3156 true if a call has been handled. */
3157
3158bool
3159pass_waccess::check_builtin (gcall *stmt)
3160{
3161 tree callee = gimple_call_fndecl (gs: stmt);
3162 if (!callee)
3163 return false;
3164
3165 switch (DECL_FUNCTION_CODE (decl: callee))
3166 {
3167 case BUILT_IN_ALLOCA:
3168 case BUILT_IN_ALLOCA_WITH_ALIGN:
3169 case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
3170 check_alloca (stmt);
3171 return true;
3172
3173 case BUILT_IN_EXECL:
3174 case BUILT_IN_EXECLE:
3175 case BUILT_IN_EXECLP:
3176 case BUILT_IN_EXECV:
3177 case BUILT_IN_EXECVE:
3178 case BUILT_IN_EXECVP:
3179 check_read_access (stmt, src: call_arg (stmt, argno: 0));
3180 return true;
3181
3182 case BUILT_IN_FREE:
3183 case BUILT_IN_REALLOC:
3184 if (!m_early_checks_p)
3185 {
3186 tree arg = call_arg (stmt, argno: 0);
3187 if (TREE_CODE (arg) == SSA_NAME)
3188 check_pointer_uses (stmt, arg);
3189 }
3190 return true;
3191
3192 case BUILT_IN_GETTEXT:
3193 case BUILT_IN_PUTS:
3194 case BUILT_IN_PUTS_UNLOCKED:
3195 case BUILT_IN_STRDUP:
3196 check_read_access (stmt, src: call_arg (stmt, argno: 0));
3197 return true;
3198
3199 case BUILT_IN_INDEX:
3200 case BUILT_IN_RINDEX:
3201 case BUILT_IN_STRCHR:
3202 case BUILT_IN_STRRCHR:
3203 case BUILT_IN_STRLEN:
3204 check_read_access (stmt, src: call_arg (stmt, argno: 0));
3205 return true;
3206
3207 case BUILT_IN_FPUTS:
3208 case BUILT_IN_FPUTS_UNLOCKED:
3209 check_read_access (stmt, src: call_arg (stmt, argno: 0));
3210 return true;
3211
3212 case BUILT_IN_STRNDUP:
3213 case BUILT_IN_STRNLEN:
3214 {
3215 tree str = call_arg (stmt, argno: 0);
3216 tree len = call_arg (stmt, argno: 1);
3217 check_read_access (stmt, src: str, bound: len);
3218 return true;
3219 }
3220
3221 case BUILT_IN_STRCAT:
3222 check_strcat (stmt);
3223 return true;
3224
3225 case BUILT_IN_STRNCAT:
3226 check_strncat (stmt);
3227 return true;
3228
3229 case BUILT_IN_STPCPY:
3230 case BUILT_IN_STRCPY:
3231 check_stxcpy (stmt);
3232 return true;
3233
3234 case BUILT_IN_STPNCPY:
3235 case BUILT_IN_STRNCPY:
3236 check_stxncpy (stmt);
3237 return true;
3238
3239 case BUILT_IN_STRCASECMP:
3240 case BUILT_IN_STRCMP:
3241 case BUILT_IN_STRPBRK:
3242 case BUILT_IN_STRSPN:
3243 case BUILT_IN_STRCSPN:
3244 case BUILT_IN_STRSTR:
3245 check_read_access (stmt, src: call_arg (stmt, argno: 0));
3246 check_read_access (stmt, src: call_arg (stmt, argno: 1));
3247 return true;
3248
3249 case BUILT_IN_STRNCASECMP:
3250 case BUILT_IN_STRNCMP:
3251 check_strncmp (stmt);
3252 return true;
3253
3254 case BUILT_IN_MEMCMP:
3255 {
3256 tree a1 = call_arg (stmt, argno: 0);
3257 tree a2 = call_arg (stmt, argno: 1);
3258 tree len = call_arg (stmt, argno: 2);
3259 check_read_access (stmt, src: a1, bound: len, ost: 0);
3260 check_read_access (stmt, src: a2, bound: len, ost: 0);
3261 return true;
3262 }
3263
3264 case BUILT_IN_MEMCPY:
3265 case BUILT_IN_MEMPCPY:
3266 case BUILT_IN_MEMMOVE:
3267 {
3268 tree dst = call_arg (stmt, argno: 0);
3269 tree src = call_arg (stmt, argno: 1);
3270 tree len = call_arg (stmt, argno: 2);
3271 check_memop_access (stmt, dest: dst, src, size: len);
3272 return true;
3273 }
3274
3275 case BUILT_IN_MEMCHR:
3276 {
3277 tree src = call_arg (stmt, argno: 0);
3278 tree len = call_arg (stmt, argno: 2);
3279 check_read_access (stmt, src, bound: len, ost: 0);
3280 return true;
3281 }
3282
3283 case BUILT_IN_MEMSET:
3284 {
3285 tree dst = call_arg (stmt, argno: 0);
3286 tree len = call_arg (stmt, argno: 2);
3287 check_memop_access (stmt, dest: dst, NULL_TREE, size: len);
3288 return true;
3289 }
3290
3291 default:
3292 if (check_atomic_builtin (stmt))
3293 return true;
3294 break;
3295 }
3296
3297 return false;
3298}
3299
3300/* Returns the type of the argument ARGNO to function with type FNTYPE
3301 or null when the type cannot be determined or no such argument exists. */
3302
3303static tree
3304fntype_argno_type (tree fntype, unsigned argno)
3305{
3306 if (!prototype_p (fntype))
3307 return NULL_TREE;
3308
3309 tree argtype;
3310 function_args_iterator it;
3311 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
3312 if (argno-- == 0)
3313 return argtype;
3314
3315 return NULL_TREE;
3316}
3317
3318/* Helper to append the "human readable" attribute access specification
3319 described by ACCESS to the array ATTRSTR with size STRSIZE. Used in
3320 diagnostics. */
3321
3322static inline void
3323append_attrname (const std::pair<int, attr_access> &access,
3324 char *attrstr, size_t strsize)
3325{
3326 if (access.second.internal_p)
3327 return;
3328
3329 tree str = access.second.to_external_string ();
3330 gcc_assert (strsize >= (size_t) TREE_STRING_LENGTH (str));
3331 strcpy (dest: attrstr, TREE_STRING_POINTER (str));
3332}
3333
3334/* Iterate over attribute access read-only, read-write, and write-only
3335 arguments and diagnose past-the-end accesses and related problems
3336 in the function call EXP. */
3337
3338void
3339pass_waccess::maybe_check_access_sizes (rdwr_map *rwm, tree fndecl, tree fntype,
3340 gimple *stmt)
3341{
3342 if (warning_suppressed_p (stmt, OPT_Wnonnull)
3343 || warning_suppressed_p (stmt, OPT_Wstringop_overflow_))
3344 return;
3345
3346 auto_diagnostic_group adg;
3347
3348 /* Set if a warning has been issued for any argument (used to decide
3349 whether to emit an informational note at the end). */
3350 opt_code opt_warned = no_warning;
3351
3352 /* A string describing the attributes that the warnings issued by this
3353 function apply to. Used to print one informational note per function
3354 call, rather than one per warning. That reduces clutter. */
3355 char attrstr[80];
3356 attrstr[0] = 0;
3357
3358 for (rdwr_map::iterator it = rwm->begin (); it != rwm->end (); ++it)
3359 {
3360 std::pair<int, attr_access> access = *it;
3361
3362 /* Get the function call arguments corresponding to the attribute's
3363 positional arguments. When both arguments have been specified
3364 there will be two entries in *RWM, one for each. They are
3365 cross-referenced by their respective argument numbers in
3366 ACCESS.PTRARG and ACCESS.SIZARG. */
3367 const int ptridx = access.second.ptrarg;
3368 const int sizidx = access.second.sizarg;
3369
3370 gcc_assert (ptridx != -1);
3371 gcc_assert (access.first == ptridx || access.first == sizidx);
3372
3373 /* The pointer is set to null for the entry corresponding to
3374 the size argument. Skip it. It's handled when the entry
3375 corresponding to the pointer argument comes up. */
3376 if (!access.second.ptr)
3377 continue;
3378
3379 tree ptrtype = fntype_argno_type (fntype, argno: ptridx);
3380 if (!ptrtype)
3381 /* A function with a prototype was redeclared without one and
3382 the prototype has been lost. See pr102759. Avoid dealing
3383 with this pathological case. */
3384 return;
3385
3386 tree argtype = TREE_TYPE (ptrtype);
3387
3388 /* The size of the access by the call in elements. */
3389 tree access_nelts;
3390 if (sizidx == -1)
3391 {
3392 /* If only the pointer attribute operand was specified and
3393 not size, set SIZE to the greater of MINSIZE or size of
3394 one element of the pointed to type to detect smaller
3395 objects (null pointers are diagnosed in this case only
3396 if the pointer is also declared with attribute nonnull. */
3397 if (access.second.minsize
3398 && access.second.minsize != HOST_WIDE_INT_M1U)
3399 access_nelts = build_int_cstu (sizetype, access.second.minsize);
3400 else if (VOID_TYPE_P (argtype) && access.second.mode == access_none)
3401 /* Treat access mode none on a void* argument as expecting
3402 as little as zero bytes. */
3403 access_nelts = size_zero_node;
3404 else
3405 access_nelts = size_one_node;
3406 }
3407 else
3408 access_nelts = rwm->get (k: sizidx)->size;
3409
3410 /* If access_nelts is e.g. a PARM_DECL with larger precision than
3411 sizetype, such as __int128 or _BitInt(34123) parameters,
3412 cast it to sizetype. */
3413 if (access_nelts
3414 && INTEGRAL_TYPE_P (TREE_TYPE (access_nelts))
3415 && (TYPE_PRECISION (TREE_TYPE (access_nelts))
3416 > TYPE_PRECISION (sizetype)))
3417 access_nelts = fold_convert (sizetype, access_nelts);
3418
3419 /* Format the value or range to avoid an explosion of messages. */
3420 char sizstr[80];
3421 tree sizrng[2] = { size_zero_node, build_all_ones_cst (sizetype) };
3422 if (get_size_range (m_ptr_qry.rvals, access_nelts, stmt, sizrng, 1))
3423 {
3424 char *s0 = print_generic_expr_to_str (sizrng[0]);
3425 if (tree_int_cst_equal (sizrng[0], sizrng[1]))
3426 {
3427 gcc_checking_assert (strlen (s0) < sizeof sizstr);
3428 strcpy (dest: sizstr, src: s0);
3429 }
3430 else
3431 {
3432 char *s1 = print_generic_expr_to_str (sizrng[1]);
3433 gcc_checking_assert (strlen (s0) + strlen (s1)
3434 < sizeof sizstr - 4);
3435 sprintf (s: sizstr, format: "[%.37s, %.37s]", s0, s1);
3436 free (ptr: s1);
3437 }
3438 free (ptr: s0);
3439 }
3440 else
3441 *sizstr = '\0';
3442
3443 /* Set if a warning has been issued for the current argument. */
3444 opt_code arg_warned = no_warning;
3445 location_t loc = get_location (stmt);
3446 tree ptr = access.second.ptr;
3447 if (*sizstr
3448 && tree_int_cst_sgn (sizrng[0]) < 0
3449 && tree_int_cst_sgn (sizrng[1]) < 0)
3450 {
3451 /* Warn about negative sizes. */
3452 if (access.second.internal_p)
3453 {
3454 const std::string argtypestr
3455 = access.second.array_as_string (ptrtype);
3456
3457 if (warning_at (loc, OPT_Wstringop_overflow_,
3458 "bound argument %i value %s is "
3459 "negative for a variable length array "
3460 "argument %i of type %s",
3461 sizidx + 1, sizstr,
3462 ptridx + 1, argtypestr.c_str ()))
3463 arg_warned = OPT_Wstringop_overflow_;
3464 }
3465 else if (warning_at (loc, OPT_Wstringop_overflow_,
3466 "argument %i value %s is negative",
3467 sizidx + 1, sizstr))
3468 arg_warned = OPT_Wstringop_overflow_;
3469
3470 if (arg_warned != no_warning)
3471 {
3472 append_attrname (access, attrstr, strsize: sizeof attrstr);
3473 /* Remember a warning has been issued and avoid warning
3474 again below for the same attribute. */
3475 opt_warned = arg_warned;
3476 continue;
3477 }
3478 }
3479
3480 /* The size of the access by the call in bytes. */
3481 tree access_size = NULL_TREE;
3482 if (tree_int_cst_sgn (sizrng[0]) >= 0)
3483 {
3484 if (COMPLETE_TYPE_P (argtype))
3485 {
3486 /* Multiply ACCESS_SIZE by the size of the type the pointer
3487 argument points to. If it's incomplete the size is used
3488 as is. */
3489 if (tree argsize = TYPE_SIZE_UNIT (argtype))
3490 if (TREE_CODE (argsize) == INTEGER_CST)
3491 {
3492 const int prec = TYPE_PRECISION (sizetype);
3493 wide_int minsize = wi::to_wide (t: sizrng[0], prec);
3494 minsize *= wi::to_wide (t: argsize, prec);
3495 access_size = wide_int_to_tree (sizetype, cst: minsize);
3496 }
3497 }
3498 else
3499 access_size = access_nelts;
3500 }
3501
3502 if (integer_zerop (ptr))
3503 {
3504 if (!access.second.internal_p
3505 && sizidx >= 0 && tree_int_cst_sgn (sizrng[0]) > 0)
3506 {
3507 /* Warn about null pointers with positive sizes. This is
3508 different from also declaring the pointer argument with
3509 attribute nonnull when the function accepts null pointers
3510 only when the corresponding size is zero. */
3511 if (warning_at (loc, OPT_Wnonnull,
3512 "argument %i is null but "
3513 "the corresponding size argument "
3514 "%i value is %s",
3515 ptridx + 1, sizidx + 1, sizstr))
3516 arg_warned = OPT_Wnonnull;
3517 }
3518
3519 if (arg_warned != no_warning)
3520 {
3521 append_attrname (access, attrstr, strsize: sizeof attrstr);
3522 /* Remember a warning has been issued and avoid warning
3523 again below for the same attribute. */
3524 opt_warned = OPT_Wnonnull;
3525 continue;
3526 }
3527 }
3528
3529 access_data data (m_ptr_qry.rvals, stmt, access.second.mode,
3530 NULL_TREE, false, NULL_TREE, false);
3531 access_ref* const pobj = (access.second.mode == access_write_only
3532 ? &data.dst : &data.src);
3533 tree objsize = compute_objsize (ptr, stmt, 1, pobj, &m_ptr_qry);
3534
3535 /* The size of the destination or source object. */
3536 tree dstsize = NULL_TREE, srcsize = NULL_TREE;
3537 if (access.second.mode == access_read_only
3538 || access.second.mode == access_none)
3539 {
3540 /* For a read-only argument there is no destination. For
3541 no access, set the source as well and differentiate via
3542 the access flag below. */
3543 srcsize = objsize;
3544 if (access.second.mode == access_read_only
3545 || access.second.mode == access_none)
3546 {
3547 /* For a read-only attribute there is no destination so
3548 clear OBJSIZE. This emits "reading N bytes" kind of
3549 diagnostics instead of the "writing N bytes" kind,
3550 unless MODE is none. */
3551 objsize = NULL_TREE;
3552 }
3553 }
3554 else
3555 dstsize = objsize;
3556
3557 /* Clear the no-warning bit in case it was set by check_access
3558 in a prior iteration so that accesses via different arguments
3559 are diagnosed. */
3560 suppress_warning (stmt, OPT_Wstringop_overflow_, false);
3561 access_mode mode = data.mode;
3562 if (mode == access_deferred)
3563 mode = TYPE_READONLY (argtype) ? access_read_only : access_read_write;
3564 check_access (stmt, dstwrite: access_size, /*maxread=*/ NULL_TREE, srcstr: srcsize,
3565 dstsize, mode, pad: &data, rvals: m_ptr_qry.rvals);
3566
3567 if (warning_suppressed_p (stmt, OPT_Wstringop_overflow_))
3568 opt_warned = OPT_Wstringop_overflow_;
3569 if (opt_warned != no_warning)
3570 {
3571 if (access.second.internal_p)
3572 {
3573 unsigned HOST_WIDE_INT nelts =
3574 access_nelts ? access.second.minsize : HOST_WIDE_INT_M1U;
3575 tree arrtype = build_printable_array_type (argtype, nelts);
3576 inform (loc, "referencing argument %u of type %qT",
3577 ptridx + 1, arrtype);
3578 }
3579 else
3580 /* If check_access issued a warning above, append the relevant
3581 attribute to the string. */
3582 append_attrname (access, attrstr, strsize: sizeof attrstr);
3583 }
3584 }
3585
3586 if (*attrstr)
3587 {
3588 if (fndecl)
3589 inform (get_location (x: fndecl),
3590 "in a call to function %qD declared with attribute %qs",
3591 fndecl, attrstr);
3592 else
3593 inform (get_location (stmt),
3594 "in a call with type %qT and attribute %qs",
3595 fntype, attrstr);
3596 }
3597 else if (opt_warned != no_warning)
3598 {
3599 if (fndecl)
3600 inform (get_location (x: fndecl),
3601 "in a call to function %qD", fndecl);
3602 else
3603 inform (get_location (stmt),
3604 "in a call with type %qT", fntype);
3605 }
3606
3607 /* Set the bit in case it was cleared and not set above. */
3608 if (opt_warned != no_warning)
3609 suppress_warning (stmt, opt_warned);
3610}
3611
3612/* Check call STMT to an ordinary (non-built-in) function for invalid
3613 accesses. Return true if a call has been handled. */
3614
3615bool
3616pass_waccess::check_call_access (gcall *stmt)
3617{
3618 tree fntype = gimple_call_fntype (gs: stmt);
3619 if (!fntype)
3620 return false;
3621
3622 tree fntypeattrs = TYPE_ATTRIBUTES (fntype);
3623 if (!fntypeattrs)
3624 return false;
3625
3626 /* Map of attribute access specifications for function arguments. */
3627 rdwr_map rdwr_idx;
3628 init_attr_rdwr_indices (&rdwr_idx, fntypeattrs);
3629
3630 unsigned nargs = call_nargs (stmt);
3631 for (unsigned i = 0; i != nargs; ++i)
3632 {
3633 tree arg = call_arg (stmt, argno: i);
3634
3635 /* Save the actual argument that corresponds to the access attribute
3636 operand for later processing. */
3637 if (attr_access *access = rdwr_idx.get (k: i))
3638 {
3639 if (POINTER_TYPE_P (TREE_TYPE (arg)))
3640 {
3641 access->ptr = arg;
3642 /* A nonnull ACCESS->SIZE contains VLA bounds. */
3643 }
3644 else
3645 {
3646 access->size = arg;
3647 gcc_assert (access->ptr == NULL_TREE);
3648 }
3649 }
3650 }
3651
3652 /* Check attribute access arguments. */
3653 tree fndecl = gimple_call_fndecl (gs: stmt);
3654 maybe_check_access_sizes (rwm: &rdwr_idx, fndecl, fntype, stmt);
3655
3656 check_alloc_size_call (stmt);
3657 return true;
3658}
3659
3660/* Check arguments in a call STMT for attribute nonstring. */
3661
3662static void
3663check_nonstring_args (gcall *stmt)
3664{
3665 tree fndecl = gimple_call_fndecl (gs: stmt);
3666
3667 /* Detect passing non-string arguments to functions expecting
3668 nul-terminated strings. */
3669 maybe_warn_nonstring_arg (fndecl, exp: stmt);
3670}
3671
3672/* Issue a warning if a deallocation function such as free, realloc,
3673 or C++ operator delete is called with an argument not returned by
3674 a matching allocation function such as malloc or the corresponding
3675 form of C++ operator new. */
3676
3677void
3678pass_waccess::maybe_check_dealloc_call (gcall *call)
3679{
3680 tree fndecl = gimple_call_fndecl (gs: call);
3681 if (!fndecl)
3682 return;
3683
3684 unsigned argno = fndecl_dealloc_argno (fndecl);
3685 if ((unsigned) call_nargs (stmt: call) <= argno)
3686 return;
3687
3688 tree ptr = gimple_call_arg (gs: call, index: argno);
3689 if (integer_zerop (ptr))
3690 return;
3691
3692 access_ref aref;
3693 if (!compute_objsize (ptr, call, 0, &aref, &m_ptr_qry))
3694 return;
3695
3696 tree ref = aref.ref;
3697 if (integer_zerop (ref))
3698 return;
3699
3700 tree dealloc_decl = fndecl;
3701 location_t loc = gimple_location (g: call);
3702
3703 if (DECL_P (ref) || EXPR_P (ref))
3704 {
3705 /* Diagnose freeing a declared object. */
3706 if (aref.ref_declared ())
3707 {
3708 auto_diagnostic_group d;
3709 if (warning_at (loc, OPT_Wfree_nonheap_object,
3710 "%qD called on unallocated object %qD",
3711 dealloc_decl, ref))
3712 {
3713 inform (get_location (x: ref), "declared here");
3714 return;
3715 }
3716 }
3717
3718 /* Diagnose freeing a pointer that includes a positive offset.
3719 Such a pointer cannot refer to the beginning of an allocated
3720 object. A negative offset may refer to it. */
3721 if (aref.sizrng[0] != aref.sizrng[1]
3722 && warn_dealloc_offset (loc, call, aref))
3723 return;
3724 }
3725 else if (CONSTANT_CLASS_P (ref))
3726 {
3727 auto_diagnostic_group d;
3728 if (warning_at (loc, OPT_Wfree_nonheap_object,
3729 "%qD called on a pointer to an unallocated "
3730 "object %qE", dealloc_decl, ref))
3731 {
3732 if (TREE_CODE (ptr) == SSA_NAME)
3733 {
3734 gimple *def_stmt = SSA_NAME_DEF_STMT (ptr);
3735 if (is_gimple_assign (gs: def_stmt))
3736 {
3737 location_t loc = gimple_location (g: def_stmt);
3738 inform (loc, "assigned here");
3739 }
3740 }
3741 return;
3742 }
3743 }
3744 else if (TREE_CODE (ref) == SSA_NAME)
3745 {
3746 /* Also warn if the pointer argument refers to the result
3747 of an allocation call like alloca or VLA. */
3748 gimple *def_stmt = SSA_NAME_DEF_STMT (ref);
3749 if (!def_stmt)
3750 return;
3751
3752 if (is_gimple_call (gs: def_stmt))
3753 {
3754 bool warned = false;
3755 if (gimple_call_alloc_p (stmt: def_stmt))
3756 {
3757 if (matching_alloc_calls_p (alloc: def_stmt, dealloc_decl))
3758 {
3759 if (warn_dealloc_offset (loc, call, aref))
3760 return;
3761 }
3762 else
3763 {
3764 tree alloc_decl = gimple_call_fndecl (gs: def_stmt);
3765 const opt_code opt =
3766 (DECL_IS_OPERATOR_NEW_P (alloc_decl)
3767 || DECL_IS_OPERATOR_DELETE_P (dealloc_decl)
3768 ? OPT_Wmismatched_new_delete
3769 : OPT_Wmismatched_dealloc);
3770 warned = warning_at (loc, opt,
3771 "%qD called on pointer returned "
3772 "from a mismatched allocation "
3773 "function", dealloc_decl);
3774 }
3775 }
3776 else if (gimple_call_builtin_p (def_stmt, BUILT_IN_ALLOCA)
3777 || gimple_call_builtin_p (def_stmt,
3778 BUILT_IN_ALLOCA_WITH_ALIGN))
3779 warned = warning_at (loc, OPT_Wfree_nonheap_object,
3780 "%qD called on pointer to "
3781 "an unallocated object",
3782 dealloc_decl);
3783 else if (warn_dealloc_offset (loc, call, aref))
3784 return;
3785
3786 if (warned)
3787 {
3788 tree fndecl = gimple_call_fndecl (gs: def_stmt);
3789 inform (gimple_location (g: def_stmt),
3790 "returned from %qD", fndecl);
3791 return;
3792 }
3793 }
3794 else if (gimple_nop_p (g: def_stmt))
3795 {
3796 ref = SSA_NAME_VAR (ref);
3797 /* Diagnose freeing a pointer that includes a positive offset. */
3798 if (TREE_CODE (ref) == PARM_DECL
3799 && !aref.deref
3800 && aref.sizrng[0] != aref.sizrng[1]
3801 && aref.offrng[0] > 0 && aref.offrng[1] > 0
3802 && warn_dealloc_offset (loc, call, aref))
3803 return;
3804 }
3805 }
3806}
3807
3808/* Return true if either USE_STMT's basic block (that of a pointer's use)
3809 is dominated by INVAL_STMT's (that of a pointer's invalidating statement,
3810 which is either a clobber or a deallocation call), or if they're in
3811 the same block, USE_STMT follows INVAL_STMT. */
3812
3813bool
3814pass_waccess::use_after_inval_p (gimple *inval_stmt, gimple *use_stmt,
3815 bool last_block /* = false */)
3816{
3817 tree clobvar =
3818 gimple_clobber_p (s: inval_stmt) ? gimple_assign_lhs (gs: inval_stmt) : NULL_TREE;
3819
3820 basic_block inval_bb = gimple_bb (g: inval_stmt);
3821 basic_block use_bb = gimple_bb (g: use_stmt);
3822
3823 if (!inval_bb || !use_bb)
3824 return false;
3825
3826 if (inval_bb != use_bb)
3827 {
3828 if (dominated_by_p (CDI_DOMINATORS, use_bb, inval_bb))
3829 return true;
3830
3831 if (!clobvar || !last_block)
3832 return false;
3833
3834 /* Proceed only when looking for uses of dangling pointers. */
3835 auto gsi = gsi_for_stmt (use_stmt);
3836
3837 /* A use statement in the last basic block in a function or one that
3838 falls through to it is after any other prior clobber of the used
3839 variable unless it's followed by a clobber of the same variable. */
3840 basic_block bb = use_bb;
3841 while (bb != inval_bb
3842 && single_succ_p (bb)
3843 && !(single_succ_edge (bb)->flags
3844 & (EDGE_EH | EDGE_ABNORMAL | EDGE_DFS_BACK)))
3845 {
3846 for (; !gsi_end_p (i: gsi); gsi_next_nondebug (i: &gsi))
3847 {
3848 gimple *stmt = gsi_stmt (i: gsi);
3849 if (gimple_clobber_p (s: stmt))
3850 {
3851 if (clobvar == gimple_assign_lhs (gs: stmt))
3852 /* The use is followed by a clobber. */
3853 return false;
3854 }
3855 }
3856
3857 bb = single_succ (bb);
3858 gsi = gsi_start_bb (bb);
3859 }
3860
3861 /* The use is one of a dangling pointer if a clobber of the variable
3862 [the pointer points to] has not been found before the function exit
3863 point. */
3864 return bb == EXIT_BLOCK_PTR_FOR_FN (cfun);
3865 }
3866
3867 if (bitmap_set_bit (m_bb_uids_set, inval_bb->index))
3868 /* The first time this basic block is visited assign increasing ids
3869 to consecutive statements in it. Use the ids to determine which
3870 precedes which. This avoids the linear traversal on subsequent
3871 visits to the same block. */
3872 renumber_gimple_stmt_uids_in_block (m_func, inval_bb);
3873
3874 return gimple_uid (g: inval_stmt) < gimple_uid (g: use_stmt);
3875}
3876
3877/* Issue a warning for the USE_STMT of pointer or reference REF rendered
3878 invalid by INVAL_STMT. REF may be null when it's been optimized away.
3879 When nonnull, INVAL_STMT is the deallocation function that rendered
3880 the pointer or reference dangling. Otherwise, VAR is the auto variable
3881 (including an unnamed temporary such as a compound literal) whose
3882 lifetime's rended it dangling. MAYBE is true to issue the "maybe"
3883 kind of warning. EQUALITY is true when the pointer is used in
3884 an equality expression. */
3885
3886void
3887pass_waccess::warn_invalid_pointer (tree ref, gimple *use_stmt,
3888 gimple *inval_stmt, tree var,
3889 bool maybe, bool equality /* = false */)
3890{
3891 /* Avoid printing the unhelpful "<unknown>" in the diagnostics. */
3892 if (ref && TREE_CODE (ref) == SSA_NAME)
3893 {
3894 tree var = SSA_NAME_VAR (ref);
3895 if (!var)
3896 ref = NULL_TREE;
3897 /* Don't warn for cases like when a cdtor returns 'this' on ARM. */
3898 else if (warning_suppressed_p (var, OPT_Wuse_after_free))
3899 return;
3900 else if (DECL_ARTIFICIAL (var))
3901 ref = NULL_TREE;
3902 }
3903
3904 location_t use_loc = gimple_location (g: use_stmt);
3905 if (use_loc == UNKNOWN_LOCATION)
3906 {
3907 use_loc = m_func->function_end_locus;
3908 if (!ref)
3909 /* Avoid issuing a warning with no context other than
3910 the function. That would make it difficult to debug
3911 in any but very simple cases. */
3912 return;
3913 }
3914
3915 if (is_gimple_call (gs: inval_stmt))
3916 {
3917 if (!m_early_checks_p
3918 || (equality && warn_use_after_free < 3)
3919 || (maybe && warn_use_after_free < 2)
3920 || warning_suppressed_p (use_stmt, OPT_Wuse_after_free))
3921 return;
3922
3923 const tree inval_decl = gimple_call_fndecl (gs: inval_stmt);
3924
3925 auto_diagnostic_group d;
3926 if ((ref && warning_at (use_loc, OPT_Wuse_after_free,
3927 (maybe
3928 ? G_("pointer %qE may be used after %qD")
3929 : G_("pointer %qE used after %qD")),
3930 ref, inval_decl))
3931 || (!ref && warning_at (use_loc, OPT_Wuse_after_free,
3932 (maybe
3933 ? G_("pointer may be used after %qD")
3934 : G_("pointer used after %qD")),
3935 inval_decl)))
3936 {
3937 location_t loc = gimple_location (g: inval_stmt);
3938 inform (loc, "call to %qD here", inval_decl);
3939 suppress_warning (use_stmt, OPT_Wuse_after_free);
3940 }
3941 return;
3942 }
3943
3944 if (equality
3945 || (maybe && warn_dangling_pointer < 2)
3946 || warning_suppressed_p (use_stmt, OPT_Wdangling_pointer_))
3947 return;
3948
3949 if (DECL_NAME (var))
3950 {
3951 auto_diagnostic_group d;
3952 if ((ref
3953 && warning_at (use_loc, OPT_Wdangling_pointer_,
3954 (maybe
3955 ? G_("dangling pointer %qE to %qD may be used")
3956 : G_("using dangling pointer %qE to %qD")),
3957 ref, var))
3958 || (!ref
3959 && warning_at (use_loc, OPT_Wdangling_pointer_,
3960 (maybe
3961 ? G_("dangling pointer to %qD may be used")
3962 : G_("using a dangling pointer to %qD")),
3963 var)))
3964 inform (DECL_SOURCE_LOCATION (var),
3965 "%qD declared here", var);
3966 suppress_warning (use_stmt, OPT_Wdangling_pointer_);
3967 return;
3968 }
3969
3970 if ((ref
3971 && warning_at (use_loc, OPT_Wdangling_pointer_,
3972 (maybe
3973 ? G_("dangling pointer %qE to an unnamed temporary "
3974 "may be used")
3975 : G_("using dangling pointer %qE to an unnamed "
3976 "temporary")),
3977 ref))
3978 || (!ref
3979 && warning_at (use_loc, OPT_Wdangling_pointer_,
3980 (maybe
3981 ? G_("dangling pointer to an unnamed temporary "
3982 "may be used")
3983 : G_("using a dangling pointer to an unnamed "
3984 "temporary")))))
3985 {
3986 inform (DECL_SOURCE_LOCATION (var),
3987 "unnamed temporary defined here");
3988 suppress_warning (use_stmt, OPT_Wdangling_pointer_);
3989 }
3990}
3991
3992/* If STMT is a call to either the standard realloc or to a user-defined
3993 reallocation function returns its LHS and set *PTR to the reallocated
3994 pointer. Otherwise return null. */
3995
3996static tree
3997get_realloc_lhs (gimple *stmt, tree *ptr)
3998{
3999 if (gimple_call_builtin_p (stmt, BUILT_IN_REALLOC))
4000 {
4001 *ptr = gimple_call_arg (gs: stmt, index: 0);
4002 return gimple_call_lhs (gs: stmt);
4003 }
4004
4005 gcall *call = dyn_cast<gcall *>(p: stmt);
4006 if (!call)
4007 return NULL_TREE;
4008
4009 tree fnattr = NULL_TREE;
4010 tree fndecl = gimple_call_fndecl (gs: call);
4011 if (fndecl)
4012 fnattr = DECL_ATTRIBUTES (fndecl);
4013 else
4014 {
4015 tree fntype = gimple_call_fntype (gs: stmt);
4016 if (!fntype)
4017 return NULL_TREE;
4018 fnattr = TYPE_ATTRIBUTES (fntype);
4019 }
4020
4021 if (!fnattr)
4022 return NULL_TREE;
4023
4024 for (tree ats = fnattr; (ats = lookup_attribute (attr_name: "*dealloc", list: ats));
4025 ats = TREE_CHAIN (ats))
4026 {
4027 tree args = TREE_VALUE (ats);
4028 if (!args)
4029 continue;
4030
4031 tree alloc = TREE_VALUE (args);
4032 if (!alloc)
4033 continue;
4034
4035 if (alloc == DECL_NAME (fndecl))
4036 {
4037 unsigned argno = 0;
4038 if (tree index = TREE_CHAIN (args))
4039 argno = TREE_INT_CST_LOW (TREE_VALUE (index)) - 1;
4040 *ptr = gimple_call_arg (gs: stmt, index: argno);
4041 return gimple_call_lhs (gs: stmt);
4042 }
4043 }
4044
4045 return NULL_TREE;
4046}
4047
4048/* Warn if STMT is a call to a deallocation function that's not a match
4049 for the REALLOC_STMT call. Return true if warned. */
4050
4051static bool
4052maybe_warn_mismatched_realloc (tree ptr, gimple *realloc_stmt, gimple *stmt)
4053{
4054 if (!is_gimple_call (gs: stmt))
4055 return false;
4056
4057 tree fndecl = gimple_call_fndecl (gs: stmt);
4058 if (!fndecl)
4059 return false;
4060
4061 unsigned argno = fndecl_dealloc_argno (fndecl);
4062 if (call_nargs (stmt) <= argno)
4063 return false;
4064
4065 if (matching_alloc_calls_p (alloc: realloc_stmt, dealloc_decl: fndecl))
4066 return false;
4067
4068 /* Avoid printing the unhelpful "<unknown>" in the diagnostics. */
4069 if (ptr && TREE_CODE (ptr) == SSA_NAME
4070 && (!SSA_NAME_VAR (ptr) || DECL_ARTIFICIAL (SSA_NAME_VAR (ptr))))
4071 ptr = NULL_TREE;
4072
4073 location_t loc = gimple_location (g: stmt);
4074 tree realloc_decl = gimple_call_fndecl (gs: realloc_stmt);
4075 tree dealloc_decl = gimple_call_fndecl (gs: stmt);
4076 if (ptr && !warning_at (loc, OPT_Wmismatched_dealloc,
4077 "%qD called on pointer %qE passed to mismatched "
4078 "allocation function %qD",
4079 dealloc_decl, ptr, realloc_decl))
4080 return false;
4081 if (!ptr && !warning_at (loc, OPT_Wmismatched_dealloc,
4082 "%qD called on a pointer passed to mismatched "
4083 "reallocation function %qD",
4084 dealloc_decl, realloc_decl))
4085 return false;
4086
4087 inform (gimple_location (g: realloc_stmt),
4088 "call to %qD", realloc_decl);
4089 return true;
4090}
4091
4092/* Return true if P and Q point to the same object, and false if they
4093 either don't or their relationship cannot be determined. */
4094
4095static bool
4096pointers_related_p (gimple *stmt, tree p, tree q, pointer_query &qry,
4097 auto_bitmap &visited)
4098{
4099 if (!ptr_derefs_may_alias_p (p, q))
4100 return false;
4101
4102 /* TODO: Work harder to rule out relatedness. */
4103 access_ref pref, qref;
4104 if (!qry.get_ref (p, stmt, &pref, 0)
4105 || !qry.get_ref (q, stmt, &qref, 0))
4106 /* GET_REF() only rarely fails. When it does, it's likely because
4107 it involves a self-referential PHI. Return a conservative result. */
4108 return false;
4109
4110 if (pref.ref == qref.ref)
4111 return true;
4112
4113 /* If either pointer is a PHI, iterate over all its operands and
4114 return true if they're all related to the other pointer. */
4115 tree ptr = q;
4116 unsigned version;
4117 gphi *phi = pref.phi ();
4118 if (phi)
4119 version = SSA_NAME_VERSION (pref.ref);
4120 else
4121 {
4122 phi = qref.phi ();
4123 if (!phi)
4124 return false;
4125
4126 ptr = p;
4127 version = SSA_NAME_VERSION (qref.ref);
4128 }
4129
4130 if (!bitmap_set_bit (visited, version))
4131 return true;
4132
4133 unsigned nargs = gimple_phi_num_args (gs: phi);
4134 for (unsigned i = 0; i != nargs; ++i)
4135 {
4136 tree arg = gimple_phi_arg_def (gs: phi, index: i);
4137 if (!pointers_related_p (stmt, p: arg, q: ptr, qry, visited))
4138 return false;
4139 }
4140
4141 return true;
4142}
4143
4144/* Convenience wrapper for the above. */
4145
4146static bool
4147pointers_related_p (gimple *stmt, tree p, tree q, pointer_query &qry)
4148{
4149 auto_bitmap visited;
4150 return pointers_related_p (stmt, p, q, qry, visited);
4151}
4152
4153/* For a STMT either a call to a deallocation function or a clobber, warn
4154 for uses of the pointer PTR it was called with (including its copies
4155 or others derived from it by pointer arithmetic). If STMT is a clobber,
4156 VAR is the decl of the clobbered variable. When MAYBE is true use
4157 a "maybe" form of diagnostic. */
4158
4159void
4160pass_waccess::check_pointer_uses (gimple *stmt, tree ptr,
4161 tree var /* = NULL_TREE */,
4162 bool maybe /* = false */)
4163{
4164 gcc_assert (TREE_CODE (ptr) == SSA_NAME);
4165
4166 const bool check_dangling = !is_gimple_call (gs: stmt);
4167 basic_block stmt_bb = gimple_bb (g: stmt);
4168
4169 /* If STMT is a reallocation function set to the reallocated pointer
4170 and the LHS of the call, respectively. */
4171 tree realloc_ptr = NULL_TREE;
4172 tree realloc_lhs = get_realloc_lhs (stmt, ptr: &realloc_ptr);
4173
4174 auto_bitmap visited;
4175
4176 auto_vec<tree, 8> pointers;
4177 pointers.quick_push (obj: ptr);
4178 hash_map<tree, int> *phi_map = nullptr;
4179
4180 /* Starting with PTR, iterate over POINTERS added by the loop, and
4181 either warn for their uses in basic blocks dominated by the STMT
4182 or in statements that follow it in the same basic block, or add
4183 them to POINTERS if they point into the same object as PTR (i.e.,
4184 are obtained by pointer arithmetic on PTR). */
4185 for (unsigned i = 0; i != pointers.length (); ++i)
4186 {
4187 tree ptr = pointers[i];
4188 if (!bitmap_set_bit (visited, SSA_NAME_VERSION (ptr)))
4189 /* Avoid revisiting the same pointer. */
4190 continue;
4191
4192 use_operand_p use_p;
4193 imm_use_iterator iter;
4194 FOR_EACH_IMM_USE_FAST (use_p, iter, ptr)
4195 {
4196 gimple *use_stmt = USE_STMT (use_p);
4197 if (use_stmt == stmt || is_gimple_debug (gs: use_stmt))
4198 continue;
4199
4200 /* A clobber isn't a use. */
4201 if (gimple_clobber_p (s: use_stmt))
4202 continue;
4203
4204 if (realloc_lhs)
4205 {
4206 /* Check to see if USE_STMT is a mismatched deallocation
4207 call for the pointer passed to realloc. That's a bug
4208 regardless of the pointer's value and so warn. */
4209 if (maybe_warn_mismatched_realloc (ptr: *use_p->use, realloc_stmt: stmt, stmt: use_stmt))
4210 continue;
4211
4212 /* Pointers passed to realloc that are used in basic blocks
4213 where the realloc call is known to have failed are valid.
4214 Ignore pointers that nothing is known about. Those could
4215 have escaped along with their nullness. */
4216 value_range vr;
4217 if (m_ptr_qry.rvals->range_of_expr (r&: vr, expr: realloc_lhs, use_stmt))
4218 {
4219 if (vr.zero_p ())
4220 continue;
4221
4222 if (!pointers_related_p (stmt, p: ptr, q: realloc_ptr, qry&: m_ptr_qry))
4223 continue;
4224 }
4225 }
4226
4227 if (check_dangling
4228 && gimple_code (g: use_stmt) == GIMPLE_RETURN)
4229 /* Avoid interfering with -Wreturn-local-addr (which runs only
4230 with optimization enabled so it won't diagnose cases that
4231 would be caught here when optimization is disabled). */
4232 continue;
4233
4234 bool equality = false;
4235 if (is_gimple_assign (gs: use_stmt))
4236 {
4237 tree_code code = gimple_assign_rhs_code (gs: use_stmt);
4238 equality = code == EQ_EXPR || code == NE_EXPR;
4239 }
4240 else if (gcond *cond = dyn_cast<gcond *>(p: use_stmt))
4241 {
4242 tree_code code = gimple_cond_code (gs: cond);
4243 equality = code == EQ_EXPR || code == NE_EXPR;
4244 }
4245 else if (gphi *phi = dyn_cast <gphi *> (p: use_stmt))
4246 {
4247 /* Only add a PHI result to POINTERS if all its
4248 operands are related to PTR, otherwise continue. The
4249 PHI result is related once we've reached all arguments
4250 through this iteration. That also means any invariant
4251 argument will make the PHI not related. For arguments
4252 flowing over natural loop backedges we are optimistic
4253 (and diagnose the first iteration). */
4254 tree lhs = gimple_phi_result (gs: phi);
4255 if (!phi_map)
4256 phi_map = new hash_map<tree, int>;
4257 bool existed_p;
4258 int &related = phi_map->get_or_insert (k: lhs, existed: &existed_p);
4259 if (!existed_p)
4260 {
4261 related = gimple_phi_num_args (gs: phi) - 1;
4262 for (unsigned j = 0; j < gimple_phi_num_args (gs: phi); ++j)
4263 {
4264 if ((unsigned) phi_arg_index_from_use (use: use_p) == j)
4265 continue;
4266 tree arg = gimple_phi_arg_def (gs: phi, index: j);
4267 edge e = gimple_phi_arg_edge (phi, i: j);
4268 basic_block arg_bb;
4269 if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest)
4270 /* Make sure we are not forward visiting a
4271 backedge argument. */
4272 && (TREE_CODE (arg) != SSA_NAME
4273 || (!SSA_NAME_IS_DEFAULT_DEF (arg)
4274 && ((arg_bb
4275 = gimple_bb (SSA_NAME_DEF_STMT (arg)))
4276 != e->dest)
4277 && !dominated_by_p (CDI_DOMINATORS,
4278 e->dest, arg_bb))))
4279 related--;
4280 }
4281 }
4282 else
4283 related--;
4284
4285 if (related == 0)
4286 pointers.safe_push (obj: lhs);
4287 continue;
4288 }
4289
4290 /* Warn if USE_STMT is dominated by the deallocation STMT.
4291 Otherwise, add the pointer to POINTERS so that the uses
4292 of any other pointers derived from it can be checked. */
4293 if (use_after_inval_p (inval_stmt: stmt, use_stmt, last_block: check_dangling))
4294 {
4295 basic_block use_bb = gimple_bb (g: use_stmt);
4296 bool this_maybe
4297 = (maybe
4298 || !dominated_by_p (CDI_POST_DOMINATORS, stmt_bb, use_bb));
4299 warn_invalid_pointer (ref: *use_p->use, use_stmt, inval_stmt: stmt, var,
4300 maybe: this_maybe, equality);
4301 continue;
4302 }
4303
4304 if (is_gimple_assign (gs: use_stmt))
4305 {
4306 tree lhs = gimple_assign_lhs (gs: use_stmt);
4307 if (TREE_CODE (lhs) == SSA_NAME)
4308 {
4309 tree_code rhs_code = gimple_assign_rhs_code (gs: use_stmt);
4310 if (rhs_code == POINTER_PLUS_EXPR || rhs_code == SSA_NAME)
4311 pointers.safe_push (obj: lhs);
4312 }
4313 continue;
4314 }
4315
4316 if (gcall *call = dyn_cast <gcall *>(p: use_stmt))
4317 {
4318 if (gimple_call_return_arg (call) == ptr)
4319 if (tree lhs = gimple_call_lhs (gs: call))
4320 if (TREE_CODE (lhs) == SSA_NAME)
4321 pointers.safe_push (obj: lhs);
4322 continue;
4323 }
4324 }
4325 }
4326
4327 if (phi_map)
4328 delete phi_map;
4329}
4330
4331/* Check call STMT for invalid accesses. */
4332
4333void
4334pass_waccess::check_call (gcall *stmt)
4335{
4336 /* Skip special calls generated by the compiler. */
4337 if (gimple_call_from_thunk_p (s: stmt))
4338 return;
4339
4340 /* .ASAN_MARK doesn't access any vars, only modifies shadow memory. */
4341 if (gimple_call_internal_p (gs: stmt)
4342 && gimple_call_internal_fn (gs: stmt) == IFN_ASAN_MARK)
4343 return;
4344
4345 if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
4346 check_builtin (stmt);
4347
4348 if (tree callee = gimple_call_fndecl (gs: stmt))
4349 {
4350 /* Check for uses of the pointer passed to either a standard
4351 or a user-defined deallocation function. */
4352 unsigned argno = fndecl_dealloc_argno (callee);
4353 if (argno < (unsigned) call_nargs (stmt))
4354 {
4355 tree arg = call_arg (stmt, argno);
4356 if (TREE_CODE (arg) == SSA_NAME)
4357 check_pointer_uses (stmt, ptr: arg);
4358 }
4359 }
4360
4361 check_call_access (stmt);
4362 check_call_dangling (stmt);
4363
4364 if (m_early_checks_p)
4365 return;
4366
4367 maybe_check_dealloc_call (call: stmt);
4368 check_nonstring_args (stmt);
4369}
4370
4371/* Check non-call STMT for invalid accesses. */
4372
4373void
4374pass_waccess::check_stmt (gimple *stmt)
4375{
4376 if (m_check_dangling_p
4377 && gimple_clobber_p (s: stmt, kind: CLOBBER_STORAGE_END))
4378 {
4379 /* Ignore clobber statements in blocks with exceptional edges. */
4380 basic_block bb = gimple_bb (g: stmt);
4381 edge e = EDGE_PRED (bb, 0);
4382 if (e->flags & EDGE_EH)
4383 return;
4384
4385 tree var = gimple_assign_lhs (gs: stmt);
4386 m_clobbers.put (k: var, v: stmt);
4387 return;
4388 }
4389
4390 if (is_gimple_assign (gs: stmt))
4391 {
4392 /* Clobbered unnamed temporaries such as compound literals can be
4393 revived. Check for an assignment to one and remove it from
4394 M_CLOBBERS. */
4395 tree lhs = gimple_assign_lhs (gs: stmt);
4396 while (handled_component_p (t: lhs))
4397 lhs = TREE_OPERAND (lhs, 0);
4398
4399 if (auto_var_p (lhs))
4400 m_clobbers.remove (k: lhs);
4401 return;
4402 }
4403
4404 if (greturn *ret = dyn_cast <greturn *> (p: stmt))
4405 {
4406 if (optimize && flag_isolate_erroneous_paths_dereference)
4407 /* Avoid interfering with -Wreturn-local-addr (which runs only
4408 with optimization enabled). */
4409 return;
4410
4411 tree arg = gimple_return_retval (gs: ret);
4412 if (!arg || TREE_CODE (arg) != ADDR_EXPR)
4413 return;
4414
4415 arg = TREE_OPERAND (arg, 0);
4416 while (handled_component_p (t: arg))
4417 arg = TREE_OPERAND (arg, 0);
4418
4419 if (!auto_var_p (arg))
4420 return;
4421
4422 gimple **pclobber = m_clobbers.get (k: arg);
4423 if (!pclobber)
4424 return;
4425
4426 if (!use_after_inval_p (inval_stmt: *pclobber, use_stmt: stmt))
4427 return;
4428
4429 warn_invalid_pointer (NULL_TREE, use_stmt: stmt, inval_stmt: *pclobber, var: arg, maybe: false);
4430 }
4431}
4432
4433/* Check basic block BB for invalid accesses. */
4434
4435void
4436pass_waccess::check_block (basic_block bb)
4437{
4438 /* Iterate over statements, looking for function calls. */
4439 for (auto si = gsi_start_bb (bb); !gsi_end_p (i: si);
4440 gsi_next_nondebug (i: &si))
4441 {
4442 gimple *stmt = gsi_stmt (i: si);
4443 if (gcall *call = dyn_cast <gcall *> (p: stmt))
4444 check_call (stmt: call);
4445 else
4446 check_stmt (stmt);
4447 }
4448}
4449
4450/* Return the argument that the call STMT to a built-in function returns
4451 (including with an offset) or null if it doesn't. */
4452
4453tree
4454pass_waccess::gimple_call_return_arg (gcall *call)
4455{
4456 /* Check for attribute fn spec to see if the function returns one
4457 of its arguments. */
4458 attr_fnspec fnspec = gimple_call_fnspec (stmt: call);
4459 unsigned int argno;
4460 if (!fnspec.returns_arg (arg_no: &argno))
4461 {
4462 if (gimple_call_num_args (gs: call) < 1)
4463 return NULL_TREE;
4464
4465 if (!gimple_call_builtin_p (call, BUILT_IN_NORMAL))
4466 return NULL_TREE;
4467
4468 tree fndecl = gimple_call_fndecl (gs: call);
4469 switch (DECL_FUNCTION_CODE (decl: fndecl))
4470 {
4471 case BUILT_IN_MEMPCPY:
4472 case BUILT_IN_MEMPCPY_CHK:
4473 case BUILT_IN_MEMCHR:
4474 case BUILT_IN_STRCHR:
4475 case BUILT_IN_STRRCHR:
4476 case BUILT_IN_STRSTR:
4477 case BUILT_IN_STPCPY:
4478 case BUILT_IN_STPCPY_CHK:
4479 case BUILT_IN_STPNCPY:
4480 case BUILT_IN_STPNCPY_CHK:
4481 argno = 0;
4482 break;
4483
4484 default:
4485 return NULL_TREE;
4486 }
4487 }
4488
4489 if (gimple_call_num_args (gs: call) <= argno)
4490 return NULL_TREE;
4491
4492 return gimple_call_arg (gs: call, index: argno);
4493}
4494
4495/* Check for and diagnose all uses of the dangling pointer VAR to the auto
4496 object DECL whose lifetime has ended. OBJREF is true when VAR denotes
4497 an access to a DECL that may have been clobbered. */
4498
4499void
4500pass_waccess::check_dangling_uses (tree var, tree decl, bool maybe /* = false */,
4501 bool objref /* = false */)
4502{
4503 if (!decl || !auto_var_p (decl))
4504 return;
4505
4506 gimple **pclob = m_clobbers.get (k: decl);
4507 if (!pclob)
4508 return;
4509
4510 if (!objref)
4511 {
4512 check_pointer_uses (stmt: *pclob, ptr: var, var: decl, maybe);
4513 return;
4514 }
4515
4516 gimple *use_stmt = SSA_NAME_DEF_STMT (var);
4517 if (!use_after_inval_p (inval_stmt: *pclob, use_stmt, last_block: true))
4518 return;
4519
4520 basic_block use_bb = gimple_bb (g: use_stmt);
4521 basic_block clob_bb = gimple_bb (g: *pclob);
4522 maybe = maybe || !dominated_by_p (CDI_POST_DOMINATORS, clob_bb, use_bb);
4523 warn_invalid_pointer (ref: var, use_stmt, inval_stmt: *pclob, var: decl, maybe, equality: false);
4524}
4525
4526/* Diagnose stores in BB and (recursively) its predecessors of the addresses
4527 of local variables into nonlocal pointers that are left dangling after
4528 the function returns. Returns true when we can continue walking
4529 the CFG to predecessors. */
4530
4531bool
4532pass_waccess::check_dangling_stores (basic_block bb,
4533 hash_set<tree> &stores)
4534{
4535 /* Iterate backwards over the statements looking for a store of
4536 the address of a local variable into a nonlocal pointer. */
4537 for (auto gsi = gsi_last_nondebug_bb (bb); ; gsi_prev_nondebug (i: &gsi))
4538 {
4539 gimple *stmt = gsi_stmt (i: gsi);
4540 if (!stmt)
4541 break;
4542
4543 if (warning_suppressed_p (stmt, OPT_Wdangling_pointer_))
4544 continue;
4545
4546 if (is_gimple_call (gs: stmt)
4547 && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
4548 /* Avoid looking before nonconst, nonpure calls since those might
4549 use the escaped locals. */
4550 return false;
4551
4552 if (!is_gimple_assign (gs: stmt) || gimple_clobber_p (s: stmt)
4553 || !gimple_store_p (gs: stmt))
4554 continue;
4555
4556 access_ref lhs_ref;
4557 tree lhs = gimple_assign_lhs (gs: stmt);
4558 if (!m_ptr_qry.get_ref (lhs, stmt, &lhs_ref, 0))
4559 continue;
4560
4561 if (TREE_CODE (lhs_ref.ref) == MEM_REF)
4562 {
4563 lhs_ref.ref = TREE_OPERAND (lhs_ref.ref, 0);
4564 ++lhs_ref.deref;
4565 }
4566 if (TREE_CODE (lhs_ref.ref) == ADDR_EXPR)
4567 {
4568 lhs_ref.ref = TREE_OPERAND (lhs_ref.ref, 0);
4569 --lhs_ref.deref;
4570 }
4571 if (TREE_CODE (lhs_ref.ref) == SSA_NAME)
4572 {
4573 gimple *def_stmt = SSA_NAME_DEF_STMT (lhs_ref.ref);
4574 if (!gimple_nop_p (g: def_stmt))
4575 /* Avoid looking at or before stores into unknown objects. */
4576 return false;
4577
4578 lhs_ref.ref = SSA_NAME_VAR (lhs_ref.ref);
4579 }
4580
4581 if (TREE_CODE (lhs_ref.ref) == PARM_DECL
4582 && (lhs_ref.deref - DECL_BY_REFERENCE (lhs_ref.ref)) > 0)
4583 /* Assignment through a (real) pointer/reference parameter. */;
4584 else if (VAR_P (lhs_ref.ref)
4585 && !auto_var_p (lhs_ref.ref))
4586 /* Assignment to/through a non-local variable. */;
4587 else
4588 /* Something else, don't warn. */
4589 continue;
4590
4591 if (stores.add (k: lhs_ref.ref))
4592 continue;
4593
4594 /* FIXME: Handle stores of alloca() and VLA. */
4595 access_ref rhs_ref;
4596 tree rhs = gimple_assign_rhs1 (gs: stmt);
4597 if (!m_ptr_qry.get_ref (rhs, stmt, &rhs_ref, 0)
4598 || rhs_ref.deref != -1)
4599 continue;
4600
4601 if (!auto_var_p (rhs_ref.ref))
4602 continue;
4603
4604 auto_diagnostic_group d;
4605 location_t loc = gimple_location (g: stmt);
4606 if (warning_at (loc, OPT_Wdangling_pointer_,
4607 "storing the address of local variable %qD in %qE",
4608 rhs_ref.ref, lhs))
4609 {
4610 suppress_warning (stmt, OPT_Wdangling_pointer_);
4611
4612 location_t loc = DECL_SOURCE_LOCATION (rhs_ref.ref);
4613 inform (loc, "%qD declared here", rhs_ref.ref);
4614
4615 loc = DECL_SOURCE_LOCATION (lhs_ref.ref);
4616 inform (loc, "%qD declared here", lhs_ref.ref);
4617 }
4618 }
4619
4620 return true;
4621}
4622
4623/* Diagnose stores of the addresses of local variables into nonlocal
4624 pointers that are left dangling after the function returns. */
4625
4626void
4627pass_waccess::check_dangling_stores ()
4628{
4629 if (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (m_func)->preds) == 0)
4630 return;
4631
4632 auto_bitmap bbs;
4633 hash_set<tree> stores;
4634 auto_vec<edge_iterator, 8> worklist (n_basic_blocks_for_fn (cfun) + 1);
4635 worklist.quick_push (ei_start (EXIT_BLOCK_PTR_FOR_FN (m_func)->preds));
4636 do
4637 {
4638 edge_iterator ei = worklist.last ();
4639 basic_block src = ei_edge (i: ei)->src;
4640 if (bitmap_set_bit (bbs, src->index))
4641 {
4642 if (check_dangling_stores (bb: src, stores)
4643 && EDGE_COUNT (src->preds) > 0)
4644 worklist.quick_push (ei_start (src->preds));
4645 }
4646 else
4647 {
4648 if (ei_one_before_end_p (i: ei))
4649 worklist.pop ();
4650 else
4651 ei_next (i: &worklist.last ());
4652 }
4653 }
4654 while (!worklist.is_empty ());
4655}
4656
4657/* Check for and diagnose uses of dangling pointers to auto objects
4658 whose lifetime has ended. */
4659
4660void
4661pass_waccess::check_dangling_uses ()
4662{
4663 tree var;
4664 unsigned i;
4665 FOR_EACH_SSA_NAME (i, var, m_func)
4666 {
4667 /* For each SSA_NAME pointer VAR find the object it points to.
4668 If the object is a clobbered local variable, check to see
4669 if any of VAR's uses (or those of other pointers derived
4670 from VAR) happens after the clobber. If so, warn. */
4671
4672 gimple *def_stmt = SSA_NAME_DEF_STMT (var);
4673 if (is_gimple_assign (gs: def_stmt))
4674 {
4675 tree rhs = gimple_assign_rhs1 (gs: def_stmt);
4676 if (TREE_CODE (rhs) == ADDR_EXPR)
4677 {
4678 if (!POINTER_TYPE_P (TREE_TYPE (var)))
4679 continue;
4680 check_dangling_uses (var, TREE_OPERAND (rhs, 0));
4681 }
4682 else
4683 {
4684 /* For other expressions, check the base DECL to see
4685 if it's been clobbered, most likely as a result of
4686 inlining a reference to it. */
4687 tree decl = get_base_address (t: rhs);
4688 if (DECL_P (decl))
4689 check_dangling_uses (var, decl, maybe: false, objref: true);
4690 }
4691 }
4692 else if (POINTER_TYPE_P (TREE_TYPE (var)))
4693 {
4694 if (gcall *call = dyn_cast<gcall *>(p: def_stmt))
4695 {
4696 if (tree arg = gimple_call_return_arg (call))
4697 {
4698 access_ref aref;
4699 if (m_ptr_qry.get_ref (arg, call, &aref, 0)
4700 && aref.deref < 0)
4701 check_dangling_uses (var, decl: aref.ref);
4702 }
4703 }
4704 else if (gphi *phi = dyn_cast <gphi *>(p: def_stmt))
4705 {
4706 unsigned nargs = gimple_phi_num_args (gs: phi);
4707 for (unsigned i = 0; i != nargs; ++i)
4708 {
4709 access_ref aref;
4710 tree arg = gimple_phi_arg_def (gs: phi, index: i);
4711 if (m_ptr_qry.get_ref (arg, phi, &aref, 0)
4712 && aref.deref < 0)
4713 check_dangling_uses (var, decl: aref.ref, maybe: true);
4714 }
4715 }
4716 }
4717 }
4718}
4719
4720/* Check CALL arguments for dangling pointers (those that have been
4721 clobbered) and warn if found. */
4722
4723void
4724pass_waccess::check_call_dangling (gcall *call)
4725{
4726 unsigned nargs = gimple_call_num_args (gs: call);
4727 for (unsigned i = 0; i != nargs; ++i)
4728 {
4729 tree arg = gimple_call_arg (gs: call, index: i);
4730 if (TREE_CODE (arg) != ADDR_EXPR)
4731 continue;
4732
4733 arg = TREE_OPERAND (arg, 0);
4734 if (!DECL_P (arg))
4735 continue;
4736
4737 gimple **pclobber = m_clobbers.get (k: arg);
4738 if (!pclobber)
4739 continue;
4740
4741 if (!use_after_inval_p (inval_stmt: *pclobber, use_stmt: call))
4742 continue;
4743
4744 warn_invalid_pointer (NULL_TREE, use_stmt: call, inval_stmt: *pclobber, var: arg, maybe: false);
4745 }
4746}
4747
4748/* Check function FUN for invalid accesses. */
4749
4750unsigned
4751pass_waccess::execute (function *fun)
4752{
4753 calculate_dominance_info (CDI_DOMINATORS);
4754 calculate_dominance_info (CDI_POST_DOMINATORS);
4755
4756 /* Set or clear EDGE_DFS_BACK bits on back edges. */
4757 mark_dfs_back_edges (fun);
4758
4759 /* Create a new ranger instance and associate it with FUN. */
4760 m_ptr_qry.rvals = enable_ranger (m: fun);
4761 m_func = fun;
4762
4763 /* Check for dangling pointers in the earliest run of the pass.
4764 The latest point -Wdangling-pointer should run is just before
4765 loop unrolling which introduces uses after clobbers. Most cases
4766 can be detected without optimization; cases where the address of
4767 the local variable is passed to and then returned from a user-
4768 defined function before its lifetime ends and the returned pointer
4769 becomes dangling depend on inlining. */
4770 m_check_dangling_p = m_early_checks_p;
4771
4772 auto_bitmap bb_uids_set (&bitmap_default_obstack);
4773 m_bb_uids_set = bb_uids_set;
4774
4775 set_gimple_stmt_max_uid (fn: m_func, maxid: 0);
4776
4777 basic_block bb;
4778 FOR_EACH_BB_FN (bb, fun)
4779 check_block (bb);
4780
4781 if (m_check_dangling_p)
4782 {
4783 check_dangling_uses ();
4784 check_dangling_stores ();
4785 }
4786
4787 if (dump_file)
4788 m_ptr_qry.dump (dump_file, (dump_flags & TDF_DETAILS) != 0);
4789
4790 m_ptr_qry.flush_cache ();
4791
4792 /* Release the ranger instance and replace it with a global ranger.
4793 Also reset the pointer since calling disable_ranger() deletes it. */
4794 disable_ranger (fun);
4795 m_ptr_qry.rvals = NULL;
4796
4797 m_clobbers.empty ();
4798 m_bb_uids_set = NULL;
4799
4800 free_dominance_info (CDI_POST_DOMINATORS);
4801 free_dominance_info (CDI_DOMINATORS);
4802 return 0;
4803}
4804
4805} // namespace
4806
4807/* Return a new instance of the pass. */
4808
4809gimple_opt_pass *
4810make_pass_warn_access (gcc::context *ctxt)
4811{
4812 return new pass_waccess (ctxt);
4813}
4814

source code of gcc/gimple-ssa-warn-access.cc