xfail gnat.dg/trampoline3.adb scan-assembler-not check on hppa*-*-*
[official-gcc.git] / gcc / gimple-ssa-warn-restrict.cc
bloba552ce8dcdf6586b2ba78f851028d32c75b4ca12
1 /* Pass to detect and issue warnings for violations of the restrict
2 qualifier.
3 Copyright (C) 2017-2024 Free Software Foundation, Inc.
4 Contributed by Martin Sebor <msebor@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "backend.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "tree-pass.h"
29 #include "pointer-query.h"
30 #include "ssa.h"
31 #include "gimple-pretty-print.h"
32 #include "gimple-ssa-warn-access.h"
33 #include "gimple-ssa-warn-restrict.h"
34 #include "diagnostic-core.h"
35 #include "fold-const.h"
36 #include "gimple-iterator.h"
37 #include "tree-dfa.h"
38 #include "tree-ssa.h"
39 #include "tree-cfg.h"
40 #include "tree-object-size.h"
41 #include "calls.h"
42 #include "cfgloop.h"
43 #include "intl.h"
44 #include "gimple-range.h"
46 namespace {
48 const pass_data pass_data_wrestrict = {
49 GIMPLE_PASS,
50 "wrestrict",
51 OPTGROUP_NONE,
52 TV_NONE,
53 PROP_cfg, /* Properties_required. */
54 0, /* properties_provided. */
55 0, /* properties_destroyed. */
56 0, /* properties_start */
57 0, /* properties_finish */
60 /* Pass to detect violations of strict aliasing requirements in calls
61 to built-in string and raw memory functions. */
62 class pass_wrestrict : public gimple_opt_pass
64 public:
65 pass_wrestrict (gcc::context *);
67 bool gate (function *) final override;
68 unsigned int execute (function *) final override;
70 void check_call (gimple *);
72 void check_block (basic_block);
74 /* A pointer_query object to store information about pointers and
75 their targets in. */
76 pointer_query m_ptr_qry;
79 pass_wrestrict::pass_wrestrict (gcc::context *ctxt)
80 : gimple_opt_pass (pass_data_wrestrict, ctxt),
81 m_ptr_qry ()
82 { }
84 bool
85 pass_wrestrict::gate (function *fun ATTRIBUTE_UNUSED)
87 return warn_array_bounds || warn_restrict || warn_stringop_overflow;
90 void
91 pass_wrestrict::check_block (basic_block bb)
93 /* Iterate over statements, looking for function calls. */
94 for (auto si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
96 gimple *stmt = gsi_stmt (si);
97 if (!is_gimple_call (stmt))
98 continue;
100 check_call (stmt);
104 unsigned
105 pass_wrestrict::execute (function *fun)
107 /* Create a new ranger instance and associate it with FUN. */
108 m_ptr_qry.rvals = enable_ranger (fun);
110 basic_block bb;
111 FOR_EACH_BB_FN (bb, fun)
112 check_block (bb);
114 m_ptr_qry.flush_cache ();
116 /* Release the ranger instance and replace it with a global ranger.
117 Also reset the pointer since calling disable_ranger() deletes it. */
118 disable_ranger (fun);
119 m_ptr_qry.rvals = NULL;
121 return 0;
124 /* Description of a memory reference by a built-in function. This
125 is similar to ao_ref but made especially suitable for -Wrestrict
126 and not for optimization. */
127 class builtin_memref
129 public:
130 /* The original pointer argument to the built-in function. */
131 tree ptr;
132 /* The referenced subobject or NULL if not available, and the base
133 object of the memory reference or NULL. */
134 tree ref;
135 tree base;
137 /* The size of the BASE object, PTRDIFF_MAX if indeterminate,
138 and negative until (possibly lazily) initialized. */
139 offset_int basesize;
140 /* Same for the subobject. */
141 offset_int refsize;
143 /* The non-negative offset of the referenced subobject. Used to avoid
144 warnings for (apparently) possibly but not definitively overlapping
145 accesses to member arrays. Negative when unknown/invalid. */
146 offset_int refoff;
148 /* The offset range relative to the base. */
149 offset_int offrange[2];
150 /* The size range of the access to this reference. */
151 offset_int sizrange[2];
153 /* Cached result of get_max_objsize(). */
154 const offset_int maxobjsize;
156 /* True for "bounded" string functions like strncat, and strncpy
157 and their variants that specify either an exact or upper bound
158 on the size of the accesses they perform. For strncat both
159 the source and destination references are bounded. For strncpy
160 only the destination reference is. */
161 bool strbounded_p;
163 builtin_memref (pointer_query &, gimple *, tree, tree);
165 tree offset_out_of_bounds (int, offset_int[3]) const;
167 private:
168 /* Call statement to the built-in. */
169 gimple *stmt;
171 pointer_query &m_ptr_qry;
173 /* Ctor helper to set or extend OFFRANGE based on argument. */
174 void extend_offset_range (tree);
176 /* Ctor helper to determine BASE and OFFRANGE from argument. */
177 void set_base_and_offset (tree);
180 /* Description of a memory access by a raw memory or string built-in
181 function involving a pair of builtin_memref's. */
182 class builtin_access
184 public:
185 /* Destination and source memory reference. */
186 builtin_memref* const dstref;
187 builtin_memref* const srcref;
188 /* The size range of the access. It's the greater of the accesses
189 to the two references. */
190 HOST_WIDE_INT sizrange[2];
192 /* The minimum and maximum offset of an overlap of the access
193 (if it does, in fact, overlap), and the size of the overlap. */
194 HOST_WIDE_INT ovloff[2];
195 HOST_WIDE_INT ovlsiz[2];
197 /* True to consider valid only accesses to the smallest subobject
198 and false for raw memory functions. */
199 bool strict () const
201 return (detect_overlap != &builtin_access::generic_overlap
202 && detect_overlap != &builtin_access::no_overlap);
205 builtin_access (pointer_query &, gimple *,
206 builtin_memref &, builtin_memref &);
208 /* Entry point to determine overlap. */
209 bool overlap ();
211 offset_int write_off (tree) const;
213 void dump (FILE *) const;
215 private:
216 /* Implementation functions used to determine overlap. */
217 bool generic_overlap ();
218 bool strcat_overlap ();
219 bool strcpy_overlap ();
221 bool no_overlap ()
223 return false;
226 offset_int overlap_size (const offset_int [2], const offset_int[2],
227 offset_int [2]);
229 private:
230 /* Temporaries used to compute the final result. */
231 offset_int dstoff[2];
232 offset_int srcoff[2];
233 offset_int dstsiz[2];
234 offset_int srcsiz[2];
236 /* Pointer to a member function to call to determine overlap. */
237 bool (builtin_access::*detect_overlap) ();
240 /* Initialize a memory reference representation from a pointer EXPR and
241 a size SIZE in bytes. If SIZE is NULL_TREE then the size is assumed
242 to be unknown. STMT is the statement in which expr appears in. */
244 builtin_memref::builtin_memref (pointer_query &ptrqry, gimple *stmt, tree expr,
245 tree size)
246 : ptr (expr),
247 ref (),
248 base (),
249 basesize (-1),
250 refsize (-1),
251 refoff (HOST_WIDE_INT_MIN),
252 offrange (),
253 sizrange (),
254 maxobjsize (tree_to_shwi (max_object_size ())),
255 strbounded_p (),
256 stmt (stmt),
257 m_ptr_qry (ptrqry)
259 /* Unfortunately, wide_int default ctor is a no-op so array members
260 of the type must be set individually. */
261 offrange[0] = offrange[1] = 0;
262 sizrange[0] = sizrange[1] = 0;
264 if (!expr)
265 return;
267 /* Find the BASE object or pointer referenced by EXPR and set
268 the offset range OFFRANGE in the process. */
269 set_base_and_offset (expr);
271 if (size)
273 tree range[2];
274 /* Determine the size range, allowing for the result to be [0, 0]
275 for SIZE in the anti-range ~[0, N] where N >= PTRDIFF_MAX. */
276 get_size_range (m_ptr_qry.rvals, size, stmt, range, SR_ALLOW_ZERO);
277 sizrange[0] = wi::to_offset (range[0]);
278 sizrange[1] = wi::to_offset (range[1]);
279 /* get_size_range returns SIZE_MAX for the maximum size.
280 Constrain it to the real maximum of PTRDIFF_MAX. */
281 if (sizrange[0] <= maxobjsize && sizrange[1] > maxobjsize)
282 sizrange[1] = maxobjsize;
284 else
285 sizrange[1] = maxobjsize;
287 if (!DECL_P (base))
288 return;
290 /* If the offset could be in the range of the referenced object
291 constrain its bounds so neither exceeds those of the object. */
292 if (offrange[0] < 0 && offrange[1] > 0)
293 offrange[0] = 0;
295 offset_int maxoff = maxobjsize;
296 tree basetype = TREE_TYPE (base);
297 if (TREE_CODE (basetype) == ARRAY_TYPE)
299 if (ref && array_ref_flexible_size_p (ref))
300 ; /* Use the maximum possible offset for an array that might
301 have flexible size. */
302 else if (tree basesize = TYPE_SIZE_UNIT (basetype))
303 if (TREE_CODE (basesize) == INTEGER_CST)
304 /* Size could be non-constant for a variable-length type such
305 as a struct with a VLA member (a GCC extension). */
306 maxoff = wi::to_offset (basesize);
309 if (offrange[0] >= 0)
311 if (offrange[1] < 0)
312 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
313 else if (offrange[0] <= maxoff && offrange[1] > maxoff)
314 offrange[1] = maxoff;
318 /* Based on the initial length of the destination STARTLEN, returns
319 the offset of the first write access from the beginning of
320 the destination. Nonzero only for strcat-type of calls. */
322 offset_int builtin_access::write_off (tree startlen) const
324 if (detect_overlap != &builtin_access::strcat_overlap
325 || !startlen || TREE_CODE (startlen) != INTEGER_CST)
326 return 0;
328 return wi::to_offset (startlen);
331 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument.
332 Pointer offsets are represented as unsigned sizetype but must be
333 treated as signed. */
335 void
336 builtin_memref::extend_offset_range (tree offset)
338 if (TREE_CODE (offset) == INTEGER_CST)
340 offset_int off = int_cst_value (offset);
341 if (off != 0)
343 offrange[0] += off;
344 offrange[1] += off;
346 return;
349 if (TREE_CODE (offset) == SSA_NAME)
351 /* A pointer offset is represented as sizetype but treated
352 as signed. */
353 wide_int min, max;
354 value_range_kind rng = VR_VARYING;
355 value_range vr;
356 if (m_ptr_qry.rvals->range_of_expr (vr, offset, stmt))
358 tree vr_min, vr_max;
359 rng = get_legacy_range (vr, vr_min, vr_max);
360 if (!vr.undefined_p ())
362 min = wi::to_wide (vr_min);
363 max = wi::to_wide (vr_max);
367 if (rng == VR_ANTI_RANGE && wi::lts_p (max, min))
369 /* Convert an anti-range whose upper bound is less than
370 its lower bound to a signed range. */
371 offrange[0] += offset_int::from (max + 1, SIGNED);
372 offrange[1] += offset_int::from (min - 1, SIGNED);
373 return;
376 if (rng == VR_RANGE
377 && (DECL_P (base) || wi::lts_p (min, max)))
379 /* Preserve the bounds of the range for an offset into
380 a known object (it may be adjusted later relative to
381 a constant offset from its beginning). Otherwise use
382 the bounds only when they are ascending when treated
383 as signed. */
384 offrange[0] += offset_int::from (min, SIGNED);
385 offrange[1] += offset_int::from (max, SIGNED);
386 return;
389 /* Handle an anti-range the same as no range at all. */
390 gimple *stmt = SSA_NAME_DEF_STMT (offset);
391 tree type;
392 if (is_gimple_assign (stmt)
393 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
394 && INTEGRAL_TYPE_P (type)
395 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (offset)))
397 tree_code code = gimple_assign_rhs_code (stmt);
398 if (code == NOP_EXPR)
400 /* Use the bounds of the type of the NOP_EXPR operand
401 even if it's signed. The result doesn't trigger
402 warnings but makes their output more readable. */
403 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
404 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
405 return;
410 const offset_int maxoff = tree_to_shwi (max_object_size ()) >> 1;
411 const offset_int minoff = -maxoff - 1;
413 offrange[0] += minoff;
414 offrange[1] += maxoff;
417 /* Determines the base object or pointer of the reference EXPR
418 and the offset range from the beginning of the base. */
420 void
421 builtin_memref::set_base_and_offset (tree expr)
423 tree offset = NULL_TREE;
425 if (TREE_CODE (expr) == SSA_NAME)
427 /* Try to tease the offset out of the pointer. */
428 gimple *stmt = SSA_NAME_DEF_STMT (expr);
429 if (!base
430 && gimple_assign_single_p (stmt)
431 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
432 expr = gimple_assign_rhs1 (stmt);
433 else if (is_gimple_assign (stmt))
435 tree_code code = gimple_assign_rhs_code (stmt);
436 if (CONVERT_EXPR_CODE_P (code))
438 tree rhs = gimple_assign_rhs1 (stmt);
439 if (POINTER_TYPE_P (TREE_TYPE (rhs)))
440 expr = gimple_assign_rhs1 (stmt);
441 else
443 base = expr;
444 return;
447 else if (code == POINTER_PLUS_EXPR)
449 expr = gimple_assign_rhs1 (stmt);
450 offset = gimple_assign_rhs2 (stmt);
452 else
454 base = expr;
455 return;
458 else
460 /* FIXME: Handle PHI nodes in case like:
461 _12 = &MEM[(void *)&a + 2B] + _10;
463 <bb> [local count: 1073741824]:
464 # prephitmp_13 = PHI <_12, &MEM[(void *)&a + 2B]>
465 memcpy (prephitmp_13, p_7(D), 6); */
466 base = expr;
467 return;
471 if (TREE_CODE (expr) == ADDR_EXPR)
472 expr = TREE_OPERAND (expr, 0);
474 /* Stash the reference for offset validation. */
475 ref = expr;
477 poly_int64 bitsize, bitpos;
478 tree var_off;
479 machine_mode mode;
480 int sign, reverse, vol;
482 /* Determine the base object or pointer of the reference and
483 the constant bit offset from the beginning of the base.
484 If the offset has a non-constant component, it will be in
485 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
486 unused here. */
487 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
488 &mode, &sign, &reverse, &vol);
490 /* get_inner_reference is not expected to return null. */
491 gcc_assert (base != NULL);
493 if (offset)
494 extend_offset_range (offset);
496 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
498 /* Convert the poly_int64 offset to offset_int. The offset
499 should be constant but be prepared for it not to be just in
500 case. */
501 offset_int cstoff;
502 if (bytepos.is_constant (&cstoff))
504 offrange[0] += cstoff;
505 offrange[1] += cstoff;
507 /* Besides the reference saved above, also stash the offset
508 for validation. */
509 if (TREE_CODE (expr) == COMPONENT_REF)
510 refoff = cstoff;
512 else
513 offrange[1] += maxobjsize;
515 if (var_off)
517 if (TREE_CODE (var_off) == INTEGER_CST)
519 cstoff = wi::to_offset (var_off);
520 offrange[0] += cstoff;
521 offrange[1] += cstoff;
523 else
524 offrange[1] += maxobjsize;
527 if (TREE_CODE (base) == MEM_REF)
529 tree memrefoff = fold_convert (ptrdiff_type_node, TREE_OPERAND (base, 1));
530 extend_offset_range (memrefoff);
532 if (refoff != HOST_WIDE_INT_MIN
533 && TREE_CODE (expr) == COMPONENT_REF)
535 /* Bump up the offset of the referenced subobject to reflect
536 the offset to the enclosing object. For example, so that
538 struct S { char a, b[3]; } s[2];
539 strcpy (s[1].b, "1234");
540 REFOFF is set to s[1].b - (char*)s. */
541 offset_int off = tree_to_shwi (memrefoff);
542 refoff += off;
544 if (!integer_zerop (memrefoff)
545 && !COMPLETE_TYPE_P (TREE_TYPE (expr))
546 && multiple_of_p (sizetype, memrefoff,
547 TYPE_SIZE_UNIT (TREE_TYPE (base)), true))
548 /* A non-zero offset into an array of struct with flexible array
549 members implies that the array is empty because there is no
550 way to initialize such a member when it belongs to an array.
551 This must be some sort of a bug. */
552 refsize = 0;
555 base = TREE_OPERAND (base, 0);
558 if (TREE_CODE (ref) == COMPONENT_REF)
559 if (tree size = component_ref_size (ref))
560 if (TREE_CODE (size) == INTEGER_CST)
561 refsize = wi::to_offset (size);
563 if (TREE_CODE (base) == SSA_NAME)
564 set_base_and_offset (base);
567 /* Return error_mark_node if the signed offset exceeds the bounds
568 of the address space (PTRDIFF_MAX). Otherwise, return either BASE
569 or REF when the offset exceeds the bounds of the BASE or REF object,
570 and set OOBOFF to the past-the-end offset formed by the reference,
571 including its size. OOBOFF is initially setto the range of offsets,
572 and OOBOFF[2] to the offset of the first write access (nonzero for
573 the strcat family). When STRICT is nonzero use REF size, when
574 available, otherwise use BASE size. When STRICT is greater than 1,
575 use the size of the last array member as the bound, otherwise treat
576 such a member as a flexible array member. Return NULL when the offset
577 is in bounds. */
579 tree
580 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[3]) const
582 if (!ptr)
583 return NULL_TREE;
585 /* The offset of the first write access or zero. */
586 offset_int wroff = ooboff[2];
588 /* A temporary, possibly adjusted, copy of the offset range. */
589 offset_int offrng[2] = { ooboff[0], ooboff[1] };
591 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
593 /* Check for offset in an anti-range with a negative lower bound.
594 For such a range, consider only the non-negative subrange. */
595 if (offrng[1] < offrng[0] && offrng[1] < 0)
596 offrng[1] = maxobjsize;
599 /* Conservative offset of the last byte of the referenced object. */
600 offset_int endoff;
602 /* The bounds need not be ordered. Set HIB to use as the index
603 of the larger of the bounds and LOB as the opposite. */
604 bool hib = wi::les_p (offrng[0], offrng[1]);
605 bool lob = !hib;
607 /* Set to the size remaining in the object after subtracting
608 REFOFF. It may become negative as a result of negative indices
609 into the enclosing object, such as in:
610 extern struct S { char a[4], b[3], c[1]; } *p;
611 strcpy (p[-3].b, "123"); */
612 offset_int size = basesize;
613 tree obj = base;
615 const bool decl_p = DECL_P (obj);
617 if (basesize < 0)
619 endoff = offrng[lob] + (sizrange[0] - wroff);
621 /* For a reference through a pointer to an object of unknown size
622 all initial offsets are considered valid, positive as well as
623 negative, since the pointer itself can point past the beginning
624 of the object. However, the sum of the lower bound of the offset
625 and that of the size must be less than or equal than PTRDIFF_MAX. */
626 if (endoff > maxobjsize)
627 return error_mark_node;
629 /* When the referenced subobject is known, the end offset must be
630 within its bounds. Otherwise there is nothing to do. */
631 if (strict
632 && !decl_p
633 && ref
634 && refsize >= 0
635 && TREE_CODE (ref) == COMPONENT_REF)
637 /* If REFOFF is negative, SIZE will become negative here. */
638 size = refoff + refsize;
639 obj = ref;
641 else
642 return NULL_TREE;
645 /* A reference to an object of known size must be within the bounds
646 of either the base object or the subobject (see above for when
647 a subobject can be used). */
648 if ((decl_p && offrng[hib] < 0) || offrng[lob] > size)
649 return obj;
651 /* The extent of the reference must also be within the bounds of
652 the base object (if known) or the subobject or the maximum object
653 size otherwise. */
654 endoff = offrng[lob] + sizrange[0];
655 if (endoff > maxobjsize)
656 return error_mark_node;
658 if (strict
659 && decl_p
660 && ref
661 && refsize >= 0
662 && TREE_CODE (ref) == COMPONENT_REF)
664 /* If the reference is to a member subobject of a declared object,
665 the offset must be within the bounds of the subobject. */
666 size = refoff + refsize;
667 obj = ref;
670 if (endoff <= size)
671 return NULL_TREE;
673 /* Set the out-of-bounds offset range to be one greater than
674 that delimited by the reference including its size. */
675 ooboff[lob] = size;
677 if (endoff > ooboff[lob])
678 ooboff[hib] = endoff - 1;
679 else
680 ooboff[hib] = offrng[lob] + sizrange[1];
682 return obj;
685 /* Create an association between the memory references DST and SRC
686 for access by a call EXPR to a memory or string built-in funtion. */
688 builtin_access::builtin_access (pointer_query &ptrqry, gimple *call,
689 builtin_memref &dst,
690 builtin_memref &src)
691 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
692 dstoff (), srcoff (), dstsiz (), srcsiz ()
694 dstoff[0] = dst.offrange[0];
695 dstoff[1] = dst.offrange[1];
697 /* Zero out since the offset_int ctors invoked above are no-op. */
698 srcoff[0] = srcoff[1] = 0;
699 dstsiz[0] = dstsiz[1] = 0;
700 srcsiz[0] = srcsiz[1] = 0;
702 /* Object Size Type to use to determine the size of the destination
703 and source objects. Overridden below for raw memory functions. */
704 int ostype = 1;
706 /* True when the size of one reference depends on the offset of
707 itself or the other. */
708 bool depends_p = true;
710 /* True when the size of the destination reference DSTREF has been
711 determined from SRCREF and so needs to be adjusted by the latter's
712 offset. Only meaningful for bounded string functions like strncpy. */
713 bool dstadjust_p = false;
715 /* The size argument number (depends on the built-in). */
716 unsigned sizeargno = 2;
718 tree func = gimple_call_fndecl (call);
719 switch (DECL_FUNCTION_CODE (func))
721 case BUILT_IN_MEMCPY:
722 case BUILT_IN_MEMCPY_CHK:
723 case BUILT_IN_MEMPCPY:
724 case BUILT_IN_MEMPCPY_CHK:
725 ostype = 0;
726 depends_p = false;
727 detect_overlap = &builtin_access::generic_overlap;
728 break;
730 case BUILT_IN_MEMMOVE:
731 case BUILT_IN_MEMMOVE_CHK:
732 /* For memmove there is never any overlap to check for. */
733 ostype = 0;
734 depends_p = false;
735 detect_overlap = &builtin_access::no_overlap;
736 break;
738 case BUILT_IN_MEMSET:
739 case BUILT_IN_MEMSET_CHK:
740 /* For memset there is never any overlap to check for. */
741 ostype = 0;
742 depends_p = false;
743 detect_overlap = &builtin_access::no_overlap;
744 break;
746 case BUILT_IN_STPNCPY:
747 case BUILT_IN_STPNCPY_CHK:
748 case BUILT_IN_STRNCPY:
749 case BUILT_IN_STRNCPY_CHK:
750 dstref->strbounded_p = true;
751 detect_overlap = &builtin_access::strcpy_overlap;
752 break;
754 case BUILT_IN_STPCPY:
755 case BUILT_IN_STPCPY_CHK:
756 case BUILT_IN_STRCPY:
757 case BUILT_IN_STRCPY_CHK:
758 detect_overlap = &builtin_access::strcpy_overlap;
759 break;
761 case BUILT_IN_STRCAT:
762 case BUILT_IN_STRCAT_CHK:
763 detect_overlap = &builtin_access::strcat_overlap;
764 break;
766 case BUILT_IN_STRNCAT:
767 case BUILT_IN_STRNCAT_CHK:
768 dstref->strbounded_p = true;
769 srcref->strbounded_p = true;
770 detect_overlap = &builtin_access::strcat_overlap;
771 break;
773 default:
774 /* Handle other string functions here whose access may need
775 to be validated for in-bounds offsets and non-overlapping
776 copies. */
777 return;
780 /* Try to determine the size of the base object. compute_objsize
781 expects a pointer so create one if BASE is a non-pointer object. */
782 if (dst.basesize < 0)
784 access_ref aref;
785 if (ptrqry.get_ref (dst.base, call, &aref, ostype) && aref.base0)
786 dst.basesize = aref.sizrng[1];
787 else
788 dst.basesize = HOST_WIDE_INT_MIN;
791 if (src.base && src.basesize < 0)
793 access_ref aref;
794 if (ptrqry.get_ref (src.base, call, &aref, ostype) && aref.base0)
795 src.basesize = aref.sizrng[1];
796 else
797 src.basesize = HOST_WIDE_INT_MIN;
800 const offset_int maxobjsize = dst.maxobjsize;
802 /* Make adjustments for references to the same object by string
803 built-in functions to reflect the constraints imposed by
804 the function. */
806 /* For bounded string functions determine the range of the bound
807 on the access. For others, the range stays unbounded. */
808 offset_int bounds[2] = { maxobjsize, maxobjsize };
809 if (dstref->strbounded_p)
811 unsigned nargs = gimple_call_num_args (call);
812 if (nargs <= sizeargno)
813 return;
815 tree size = gimple_call_arg (call, sizeargno);
816 tree range[2];
817 if (get_size_range (ptrqry.rvals, size, call, range, true))
819 bounds[0] = wi::to_offset (range[0]);
820 bounds[1] = wi::to_offset (range[1]);
823 /* If both references' size ranges are indeterminate use the last
824 (size) argument from the function call as a substitute. This
825 may only be necessary for strncpy (but not for memcpy where
826 the size range would have been already determined this way). */
827 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
828 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
830 dstref->sizrange[0] = bounds[0];
831 dstref->sizrange[1] = bounds[1];
835 bool dstsize_set = false;
836 /* The size range of one reference involving the same base object
837 can be determined from the size range of the other reference.
838 This makes it possible to compute accurate offsets for warnings
839 involving functions like strcpy where the length of just one of
840 the two arguments is known (determined by tree-ssa-strlen). */
841 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
843 /* When the destination size is unknown set it to the size of
844 the source. */
845 dstref->sizrange[0] = srcref->sizrange[0];
846 dstref->sizrange[1] = srcref->sizrange[1];
847 dstsize_set = true;
849 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
851 /* When the size of the source access is unknown set it to the size
852 of the destination first and adjust it later if necessary. */
853 srcref->sizrange[0] = dstref->sizrange[0];
854 srcref->sizrange[1] = dstref->sizrange[1];
856 if (depends_p)
858 if (dstref->strbounded_p)
860 /* Read access by strncpy is constrained by the third
861 argument but except for a zero bound is at least one. */
862 srcref->sizrange[0] = bounds[1] > 0 ? 1 : 0;
863 offset_int bound = wi::umin (srcref->basesize, bounds[1]);
864 if (bound < srcref->sizrange[1])
865 srcref->sizrange[1] = bound;
867 /* For string functions, adjust the size range of the source
868 reference by the inverse boundaries of the offset (because
869 the higher the offset into the string the shorter its
870 length). */
871 if (srcref->offrange[1] >= 0
872 && srcref->offrange[1] < srcref->sizrange[0])
873 srcref->sizrange[0] -= srcref->offrange[1];
874 else
875 srcref->sizrange[0] = 1;
877 if (srcref->offrange[0] > 0)
879 if (srcref->offrange[0] < srcref->sizrange[1])
880 srcref->sizrange[1] -= srcref->offrange[0];
881 else
882 srcref->sizrange[1] = 0;
885 dstadjust_p = true;
889 if (detect_overlap == &builtin_access::generic_overlap)
891 if (dstref->strbounded_p)
893 dstref->sizrange[0] = bounds[0];
894 dstref->sizrange[1] = bounds[1];
896 if (dstref->sizrange[0] < srcref->sizrange[0])
897 srcref->sizrange[0] = dstref->sizrange[0];
899 if (dstref->sizrange[1] < srcref->sizrange[1])
900 srcref->sizrange[1] = dstref->sizrange[1];
903 else if (detect_overlap == &builtin_access::strcpy_overlap)
905 if (!dstref->strbounded_p)
907 /* For strcpy, adjust the destination size range to match that
908 of the source computed above. */
909 if (depends_p && dstadjust_p)
911 dstref->sizrange[0] = srcref->sizrange[0];
912 dstref->sizrange[1] = srcref->sizrange[1];
916 else if (!dstsize_set && detect_overlap == &builtin_access::strcat_overlap)
918 dstref->sizrange[0] += srcref->sizrange[0] - 1;
919 dstref->sizrange[1] += srcref->sizrange[1] - 1;
922 if (dstref->strbounded_p)
924 /* For strncpy, adjust the destination size range to match that
925 of the source computed above. */
926 dstref->sizrange[0] = bounds[0];
927 dstref->sizrange[1] = bounds[1];
929 if (bounds[0] < srcref->sizrange[0])
930 srcref->sizrange[0] = bounds[0];
932 if (bounds[1] < srcref->sizrange[1])
933 srcref->sizrange[1] = bounds[1];
937 offset_int
938 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
939 offset_int *off)
941 const offset_int *p = a;
942 const offset_int *q = b;
944 /* Point P at the bigger of the two ranges and Q at the smaller. */
945 if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
947 p = b;
948 q = a;
951 if (p[0] < q[0])
953 if (p[1] < q[0])
954 return 0;
956 *off = q[0];
957 return wi::smin (p[1], q[1]) - q[0];
960 if (q[1] < p[0])
961 return 0;
963 off[0] = p[0];
964 return q[1] - p[0];
967 /* Return true if the bounded mempry (memcpy amd similar) or string function
968 access (strncpy and similar) ACS overlaps. */
970 bool
971 builtin_access::generic_overlap ()
973 builtin_access &acs = *this;
974 const builtin_memref *dstref = acs.dstref;
975 const builtin_memref *srcref = acs.srcref;
977 gcc_assert (dstref->base == srcref->base);
979 const offset_int maxobjsize = acs.dstref->maxobjsize;
981 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
983 /* Adjust the larger bounds of the offsets (which may be the first
984 element if the lower bound is larger than the upper bound) to
985 make them valid for the smallest access (if possible) but no smaller
986 than the smaller bounds. */
987 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
989 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
990 acs.dstoff[1] = maxsize - acs.dstsiz[0];
991 if (acs.dstoff[1] < acs.dstoff[0])
992 acs.dstoff[1] = acs.dstoff[0];
994 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
996 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
997 acs.srcoff[1] = maxsize - acs.srcsiz[0];
998 if (acs.srcoff[1] < acs.srcoff[0])
999 acs.srcoff[1] = acs.srcoff[0];
1001 /* Determine the minimum and maximum space for the access given
1002 the offsets. */
1003 offset_int space[2];
1004 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1005 space[1] = space[0];
1007 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1008 if (acs.srcsiz[0] > 0)
1010 if (d < space[0])
1011 space[0] = d;
1013 if (space[1] < d)
1014 space[1] = d;
1016 else
1017 space[1] = acs.dstsiz[1];
1019 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1020 if (d < space[0])
1021 space[0] = d;
1023 if (space[1] < d)
1024 space[1] = d;
1026 /* Treat raw memory functions both of whose references are bounded
1027 as special and permit uncertain overlaps to go undetected. For
1028 all kinds of constant offset and constant size accesses, if
1029 overlap isn't certain it is not possible. */
1030 bool overlap_possible = space[0] < acs.dstsiz[1];
1031 if (!overlap_possible)
1032 return false;
1034 bool overlap_certain = space[1] < acs.dstsiz[0];
1036 /* True when the size of one reference depends on the offset of
1037 the other. */
1038 bool depends_p = detect_overlap != &builtin_access::generic_overlap;
1040 if (!overlap_certain)
1042 if (!dstref->strbounded_p && !depends_p)
1043 /* Memcpy only considers certain overlap. */
1044 return false;
1046 /* There's no way to distinguish an access to the same member
1047 of a structure from one to two distinct members of the same
1048 structure. Give up to avoid excessive false positives. */
1049 tree basetype = TREE_TYPE (dstref->base);
1051 if (POINTER_TYPE_P (basetype))
1052 basetype = TREE_TYPE (basetype);
1053 else
1054 while (TREE_CODE (basetype) == ARRAY_TYPE)
1055 basetype = TREE_TYPE (basetype);
1057 if (RECORD_OR_UNION_TYPE_P (basetype))
1058 return false;
1061 /* True for stpcpy and strcpy. */
1062 bool stxcpy_p = (!dstref->strbounded_p
1063 && detect_overlap == &builtin_access::strcpy_overlap);
1065 if (dstref->refoff >= 0
1066 && srcref->refoff >= 0
1067 && dstref->refoff != srcref->refoff
1068 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
1069 return false;
1071 offset_int siz[2] = { maxobjsize + 1, 0 };
1073 ovloff[0] = HOST_WIDE_INT_MAX;
1074 ovloff[1] = HOST_WIDE_INT_MIN;
1076 if (stxcpy_p)
1078 /* Iterate over the extreme locations (on the horizontal axis formed
1079 by their offsets) and sizes of two regions and find their smallest
1080 and largest overlap and the corresponding offsets. */
1081 for (unsigned i = 0; i != 2; ++i)
1083 const offset_int a[2] = {
1084 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
1087 const offset_int b[2] = {
1088 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
1091 offset_int off;
1092 offset_int sz = overlap_size (a, b, &off);
1093 if (sz < siz[0])
1094 siz[0] = sz;
1096 if (siz[1] <= sz)
1097 siz[1] = sz;
1099 if (sz != 0)
1101 if (wi::lts_p (off, ovloff[0]))
1102 ovloff[0] = off.to_shwi ();
1103 if (wi::lts_p (ovloff[1], off))
1104 ovloff[1] = off.to_shwi ();
1108 else
1110 /* Iterate over the extreme locations (on the horizontal axis
1111 formed by their offsets) and sizes of the two regions and
1112 find their smallest and largest overlap and the corresponding
1113 offsets. */
1115 for (unsigned io = 0; io != 2; ++io)
1116 for (unsigned is = 0; is != 2; ++is)
1118 const offset_int a[2] = {
1119 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1122 for (unsigned jo = 0; jo != 2; ++jo)
1123 for (unsigned js = 0; js != 2; ++js)
1125 const offset_int b[2] = {
1126 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1129 offset_int off;
1130 offset_int sz = overlap_size (a, b, &off);
1131 if (sz < siz[0])
1132 siz[0] = sz;
1134 if (siz[1] <= sz)
1135 siz[1] = sz;
1137 if (sz != 0)
1139 if (wi::lts_p (off, ovloff[0]))
1140 ovloff[0] = off.to_shwi ();
1141 if (wi::lts_p (ovloff[1], off))
1142 ovloff[1] = off.to_shwi ();
1148 ovlsiz[0] = siz[0].to_shwi ();
1149 ovlsiz[1] = siz[1].to_shwi ();
1151 /* Adjust the overlap offset range to reflect the overlap size range. */
1152 if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1153 ovloff[1] = ovloff[0] + ovlsiz[1] - 1;
1155 return true;
1158 /* Return true if the strcat-like access overlaps. */
1160 bool
1161 builtin_access::strcat_overlap ()
1163 builtin_access &acs = *this;
1164 const builtin_memref *dstref = acs.dstref;
1165 const builtin_memref *srcref = acs.srcref;
1167 gcc_assert (dstref->base == srcref->base);
1169 const offset_int maxobjsize = acs.dstref->maxobjsize;
1171 gcc_assert (dstref->base && dstref->base == srcref->base);
1173 /* Adjust for strcat-like accesses. */
1175 /* As a special case for strcat, set the DSTREF offsets to the length
1176 of the destination string since the function starts writing over
1177 its terminating nul, and set the destination size to 1 for the length
1178 of the nul. */
1179 acs.dstoff[0] += dstsiz[0] - srcref->sizrange[0];
1180 acs.dstoff[1] += dstsiz[1] - srcref->sizrange[1];
1182 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1184 /* The lower bound is zero when the size is unknown because then
1185 overlap is not certain. */
1186 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1187 acs.dstsiz[1] = 1;
1189 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1191 /* For references to the same base object, determine if there's a pair
1192 of valid offsets into the two references such that access between
1193 them doesn't overlap. Adjust both upper bounds to be valid for
1194 the smaller size (i.e., at most MAXSIZE - SIZE). */
1196 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1197 acs.dstoff[1] = maxsize - acs.dstsiz[0];
1199 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1200 acs.srcoff[1] = maxsize - acs.srcsiz[0];
1202 /* Check to see if there's enough space for both accesses without
1203 overlap. Determine the optimistic (maximum) amount of available
1204 space. */
1205 offset_int space;
1206 if (acs.dstoff[0] <= acs.srcoff[0])
1208 if (acs.dstoff[1] < acs.srcoff[1])
1209 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1210 else
1211 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1213 else
1214 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1216 /* Overlap is certain if the distance between the farthest offsets
1217 of the opposite accesses is less than the sum of the lower bounds
1218 of the sizes of the two accesses. */
1219 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1221 /* For a constant-offset, constant size access, consider the largest
1222 distance between the offset bounds and the lower bound of the access
1223 size. If the overlap isn't certain return success. */
1224 if (!overlap_certain
1225 && acs.dstoff[0] == acs.dstoff[1]
1226 && acs.srcoff[0] == acs.srcoff[1]
1227 && acs.dstsiz[0] == acs.dstsiz[1]
1228 && acs.srcsiz[0] == acs.srcsiz[1])
1229 return false;
1231 /* Overlap is not certain but may be possible. */
1233 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1235 /* Determine the conservative (minimum) amount of space. */
1236 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1237 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1238 if (d < space)
1239 space = d;
1240 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1241 if (d < space)
1242 space = d;
1244 /* For a strict test (used for strcpy and similar with unknown or
1245 variable bounds or sizes), consider the smallest distance between
1246 the offset bounds and either the upper bound of the access size
1247 if known, or the lower bound otherwise. */
1248 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1249 return false;
1251 /* When strcat overlap is certain it is always a single byte:
1252 the terminating NUL, regardless of offsets and sizes. When
1253 overlap is only possible its range is [0, 1]. */
1254 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1255 acs.ovlsiz[1] = 1;
1257 offset_int endoff
1258 = dstref->offrange[0] + (dstref->sizrange[0] - srcref->sizrange[0]);
1259 if (endoff <= srcref->offrange[0])
1260 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1261 else
1262 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1264 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1265 srcref->sizrange[0]).to_shwi ();
1266 if (dstref->offrange[0] == dstref->offrange[1])
1268 if (srcref->offrange[0] == srcref->offrange[1])
1269 acs.ovloff[1] = acs.ovloff[0];
1270 else
1271 acs.ovloff[1]
1272 = wi::smin (maxobjsize,
1273 srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1275 else
1276 acs.ovloff[1]
1277 = wi::smin (maxobjsize,
1278 dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1280 if (acs.sizrange[0] == 0)
1281 acs.sizrange[0] = 1;
1282 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1283 return true;
1286 /* Return true if the strcpy-like access overlaps. */
1288 bool
1289 builtin_access::strcpy_overlap ()
1291 return generic_overlap ();
1294 /* For a BASE of array type, clamp REFOFF to at most [0, BASE_SIZE]
1295 if known, or [0, MAXOBJSIZE] otherwise. */
1297 static void
1298 clamp_offset (tree base, offset_int refoff[2], offset_int maxobjsize)
1300 if (!base || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
1301 return;
1303 if (refoff[0] < 0 && refoff[1] >= 0)
1304 refoff[0] = 0;
1306 if (refoff[1] < refoff[0])
1308 offset_int maxsize = maxobjsize;
1309 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (base)))
1310 maxsize = wi::to_offset (size);
1312 refoff[1] = wi::umin (refoff[1], maxsize);
1316 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1317 one another or that, in order not to overlap, would imply that the size
1318 of the referenced object(s) exceeds the maximum size of an object. Set
1319 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1320 they may overlap in a way that's not apparent from the available data),
1321 return false. */
1323 bool
1324 builtin_access::overlap ()
1326 builtin_access &acs = *this;
1328 const offset_int maxobjsize = dstref->maxobjsize;
1330 acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1331 srcref->sizrange[0]).to_shwi ();
1332 acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1333 srcref->sizrange[1]).to_shwi ();
1335 /* Check to see if the two references refer to regions that are
1336 too large not to overlap in the address space (whose maximum
1337 size is PTRDIFF_MAX). */
1338 offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1339 if (maxobjsize < size)
1341 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1342 acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1343 return true;
1346 /* If both base objects aren't known return the maximum possible
1347 offset that would make them not overlap. */
1348 if (!dstref->base || !srcref->base)
1349 return false;
1351 /* If the base object is an array adjust the bounds of the offset
1352 to be non-negative and within the bounds of the array if possible. */
1353 clamp_offset (dstref->base, acs.dstoff, maxobjsize);
1355 acs.srcoff[0] = srcref->offrange[0];
1356 acs.srcoff[1] = srcref->offrange[1];
1358 clamp_offset (srcref->base, acs.srcoff, maxobjsize);
1360 /* When the upper bound of the offset is less than the lower bound
1361 the former is the result of a negative offset being represented
1362 as a large positive value or vice versa. The resulting range is
1363 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1364 a union is not representable using the current data structure
1365 replace it with the full range of offsets. */
1366 if (acs.dstoff[1] < acs.dstoff[0])
1368 acs.dstoff[0] = -maxobjsize - 1;
1369 acs.dstoff[1] = maxobjsize;
1372 /* Validate the offset and size of each reference on its own first.
1373 This is independent of whether or not the base objects are the
1374 same. Normally, this would have already been detected and
1375 diagnosed by -Warray-bounds, unless it has been disabled. */
1376 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1377 if (maxobjsize < maxoff)
1379 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1380 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1381 return true;
1384 /* Repeat the same as above but for the source offsets. */
1385 if (acs.srcoff[1] < acs.srcoff[0])
1387 acs.srcoff[0] = -maxobjsize - 1;
1388 acs.srcoff[1] = maxobjsize;
1391 maxoff = acs.srcoff[0] + srcref->sizrange[0];
1392 if (maxobjsize < maxoff)
1394 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1395 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1396 - maxobjsize).to_shwi ();
1397 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1398 return true;
1401 if (dstref->base != srcref->base)
1402 return false;
1404 acs.dstsiz[0] = dstref->sizrange[0];
1405 acs.dstsiz[1] = dstref->sizrange[1];
1407 acs.srcsiz[0] = srcref->sizrange[0];
1408 acs.srcsiz[1] = srcref->sizrange[1];
1410 /* Call the appropriate function to determine the overlap. */
1411 if ((this->*detect_overlap) ())
1413 if (!sizrange[1])
1415 /* Unless the access size range has already been set, do so here. */
1416 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1417 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1419 return true;
1422 return false;
1425 /* Attempt to detect and diagnose an overlapping copy in a call expression
1426 EXPR involving an access ACS to a built-in memory or string function.
1427 Return true when one has been detected, false otherwise. */
1429 static bool
1430 maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
1432 if (!acs.overlap ())
1433 return false;
1435 if (warning_suppressed_p (call, OPT_Wrestrict))
1436 return true;
1438 /* For convenience. */
1439 const builtin_memref &dstref = *acs.dstref;
1440 const builtin_memref &srcref = *acs.srcref;
1442 /* Determine the range of offsets and sizes of the overlap if it
1443 exists and issue diagnostics. */
1444 HOST_WIDE_INT *ovloff = acs.ovloff;
1445 HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1446 HOST_WIDE_INT *sizrange = acs.sizrange;
1448 tree func = gimple_call_fndecl (call);
1450 /* To avoid a combinatorial explosion of diagnostics format the offsets
1451 or their ranges as strings and use them in the warning calls below. */
1452 char offstr[3][64];
1454 if (dstref.offrange[0] == dstref.offrange[1]
1455 || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1456 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1457 dstref.offrange[0].to_shwi ());
1458 else
1459 sprintf (offstr[0],
1460 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1461 dstref.offrange[0].to_shwi (),
1462 dstref.offrange[1].to_shwi ());
1464 if (srcref.offrange[0] == srcref.offrange[1]
1465 || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1466 sprintf (offstr[1],
1467 HOST_WIDE_INT_PRINT_DEC,
1468 srcref.offrange[0].to_shwi ());
1469 else
1470 sprintf (offstr[1],
1471 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1472 srcref.offrange[0].to_shwi (),
1473 srcref.offrange[1].to_shwi ());
1475 if (ovloff[0] == ovloff[1] || !ovloff[1])
1476 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1477 else
1478 sprintf (offstr[2],
1479 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1480 ovloff[0], ovloff[1]);
1482 const offset_int maxobjsize = dstref.maxobjsize;
1483 bool must_overlap = ovlsiz[0] > 0;
1485 if (ovlsiz[1] == 0)
1486 ovlsiz[1] = ovlsiz[0];
1488 if (must_overlap)
1490 /* Issue definitive "overlaps" diagnostic in this block. */
1492 if (sizrange[0] == sizrange[1])
1494 if (ovlsiz[0] == ovlsiz[1])
1495 warning_at (loc, OPT_Wrestrict,
1496 sizrange[0] == 1
1497 ? (ovlsiz[0] == 1
1498 ? G_("%qD accessing %wu byte at offsets %s "
1499 "and %s overlaps %wu byte at offset %s")
1500 : G_("%qD accessing %wu byte at offsets %s "
1501 "and %s overlaps %wu bytes at offset "
1502 "%s"))
1503 : (ovlsiz[0] == 1
1504 ? G_("%qD accessing %wu bytes at offsets %s "
1505 "and %s overlaps %wu byte at offset %s")
1506 : G_("%qD accessing %wu bytes at offsets %s "
1507 "and %s overlaps %wu bytes at offset "
1508 "%s")),
1509 func, sizrange[0],
1510 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1511 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1512 warning_n (loc, OPT_Wrestrict, sizrange[0],
1513 "%qD accessing %wu byte at offsets %s "
1514 "and %s overlaps between %wu and %wu bytes "
1515 "at offset %s",
1516 "%qD accessing %wu bytes at offsets %s "
1517 "and %s overlaps between %wu and %wu bytes "
1518 "at offset %s",
1519 func, sizrange[0], offstr[0], offstr[1],
1520 ovlsiz[0], ovlsiz[1], offstr[2]);
1521 else
1522 warning_n (loc, OPT_Wrestrict, sizrange[0],
1523 "%qD accessing %wu byte at offsets %s and "
1524 "%s overlaps %wu or more bytes at offset %s",
1525 "%qD accessing %wu bytes at offsets %s and "
1526 "%s overlaps %wu or more bytes at offset %s",
1527 func, sizrange[0],
1528 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1529 return true;
1532 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1534 if (ovlsiz[0] == ovlsiz[1])
1535 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1536 "%qD accessing between %wu and %wu bytes "
1537 "at offsets %s and %s overlaps %wu byte at "
1538 "offset %s",
1539 "%qD accessing between %wu and %wu bytes "
1540 "at offsets %s and %s overlaps %wu bytes "
1541 "at offset %s",
1542 func, sizrange[0], sizrange[1],
1543 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1544 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1545 warning_at (loc, OPT_Wrestrict,
1546 "%qD accessing between %wu and %wu bytes at "
1547 "offsets %s and %s overlaps between %wu and %wu "
1548 "bytes at offset %s",
1549 func, sizrange[0], sizrange[1],
1550 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1551 offstr[2]);
1552 else
1553 warning_at (loc, OPT_Wrestrict,
1554 "%qD accessing between %wu and %wu bytes at "
1555 "offsets %s and %s overlaps %wu or more bytes "
1556 "at offset %s",
1557 func, sizrange[0], sizrange[1],
1558 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1559 return true;
1562 if (ovlsiz[0] != ovlsiz[1])
1563 ovlsiz[1] = maxobjsize.to_shwi ();
1565 if (ovlsiz[0] == ovlsiz[1])
1566 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1567 "%qD accessing %wu or more bytes at offsets "
1568 "%s and %s overlaps %wu byte at offset %s",
1569 "%qD accessing %wu or more bytes at offsets "
1570 "%s and %s overlaps %wu bytes at offset %s",
1571 func, sizrange[0], offstr[0], offstr[1],
1572 ovlsiz[0], offstr[2]);
1573 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1574 warning_at (loc, OPT_Wrestrict,
1575 "%qD accessing %wu or more bytes at offsets %s "
1576 "and %s overlaps between %wu and %wu bytes "
1577 "at offset %s",
1578 func, sizrange[0], offstr[0], offstr[1],
1579 ovlsiz[0], ovlsiz[1], offstr[2]);
1580 else
1581 warning_at (loc, OPT_Wrestrict,
1582 "%qD accessing %wu or more bytes at offsets %s "
1583 "and %s overlaps %wu or more bytes at offset %s",
1584 func, sizrange[0], offstr[0], offstr[1],
1585 ovlsiz[0], offstr[2]);
1586 return true;
1589 /* Use more concise wording when one of the offsets is unbounded
1590 to avoid confusing the user with large and mostly meaningless
1591 numbers. */
1592 bool open_range;
1593 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1594 open_range = ((dstref.offrange[0] == 0
1595 && dstref.offrange[1] == maxobjsize)
1596 || (srcref.offrange[0] == 0
1597 && srcref.offrange[1] == maxobjsize));
1598 else
1599 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1600 && dstref.offrange[1] == maxobjsize)
1601 || (srcref.offrange[0] == -maxobjsize - 1
1602 && srcref.offrange[1] == maxobjsize));
1604 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1606 if (ovlsiz[1] == 1)
1608 if (open_range)
1609 warning_n (loc, OPT_Wrestrict, sizrange[1],
1610 "%qD accessing %wu byte may overlap "
1611 "%wu byte",
1612 "%qD accessing %wu bytes may overlap "
1613 "%wu byte",
1614 func, sizrange[1], ovlsiz[1]);
1615 else
1616 warning_n (loc, OPT_Wrestrict, sizrange[1],
1617 "%qD accessing %wu byte at offsets %s "
1618 "and %s may overlap %wu byte at offset %s",
1619 "%qD accessing %wu bytes at offsets %s "
1620 "and %s may overlap %wu byte at offset %s",
1621 func, sizrange[1], offstr[0], offstr[1],
1622 ovlsiz[1], offstr[2]);
1623 return true;
1626 if (open_range)
1627 warning_n (loc, OPT_Wrestrict, sizrange[1],
1628 "%qD accessing %wu byte may overlap "
1629 "up to %wu bytes",
1630 "%qD accessing %wu bytes may overlap "
1631 "up to %wu bytes",
1632 func, sizrange[1], ovlsiz[1]);
1633 else
1634 warning_n (loc, OPT_Wrestrict, sizrange[1],
1635 "%qD accessing %wu byte at offsets %s and "
1636 "%s may overlap up to %wu bytes at offset %s",
1637 "%qD accessing %wu bytes at offsets %s and "
1638 "%s may overlap up to %wu bytes at offset %s",
1639 func, sizrange[1], offstr[0], offstr[1],
1640 ovlsiz[1], offstr[2]);
1641 return true;
1644 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1646 if (open_range)
1647 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1648 "%qD accessing between %wu and %wu bytes "
1649 "may overlap %wu byte",
1650 "%qD accessing between %wu and %wu bytes "
1651 "may overlap up to %wu bytes",
1652 func, sizrange[0], sizrange[1], ovlsiz[1]);
1653 else
1654 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1655 "%qD accessing between %wu and %wu bytes "
1656 "at offsets %s and %s may overlap %wu byte "
1657 "at offset %s",
1658 "%qD accessing between %wu and %wu bytes "
1659 "at offsets %s and %s may overlap up to %wu "
1660 "bytes at offset %s",
1661 func, sizrange[0], sizrange[1],
1662 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1663 return true;
1666 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1667 "%qD accessing %wu or more bytes at offsets %s "
1668 "and %s may overlap %wu byte at offset %s",
1669 "%qD accessing %wu or more bytes at offsets %s "
1670 "and %s may overlap up to %wu bytes at offset %s",
1671 func, sizrange[0], offstr[0], offstr[1],
1672 ovlsiz[1], offstr[2]);
1674 return true;
1677 /* Validate REF size and offsets in an expression passed as an argument
1678 to a CALL to a built-in function FUNC to make sure they are within
1679 the bounds of the referenced object if its size is known, or
1680 PTRDIFF_MAX otherwise. DO_WARN is true when a diagnostic should
1681 be issued, false otherwise.
1682 Both initial values of the offsets and their final value computed
1683 by the function by incrementing the initial value by the size are
1684 validated. Return the warning number if the offsets are not valid
1685 and a diagnostic has been issued, or would have been issued if
1686 DO_WARN had been true, otherwise an invalid warning number. */
1688 static opt_code
1689 maybe_diag_access_bounds (gimple *call, tree func, int strict,
1690 const builtin_memref &ref, offset_int wroff,
1691 bool do_warn)
1693 location_t loc = gimple_location (call);
1694 const offset_int maxobjsize = ref.maxobjsize;
1696 /* Check for excessive size first and regardless of warning options
1697 since the result is used to make codegen decisions. */
1698 if (ref.sizrange[0] > maxobjsize)
1700 const opt_code opt = OPT_Wstringop_overflow_;
1701 /* Return true without issuing a warning. */
1702 if (!do_warn)
1703 return opt;
1705 if (ref.ref && warning_suppressed_p (ref.ref, OPT_Wstringop_overflow_))
1706 return no_warning;
1708 bool warned = false;
1709 if (warn_stringop_overflow)
1711 if (ref.sizrange[0] == ref.sizrange[1])
1712 warned = warning_at (loc, opt,
1713 "%qD specified bound %wu "
1714 "exceeds maximum object size %wu",
1715 func, ref.sizrange[0].to_uhwi (),
1716 maxobjsize.to_uhwi ());
1717 else
1718 warned = warning_at (loc, opt,
1719 "%qD specified bound between %wu and %wu "
1720 "exceeds maximum object size %wu",
1721 func, ref.sizrange[0].to_uhwi (),
1722 ref.sizrange[1].to_uhwi (),
1723 maxobjsize.to_uhwi ());
1724 return warned ? opt : no_warning;
1728 /* Check for out-bounds pointers regardless of warning options since
1729 the result is used to make codegen decisions. An excessive WROFF
1730 can only come up as a result of an invalid strncat bound and is
1731 diagnosed separately using a more meaningful warning. */
1732 if (maxobjsize < wroff)
1733 wroff = 0;
1734 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1], wroff };
1735 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1736 if (!oobref)
1737 return no_warning;
1739 const opt_code opt = OPT_Warray_bounds_;
1740 /* Return true without issuing a warning. */
1741 if (!do_warn)
1742 return opt;
1744 if (!warn_array_bounds)
1745 return no_warning;
1747 if (warning_suppressed_p (ref.ptr, opt)
1748 || (ref.ref && warning_suppressed_p (ref.ref, opt)))
1749 return no_warning;
1751 char rangestr[2][64];
1752 if (ooboff[0] == ooboff[1]
1753 || (ooboff[0] != ref.offrange[0]
1754 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1755 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1756 else
1757 sprintf (rangestr[0], "[%lli, %lli]",
1758 (long long) ooboff[0].to_shwi (),
1759 (long long) ooboff[1].to_shwi ());
1761 bool warned = false;
1763 if (oobref == error_mark_node)
1765 if (ref.sizrange[0] == ref.sizrange[1])
1766 sprintf (rangestr[1], "%llu",
1767 (unsigned long long) ref.sizrange[0].to_shwi ());
1768 else
1769 sprintf (rangestr[1], "[%lli, %lli]",
1770 (unsigned long long) ref.sizrange[0].to_uhwi (),
1771 (unsigned long long) ref.sizrange[1].to_uhwi ());
1773 tree type;
1775 if (DECL_P (ref.base)
1776 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1778 auto_diagnostic_group d;
1779 if (warning_at (loc, opt,
1780 "%qD pointer overflow between offset %s "
1781 "and size %s accessing array %qD with type %qT",
1782 func, rangestr[0], rangestr[1], ref.base, type))
1784 inform (DECL_SOURCE_LOCATION (ref.base),
1785 "array %qD declared here", ref.base);
1786 warned = true;
1788 else
1789 warned = warning_at (loc, opt,
1790 "%qD pointer overflow between offset %s "
1791 "and size %s",
1792 func, rangestr[0], rangestr[1]);
1794 else
1795 warned = warning_at (loc, opt,
1796 "%qD pointer overflow between offset %s "
1797 "and size %s",
1798 func, rangestr[0], rangestr[1]);
1800 else if (oobref == ref.base)
1802 /* True when the offset formed by an access to the reference
1803 is out of bounds, rather than the initial offset wich is
1804 in bounds. This implies access past the end. */
1805 bool form = ooboff[0] != ref.offrange[0];
1807 if (DECL_P (ref.base))
1809 auto_diagnostic_group d;
1810 if ((ref.basesize < maxobjsize
1811 && warning_at (loc, opt,
1812 form
1813 ? G_("%qD forming offset %s is out of "
1814 "the bounds [0, %wu] of object %qD with "
1815 "type %qT")
1816 : G_("%qD offset %s is out of the bounds "
1817 "[0, %wu] of object %qD with type %qT"),
1818 func, rangestr[0], ref.basesize.to_uhwi (),
1819 ref.base, TREE_TYPE (ref.base)))
1820 || warning_at (loc, opt,
1821 form
1822 ? G_("%qD forming offset %s is out of "
1823 "the bounds of object %qD with type %qT")
1824 : G_("%qD offset %s is out of the bounds "
1825 "of object %qD with type %qT"),
1826 func, rangestr[0],
1827 ref.base, TREE_TYPE (ref.base)))
1829 inform (DECL_SOURCE_LOCATION (ref.base),
1830 "%qD declared here", ref.base);
1831 warned = true;
1834 else if (ref.basesize < maxobjsize)
1835 warned = warning_at (loc, opt,
1836 form
1837 ? G_("%qD forming offset %s is out "
1838 "of the bounds [0, %wu]")
1839 : G_("%qD offset %s is out "
1840 "of the bounds [0, %wu]"),
1841 func, rangestr[0], ref.basesize.to_uhwi ());
1842 else
1843 warned = warning_at (loc, opt,
1844 form
1845 ? G_("%qD forming offset %s is out of bounds")
1846 : G_("%qD offset %s is out of bounds"),
1847 func, rangestr[0]);
1849 else if (TREE_CODE (ref.ref) == MEM_REF)
1851 tree refop = TREE_OPERAND (ref.ref, 0);
1852 tree type = TREE_TYPE (refop);
1853 if (POINTER_TYPE_P (type))
1854 type = TREE_TYPE (type);
1855 type = TYPE_MAIN_VARIANT (type);
1857 if (warning_at (loc, opt,
1858 "%qD offset %s from the object at %qE is out "
1859 "of the bounds of %qT",
1860 func, rangestr[0], ref.base, type))
1862 if (TREE_CODE (ref.ref) == COMPONENT_REF)
1863 refop = TREE_OPERAND (ref.ref, 1);
1864 if (DECL_P (refop))
1865 inform (DECL_SOURCE_LOCATION (refop),
1866 "subobject %qD declared here", refop);
1867 warned = true;
1870 else
1872 tree refop = TREE_OPERAND (ref.ref, 0);
1873 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1875 if (warning_at (loc, opt,
1876 "%qD offset %s from the object at %qE is out "
1877 "of the bounds of referenced subobject %qD with "
1878 "type %qT at offset %wi",
1879 func, rangestr[0], ref.base,
1880 TREE_OPERAND (ref.ref, 1), type,
1881 ref.refoff.to_shwi ()))
1883 if (TREE_CODE (ref.ref) == COMPONENT_REF)
1884 refop = TREE_OPERAND (ref.ref, 1);
1885 if (DECL_P (refop))
1886 inform (DECL_SOURCE_LOCATION (refop),
1887 "subobject %qD declared here", refop);
1888 warned = true;
1892 return warned ? opt : no_warning;
1895 /* Check a CALL statement for restrict-violations and issue warnings
1896 if/when appropriate. */
1898 void
1899 pass_wrestrict::check_call (gimple *call)
1901 /* Avoid checking the call if it has already been diagnosed for
1902 some reason. */
1903 if (warning_suppressed_p (call, OPT_Wrestrict))
1904 return;
1906 tree func = gimple_call_fndecl (call);
1907 if (!func || !fndecl_built_in_p (func, BUILT_IN_NORMAL))
1908 return;
1910 /* Argument number to extract from the call (depends on the built-in
1911 and its kind). */
1912 unsigned dst_idx = -1;
1913 unsigned src_idx = -1;
1914 unsigned bnd_idx = -1;
1916 /* Is this CALL to a string function (as opposed to one to a raw
1917 memory function). */
1918 bool strfun = true;
1920 switch (DECL_FUNCTION_CODE (func))
1922 case BUILT_IN_MEMCPY:
1923 case BUILT_IN_MEMCPY_CHK:
1924 case BUILT_IN_MEMPCPY:
1925 case BUILT_IN_MEMPCPY_CHK:
1926 case BUILT_IN_MEMMOVE:
1927 case BUILT_IN_MEMMOVE_CHK:
1928 strfun = false;
1929 /* Fall through. */
1931 case BUILT_IN_STPNCPY:
1932 case BUILT_IN_STPNCPY_CHK:
1933 case BUILT_IN_STRNCAT:
1934 case BUILT_IN_STRNCAT_CHK:
1935 case BUILT_IN_STRNCPY:
1936 case BUILT_IN_STRNCPY_CHK:
1937 dst_idx = 0;
1938 src_idx = 1;
1939 bnd_idx = 2;
1940 break;
1942 case BUILT_IN_MEMSET:
1943 case BUILT_IN_MEMSET_CHK:
1944 dst_idx = 0;
1945 bnd_idx = 2;
1946 break;
1948 case BUILT_IN_STPCPY:
1949 case BUILT_IN_STPCPY_CHK:
1950 case BUILT_IN_STRCPY:
1951 case BUILT_IN_STRCPY_CHK:
1952 case BUILT_IN_STRCAT:
1953 case BUILT_IN_STRCAT_CHK:
1954 dst_idx = 0;
1955 src_idx = 1;
1956 break;
1958 default:
1959 /* Handle other string functions here whose access may need
1960 to be validated for in-bounds offsets and non-overlapping
1961 copies. */
1962 return;
1965 unsigned nargs = gimple_call_num_args (call);
1967 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1968 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1969 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1971 /* For string functions with an unspecified or unknown bound,
1972 assume the size of the access is one. */
1973 if (!dstwr && strfun)
1974 dstwr = size_one_node;
1976 /* DST and SRC can be null for a call with an insufficient number
1977 of arguments to a built-in function declared without a protype. */
1978 if (!dst || (src_idx < nargs && !src))
1979 return;
1981 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1982 a function declared without a prototype. Avoid checking such
1983 invalid calls. */
1984 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1985 || (src && TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE)
1986 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1987 return;
1989 opt_code opt = check_bounds_or_overlap (m_ptr_qry, call, dst, src, dstwr,
1990 NULL_TREE);
1991 /* Avoid diagnosing the call again. */
1992 suppress_warning (call, opt);
1995 } /* anonymous namespace */
1997 /* Attempt to detect and diagnose invalid offset bounds and (except for
1998 memmove) overlapping copy in a call expression EXPR from SRC to DST
1999 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
2000 SRCSIZE may be NULL. DO_WARN is false to detect either problem
2001 without issue a warning. Return the OPT_Wxxx constant corresponding
2002 to the warning if one has been detected and zero otherwise. */
2004 opt_code
2005 check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
2006 tree srcsize, bool bounds_only /* = false */,
2007 bool do_warn /* = true */)
2009 pointer_query ptrqry (get_range_query (cfun));
2010 return check_bounds_or_overlap (ptrqry,
2011 call, dst, src, dstsize, srcsize,
2012 bounds_only, do_warn);
2015 opt_code
2016 check_bounds_or_overlap (pointer_query &ptrqry,
2017 gimple *call, tree dst, tree src, tree dstsize,
2018 tree srcsize, bool bounds_only /* = false */,
2019 bool do_warn /* = true */)
2021 tree func = gimple_call_fndecl (call);
2023 builtin_memref dstref (ptrqry, call, dst, dstsize);
2024 builtin_memref srcref (ptrqry, call, src, srcsize);
2026 /* Create a descriptor of the access. This may adjust both DSTREF
2027 and SRCREF based on one another and the kind of the access. */
2028 builtin_access acs (ptrqry, call, dstref, srcref);
2030 /* Set STRICT to the value of the -Warray-bounds=N argument for
2031 string functions or when N > 1. */
2032 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
2034 /* The starting offset of the destination write access. Nonzero only
2035 for the strcat family of functions. */
2036 offset_int wroff = acs.write_off (dstsize);
2038 /* Validate offsets to each reference before the access first to make
2039 sure they are within the bounds of the destination object if its
2040 size is known, or PTRDIFF_MAX otherwise. */
2041 opt_code opt
2042 = maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn);
2043 if (opt == no_warning)
2044 opt = maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn);
2046 if (opt != no_warning)
2048 if (do_warn)
2049 suppress_warning (call, opt);
2050 return opt;
2053 if (!warn_restrict || bounds_only || !src)
2054 return no_warning;
2056 if (!bounds_only)
2058 switch (DECL_FUNCTION_CODE (func))
2060 case BUILT_IN_MEMMOVE:
2061 case BUILT_IN_MEMMOVE_CHK:
2062 case BUILT_IN_MEMSET:
2063 case BUILT_IN_MEMSET_CHK:
2064 return no_warning;
2065 default:
2066 break;
2070 location_t loc = gimple_location (call);
2071 if (operand_equal_p (dst, src, 0))
2073 /* Issue -Wrestrict unless the pointers are null (those do
2074 not point to objects and so do not indicate an overlap;
2075 such calls could be the result of sanitization and jump
2076 threading). */
2077 if (!integer_zerop (dst) && !warning_suppressed_p (call, OPT_Wrestrict))
2079 warning_at (loc, OPT_Wrestrict,
2080 "%qD source argument is the same as destination",
2081 func);
2082 suppress_warning (call, OPT_Wrestrict);
2083 return OPT_Wrestrict;
2086 return no_warning;
2089 /* Return false when overlap has been detected. */
2090 if (maybe_diag_overlap (loc, call, acs))
2092 suppress_warning (call, OPT_Wrestrict);
2093 return OPT_Wrestrict;
2096 return no_warning;
2099 gimple_opt_pass *
2100 make_pass_warn_restrict (gcc::context *ctxt)
2102 return new pass_wrestrict (ctxt);
2105 DEBUG_FUNCTION void
2106 dump_builtin_memref (FILE *fp, const builtin_memref &ref)
2108 fprintf (fp, "\n ptr = ");
2109 print_generic_expr (fp, ref.ptr, TDF_LINENO);
2110 fprintf (fp, "\n ref = ");
2111 if (ref.ref)
2112 print_generic_expr (fp, ref.ref, TDF_LINENO);
2113 else
2114 fputs ("null", fp);
2115 fprintf (fp, "\n base = ");
2116 print_generic_expr (fp, ref.base, TDF_LINENO);
2117 fprintf (fp,
2118 "\n basesize = %lli"
2119 "\n refsize = %lli"
2120 "\n refoff = %lli"
2121 "\n offrange = [%lli, %lli]"
2122 "\n sizrange = [%lli, %lli]"
2123 "\n strbounded_p = %s\n",
2124 (long long)ref.basesize.to_shwi (),
2125 (long long)ref.refsize.to_shwi (),
2126 (long long)ref.refoff.to_shwi (),
2127 (long long)ref.offrange[0].to_shwi (),
2128 (long long)ref.offrange[1].to_shwi (),
2129 (long long)ref.sizrange[0].to_shwi (),
2130 (long long)ref.sizrange[1].to_shwi (),
2131 ref.strbounded_p ? "true" : "false");
2134 void
2135 builtin_access::dump (FILE *fp) const
2137 fprintf (fp, " dstref:");
2138 dump_builtin_memref (fp, *dstref);
2139 fprintf (fp, "\n srcref:");
2140 dump_builtin_memref (fp, *srcref);
2142 fprintf (fp,
2143 " sizrange = [%lli, %lli]\n"
2144 " ovloff = [%lli, %lli]\n"
2145 " ovlsiz = [%lli, %lli]\n"
2146 " dstoff = [%lli, %lli]\n"
2147 " dstsiz = [%lli, %lli]\n"
2148 " srcoff = [%lli, %lli]\n"
2149 " srcsiz = [%lli, %lli]\n",
2150 (long long)sizrange[0], (long long)sizrange[1],
2151 (long long)ovloff[0], (long long)ovloff[1],
2152 (long long)ovlsiz[0], (long long)ovlsiz[1],
2153 (long long)dstoff[0].to_shwi (), (long long)dstoff[1].to_shwi (),
2154 (long long)dstsiz[0].to_shwi (), (long long)dstsiz[1].to_shwi (),
2155 (long long)srcoff[0].to_shwi (), (long long)srcoff[1].to_shwi (),
2156 (long long)srcsiz[0].to_shwi (), (long long)srcsiz[1].to_shwi ());
2159 DEBUG_FUNCTION void
2160 dump_builtin_access (FILE *fp, gimple *stmt, const builtin_access &acs)
2162 if (stmt)
2164 fprintf (fp, "\nDumping builtin_access for ");
2165 print_gimple_expr (fp, stmt, TDF_LINENO);
2166 fputs (":\n", fp);
2169 acs.dump (fp);
2172 DEBUG_FUNCTION void
2173 debug (gimple *stmt, const builtin_access &acs)
2175 dump_builtin_access (stdout, stmt, acs);