Fix previous commit
[official-gcc.git] / gcc / gimple-ssa-warn-restrict.c
blobf452debf93b77ca393432634a6e90131cc8c24e5
1 /* Pass to detect and issue warnings for violations of the restrict
2 qualifier.
3 Copyright (C) 2017-2019 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 "domwalk.h"
29 #include "tree-pass.h"
30 #include "builtins.h"
31 #include "ssa.h"
32 #include "gimple-pretty-print.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 "params.h"
40 #include "tree-cfg.h"
41 #include "tree-object-size.h"
42 #include "calls.h"
43 #include "cfgloop.h"
44 #include "intl.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 *ctxt)
66 : gimple_opt_pass (pass_data_wrestrict, ctxt)
67 { }
69 opt_pass *clone () { return new pass_wrestrict (m_ctxt); }
71 virtual bool gate (function *);
72 virtual unsigned int execute (function *);
75 bool
76 pass_wrestrict::gate (function *fun ATTRIBUTE_UNUSED)
78 return warn_array_bounds || warn_restrict || warn_stringop_overflow;
81 /* Class to walk the basic blocks of a function in dominator order. */
82 class wrestrict_dom_walker : public dom_walker
84 public:
85 wrestrict_dom_walker () : dom_walker (CDI_DOMINATORS) {}
87 edge before_dom_children (basic_block) FINAL OVERRIDE;
88 bool handle_gimple_call (gimple_stmt_iterator *);
90 private:
91 void check_call (gimple *);
94 edge
95 wrestrict_dom_walker::before_dom_children (basic_block bb)
97 /* Iterate over statements, looking for function calls. */
98 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
99 gsi_next (&si))
101 gimple *stmt = gsi_stmt (si);
102 if (!is_gimple_call (stmt))
103 continue;
105 check_call (stmt);
108 return NULL;
111 /* Execute the pass for function FUN, walking in dominator order. */
113 unsigned
114 pass_wrestrict::execute (function *fun)
116 calculate_dominance_info (CDI_DOMINATORS);
118 wrestrict_dom_walker walker;
119 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
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 (tree, tree);
165 tree offset_out_of_bounds (int, offset_int[3]) const;
167 private:
169 /* Ctor helper to set or extend OFFRANGE based on argument. */
170 void extend_offset_range (tree);
172 /* Ctor helper to determine BASE and OFFRANGE from argument. */
173 void set_base_and_offset (tree);
176 /* Description of a memory access by a raw memory or string built-in
177 function involving a pair of builtin_memref's. */
178 class builtin_access
180 public:
181 /* Destination and source memory reference. */
182 builtin_memref* const dstref;
183 builtin_memref* const srcref;
184 /* The size range of the access. It's the greater of the accesses
185 to the two references. */
186 HOST_WIDE_INT sizrange[2];
188 /* The minimum and maximum offset of an overlap of the access
189 (if it does, in fact, overlap), and the size of the overlap. */
190 HOST_WIDE_INT ovloff[2];
191 HOST_WIDE_INT ovlsiz[2];
193 /* True to consider valid only accesses to the smallest subobject
194 and false for raw memory functions. */
195 bool strict () const
197 return (detect_overlap != &builtin_access::generic_overlap
198 && detect_overlap != &builtin_access::no_overlap);
201 builtin_access (gimple *, builtin_memref &, builtin_memref &);
203 /* Entry point to determine overlap. */
204 bool overlap ();
206 offset_int write_off (tree) const;
208 void dump (FILE *) const;
210 private:
211 /* Implementation functions used to determine overlap. */
212 bool generic_overlap ();
213 bool strcat_overlap ();
214 bool strcpy_overlap ();
216 bool no_overlap ()
218 return false;
221 offset_int overlap_size (const offset_int [2], const offset_int[2],
222 offset_int [2]);
224 private:
225 /* Temporaries used to compute the final result. */
226 offset_int dstoff[2];
227 offset_int srcoff[2];
228 offset_int dstsiz[2];
229 offset_int srcsiz[2];
231 /* Pointer to a member function to call to determine overlap. */
232 bool (builtin_access::*detect_overlap) ();
235 /* Initialize a memory reference representation from a pointer EXPR and
236 a size SIZE in bytes. If SIZE is NULL_TREE then the size is assumed
237 to be unknown. */
239 builtin_memref::builtin_memref (tree expr, tree size)
240 : ptr (expr),
241 ref (),
242 base (),
243 basesize (-1),
244 refsize (-1),
245 refoff (HOST_WIDE_INT_MIN),
246 offrange (),
247 sizrange (),
248 maxobjsize (tree_to_shwi (max_object_size ())),
249 strbounded_p ()
251 /* Unfortunately, wide_int default ctor is a no-op so array members
252 of the type must be set individually. */
253 offrange[0] = offrange[1] = 0;
254 sizrange[0] = sizrange[1] = 0;
256 if (!expr)
257 return;
259 /* Find the BASE object or pointer referenced by EXPR and set
260 the offset range OFFRANGE in the process. */
261 set_base_and_offset (expr);
263 if (size)
265 tree range[2];
266 /* Determine the size range, allowing for the result to be [0, 0]
267 for SIZE in the anti-range ~[0, N] where N >= PTRDIFF_MAX. */
268 get_size_range (size, range, true);
269 sizrange[0] = wi::to_offset (range[0]);
270 sizrange[1] = wi::to_offset (range[1]);
271 /* get_size_range returns SIZE_MAX for the maximum size.
272 Constrain it to the real maximum of PTRDIFF_MAX. */
273 if (sizrange[0] <= maxobjsize && sizrange[1] > maxobjsize)
274 sizrange[1] = maxobjsize;
276 else
277 sizrange[1] = maxobjsize;
279 if (!DECL_P (base))
280 return;
282 /* If the offset could be in the range of the referenced object
283 constrain its bounds so neither exceeds those of the object. */
284 if (offrange[0] < 0 && offrange[1] > 0)
285 offrange[0] = 0;
287 offset_int maxoff = maxobjsize;
288 tree basetype = TREE_TYPE (base);
289 if (TREE_CODE (basetype) == ARRAY_TYPE)
291 if (ref && array_at_struct_end_p (ref))
292 ; /* Use the maximum possible offset for last member arrays. */
293 else if (tree basesize = TYPE_SIZE_UNIT (basetype))
294 if (TREE_CODE (basesize) == INTEGER_CST)
295 /* Size could be non-constant for a variable-length type such
296 as a struct with a VLA member (a GCC extension). */
297 maxoff = wi::to_offset (basesize);
300 if (offrange[0] >= 0)
302 if (offrange[1] < 0)
303 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
304 else if (offrange[0] <= maxoff && offrange[1] > maxoff)
305 offrange[1] = maxoff;
309 /* Based on the initial length of the destination STARTLEN, returns
310 the offset of the first write access from the beginning of
311 the destination. Nonzero only for strcat-type of calls. */
313 offset_int builtin_access::write_off (tree startlen) const
315 if (detect_overlap != &builtin_access::strcat_overlap
316 || !startlen || TREE_CODE (startlen) != INTEGER_CST)
317 return 0;
319 return wi::to_offset (startlen);
322 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument.
323 Pointer offsets are represented as unsigned sizetype but must be
324 treated as signed. */
326 void
327 builtin_memref::extend_offset_range (tree offset)
329 if (TREE_CODE (offset) == INTEGER_CST)
331 offset_int off = int_cst_value (offset);
332 if (off != 0)
334 offrange[0] += off;
335 offrange[1] += off;
337 return;
340 if (TREE_CODE (offset) == SSA_NAME)
342 /* A pointer offset is represented as sizetype but treated
343 as signed. */
344 wide_int min, max;
345 value_range_kind rng = get_range_info (offset, &min, &max);
346 if (rng == VR_ANTI_RANGE && wi::lts_p (max, min))
348 /* Convert an anti-range whose upper bound is less than
349 its lower bound to a signed range. */
350 offrange[0] += offset_int::from (max + 1, SIGNED);
351 offrange[1] += offset_int::from (min - 1, SIGNED);
352 return;
355 if (rng == VR_RANGE
356 && (DECL_P (base) || wi::lts_p (min, max)))
358 /* Preserve the bounds of the range for an offset into
359 a known object (it may be adjusted later relative to
360 a constant offset from its beginning). Otherwise use
361 the bounds only when they are ascending when treated
362 as signed. */
363 offrange[0] += offset_int::from (min, SIGNED);
364 offrange[1] += offset_int::from (max, SIGNED);
365 return;
368 /* Handle an anti-range the same as no range at all. */
369 gimple *stmt = SSA_NAME_DEF_STMT (offset);
370 tree type;
371 if (is_gimple_assign (stmt)
372 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
373 && INTEGRAL_TYPE_P (type))
375 tree_code code = gimple_assign_rhs_code (stmt);
376 if (code == NOP_EXPR)
378 /* Use the bounds of the type of the NOP_EXPR operand
379 even if it's signed. The result doesn't trigger
380 warnings but makes their output more readable. */
381 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
382 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
383 return;
388 const offset_int maxoff = tree_to_shwi (max_object_size ()) >> 1;
389 const offset_int minoff = -maxoff - 1;
391 offrange[0] += minoff;
392 offrange[1] += maxoff;
395 /* Determines the base object or pointer of the reference EXPR
396 and the offset range from the beginning of the base. */
398 void
399 builtin_memref::set_base_and_offset (tree expr)
401 tree offset = NULL_TREE;
403 if (TREE_CODE (expr) == SSA_NAME)
405 /* Try to tease the offset out of the pointer. */
406 gimple *stmt = SSA_NAME_DEF_STMT (expr);
407 if (!base
408 && gimple_assign_single_p (stmt)
409 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
410 expr = gimple_assign_rhs1 (stmt);
411 else if (is_gimple_assign (stmt))
413 tree_code code = gimple_assign_rhs_code (stmt);
414 if (code == NOP_EXPR)
416 tree rhs = gimple_assign_rhs1 (stmt);
417 if (POINTER_TYPE_P (TREE_TYPE (rhs)))
418 expr = gimple_assign_rhs1 (stmt);
419 else
421 base = expr;
422 return;
425 else if (code == POINTER_PLUS_EXPR)
427 expr = gimple_assign_rhs1 (stmt);
428 offset = gimple_assign_rhs2 (stmt);
430 else
432 base = expr;
433 return;
436 else
438 /* FIXME: Handle PHI nodes in case like:
439 _12 = &MEM[(void *)&a + 2B] + _10;
441 <bb> [local count: 1073741824]:
442 # prephitmp_13 = PHI <_12, &MEM[(void *)&a + 2B]>
443 memcpy (prephitmp_13, p_7(D), 6); */
444 base = expr;
445 return;
449 if (TREE_CODE (expr) == ADDR_EXPR)
450 expr = TREE_OPERAND (expr, 0);
452 /* Stash the reference for offset validation. */
453 ref = expr;
455 poly_int64 bitsize, bitpos;
456 tree var_off;
457 machine_mode mode;
458 int sign, reverse, vol;
460 /* Determine the base object or pointer of the reference and
461 the constant bit offset from the beginning of the base.
462 If the offset has a non-constant component, it will be in
463 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
464 unused here. */
465 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
466 &mode, &sign, &reverse, &vol);
468 /* get_inner_reference is not expected to return null. */
469 gcc_assert (base != NULL);
471 if (offset)
472 extend_offset_range (offset);
474 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
476 /* Convert the poly_int64 offset to offset_int. The offset
477 should be constant but be prepared for it not to be just in
478 case. */
479 offset_int cstoff;
480 if (bytepos.is_constant (&cstoff))
482 offrange[0] += cstoff;
483 offrange[1] += cstoff;
485 /* Besides the reference saved above, also stash the offset
486 for validation. */
487 if (TREE_CODE (expr) == COMPONENT_REF)
488 refoff = cstoff;
490 else
491 offrange[1] += maxobjsize;
493 if (var_off)
495 if (TREE_CODE (var_off) == INTEGER_CST)
497 cstoff = wi::to_offset (var_off);
498 offrange[0] += cstoff;
499 offrange[1] += cstoff;
501 else
502 offrange[1] += maxobjsize;
505 if (TREE_CODE (base) == MEM_REF)
507 tree memrefoff = fold_convert (ptrdiff_type_node, TREE_OPERAND (base, 1));
508 extend_offset_range (memrefoff);
509 base = TREE_OPERAND (base, 0);
511 if (refoff != HOST_WIDE_INT_MIN
512 && TREE_CODE (expr) == COMPONENT_REF)
514 /* Bump up the offset of the referenced subobject to reflect
515 the offset to the enclosing object. For example, so that
517 struct S { char a, b[3]; } s[2];
518 strcpy (s[1].b, "1234");
519 REFOFF is set to s[1].b - (char*)s. */
520 offset_int off = tree_to_shwi (memrefoff);
521 refoff += off;
524 if (!integer_zerop (memrefoff))
525 /* A non-zero offset into an array of struct with flexible array
526 members implies that the array is empty because there is no
527 way to initialize such a member when it belongs to an array.
528 This must be some sort of a bug. */
529 refsize = 0;
532 if (TREE_CODE (ref) == COMPONENT_REF)
533 if (tree size = component_ref_size (ref))
534 if (TREE_CODE (size) == INTEGER_CST)
535 refsize = wi::to_offset (size);
537 if (TREE_CODE (base) == SSA_NAME)
538 set_base_and_offset (base);
541 /* Return error_mark_node if the signed offset exceeds the bounds
542 of the address space (PTRDIFF_MAX). Otherwise, return either BASE
543 or REF when the offset exceeds the bounds of the BASE or REF object,
544 and set OOBOFF to the past-the-end offset formed by the reference,
545 including its size. OOBOFF is initially setto the range of offsets,
546 and OOBOFF[2] to the offset of the first write access (nonzero for
547 the strcat family). When STRICT is nonzero use REF size, when
548 available, otherwise use BASE size. When STRICT is greater than 1,
549 use the size of the last array member as the bound, otherwise treat
550 such a member as a flexible array member. Return NULL when the offset
551 is in bounds. */
553 tree
554 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[3]) const
556 if (!ptr)
557 return NULL_TREE;
559 /* The offset of the first write access or zero. */
560 offset_int wroff = ooboff[2];
562 /* A temporary, possibly adjusted, copy of the offset range. */
563 offset_int offrng[2] = { ooboff[0], ooboff[1] };
565 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
567 /* Check for offset in an anti-range with a negative lower bound.
568 For such a range, consider only the non-negative subrange. */
569 if (offrng[1] < offrng[0] && offrng[1] < 0)
570 offrng[1] = maxobjsize;
573 /* Conservative offset of the last byte of the referenced object. */
574 offset_int endoff;
576 /* The bounds need not be ordered. Set HIB to use as the index
577 of the larger of the bounds and LOB as the opposite. */
578 bool hib = wi::les_p (offrng[0], offrng[1]);
579 bool lob = !hib;
581 /* Set to the size remaining in the object object after subtracting
582 REFOFF. It may become negative as a result of negative indices
583 into the enclosing object, such as in:
584 extern struct S { char a[4], b[3], c[1]; } *p;
585 strcpy (p[-3].b, "123"); */
586 offset_int size = basesize;
587 tree obj = base;
589 const bool decl_p = DECL_P (obj);
591 if (basesize < 0)
593 endoff = offrng[lob] + (sizrange[0] - wroff);
595 /* For a reference through a pointer to an object of unknown size
596 all initial offsets are considered valid, positive as well as
597 negative, since the pointer itself can point past the beginning
598 of the object. However, the sum of the lower bound of the offset
599 and that of the size must be less than or equal than PTRDIFF_MAX. */
600 if (endoff > maxobjsize)
601 return error_mark_node;
603 /* When the referenced subobject is known, the end offset must be
604 within its bounds. Otherwise there is nothing to do. */
605 if (strict
606 && !decl_p
607 && ref
608 && refsize >= 0
609 && TREE_CODE (ref) == COMPONENT_REF)
611 /* If REFOFF is negative, SIZE will become negative here. */
612 size = refoff + refsize;
613 obj = ref;
615 else
616 return NULL_TREE;
619 /* A reference to an object of known size must be within the bounds
620 of either the base object or the subobject (see above for when
621 a subobject can be used). */
622 if ((decl_p && offrng[hib] < 0) || offrng[lob] > size)
623 return obj;
625 /* The extent of the reference must also be within the bounds of
626 the base object (if known) or the subobject or the maximum object
627 size otherwise. */
628 endoff = offrng[lob] + sizrange[0];
629 if (endoff > maxobjsize)
630 return error_mark_node;
632 if (strict
633 && decl_p
634 && ref
635 && refsize >= 0
636 && TREE_CODE (ref) == COMPONENT_REF)
638 /* If the reference is to a member subobject of a declared object,
639 the offset must be within the bounds of the subobject. */
640 size = refoff + refsize;
641 obj = ref;
644 if (endoff <= size)
645 return NULL_TREE;
647 /* Set the out-of-bounds offset range to be one greater than
648 that delimited by the reference including its size. */
649 ooboff[lob] = size;
651 if (endoff > ooboff[lob])
652 ooboff[hib] = endoff - 1;
653 else
654 ooboff[hib] = offrng[lob] + sizrange[1];
656 return obj;
659 /* Create an association between the memory references DST and SRC
660 for access by a call EXPR to a memory or string built-in funtion. */
662 builtin_access::builtin_access (gimple *call, builtin_memref &dst,
663 builtin_memref &src)
664 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
665 dstoff (), srcoff (), dstsiz (), srcsiz ()
667 dstoff[0] = dst.offrange[0];
668 dstoff[1] = dst.offrange[1];
670 /* Zero out since the offset_int ctors invoked above are no-op. */
671 srcoff[0] = srcoff[1] = 0;
672 dstsiz[0] = dstsiz[1] = 0;
673 srcsiz[0] = srcsiz[1] = 0;
675 /* Object Size Type to use to determine the size of the destination
676 and source objects. Overridden below for raw memory functions. */
677 int ostype = 1;
679 /* True when the size of one reference depends on the offset of
680 itself or the other. */
681 bool depends_p = true;
683 /* True when the size of the destination reference DSTREF has been
684 determined from SRCREF and so needs to be adjusted by the latter's
685 offset. Only meaningful for bounded string functions like strncpy. */
686 bool dstadjust_p = false;
688 /* The size argument number (depends on the built-in). */
689 unsigned sizeargno = 2;
691 tree func = gimple_call_fndecl (call);
692 switch (DECL_FUNCTION_CODE (func))
694 case BUILT_IN_MEMCPY:
695 case BUILT_IN_MEMCPY_CHK:
696 case BUILT_IN_MEMPCPY:
697 case BUILT_IN_MEMPCPY_CHK:
698 ostype = 0;
699 depends_p = false;
700 detect_overlap = &builtin_access::generic_overlap;
701 break;
703 case BUILT_IN_MEMMOVE:
704 case BUILT_IN_MEMMOVE_CHK:
705 /* For memmove there is never any overlap to check for. */
706 ostype = 0;
707 depends_p = false;
708 detect_overlap = &builtin_access::no_overlap;
709 break;
711 case BUILT_IN_MEMSET:
712 case BUILT_IN_MEMSET_CHK:
713 /* For memset there is never any overlap to check for. */
714 ostype = 0;
715 depends_p = false;
716 detect_overlap = &builtin_access::no_overlap;
717 break;
719 case BUILT_IN_STPNCPY:
720 case BUILT_IN_STPNCPY_CHK:
721 case BUILT_IN_STRNCPY:
722 case BUILT_IN_STRNCPY_CHK:
723 dstref->strbounded_p = true;
724 detect_overlap = &builtin_access::strcpy_overlap;
725 break;
727 case BUILT_IN_STPCPY:
728 case BUILT_IN_STPCPY_CHK:
729 case BUILT_IN_STRCPY:
730 case BUILT_IN_STRCPY_CHK:
731 detect_overlap = &builtin_access::strcpy_overlap;
732 break;
734 case BUILT_IN_STRCAT:
735 case BUILT_IN_STRCAT_CHK:
736 detect_overlap = &builtin_access::strcat_overlap;
737 break;
739 case BUILT_IN_STRNCAT:
740 case BUILT_IN_STRNCAT_CHK:
741 dstref->strbounded_p = true;
742 srcref->strbounded_p = true;
743 detect_overlap = &builtin_access::strcat_overlap;
744 break;
746 default:
747 /* Handle other string functions here whose access may need
748 to be validated for in-bounds offsets and non-overlapping
749 copies. */
750 return;
753 const offset_int maxobjsize = dst.maxobjsize;
755 /* Try to determine the size of the base object. compute_objsize
756 expects a pointer so create one if BASE is a non-pointer object. */
757 tree addr;
758 if (dst.basesize < 0)
760 addr = dst.base;
761 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
762 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
764 if (tree dstsize = compute_objsize (addr, ostype))
765 dst.basesize = wi::to_offset (dstsize);
766 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
767 dst.basesize = HOST_WIDE_INT_MIN;
768 else
769 dst.basesize = maxobjsize;
772 if (src.base && src.basesize < 0)
774 addr = src.base;
775 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
776 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
778 if (tree srcsize = compute_objsize (addr, ostype))
779 src.basesize = wi::to_offset (srcsize);
780 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
781 src.basesize = HOST_WIDE_INT_MIN;
782 else
783 src.basesize = maxobjsize;
786 /* Make adjustments for references to the same object by string
787 built-in functions to reflect the constraints imposed by
788 the function. */
790 /* For bounded string functions determine the range of the bound
791 on the access. For others, the range stays unbounded. */
792 offset_int bounds[2] = { maxobjsize, maxobjsize };
793 if (dstref->strbounded_p)
795 unsigned nargs = gimple_call_num_args (call);
796 if (nargs <= sizeargno)
797 return;
799 tree size = gimple_call_arg (call, sizeargno);
800 tree range[2];
801 if (get_size_range (size, range, true))
803 bounds[0] = wi::to_offset (range[0]);
804 bounds[1] = wi::to_offset (range[1]);
807 /* If both references' size ranges are indeterminate use the last
808 (size) argument from the function call as a substitute. This
809 may only be necessary for strncpy (but not for memcpy where
810 the size range would have been already determined this way). */
811 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
812 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
814 dstref->sizrange[0] = bounds[0];
815 dstref->sizrange[1] = bounds[1];
819 bool dstsize_set = false;
820 /* The size range of one reference involving the same base object
821 can be determined from the size range of the other reference.
822 This makes it possible to compute accurate offsets for warnings
823 involving functions like strcpy where the length of just one of
824 the two arguments is known (determined by tree-ssa-strlen). */
825 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
827 /* When the destination size is unknown set it to the size of
828 the source. */
829 dstref->sizrange[0] = srcref->sizrange[0];
830 dstref->sizrange[1] = srcref->sizrange[1];
831 dstsize_set = true;
833 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
835 /* When the source size is unknown set it to the size of
836 the destination. */
837 srcref->sizrange[0] = dstref->sizrange[0];
838 srcref->sizrange[1] = dstref->sizrange[1];
840 if (depends_p)
842 if (dstref->strbounded_p)
844 /* Read access by strncpy is constrained by the third
845 argument but except for a zero bound is at least one. */
846 offset_int size = wi::umax (srcref->basesize, 1);
847 offset_int bound = wi::umin (size, bounds[0]);
848 if (bound < srcref->sizrange[0])
849 srcref->sizrange[0] = bound;
850 bound = wi::umin (srcref->basesize, bounds[1]);
851 if (bound < srcref->sizrange[1])
852 srcref->sizrange[1] = bound;
855 /* For string functions, adjust the size range of the source
856 reference by the inverse boundaries of the offset (because
857 the higher the offset into the string the shorter its
858 length). */
859 if (srcref->offrange[1] >= 0
860 && srcref->offrange[1] < srcref->sizrange[0])
861 srcref->sizrange[0] -= srcref->offrange[1];
862 else
863 srcref->sizrange[0] = 0;
865 if (srcref->offrange[0] > 0)
867 if (srcref->offrange[0] < srcref->sizrange[1])
868 srcref->sizrange[1] -= srcref->offrange[0];
869 else
870 srcref->sizrange[1] = 0;
873 dstadjust_p = true;
877 if (detect_overlap == &builtin_access::generic_overlap)
879 if (dstref->strbounded_p)
881 dstref->sizrange[0] = bounds[0];
882 dstref->sizrange[1] = bounds[1];
884 if (dstref->sizrange[0] < srcref->sizrange[0])
885 srcref->sizrange[0] = dstref->sizrange[0];
887 if (dstref->sizrange[1] < srcref->sizrange[1])
888 srcref->sizrange[1] = dstref->sizrange[1];
891 else if (detect_overlap == &builtin_access::strcpy_overlap)
893 if (!dstref->strbounded_p)
895 /* For strcpy, adjust the destination size range to match that
896 of the source computed above. */
897 if (depends_p && dstadjust_p)
899 dstref->sizrange[0] = srcref->sizrange[0];
900 dstref->sizrange[1] = srcref->sizrange[1];
904 else if (!dstsize_set && detect_overlap == &builtin_access::strcat_overlap)
906 dstref->sizrange[0] += srcref->sizrange[0] - 1;
907 dstref->sizrange[1] += srcref->sizrange[1] - 1;
910 if (dstref->strbounded_p)
912 /* For strncpy, adjust the destination size range to match that
913 of the source computed above. */
914 dstref->sizrange[0] = bounds[0];
915 dstref->sizrange[1] = bounds[1];
917 if (bounds[0] < srcref->sizrange[0])
918 srcref->sizrange[0] = bounds[0];
920 if (bounds[1] < srcref->sizrange[1])
921 srcref->sizrange[1] = bounds[1];
925 offset_int
926 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
927 offset_int *off)
929 const offset_int *p = a;
930 const offset_int *q = b;
932 /* Point P at the bigger of the two ranges and Q at the smaller. */
933 if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
935 p = b;
936 q = a;
939 if (p[0] < q[0])
941 if (p[1] < q[0])
942 return 0;
944 *off = q[0];
945 return wi::smin (p[1], q[1]) - q[0];
948 if (q[1] < p[0])
949 return 0;
951 off[0] = p[0];
952 return q[1] - p[0];
955 /* Return true if the bounded mempry (memcpy amd similar) or string function
956 access (strncpy and similar) ACS overlaps. */
958 bool
959 builtin_access::generic_overlap ()
961 builtin_access &acs = *this;
962 const builtin_memref *dstref = acs.dstref;
963 const builtin_memref *srcref = acs.srcref;
965 gcc_assert (dstref->base == srcref->base);
967 const offset_int maxobjsize = acs.dstref->maxobjsize;
969 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
970 gcc_assert (maxsize <= maxobjsize);
972 /* Adjust the larger bounds of the offsets (which may be the first
973 element if the lower bound is larger than the upper bound) to
974 make them valid for the smallest access (if possible) but no smaller
975 than the smaller bounds. */
976 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
978 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
979 acs.dstoff[1] = maxsize - acs.dstsiz[0];
980 if (acs.dstoff[1] < acs.dstoff[0])
981 acs.dstoff[1] = acs.dstoff[0];
983 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
985 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
986 acs.srcoff[1] = maxsize - acs.srcsiz[0];
987 if (acs.srcoff[1] < acs.srcoff[0])
988 acs.srcoff[1] = acs.srcoff[0];
990 /* Determine the minimum and maximum space for the access given
991 the offsets. */
992 offset_int space[2];
993 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
994 space[1] = space[0];
996 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
997 if (acs.srcsiz[0] > 0)
999 if (d < space[0])
1000 space[0] = d;
1002 if (space[1] < d)
1003 space[1] = d;
1005 else
1006 space[1] = acs.dstsiz[1];
1008 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1009 if (d < space[0])
1010 space[0] = d;
1012 if (space[1] < d)
1013 space[1] = d;
1015 /* Treat raw memory functions both of whose references are bounded
1016 as special and permit uncertain overlaps to go undetected. For
1017 all kinds of constant offset and constant size accesses, if
1018 overlap isn't certain it is not possible. */
1019 bool overlap_possible = space[0] < acs.dstsiz[1];
1020 if (!overlap_possible)
1021 return false;
1023 bool overlap_certain = space[1] < acs.dstsiz[0];
1025 /* True when the size of one reference depends on the offset of
1026 the other. */
1027 bool depends_p = detect_overlap != &builtin_access::generic_overlap;
1029 if (!overlap_certain)
1031 if (!dstref->strbounded_p && !depends_p)
1032 /* Memcpy only considers certain overlap. */
1033 return false;
1035 /* There's no way to distinguish an access to the same member
1036 of a structure from one to two distinct members of the same
1037 structure. Give up to avoid excessive false positives. */
1038 tree basetype = TREE_TYPE (dstref->base);
1040 if (POINTER_TYPE_P (basetype))
1041 basetype = TREE_TYPE (basetype);
1042 else
1043 while (TREE_CODE (basetype) == ARRAY_TYPE)
1044 basetype = TREE_TYPE (basetype);
1046 if (RECORD_OR_UNION_TYPE_P (basetype))
1047 return false;
1050 /* True for stpcpy and strcpy. */
1051 bool stxcpy_p = (!dstref->strbounded_p
1052 && detect_overlap == &builtin_access::strcpy_overlap);
1054 if (dstref->refoff >= 0
1055 && srcref->refoff >= 0
1056 && dstref->refoff != srcref->refoff
1057 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
1058 return false;
1060 offset_int siz[2] = { maxobjsize + 1, 0 };
1062 ovloff[0] = HOST_WIDE_INT_MAX;
1063 ovloff[1] = HOST_WIDE_INT_MIN;
1065 /* Adjustment to the lower bound of the offset of the overlap to
1066 account for a subset of unbounded string calls where the size
1067 of the destination string depends on the length of the source
1068 which in turn depends on the offset into it. */
1069 bool sub1;
1071 if (stxcpy_p)
1073 sub1 = acs.dstoff[0] <= acs.srcoff[0];
1075 /* Iterate over the extreme locations (on the horizontal axis formed
1076 by their offsets) and sizes of two regions and find their smallest
1077 and largest overlap and the corresponding offsets. */
1078 for (unsigned i = 0; i != 2; ++i)
1080 const offset_int a[2] = {
1081 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
1084 const offset_int b[2] = {
1085 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
1088 offset_int off;
1089 offset_int sz = overlap_size (a, b, &off);
1090 if (sz < siz[0])
1091 siz[0] = sz;
1093 if (siz[1] <= sz)
1094 siz[1] = sz;
1096 if (sz != 0)
1098 if (wi::lts_p (off, ovloff[0]))
1099 ovloff[0] = off.to_shwi ();
1100 if (wi::lts_p (ovloff[1], off))
1101 ovloff[1] = off.to_shwi ();
1105 else
1107 sub1 = !depends_p;
1109 /* Iterate over the extreme locations (on the horizontal axis
1110 formed by their offsets) and sizes of two regions and find
1111 their smallest and largest overlap and the corresponding
1112 offsets. */
1114 for (unsigned io = 0; io != 2; ++io)
1115 for (unsigned is = 0; is != 2; ++is)
1117 const offset_int a[2] = {
1118 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1121 for (unsigned jo = 0; jo != 2; ++jo)
1122 for (unsigned js = 0; js != 2; ++js)
1124 if (depends_p)
1126 /* For st{p,r}ncpy the size of the source sequence
1127 depends on the offset into it. */
1128 if (js)
1129 break;
1130 js = !jo;
1133 const offset_int b[2] = {
1134 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1137 offset_int off;
1138 offset_int sz = overlap_size (a, b, &off);
1139 if (sz < siz[0])
1140 siz[0] = sz;
1142 if (siz[1] <= sz)
1143 siz[1] = sz;
1145 if (sz != 0)
1147 if (wi::lts_p (off, ovloff[0]))
1148 ovloff[0] = off.to_shwi ();
1149 if (wi::lts_p (ovloff[1], off))
1150 ovloff[1] = off.to_shwi ();
1156 ovlsiz[0] = siz[0].to_shwi ();
1157 ovlsiz[1] = siz[1].to_shwi ();
1159 if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1160 ovloff[0] = ovloff[1] + ovlsiz[1] - 1 - sub1;
1162 return true;
1165 /* Return true if the strcat-like access overlaps. */
1167 bool
1168 builtin_access::strcat_overlap ()
1170 builtin_access &acs = *this;
1171 const builtin_memref *dstref = acs.dstref;
1172 const builtin_memref *srcref = acs.srcref;
1174 gcc_assert (dstref->base == srcref->base);
1176 const offset_int maxobjsize = acs.dstref->maxobjsize;
1178 gcc_assert (dstref->base && dstref->base == srcref->base);
1180 /* Adjust for strcat-like accesses. */
1182 /* As a special case for strcat, set the DSTREF offsets to the length
1183 of the destination string since the function starts writing over
1184 its terminating nul, and set the destination size to 1 for the length
1185 of the nul. */
1186 acs.dstoff[0] += dstsiz[0] - srcref->sizrange[0];
1187 acs.dstoff[1] += dstsiz[1] - srcref->sizrange[1];
1189 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1191 /* The lower bound is zero when the size is unknown because then
1192 overlap is not certain. */
1193 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1194 acs.dstsiz[1] = 1;
1196 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1197 gcc_assert (maxsize <= maxobjsize);
1199 /* For references to the same base object, determine if there's a pair
1200 of valid offsets into the two references such that access between
1201 them doesn't overlap. Adjust both upper bounds to be valid for
1202 the smaller size (i.e., at most MAXSIZE - SIZE). */
1204 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1205 acs.dstoff[1] = maxsize - acs.dstsiz[0];
1207 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1208 acs.srcoff[1] = maxsize - acs.srcsiz[0];
1210 /* Check to see if there's enough space for both accesses without
1211 overlap. Determine the optimistic (maximum) amount of available
1212 space. */
1213 offset_int space;
1214 if (acs.dstoff[0] <= acs.srcoff[0])
1216 if (acs.dstoff[1] < acs.srcoff[1])
1217 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1218 else
1219 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1221 else
1222 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1224 /* Overlap is certain if the distance between the farthest offsets
1225 of the opposite accesses is less than the sum of the lower bounds
1226 of the sizes of the two accesses. */
1227 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1229 /* For a constant-offset, constant size access, consider the largest
1230 distance between the offset bounds and the lower bound of the access
1231 size. If the overlap isn't certain return success. */
1232 if (!overlap_certain
1233 && acs.dstoff[0] == acs.dstoff[1]
1234 && acs.srcoff[0] == acs.srcoff[1]
1235 && acs.dstsiz[0] == acs.dstsiz[1]
1236 && acs.srcsiz[0] == acs.srcsiz[1])
1237 return false;
1239 /* Overlap is not certain but may be possible. */
1241 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1243 /* Determine the conservative (minimum) amount of space. */
1244 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1245 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1246 if (d < space)
1247 space = d;
1248 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1249 if (d < space)
1250 space = d;
1252 /* For a strict test (used for strcpy and similar with unknown or
1253 variable bounds or sizes), consider the smallest distance between
1254 the offset bounds and either the upper bound of the access size
1255 if known, or the lower bound otherwise. */
1256 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1257 return false;
1259 /* When strcat overlap is certain it is always a single byte:
1260 the terminating NUL, regardless of offsets and sizes. When
1261 overlap is only possible its range is [0, 1]. */
1262 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1263 acs.ovlsiz[1] = 1;
1265 offset_int endoff
1266 = dstref->offrange[0] + (dstref->sizrange[0] - srcref->sizrange[0]);
1267 if (endoff <= srcref->offrange[0])
1268 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1269 else
1270 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1272 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1273 srcref->sizrange[0]).to_shwi ();
1274 if (dstref->offrange[0] == dstref->offrange[1])
1276 if (srcref->offrange[0] == srcref->offrange[1])
1277 acs.ovloff[1] = acs.ovloff[0];
1278 else
1279 acs.ovloff[1]
1280 = wi::smin (maxobjsize,
1281 srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1283 else
1284 acs.ovloff[1]
1285 = wi::smin (maxobjsize,
1286 dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1288 if (acs.sizrange[0] == 0)
1289 acs.sizrange[0] = 1;
1290 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1291 return true;
1294 /* Return true if the strcpy-like access overlaps. */
1296 bool
1297 builtin_access::strcpy_overlap ()
1299 return generic_overlap ();
1303 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1304 one another or that, in order not to overlap, would imply that the size
1305 of the referenced object(s) exceeds the maximum size of an object. Set
1306 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1307 they may overlap in a way that's not apparent from the available data),
1308 return false. */
1310 bool
1311 builtin_access::overlap ()
1313 builtin_access &acs = *this;
1315 const offset_int maxobjsize = dstref->maxobjsize;
1317 acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1318 srcref->sizrange[0]).to_shwi ();
1319 acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1320 srcref->sizrange[1]).to_shwi ();
1322 /* Check to see if the two references refer to regions that are
1323 too large not to overlap in the address space (whose maximum
1324 size is PTRDIFF_MAX). */
1325 offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1326 if (maxobjsize < size)
1328 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1329 acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1330 return true;
1333 /* If both base objects aren't known return the maximum possible
1334 offset that would make them not overlap. */
1335 if (!dstref->base || !srcref->base)
1336 return false;
1338 /* If the base object is an array adjust the bounds of the offset
1339 to be non-negative and within the bounds of the array if possible. */
1340 if (dstref->base
1341 && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE)
1343 if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0)
1344 acs.dstoff[0] = 0;
1346 if (acs.dstoff[1] < acs.dstoff[0])
1348 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base)))
1349 acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size));
1350 else
1351 acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize);
1355 acs.srcoff[0] = srcref->offrange[0];
1356 acs.srcoff[1] = srcref->offrange[1];
1358 if (srcref->base
1359 && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE)
1361 if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0)
1362 acs.srcoff[0] = 0;
1364 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base)))
1365 acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size));
1366 else if (acs.srcoff[1] < acs.srcoff[0])
1367 acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize);
1370 /* When the upper bound of the offset is less than the lower bound
1371 the former is the result of a negative offset being represented
1372 as a large positive value or vice versa. The resulting range is
1373 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1374 a union is not representable using the current data structure
1375 replace it with the full range of offsets. */
1376 if (acs.dstoff[1] < acs.dstoff[0])
1378 acs.dstoff[0] = -maxobjsize - 1;
1379 acs.dstoff[1] = maxobjsize;
1382 /* Validate the offset and size of each reference on its own first.
1383 This is independent of whether or not the base objects are the
1384 same. Normally, this would have already been detected and
1385 diagnosed by -Warray-bounds, unless it has been disabled. */
1386 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1387 if (maxobjsize < maxoff)
1389 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1390 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1391 return true;
1394 /* Repeat the same as above but for the source offsets. */
1395 if (acs.srcoff[1] < acs.srcoff[0])
1397 acs.srcoff[0] = -maxobjsize - 1;
1398 acs.srcoff[1] = maxobjsize;
1401 maxoff = acs.srcoff[0] + srcref->sizrange[0];
1402 if (maxobjsize < maxoff)
1404 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1405 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1406 - maxobjsize).to_shwi ();
1407 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1408 return true;
1411 if (dstref->base != srcref->base)
1412 return false;
1414 acs.dstsiz[0] = dstref->sizrange[0];
1415 acs.dstsiz[1] = dstref->sizrange[1];
1417 acs.srcsiz[0] = srcref->sizrange[0];
1418 acs.srcsiz[1] = srcref->sizrange[1];
1420 /* Call the appropriate function to determine the overlap. */
1421 if ((this->*detect_overlap) ())
1423 if (!sizrange[1])
1425 /* Unless the access size range has already been set, do so here. */
1426 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1427 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1429 return true;
1432 return false;
1435 /* Attempt to detect and diagnose an overlapping copy in a call expression
1436 EXPR involving an an access ACS to a built-in memory or string function.
1437 Return true when one has been detected, false otherwise. */
1439 static bool
1440 maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
1442 if (!acs.overlap ())
1443 return false;
1445 if (gimple_no_warning_p (call))
1446 return true;
1448 /* For convenience. */
1449 const builtin_memref &dstref = *acs.dstref;
1450 const builtin_memref &srcref = *acs.srcref;
1452 /* Determine the range of offsets and sizes of the overlap if it
1453 exists and issue diagnostics. */
1454 HOST_WIDE_INT *ovloff = acs.ovloff;
1455 HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1456 HOST_WIDE_INT *sizrange = acs.sizrange;
1458 tree func = gimple_call_fndecl (call);
1460 /* To avoid a combinatorial explosion of diagnostics format the offsets
1461 or their ranges as strings and use them in the warning calls below. */
1462 char offstr[3][64];
1464 if (dstref.offrange[0] == dstref.offrange[1]
1465 || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1466 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1467 dstref.offrange[0].to_shwi ());
1468 else
1469 sprintf (offstr[0],
1470 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1471 dstref.offrange[0].to_shwi (),
1472 dstref.offrange[1].to_shwi ());
1474 if (srcref.offrange[0] == srcref.offrange[1]
1475 || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1476 sprintf (offstr[1],
1477 HOST_WIDE_INT_PRINT_DEC,
1478 srcref.offrange[0].to_shwi ());
1479 else
1480 sprintf (offstr[1],
1481 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1482 srcref.offrange[0].to_shwi (),
1483 srcref.offrange[1].to_shwi ());
1485 if (ovloff[0] == ovloff[1] || !ovloff[1])
1486 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1487 else
1488 sprintf (offstr[2],
1489 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1490 ovloff[0], ovloff[1]);
1492 const offset_int maxobjsize = dstref.maxobjsize;
1493 bool must_overlap = ovlsiz[0] > 0;
1495 if (ovlsiz[1] == 0)
1496 ovlsiz[1] = ovlsiz[0];
1498 if (must_overlap)
1500 /* Issue definitive "overlaps" diagnostic in this block. */
1502 if (sizrange[0] == sizrange[1])
1504 if (ovlsiz[0] == ovlsiz[1])
1505 warning_at (loc, OPT_Wrestrict,
1506 sizrange[0] == 1
1507 ? (ovlsiz[0] == 1
1508 ? G_("%G%qD accessing %wu byte at offsets %s "
1509 "and %s overlaps %wu byte at offset %s")
1510 : G_("%G%qD accessing %wu byte at offsets %s "
1511 "and %s overlaps %wu bytes at offset "
1512 "%s"))
1513 : (ovlsiz[0] == 1
1514 ? G_("%G%qD accessing %wu bytes at offsets %s "
1515 "and %s overlaps %wu byte at offset %s")
1516 : G_("%G%qD accessing %wu bytes at offsets %s "
1517 "and %s overlaps %wu bytes at offset "
1518 "%s")),
1519 call, func, sizrange[0],
1520 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1521 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1522 warning_n (loc, OPT_Wrestrict, sizrange[0],
1523 "%G%qD accessing %wu byte at offsets %s "
1524 "and %s overlaps between %wu and %wu bytes "
1525 "at offset %s",
1526 "%G%qD accessing %wu bytes at offsets %s "
1527 "and %s overlaps between %wu and %wu bytes "
1528 "at offset %s",
1529 call, func, sizrange[0], offstr[0], offstr[1],
1530 ovlsiz[0], ovlsiz[1], offstr[2]);
1531 else
1532 warning_n (loc, OPT_Wrestrict, sizrange[0],
1533 "%G%qD accessing %wu byte at offsets %s and "
1534 "%s overlaps %wu or more bytes at offset %s",
1535 "%G%qD accessing %wu bytes at offsets %s and "
1536 "%s overlaps %wu or more bytes at offset %s",
1537 call, func, sizrange[0],
1538 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1539 return true;
1542 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1544 if (ovlsiz[0] == ovlsiz[1])
1545 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1546 "%G%qD accessing between %wu and %wu bytes "
1547 "at offsets %s and %s overlaps %wu byte at "
1548 "offset %s",
1549 "%G%qD accessing between %wu and %wu bytes "
1550 "at offsets %s and %s overlaps %wu bytes "
1551 "at offset %s",
1552 call, func, sizrange[0], sizrange[1],
1553 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1554 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1555 warning_at (loc, OPT_Wrestrict,
1556 "%G%qD accessing between %wu and %wu bytes at "
1557 "offsets %s and %s overlaps between %wu and %wu "
1558 "bytes at offset %s",
1559 call, func, sizrange[0], sizrange[1],
1560 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1561 offstr[2]);
1562 else
1563 warning_at (loc, OPT_Wrestrict,
1564 "%G%qD accessing between %wu and %wu bytes at "
1565 "offsets %s and %s overlaps %wu or more bytes "
1566 "at offset %s",
1567 call, func, sizrange[0], sizrange[1],
1568 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1569 return true;
1572 if (ovlsiz[0] != ovlsiz[1])
1573 ovlsiz[1] = maxobjsize.to_shwi ();
1575 if (ovlsiz[0] == ovlsiz[1])
1576 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1577 "%G%qD accessing %wu or more bytes at offsets "
1578 "%s and %s overlaps %wu byte at offset %s",
1579 "%G%qD accessing %wu or more bytes at offsets "
1580 "%s and %s overlaps %wu bytes at offset %s",
1581 call, func, sizrange[0], offstr[0], offstr[1],
1582 ovlsiz[0], offstr[2]);
1583 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1584 warning_at (loc, OPT_Wrestrict,
1585 "%G%qD accessing %wu or more bytes at offsets %s "
1586 "and %s overlaps between %wu and %wu bytes "
1587 "at offset %s",
1588 call, func, sizrange[0], offstr[0], offstr[1],
1589 ovlsiz[0], ovlsiz[1], offstr[2]);
1590 else
1591 warning_at (loc, OPT_Wrestrict,
1592 "%G%qD accessing %wu or more bytes at offsets %s "
1593 "and %s overlaps %wu or more bytes at offset %s",
1594 call, func, sizrange[0], offstr[0], offstr[1],
1595 ovlsiz[0], offstr[2]);
1596 return true;
1599 /* Use more concise wording when one of the offsets is unbounded
1600 to avoid confusing the user with large and mostly meaningless
1601 numbers. */
1602 bool open_range;
1603 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1604 open_range = ((dstref.offrange[0] == 0
1605 && dstref.offrange[1] == maxobjsize)
1606 || (srcref.offrange[0] == 0
1607 && srcref.offrange[1] == maxobjsize));
1608 else
1609 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1610 && dstref.offrange[1] == maxobjsize)
1611 || (srcref.offrange[0] == -maxobjsize - 1
1612 && srcref.offrange[1] == maxobjsize));
1614 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1616 if (ovlsiz[1] == 1)
1618 if (open_range)
1619 warning_n (loc, OPT_Wrestrict, sizrange[1],
1620 "%G%qD accessing %wu byte may overlap "
1621 "%wu byte",
1622 "%G%qD accessing %wu bytes may overlap "
1623 "%wu byte",
1624 call, func, sizrange[1], ovlsiz[1]);
1625 else
1626 warning_n (loc, OPT_Wrestrict, sizrange[1],
1627 "%G%qD accessing %wu byte at offsets %s "
1628 "and %s may overlap %wu byte at offset %s",
1629 "%G%qD accessing %wu bytes at offsets %s "
1630 "and %s may overlap %wu byte at offset %s",
1631 call, func, sizrange[1], offstr[0], offstr[1],
1632 ovlsiz[1], offstr[2]);
1633 return true;
1636 if (open_range)
1637 warning_n (loc, OPT_Wrestrict, sizrange[1],
1638 "%G%qD accessing %wu byte may overlap "
1639 "up to %wu bytes",
1640 "%G%qD accessing %wu bytes may overlap "
1641 "up to %wu bytes",
1642 call, func, sizrange[1], ovlsiz[1]);
1643 else
1644 warning_n (loc, OPT_Wrestrict, sizrange[1],
1645 "%G%qD accessing %wu byte at offsets %s and "
1646 "%s may overlap up to %wu bytes at offset %s",
1647 "%G%qD accessing %wu bytes at offsets %s and "
1648 "%s may overlap up to %wu bytes at offset %s",
1649 call, func, sizrange[1], offstr[0], offstr[1],
1650 ovlsiz[1], offstr[2]);
1651 return true;
1654 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1656 if (open_range)
1657 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1658 "%G%qD accessing between %wu and %wu bytes "
1659 "may overlap %wu byte",
1660 "%G%qD accessing between %wu and %wu bytes "
1661 "may overlap up to %wu bytes",
1662 call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1663 else
1664 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1665 "%G%qD accessing between %wu and %wu bytes "
1666 "at offsets %s and %s may overlap %wu byte "
1667 "at offset %s",
1668 "%G%qD accessing between %wu and %wu bytes "
1669 "at offsets %s and %s may overlap up to %wu "
1670 "bytes at offset %s",
1671 call, func, sizrange[0], sizrange[1],
1672 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1673 return true;
1676 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1677 "%G%qD accessing %wu or more bytes at offsets %s "
1678 "and %s may overlap %wu byte at offset %s",
1679 "%G%qD accessing %wu or more bytes at offsets %s "
1680 "and %s may overlap up to %wu bytes at offset %s",
1681 call, func, sizrange[0], offstr[0], offstr[1],
1682 ovlsiz[1], offstr[2]);
1684 return true;
1687 /* Validate REF size and offsets in an expression passed as an argument
1688 to a CALL to a built-in function FUNC to make sure they are within
1689 the bounds of the referenced object if its size is known, or
1690 PTRDIFF_MAX otherwise. DO_WARN is true when a diagnostic should
1691 be issued, false otherwise.
1692 Both initial values of the offsets and their final value computed
1693 by the function by incrementing the initial value by the size are
1694 validated. Return true if the offsets are not valid and a diagnostic
1695 has been issued, or would have been issued if DO_WARN had been true. */
1697 static bool
1698 maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict,
1699 const builtin_memref &ref, offset_int wroff,
1700 bool do_warn)
1702 const offset_int maxobjsize = ref.maxobjsize;
1704 /* Check for excessive size first and regardless of warning options
1705 since the result is used to make codegen decisions. */
1706 if (ref.sizrange[0] > maxobjsize)
1708 /* Return true without issuing a warning. */
1709 if (!do_warn)
1710 return true;
1712 if (ref.ref && TREE_NO_WARNING (ref.ref))
1713 return false;
1715 if (warn_stringop_overflow)
1717 if (EXPR_HAS_LOCATION (ref.ptr))
1718 loc = EXPR_LOCATION (ref.ptr);
1720 loc = expansion_point_location_if_in_system_header (loc);
1722 if (ref.sizrange[0] == ref.sizrange[1])
1723 return warning_at (loc, OPT_Wstringop_overflow_,
1724 "%G%qD specified bound %wu "
1725 "exceeds maximum object size %wu",
1726 call, func, ref.sizrange[0].to_uhwi (),
1727 maxobjsize.to_uhwi ());
1729 return warning_at (loc, OPT_Wstringop_overflow_,
1730 "%G%qD specified bound between %wu and %wu "
1731 "exceeds maximum object size %wu",
1732 call, func, ref.sizrange[0].to_uhwi (),
1733 ref.sizrange[1].to_uhwi (),
1734 maxobjsize.to_uhwi ());
1738 /* Check for out-bounds pointers regardless of warning options since
1739 the result is used to make codegen decisions. An excessive WROFF
1740 can only come up as a result of an invalid strncat bound and is
1741 diagnosed separately using a more meaningful warning. */
1742 if (maxobjsize < wroff)
1743 wroff = 0;
1744 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1], wroff };
1745 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1746 if (!oobref)
1747 return false;
1749 /* Return true without issuing a warning. */
1750 if (!do_warn)
1751 return true;
1753 if (!warn_array_bounds)
1754 return false;
1756 if (TREE_NO_WARNING (ref.ptr)
1757 || (ref.ref && TREE_NO_WARNING (ref.ref)))
1758 return false;
1760 if (EXPR_HAS_LOCATION (ref.ptr))
1761 loc = EXPR_LOCATION (ref.ptr);
1763 loc = expansion_point_location_if_in_system_header (loc);
1765 char rangestr[2][64];
1766 if (ooboff[0] == ooboff[1]
1767 || (ooboff[0] != ref.offrange[0]
1768 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1769 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1770 else
1771 sprintf (rangestr[0], "[%lli, %lli]",
1772 (long long) ooboff[0].to_shwi (),
1773 (long long) ooboff[1].to_shwi ());
1775 bool warned = false;
1777 if (oobref == error_mark_node)
1779 if (ref.sizrange[0] == ref.sizrange[1])
1780 sprintf (rangestr[1], "%llu",
1781 (unsigned long long) ref.sizrange[0].to_shwi ());
1782 else
1783 sprintf (rangestr[1], "[%lli, %lli]",
1784 (unsigned long long) ref.sizrange[0].to_uhwi (),
1785 (unsigned long long) ref.sizrange[1].to_uhwi ());
1787 tree type;
1789 if (DECL_P (ref.base)
1790 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1792 auto_diagnostic_group d;
1793 if (warning_at (loc, OPT_Warray_bounds,
1794 "%G%qD pointer overflow between offset %s "
1795 "and size %s accessing array %qD with type %qT",
1796 call, func, rangestr[0], rangestr[1], ref.base, type))
1798 inform (DECL_SOURCE_LOCATION (ref.base),
1799 "array %qD declared here", ref.base);
1800 warned = true;
1802 else
1803 warned = warning_at (loc, OPT_Warray_bounds,
1804 "%G%qD pointer overflow between offset %s "
1805 "and size %s",
1806 call, func, rangestr[0], rangestr[1]);
1808 else
1809 warned = warning_at (loc, OPT_Warray_bounds,
1810 "%G%qD pointer overflow between offset %s "
1811 "and size %s",
1812 call, func, rangestr[0], rangestr[1]);
1814 else if (oobref == ref.base)
1816 /* True when the offset formed by an access to the reference
1817 is out of bounds, rather than the initial offset wich is
1818 in bounds. This implies access past the end. */
1819 bool form = ooboff[0] != ref.offrange[0];
1821 if (DECL_P (ref.base))
1823 auto_diagnostic_group d;
1824 if ((ref.basesize < maxobjsize
1825 && warning_at (loc, OPT_Warray_bounds,
1826 form
1827 ? G_("%G%qD forming offset %s is out of "
1828 "the bounds [0, %wu] of object %qD with "
1829 "type %qT")
1830 : G_("%G%qD offset %s is out of the bounds "
1831 "[0, %wu] of object %qD with type %qT"),
1832 call, func, rangestr[0], ref.basesize.to_uhwi (),
1833 ref.base, TREE_TYPE (ref.base)))
1834 || warning_at (loc, OPT_Warray_bounds,
1835 form
1836 ? G_("%G%qD forming offset %s is out of "
1837 "the bounds of object %qD with type %qT")
1838 : G_("%G%qD offset %s is out of the bounds "
1839 "of object %qD with type %qT"),
1840 call, func, rangestr[0],
1841 ref.base, TREE_TYPE (ref.base)))
1843 inform (DECL_SOURCE_LOCATION (ref.base),
1844 "%qD declared here", ref.base);
1845 warned = true;
1848 else if (ref.basesize < maxobjsize)
1849 warned = warning_at (loc, OPT_Warray_bounds,
1850 form
1851 ? G_("%G%qD forming offset %s is out "
1852 "of the bounds [0, %wu]")
1853 : G_("%G%qD offset %s is out "
1854 "of the bounds [0, %wu]"),
1855 call, func, rangestr[0], ref.basesize.to_uhwi ());
1856 else
1857 warned = warning_at (loc, OPT_Warray_bounds,
1858 form
1859 ? G_("%G%qD forming offset %s is out of bounds")
1860 : G_("%G%qD offset %s is out of bounds"),
1861 call, func, rangestr[0]);
1863 else if (TREE_CODE (ref.ref) == MEM_REF)
1865 tree refop = TREE_OPERAND (ref.ref, 0);
1866 tree type = TREE_TYPE (refop);
1867 if (POINTER_TYPE_P (type))
1868 type = TREE_TYPE (type);
1869 type = TYPE_MAIN_VARIANT (type);
1871 if (warning_at (loc, OPT_Warray_bounds,
1872 "%G%qD offset %s from the object at %qE is out "
1873 "of the bounds of %qT",
1874 call, func, rangestr[0], ref.base, type))
1876 if (TREE_CODE (ref.ref) == COMPONENT_REF)
1877 refop = TREE_OPERAND (ref.ref, 1);
1878 if (DECL_P (refop))
1879 inform (DECL_SOURCE_LOCATION (refop),
1880 "subobject %qD declared here", refop);
1881 warned = true;
1884 else
1886 tree refop = TREE_OPERAND (ref.ref, 0);
1887 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1889 if (warning_at (loc, OPT_Warray_bounds,
1890 "%G%qD offset %s from the object at %qE is out "
1891 "of the bounds of referenced subobject %qD with "
1892 "type %qT at offset %wi",
1893 call, func, rangestr[0], ref.base,
1894 TREE_OPERAND (ref.ref, 1), type,
1895 ref.refoff.to_shwi ()))
1897 if (TREE_CODE (ref.ref) == COMPONENT_REF)
1898 refop = TREE_OPERAND (ref.ref, 1);
1899 if (DECL_P (refop))
1900 inform (DECL_SOURCE_LOCATION (refop),
1901 "subobject %qD declared here", refop);
1902 warned = true;
1906 return warned;
1909 /* Check a CALL statement for restrict-violations and issue warnings
1910 if/when appropriate. */
1912 void
1913 wrestrict_dom_walker::check_call (gimple *call)
1915 /* Avoid checking the call if it has already been diagnosed for
1916 some reason. */
1917 if (gimple_no_warning_p (call))
1918 return;
1920 tree func = gimple_call_fndecl (call);
1921 if (!func || !fndecl_built_in_p (func, BUILT_IN_NORMAL))
1922 return;
1924 /* Argument number to extract from the call (depends on the built-in
1925 and its kind). */
1926 unsigned dst_idx = -1;
1927 unsigned src_idx = -1;
1928 unsigned bnd_idx = -1;
1930 /* Is this CALL to a string function (as opposed to one to a raw
1931 memory function). */
1932 bool strfun = true;
1934 switch (DECL_FUNCTION_CODE (func))
1936 case BUILT_IN_MEMCPY:
1937 case BUILT_IN_MEMCPY_CHK:
1938 case BUILT_IN_MEMPCPY:
1939 case BUILT_IN_MEMPCPY_CHK:
1940 case BUILT_IN_MEMMOVE:
1941 case BUILT_IN_MEMMOVE_CHK:
1942 strfun = false;
1943 /* Fall through. */
1945 case BUILT_IN_STPNCPY:
1946 case BUILT_IN_STPNCPY_CHK:
1947 case BUILT_IN_STRNCAT:
1948 case BUILT_IN_STRNCAT_CHK:
1949 case BUILT_IN_STRNCPY:
1950 case BUILT_IN_STRNCPY_CHK:
1951 dst_idx = 0;
1952 src_idx = 1;
1953 bnd_idx = 2;
1954 break;
1956 case BUILT_IN_MEMSET:
1957 case BUILT_IN_MEMSET_CHK:
1958 dst_idx = 0;
1959 bnd_idx = 2;
1960 break;
1962 case BUILT_IN_STPCPY:
1963 case BUILT_IN_STPCPY_CHK:
1964 case BUILT_IN_STRCPY:
1965 case BUILT_IN_STRCPY_CHK:
1966 case BUILT_IN_STRCAT:
1967 case BUILT_IN_STRCAT_CHK:
1968 dst_idx = 0;
1969 src_idx = 1;
1970 break;
1972 default:
1973 /* Handle other string functions here whose access may need
1974 to be validated for in-bounds offsets and non-overlapping
1975 copies. */
1976 return;
1979 unsigned nargs = gimple_call_num_args (call);
1981 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1982 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1983 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1985 /* For string functions with an unspecified or unknown bound,
1986 assume the size of the access is one. */
1987 if (!dstwr && strfun)
1988 dstwr = size_one_node;
1990 /* DST and SRC can be null for a call with an insufficient number
1991 of arguments to a built-in function declared without a protype. */
1992 if (!dst || (src_idx < nargs && !src))
1993 return;
1995 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1996 a function declared without a prototype. Avoid checking such
1997 invalid calls. */
1998 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1999 || (src && TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE)
2000 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
2001 return;
2003 if (!check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
2004 return;
2006 /* Avoid diagnosing the call again. */
2007 gimple_set_no_warning (call, true);
2010 } /* anonymous namespace */
2012 /* Attempt to detect and diagnose invalid offset bounds and (except for
2013 memmove) overlapping copy in a call expression EXPR from SRC to DST
2014 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
2015 SRCSIZE may be NULL. DO_WARN is false to detect either problem
2016 without issue a warning. Return the OPT_Wxxx constant corresponding
2017 to the warning if one has been detected and zero otherwise. */
2020 check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
2021 tree srcsize, bool bounds_only /* = false */,
2022 bool do_warn /* = true */)
2024 location_t loc = gimple_nonartificial_location (call);
2025 loc = expansion_point_location_if_in_system_header (loc);
2027 tree func = gimple_call_fndecl (call);
2029 builtin_memref dstref (dst, dstsize);
2030 builtin_memref srcref (src, srcsize);
2032 /* Create a descriptor of the access. This may adjust both DSTREF
2033 and SRCREF based on one another and the kind of the access. */
2034 builtin_access acs (call, dstref, srcref);
2036 /* Set STRICT to the value of the -Warray-bounds=N argument for
2037 string functions or when N > 1. */
2038 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
2040 /* The starting offset of the destination write access. Nonzero only
2041 for the strcat family of functions. */
2042 offset_int wroff = acs.write_off (dstsize);
2044 /* Validate offsets to each reference before the access first to make
2045 sure they are within the bounds of the destination object if its
2046 size is known, or PTRDIFF_MAX otherwise. */
2047 if (maybe_diag_access_bounds (loc, call, func, strict, dstref, wroff, do_warn)
2048 || maybe_diag_access_bounds (loc, call, func, strict, srcref, 0, do_warn))
2050 if (do_warn)
2051 gimple_set_no_warning (call, true);
2052 return OPT_Warray_bounds;
2055 if (!warn_restrict || bounds_only || !src)
2056 return 0;
2058 if (!bounds_only)
2060 switch (DECL_FUNCTION_CODE (func))
2062 case BUILT_IN_MEMMOVE:
2063 case BUILT_IN_MEMMOVE_CHK:
2064 case BUILT_IN_MEMSET:
2065 case BUILT_IN_MEMSET_CHK:
2066 return 0;
2067 default:
2068 break;
2072 if (operand_equal_p (dst, src, 0))
2074 /* Issue -Wrestrict unless the pointers are null (those do
2075 not point to objects and so do not indicate an overlap;
2076 such calls could be the result of sanitization and jump
2077 threading). */
2078 if (!integer_zerop (dst) && !gimple_no_warning_p (call))
2080 warning_at (loc, OPT_Wrestrict,
2081 "%G%qD source argument is the same as destination",
2082 call, func);
2083 gimple_set_no_warning (call, true);
2084 return OPT_Wrestrict;
2087 return 0;
2090 /* Return false when overlap has been detected. */
2091 if (maybe_diag_overlap (loc, call, acs))
2093 gimple_set_no_warning (call, true);
2094 return OPT_Wrestrict;
2097 return 0;
2100 gimple_opt_pass *
2101 make_pass_warn_restrict (gcc::context *ctxt)
2103 return new pass_wrestrict (ctxt);
2106 DEBUG_FUNCTION void
2107 dump_builtin_memref (FILE *fp, const builtin_memref &ref)
2109 fprintf (fp, "\n ptr = ");
2110 print_generic_expr (fp, ref.ptr, TDF_LINENO);
2111 fprintf (fp, "\n ref = ");
2112 if (ref.ref)
2113 print_generic_expr (fp, ref.ref, TDF_LINENO);
2114 else
2115 fputs ("null", fp);
2116 fprintf (fp, "\n base = ");
2117 print_generic_expr (fp, ref.base, TDF_LINENO);
2118 fprintf (fp,
2119 "\n basesize = %lli"
2120 "\n refsize = %lli"
2121 "\n refoff = %lli"
2122 "\n offrange = [%lli, %lli]"
2123 "\n sizrange = [%lli, %lli]"
2124 "\n strbounded_p = %s\n",
2125 (long long)ref.basesize.to_shwi (),
2126 (long long)ref.refsize.to_shwi (),
2127 (long long)ref.refoff.to_shwi (),
2128 (long long)ref.offrange[0].to_shwi (),
2129 (long long)ref.offrange[1].to_shwi (),
2130 (long long)ref.sizrange[0].to_shwi (),
2131 (long long)ref.sizrange[1].to_shwi (),
2132 ref.strbounded_p ? "true" : "false");
2135 void
2136 builtin_access::dump (FILE *fp) const
2138 fprintf (fp, " dstref:");
2139 dump_builtin_memref (fp, *dstref);
2140 fprintf (fp, "\n srcref:");
2141 dump_builtin_memref (fp, *srcref);
2143 fprintf (fp,
2144 " sizrange = [%lli, %lli]\n"
2145 " ovloff = [%lli, %lli]\n"
2146 " ovlsiz = [%lli, %lli]\n"
2147 " dstoff = [%lli, %lli]\n"
2148 " dstsiz = [%lli, %lli]\n"
2149 " srcoff = [%lli, %lli]\n"
2150 " srcsiz = [%lli, %lli]\n",
2151 (long long)sizrange[0], (long long)sizrange[1],
2152 (long long)ovloff[0], (long long)ovloff[1],
2153 (long long)ovlsiz[0], (long long)ovlsiz[1],
2154 (long long)dstoff[0].to_shwi (), (long long)dstoff[1].to_shwi (),
2155 (long long)dstsiz[0].to_shwi (), (long long)dstsiz[1].to_shwi (),
2156 (long long)srcoff[0].to_shwi (), (long long)srcoff[1].to_shwi (),
2157 (long long)srcsiz[0].to_shwi (), (long long)srcsiz[1].to_shwi ());
2160 DEBUG_FUNCTION void
2161 dump_builtin_access (FILE *fp, gimple *stmt, const builtin_access &acs)
2163 if (stmt)
2165 fprintf (fp, "\nDumping builtin_access for ");
2166 print_gimple_expr (fp, stmt, TDF_LINENO);
2167 fputs (":\n", fp);
2170 acs.dump (fp);
2173 DEBUG_FUNCTION void
2174 debug (gimple *stmt, const builtin_access &acs)
2176 dump_builtin_access (stdout, stmt, acs);