Fix GNU coding style for G_.
[official-gcc.git] / gcc / gimple-ssa-warn-restrict.c
blob9f23f57c426d1b0943d6235ae15dd25fb6cf2067
1 /* Pass to detect and issue warnings for violations of the restrict
2 qualifier.
3 Copyright (C) 2017-2018 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 != 0 || warn_restrict != 0;
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 (gcall *);
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 if (gcall *call = as_a <gcall *> (stmt))
106 check_call (call);
109 return NULL;
112 /* Execute the pass for function FUN, walking in dominator order. */
114 unsigned
115 pass_wrestrict::execute (function *fun)
117 calculate_dominance_info (CDI_DOMINATORS);
119 wrestrict_dom_walker walker;
120 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
122 return 0;
125 /* Description of a memory reference by a built-in function. This
126 is similar to ao_ref but made especially suitable for -Wrestrict
127 and not for optimization. */
128 struct builtin_memref
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;
141 /* The non-negative offset of the referenced subobject. Used to avoid
142 warnings for (apparently) possibly but not definitively overlapping
143 accesses to member arrays. Negative when unknown/invalid. */
144 offset_int refoff;
146 /* The offset range relative to the base. */
147 offset_int offrange[2];
148 /* The size range of the access to this reference. */
149 offset_int sizrange[2];
151 /* True for "bounded" string functions like strncat, and strncpy
152 and their variants that specify either an exact or upper bound
153 on the size of the accesses they perform. For strncat both
154 the source and destination references are bounded. For strncpy
155 only the destination reference is. */
156 bool strbounded_p;
158 builtin_memref (tree, tree);
160 tree offset_out_of_bounds (int, offset_int[2]) const;
162 private:
164 /* Ctor helper to set or extend OFFRANGE based on argument. */
165 void extend_offset_range (tree);
167 /* Ctor helper to determine BASE and OFFRANGE from argument. */
168 void set_base_and_offset (tree);
171 /* Description of a memory access by a raw memory or string built-in
172 function involving a pair of builtin_memref's. */
173 class builtin_access
175 public:
176 /* Destination and source memory reference. */
177 builtin_memref* const dstref;
178 builtin_memref* const srcref;
179 /* The size range of the access. It's the greater of the accesses
180 to the two references. */
181 HOST_WIDE_INT sizrange[2];
183 /* The minimum and maximum offset of an overlap of the access
184 (if it does, in fact, overlap), and the size of the overlap. */
185 HOST_WIDE_INT ovloff[2];
186 HOST_WIDE_INT ovlsiz[2];
188 /* True to consider valid only accesses to the smallest subobject
189 and false for raw memory functions. */
190 bool strict () const
192 return detect_overlap != &builtin_access::generic_overlap;
195 builtin_access (gcall *, builtin_memref &, builtin_memref &);
197 /* Entry point to determine overlap. */
198 bool overlap ();
200 private:
201 /* Implementation functions used to determine overlap. */
202 bool generic_overlap ();
203 bool strcat_overlap ();
204 bool strcpy_overlap ();
206 bool no_overlap ()
208 return false;
211 offset_int overlap_size (const offset_int [2], const offset_int[2],
212 offset_int [2]);
214 private:
215 /* Temporaries used to compute the final result. */
216 offset_int dstoff[2];
217 offset_int srcoff[2];
218 offset_int dstsiz[2];
219 offset_int srcsiz[2];
221 /* Pointer to a member function to call to determine overlap. */
222 bool (builtin_access::*detect_overlap) ();
225 /* Initialize a memory reference representation from a pointer EXPR and
226 a size SIZE in bytes. If SIZE is NULL_TREE then the size is assumed
227 to be unknown. */
229 builtin_memref::builtin_memref (tree expr, tree size)
230 : ptr (expr),
231 ref (),
232 base (),
233 basesize (-1),
234 refoff (HOST_WIDE_INT_MIN),
235 offrange (),
236 sizrange (),
237 strbounded_p ()
239 /* Unfortunately, wide_int default ctor is a no-op so array members
240 of the type must be set individually. */
241 offrange[0] = offrange[1] = 0;
242 sizrange[0] = sizrange[1] = 0;
244 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
246 /* Find the BASE object or pointer referenced by EXPR and set
247 the offset range OFFRANGE in the process. */
248 set_base_and_offset (expr);
250 if (size)
252 tree range[2];
253 /* Determine the size range, allowing for the result to be [0, 0]
254 for SIZE in the anti-range ~[0, N] where N >= PTRDIFF_MAX. */
255 get_size_range (size, range, true);
256 sizrange[0] = wi::to_offset (range[0]);
257 sizrange[1] = wi::to_offset (range[1]);
258 /* get_size_range returns SIZE_MAX for the maximum size.
259 Constrain it to the real maximum of PTRDIFF_MAX. */
260 if (sizrange[1] > maxobjsize)
261 sizrange[1] = maxobjsize;
263 else
264 sizrange[1] = maxobjsize;
266 if (!DECL_P (base))
267 return;
269 /* If the offset could be in the range of the referenced object
270 constrain its bounds so neither exceeds those of the object. */
271 if (offrange[0] < 0 && offrange[1] > 0)
272 offrange[0] = 0;
274 offset_int maxoff = maxobjsize;
275 tree basetype = TREE_TYPE (base);
276 if (TREE_CODE (basetype) == ARRAY_TYPE
277 && ref
278 && array_at_struct_end_p (ref))
279 ; /* Use the maximum possible offset for last member arrays. */
280 else if (tree basesize = TYPE_SIZE_UNIT (basetype))
281 maxoff = wi::to_offset (basesize);
283 if (offrange[0] >= 0)
285 if (offrange[1] < 0)
286 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
287 else if (offrange[0] <= maxoff && offrange[1] > maxoff)
288 offrange[1] = maxoff;
292 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. */
294 void
295 builtin_memref::extend_offset_range (tree offset)
297 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
299 if (TREE_CODE (offset) == INTEGER_CST)
301 offset_int off = int_cst_value (offset);
302 if (off != 0)
304 offrange[0] += off;
305 offrange[1] += off;
307 return;
310 if (TREE_CODE (offset) == SSA_NAME)
312 wide_int min, max;
313 value_range_type rng = get_range_info (offset, &min, &max);
314 if (rng == VR_RANGE)
316 offrange[0] += offset_int::from (min, SIGNED);
317 offrange[1] += offset_int::from (max, SIGNED);
319 else if (rng == VR_ANTI_RANGE)
321 offrange[0] += offset_int::from (max + 1, SIGNED);
322 offrange[1] += offset_int::from (min - 1, SIGNED);
324 else
326 gimple *stmt = SSA_NAME_DEF_STMT (offset);
327 tree type;
328 if (is_gimple_assign (stmt)
329 && gimple_assign_rhs_code (stmt) == NOP_EXPR
330 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
331 && INTEGRAL_TYPE_P (type))
333 /* Use the bounds of the type of the NOP_EXPR operand
334 even if it's signed. The result doesn't trigger
335 warnings but makes their output more readable. */
336 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
337 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
339 else
340 offrange[1] += maxobjsize;
342 return;
345 offrange[1] += maxobjsize;
348 /* Determines the base object or pointer of the reference EXPR
349 and the offset range from the beginning of the base. */
351 void
352 builtin_memref::set_base_and_offset (tree expr)
354 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
356 if (TREE_CODE (expr) == SSA_NAME)
358 /* Try to tease the offset out of the pointer. */
359 gimple *stmt = SSA_NAME_DEF_STMT (expr);
360 if (!base
361 && gimple_assign_single_p (stmt)
362 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
363 expr = gimple_assign_rhs1 (stmt);
364 else if (is_gimple_assign (stmt))
366 tree_code code = gimple_assign_rhs_code (stmt);
367 if (code == NOP_EXPR)
369 tree rhs = gimple_assign_rhs1 (stmt);
370 if (POINTER_TYPE_P (TREE_TYPE (rhs)))
371 expr = gimple_assign_rhs1 (stmt);
372 else
374 base = expr;
375 return;
378 else if (code == POINTER_PLUS_EXPR)
380 expr = gimple_assign_rhs1 (stmt);
382 tree offset = gimple_assign_rhs2 (stmt);
383 extend_offset_range (offset);
385 else
387 base = expr;
388 return;
391 else
393 base = expr;
394 return;
398 if (TREE_CODE (expr) == ADDR_EXPR)
399 expr = TREE_OPERAND (expr, 0);
401 /* Stash the reference for offset validation. */
402 ref = expr;
404 poly_int64 bitsize, bitpos;
405 tree var_off;
406 machine_mode mode;
407 int sign, reverse, vol;
409 /* Determine the base object or pointer of the reference and
410 the constant bit offset from the beginning of the base.
411 If the offset has a non-constant component, it will be in
412 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
413 unused here. */
414 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
415 &mode, &sign, &reverse, &vol);
417 /* get_inner_reference is not expected to return null. */
418 gcc_assert (base != NULL);
420 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
422 /* Convert the poly_int64 offset to offset_int. The offset
423 should be constant but be prepared for it not to be just in
424 case. */
425 offset_int cstoff;
426 if (bytepos.is_constant (&cstoff))
428 offrange[0] += cstoff;
429 offrange[1] += cstoff;
431 /* Besides the reference saved above, also stash the offset
432 for validation. */
433 if (TREE_CODE (expr) == COMPONENT_REF)
434 refoff = cstoff;
436 else
437 offrange[1] += maxobjsize;
439 if (var_off)
441 if (TREE_CODE (var_off) == INTEGER_CST)
443 cstoff = wi::to_offset (var_off);
444 offrange[0] += cstoff;
445 offrange[1] += cstoff;
447 else
448 offrange[1] += maxobjsize;
451 if (TREE_CODE (base) == MEM_REF)
453 tree memrefoff = TREE_OPERAND (base, 1);
454 extend_offset_range (memrefoff);
455 base = TREE_OPERAND (base, 0);
458 if (TREE_CODE (base) == SSA_NAME)
459 set_base_and_offset (base);
462 /* Return error_mark_node if the signed offset exceeds the bounds
463 of the address space (PTRDIFF_MAX). Otherwise, return either
464 BASE or REF when the offset exceeds the bounds of the BASE or
465 REF object, and set OOBOFF to the past-the-end offset formed
466 by the reference, including its size. When STRICT is non-zero
467 use REF size, when available, otherwise use BASE size. When
468 STRICT is greater than 1, use the size of the last array member
469 as the bound, otherwise treat such a member as a flexible array
470 member. Return NULL when the offset is in bounds. */
472 tree
473 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[2]) const
475 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
477 /* A temporary, possibly adjusted, copy of the offset range. */
478 offset_int offrng[2] = { offrange[0], offrange[1] };
480 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
482 /* Check for offset in an anti-range with a negative lower bound.
483 For such a range, consider only the non-negative subrange. */
484 if (offrng[1] < offrng[0] && offrng[1] < 0)
485 offrng[1] = maxobjsize;
488 /* Conservative offset of the last byte of the referenced object. */
489 offset_int endoff;
491 /* The bounds need not be ordered. Set HIB to use as the index
492 of the larger of the bounds and LOB as the opposite. */
493 bool hib = wi::les_p (offrng[0], offrng[1]);
494 bool lob = !hib;
496 if (basesize < 0)
498 endoff = offrng[lob] + sizrange[0];
500 /* For a reference through a pointer to an object of unknown size
501 all initial offsets are considered valid, positive as well as
502 negative, since the pointer itself can point past the beginning
503 of the object. However, the sum of the lower bound of the offset
504 and that of the size must be less than or equal than PTRDIFF_MAX. */
505 if (endoff > maxobjsize)
506 return error_mark_node;
508 return NULL_TREE;
511 /* A reference to an object of known size must be within the bounds
512 of the base object. */
513 if (offrng[hib] < 0 || offrng[lob] > basesize)
514 return base;
516 /* The extent of the reference must also be within the bounds of
517 the base object (if known) or the maximum object size otherwise. */
518 endoff = wi::smax (offrng[lob], 0) + sizrange[0];
519 if (endoff > maxobjsize)
520 return error_mark_node;
522 offset_int size = basesize;
523 tree obj = base;
525 if (strict
526 && DECL_P (obj)
527 && ref
528 && refoff >= 0
529 && TREE_CODE (ref) == COMPONENT_REF
530 && (strict > 1
531 || !array_at_struct_end_p (ref)))
533 /* If the reference is to a member subobject, the offset must
534 be within the bounds of the subobject. */
535 tree field = TREE_OPERAND (ref, 1);
536 tree type = TREE_TYPE (field);
537 if (tree sz = TYPE_SIZE_UNIT (type))
538 if (TREE_CODE (sz) == INTEGER_CST)
540 size = refoff + wi::to_offset (sz);
541 obj = ref;
545 if (endoff <= size)
546 return NULL_TREE;
548 /* Set the out-of-bounds offset range to be one greater than
549 that delimited by the reference including its size. */
550 ooboff[lob] = size + 1;
552 if (endoff > ooboff[lob])
553 ooboff[hib] = endoff;
554 else
555 ooboff[hib] = wi::smax (offrng[lob], 0) + sizrange[1];
557 return obj;
560 /* Create an association between the memory references DST and SRC
561 for access by a call EXPR to a memory or string built-in funtion. */
563 builtin_access::builtin_access (gcall *call, builtin_memref &dst,
564 builtin_memref &src)
565 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
566 dstoff (), srcoff (), dstsiz (), srcsiz ()
568 /* Zero out since the offset_int ctors invoked above are no-op. */
569 dstoff[0] = dstoff[1] = 0;
570 srcoff[0] = srcoff[1] = 0;
571 dstsiz[0] = dstsiz[1] = 0;
572 srcsiz[0] = srcsiz[1] = 0;
574 /* Object Size Type to use to determine the size of the destination
575 and source objects. Overridden below for raw memory functions. */
576 int ostype = 1;
578 /* True when the size of one reference depends on the offset of
579 itself or the other. */
580 bool depends_p = true;
582 /* True when the size of the destination reference DSTREF has been
583 determined from SRCREF and so needs to be adjusted by the latter's
584 offset. Only meaningful for bounded string functions like strncpy. */
585 bool dstadjust_p = false;
587 /* The size argument number (depends on the built-in). */
588 unsigned sizeargno = 2;
589 if (gimple_call_with_bounds_p (call))
590 sizeargno += 2;
592 tree func = gimple_call_fndecl (call);
593 switch (DECL_FUNCTION_CODE (func))
595 case BUILT_IN_MEMCPY:
596 case BUILT_IN_MEMCPY_CHK:
597 case BUILT_IN_MEMCPY_CHKP:
598 case BUILT_IN_MEMCPY_CHK_CHKP:
599 case BUILT_IN_MEMPCPY:
600 case BUILT_IN_MEMPCPY_CHK:
601 case BUILT_IN_MEMPCPY_CHKP:
602 case BUILT_IN_MEMPCPY_CHK_CHKP:
603 ostype = 0;
604 depends_p = false;
605 detect_overlap = &builtin_access::generic_overlap;
606 break;
608 case BUILT_IN_MEMMOVE:
609 case BUILT_IN_MEMMOVE_CHK:
610 case BUILT_IN_MEMMOVE_CHKP:
611 case BUILT_IN_MEMMOVE_CHK_CHKP:
612 /* For memmove there is never any overlap to check for. */
613 ostype = 0;
614 depends_p = false;
615 detect_overlap = &builtin_access::no_overlap;
616 break;
618 case BUILT_IN_STPNCPY:
619 case BUILT_IN_STPNCPY_CHK:
620 case BUILT_IN_STRNCPY:
621 case BUILT_IN_STRNCPY_CHK:
622 dstref->strbounded_p = true;
623 detect_overlap = &builtin_access::strcpy_overlap;
624 break;
626 case BUILT_IN_STPCPY:
627 case BUILT_IN_STPCPY_CHK:
628 case BUILT_IN_STPCPY_CHKP:
629 case BUILT_IN_STPCPY_CHK_CHKP:
630 case BUILT_IN_STRCPY:
631 case BUILT_IN_STRCPY_CHK:
632 case BUILT_IN_STRCPY_CHKP:
633 case BUILT_IN_STRCPY_CHK_CHKP:
634 detect_overlap = &builtin_access::strcpy_overlap;
635 break;
637 case BUILT_IN_STRCAT:
638 case BUILT_IN_STRCAT_CHK:
639 case BUILT_IN_STRCAT_CHKP:
640 case BUILT_IN_STRCAT_CHK_CHKP:
641 detect_overlap = &builtin_access::strcat_overlap;
642 break;
644 case BUILT_IN_STRNCAT:
645 case BUILT_IN_STRNCAT_CHK:
646 dstref->strbounded_p = true;
647 srcref->strbounded_p = true;
648 detect_overlap = &builtin_access::strcat_overlap;
649 break;
651 default:
652 /* Handle other string functions here whose access may need
653 to be validated for in-bounds offsets and non-overlapping
654 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
655 macros so they need to be handled here.) */
656 return;
659 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
661 /* Try to determine the size of the base object. compute_objsize
662 expects a pointer so create one if BASE is a non-pointer object. */
663 tree addr;
664 if (dst.basesize < 0)
666 addr = dst.base;
667 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
668 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
670 if (tree dstsize = compute_objsize (addr, ostype))
671 dst.basesize = wi::to_offset (dstsize);
672 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
673 dst.basesize = HOST_WIDE_INT_MIN;
674 else
675 dst.basesize = maxobjsize;
678 if (src.basesize < 0)
680 addr = src.base;
681 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
682 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
684 if (tree srcsize = compute_objsize (addr, ostype))
685 src.basesize = wi::to_offset (srcsize);
686 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
687 src.basesize = HOST_WIDE_INT_MIN;
688 else
689 src.basesize = maxobjsize;
692 /* If there is no dependency between the references or the base
693 objects of the two references aren't the same there's nothing
694 else to do. */
695 if (depends_p && dstref->base != srcref->base)
696 return;
698 /* ...otherwise, make adjustments for references to the same object
699 by string built-in functions to reflect the constraints imposed
700 by the function. */
702 /* For bounded string functions determine the range of the bound
703 on the access. For others, the range stays unbounded. */
704 offset_int bounds[2] = { maxobjsize, maxobjsize };
705 if (dstref->strbounded_p)
707 tree size = gimple_call_arg (call, sizeargno);
708 tree range[2];
709 if (get_size_range (size, range, true))
711 bounds[0] = wi::to_offset (range[0]);
712 bounds[1] = wi::to_offset (range[1]);
715 /* If both references' size ranges are indeterminate use the last
716 (size) argument from the function call as a substitute. This
717 may only be necessary for strncpy (but not for memcpy where
718 the size range would have been already determined this way). */
719 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
720 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
722 dstref->sizrange[0] = bounds[0];
723 dstref->sizrange[1] = bounds[1];
727 /* The size range of one reference involving the same base object
728 can be determined from the size range of the other reference.
729 This makes it possible to compute accurate offsets for warnings
730 involving functions like strcpy where the length of just one of
731 the two arguments is known (determined by tree-ssa-strlen). */
732 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
734 /* When the destination size is unknown set it to the size of
735 the source. */
736 dstref->sizrange[0] = srcref->sizrange[0];
737 dstref->sizrange[1] = srcref->sizrange[1];
739 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
741 /* When the source size is unknown set it to the size of
742 the destination. */
743 srcref->sizrange[0] = dstref->sizrange[0];
744 srcref->sizrange[1] = dstref->sizrange[1];
746 if (depends_p)
748 if (dstref->strbounded_p)
750 /* Read access by strncpy is bounded. */
751 if (bounds[0] < srcref->sizrange[0])
752 srcref->sizrange[0] = bounds[0];
753 if (bounds[1] < srcref->sizrange[1])
754 srcref->sizrange[1] = bounds[1];
757 /* For string functions, adjust the size range of the source
758 reference by the inverse boundaries of the offset (because
759 the higher the offset into the string the shorter its
760 length). */
761 if (srcref->offrange[1] >= 0
762 && srcref->offrange[1] < srcref->sizrange[0])
763 srcref->sizrange[0] -= srcref->offrange[1];
764 else
765 srcref->sizrange[0] = 0;
767 if (srcref->offrange[0] > 0)
769 if (srcref->offrange[0] < srcref->sizrange[1])
770 srcref->sizrange[1] -= srcref->offrange[0];
771 else
772 srcref->sizrange[1] = 0;
775 dstadjust_p = true;
779 if (detect_overlap == &builtin_access::generic_overlap)
781 if (dstref->strbounded_p)
783 dstref->sizrange[0] = bounds[0];
784 dstref->sizrange[1] = bounds[1];
786 if (dstref->sizrange[0] < srcref->sizrange[0])
787 srcref->sizrange[0] = dstref->sizrange[0];
789 if (dstref->sizrange[1] < srcref->sizrange[1])
790 srcref->sizrange[1] = dstref->sizrange[1];
793 else if (detect_overlap == &builtin_access::strcpy_overlap)
795 if (!dstref->strbounded_p)
797 /* For strcpy, adjust the destination size range to match that
798 of the source computed above. */
799 if (depends_p && dstadjust_p)
801 dstref->sizrange[0] = srcref->sizrange[0];
802 dstref->sizrange[1] = srcref->sizrange[1];
807 if (dstref->strbounded_p)
809 /* For strncpy, adjust the destination size range to match that
810 of the source computed above. */
811 dstref->sizrange[0] = bounds[0];
812 dstref->sizrange[1] = bounds[1];
814 if (bounds[0] < srcref->sizrange[0])
815 srcref->sizrange[0] = bounds[0];
817 if (bounds[1] < srcref->sizrange[1])
818 srcref->sizrange[1] = bounds[1];
822 offset_int
823 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
824 offset_int *off)
826 const offset_int *p = a;
827 const offset_int *q = b;
829 /* Point P at the bigger of the two ranges and Q at the smaller. */
830 if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
832 p = b;
833 q = a;
836 if (p[0] < q[0])
838 if (p[1] < q[0])
839 return 0;
841 *off = q[0];
842 return wi::smin (p[1], q[1]) - q[0];
845 if (q[1] < p[0])
846 return 0;
848 off[0] = p[0];
849 return q[1] - p[0];
852 /* Return true if the bounded mempry (memcpy amd similar) or string function
853 access (strncpy and similar) ACS overlaps. */
855 bool
856 builtin_access::generic_overlap ()
858 builtin_access &acs = *this;
859 const builtin_memref *dstref = acs.dstref;
860 const builtin_memref *srcref = acs.srcref;
862 gcc_assert (dstref->base == srcref->base);
864 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
866 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
867 gcc_assert (maxsize <= maxobjsize);
869 /* Adjust the larger bounds of the offsets (which may be the first
870 element if the lower bound is larger than the upper bound) to
871 make them valid for the smallest access (if possible) but no smaller
872 than the smaller bounds. */
873 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
875 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
876 acs.dstoff[1] = maxsize - acs.dstsiz[0];
877 if (acs.dstoff[1] < acs.dstoff[0])
878 acs.dstoff[1] = acs.dstoff[0];
880 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
882 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
883 acs.srcoff[1] = maxsize - acs.srcsiz[0];
884 if (acs.srcoff[1] < acs.srcoff[0])
885 acs.srcoff[1] = acs.srcoff[0];
887 /* Determine the minimum and maximum space for the access given
888 the offsets. */
889 offset_int space[2];
890 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
891 space[1] = space[0];
893 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
894 if (acs.srcsiz[0] > 0)
896 if (d < space[0])
897 space[0] = d;
899 if (space[1] < d)
900 space[1] = d;
902 else
903 space[1] = acs.dstsiz[1];
905 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
906 if (d < space[0])
907 space[0] = d;
909 if (space[1] < d)
910 space[1] = d;
912 /* Treat raw memory functions both of whose references are bounded
913 as special and permit uncertain overlaps to go undetected. For
914 all kinds of constant offset and constant size accesses, if
915 overlap isn't certain it is not possible. */
916 bool overlap_possible = space[0] < acs.dstsiz[1];
917 if (!overlap_possible)
918 return false;
920 bool overlap_certain = space[1] < acs.dstsiz[0];
922 /* True when the size of one reference depends on the offset of
923 the other. */
924 bool depends_p = detect_overlap != &builtin_access::generic_overlap;
926 if (!overlap_certain)
928 if (!dstref->strbounded_p && !depends_p)
929 /* Memcpy only considers certain overlap. */
930 return false;
932 /* There's no way to distinguish an access to the same member
933 of a structure from one to two distinct members of the same
934 structure. Give up to avoid excessive false positives. */
935 tree basetype = TREE_TYPE (dstref->base);
937 if (POINTER_TYPE_P (basetype))
938 basetype = TREE_TYPE (basetype);
939 else
940 while (TREE_CODE (basetype) == ARRAY_TYPE)
941 basetype = TREE_TYPE (basetype);
943 if (RECORD_OR_UNION_TYPE_P (basetype))
944 return false;
947 /* True for stpcpy and strcpy. */
948 bool stxcpy_p = (!dstref->strbounded_p
949 && detect_overlap == &builtin_access::strcpy_overlap);
951 if (dstref->refoff >= 0
952 && srcref->refoff >= 0
953 && dstref->refoff != srcref->refoff
954 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
955 return false;
957 offset_int siz[2] = { maxobjsize + 1, 0 };
959 ovloff[0] = HOST_WIDE_INT_MAX;
960 ovloff[1] = HOST_WIDE_INT_MIN;
962 /* Adjustment to the lower bound of the offset of the overlap to
963 account for a subset of unbounded string calls where the size
964 of the destination string depends on the length of the source
965 which in turn depends on the offset into it. */
966 bool sub1;
968 if (stxcpy_p)
970 sub1 = acs.dstoff[0] <= acs.srcoff[0];
972 /* Iterate over the extreme locations (on the horizontal axis formed
973 by their offsets) and sizes of two regions and find their smallest
974 and largest overlap and the corresponding offsets. */
975 for (unsigned i = 0; i != 2; ++i)
977 const offset_int a[2] = {
978 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
981 const offset_int b[2] = {
982 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
985 offset_int off;
986 offset_int sz = overlap_size (a, b, &off);
987 if (sz < siz[0])
988 siz[0] = sz;
990 if (siz[1] <= sz)
991 siz[1] = sz;
993 if (sz != 0)
995 if (wi::lts_p (off, ovloff[0]))
996 ovloff[0] = off.to_shwi ();
997 if (wi::lts_p (ovloff[1], off))
998 ovloff[1] = off.to_shwi ();
1002 else
1004 sub1 = !depends_p;
1006 /* Iterate over the extreme locations (on the horizontal axis
1007 formed by their offsets) and sizes of two regions and find
1008 their smallest and largest overlap and the corresponding
1009 offsets. */
1011 for (unsigned io = 0; io != 2; ++io)
1012 for (unsigned is = 0; is != 2; ++is)
1014 const offset_int a[2] = {
1015 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1018 for (unsigned jo = 0; jo != 2; ++jo)
1019 for (unsigned js = 0; js != 2; ++js)
1021 if (depends_p)
1023 /* For st{p,r}ncpy the size of the source sequence
1024 depends on the offset into it. */
1025 if (js)
1026 break;
1027 js = !jo;
1030 const offset_int b[2] = {
1031 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1034 offset_int off;
1035 offset_int sz = overlap_size (a, b, &off);
1036 if (sz < siz[0])
1037 siz[0] = sz;
1039 if (siz[1] <= sz)
1040 siz[1] = sz;
1042 if (sz != 0)
1044 if (wi::lts_p (off, ovloff[0]))
1045 ovloff[0] = off.to_shwi ();
1046 if (wi::lts_p (ovloff[1], off))
1047 ovloff[1] = off.to_shwi ();
1053 ovlsiz[0] = siz[0].to_shwi ();
1054 ovlsiz[1] = siz[1].to_shwi ();
1056 if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1057 ovloff[0] = ovloff[1] + ovlsiz[1] - 1 - sub1;
1059 return true;
1062 /* Return true if the strcat-like access overlaps. */
1064 bool
1065 builtin_access::strcat_overlap ()
1067 builtin_access &acs = *this;
1068 const builtin_memref *dstref = acs.dstref;
1069 const builtin_memref *srcref = acs.srcref;
1071 gcc_assert (dstref->base == srcref->base);
1073 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1075 gcc_assert (dstref->base && dstref->base == srcref->base);
1077 /* Adjust for strcat-like accesses. */
1079 /* As a special case for strcat, set the DSTREF offsets to the length
1080 of the source string since the function starts writing at the first
1081 nul, and set the size to 1 for the length of the nul. */
1082 acs.dstoff[0] += acs.dstsiz[0];
1083 acs.dstoff[1] += acs.dstsiz[1];
1085 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1087 /* The lower bound is zero when the size is unknown because then
1088 overlap is not certain. */
1089 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1090 acs.dstsiz[1] = 1;
1092 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1093 gcc_assert (maxsize <= maxobjsize);
1095 /* For references to the same base object, determine if there's a pair
1096 of valid offsets into the two references such that access between
1097 them doesn't overlap. Adjust both upper bounds to be valid for
1098 the smaller size (i.e., at most MAXSIZE - SIZE). */
1100 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1101 acs.dstoff[1] = maxsize - acs.dstsiz[0];
1103 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1104 acs.srcoff[1] = maxsize - acs.srcsiz[0];
1106 /* Check to see if there's enough space for both accesses without
1107 overlap. Determine the optimistic (maximum) amount of available
1108 space. */
1109 offset_int space;
1110 if (acs.dstoff[0] <= acs.srcoff[0])
1112 if (acs.dstoff[1] < acs.srcoff[1])
1113 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1114 else
1115 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1117 else
1118 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1120 /* Overlap is certain if the distance between the farthest offsets
1121 of the opposite accesses is less than the sum of the lower bounds
1122 of the sizes of the two accesses. */
1123 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1125 /* For a constant-offset, constant size access, consider the largest
1126 distance between the offset bounds and the lower bound of the access
1127 size. If the overlap isn't certain return success. */
1128 if (!overlap_certain
1129 && acs.dstoff[0] == acs.dstoff[1]
1130 && acs.srcoff[0] == acs.srcoff[1]
1131 && acs.dstsiz[0] == acs.dstsiz[1]
1132 && acs.srcsiz[0] == acs.srcsiz[1])
1133 return false;
1135 /* Overlap is not certain but may be possible. */
1137 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1139 /* Determine the conservative (minimum) amount of space. */
1140 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1141 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1142 if (d < space)
1143 space = d;
1144 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1145 if (d < space)
1146 space = d;
1148 /* For a strict test (used for strcpy and similar with unknown or
1149 variable bounds or sizes), consider the smallest distance between
1150 the offset bounds and either the upper bound of the access size
1151 if known, or the lower bound otherwise. */
1152 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1153 return false;
1155 /* When strcat overlap is certain it is always a single byte:
1156 the terminating NUL, regardless of offsets and sizes. When
1157 overlap is only possible its range is [0, 1]. */
1158 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1159 acs.ovlsiz[1] = 1;
1161 offset_int endoff = dstref->offrange[0] + dstref->sizrange[0];
1162 if (endoff <= srcref->offrange[0])
1163 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1164 else
1165 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1167 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1168 srcref->sizrange[0]).to_shwi ();
1169 if (dstref->offrange[0] == dstref->offrange[1])
1171 if (srcref->offrange[0] == srcref->offrange[1])
1172 acs.ovloff[1] = acs.ovloff[0];
1173 else
1174 acs.ovloff[1]
1175 = wi::smin (maxobjsize,
1176 srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1178 else
1179 acs.ovloff[1]
1180 = wi::smin (maxobjsize,
1181 dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1183 if (acs.sizrange[0] == 0)
1184 acs.sizrange[0] = 1;
1185 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1186 return true;
1189 /* Return true if the strcpy-like access overlaps. */
1191 bool
1192 builtin_access::strcpy_overlap ()
1194 return generic_overlap ();
1198 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1199 one another or that, in order not to overlap, would imply that the size
1200 of the referenced object(s) exceeds the maximum size of an object. Set
1201 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1202 they may overlap in a way that's not apparent from the available data),
1203 return false. */
1205 bool
1206 builtin_access::overlap ()
1208 builtin_access &acs = *this;
1210 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1212 acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1213 srcref->sizrange[0]).to_shwi ();
1214 acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1215 srcref->sizrange[1]).to_shwi ();
1217 /* Check to see if the two references refer to regions that are
1218 too large not to overlap in the address space (whose maximum
1219 size is PTRDIFF_MAX). */
1220 offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1221 if (maxobjsize < size)
1223 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1224 acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1225 return true;
1228 /* If both base objects aren't known return the maximum possible
1229 offset that would make them not overlap. */
1230 if (!dstref->base || !srcref->base)
1231 return false;
1233 /* Set the access offsets. */
1234 acs.dstoff[0] = dstref->offrange[0];
1235 acs.dstoff[1] = dstref->offrange[1];
1237 /* If the base object is an array adjust the bounds of the offset
1238 to be non-negative and within the bounds of the array if possible. */
1239 if (dstref->base
1240 && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE)
1242 if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0)
1243 acs.dstoff[0] = 0;
1245 if (acs.dstoff[1] < acs.dstoff[0])
1247 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base)))
1248 acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size));
1249 else
1250 acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize);
1254 acs.srcoff[0] = srcref->offrange[0];
1255 acs.srcoff[1] = srcref->offrange[1];
1257 if (srcref->base
1258 && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE)
1260 if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0)
1261 acs.srcoff[0] = 0;
1263 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base)))
1264 acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size));
1265 else if (acs.srcoff[1] < acs.srcoff[0])
1266 acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize);
1269 /* When the upper bound of the offset is less than the lower bound
1270 the former is the result of a negative offset being represented
1271 as a large positive value or vice versa. The resulting range is
1272 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1273 a union is not representable using the current data structure
1274 replace it with the full range of offsets. */
1275 if (acs.dstoff[1] < acs.dstoff[0])
1277 acs.dstoff[0] = -maxobjsize - 1;
1278 acs.dstoff[1] = maxobjsize;
1281 /* Validate the offset and size of each reference on its own first.
1282 This is independent of whether or not the base objects are the
1283 same. Normally, this would have already been detected and
1284 diagnosed by -Warray-bounds, unless it has been disabled. */
1285 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1286 if (maxobjsize < maxoff)
1288 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1289 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1290 return true;
1293 /* Repeat the same as above but for the source offsets. */
1294 if (acs.srcoff[1] < acs.srcoff[0])
1296 acs.srcoff[0] = -maxobjsize - 1;
1297 acs.srcoff[1] = maxobjsize;
1300 maxoff = acs.srcoff[0] + srcref->sizrange[0];
1301 if (maxobjsize < maxoff)
1303 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1304 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1305 - maxobjsize).to_shwi ();
1306 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1307 return true;
1310 if (dstref->base != srcref->base)
1311 return false;
1313 acs.dstsiz[0] = dstref->sizrange[0];
1314 acs.dstsiz[1] = dstref->sizrange[1];
1316 acs.srcsiz[0] = srcref->sizrange[0];
1317 acs.srcsiz[1] = srcref->sizrange[1];
1319 /* Call the appropriate function to determine the overlap. */
1320 if ((this->*detect_overlap) ())
1322 if (!sizrange[1])
1324 /* Unless the access size range has already been set, do so here. */
1325 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1326 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1328 return true;
1331 return false;
1334 /* Attempt to detect and diagnose an overlapping copy in a call expression
1335 EXPR involving an an access ACS to a built-in memory or string function.
1336 Return true when one has been detected, false otherwise. */
1338 static bool
1339 maybe_diag_overlap (location_t loc, gcall *call, builtin_access &acs)
1341 if (!acs.overlap ())
1342 return false;
1344 /* For convenience. */
1345 const builtin_memref &dstref = *acs.dstref;
1346 const builtin_memref &srcref = *acs.srcref;
1348 /* Determine the range of offsets and sizes of the overlap if it
1349 exists and issue diagnostics. */
1350 HOST_WIDE_INT *ovloff = acs.ovloff;
1351 HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1352 HOST_WIDE_INT *sizrange = acs.sizrange;
1354 tree func = gimple_call_fndecl (call);
1356 /* To avoid a combinatorial explosion of diagnostics format the offsets
1357 or their ranges as strings and use them in the warning calls below. */
1358 char offstr[3][64];
1360 if (dstref.offrange[0] == dstref.offrange[1]
1361 || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1362 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1363 dstref.offrange[0].to_shwi ());
1364 else
1365 sprintf (offstr[0],
1366 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1367 dstref.offrange[0].to_shwi (),
1368 dstref.offrange[1].to_shwi ());
1370 if (srcref.offrange[0] == srcref.offrange[1]
1371 || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1372 sprintf (offstr[1],
1373 HOST_WIDE_INT_PRINT_DEC,
1374 srcref.offrange[0].to_shwi ());
1375 else
1376 sprintf (offstr[1],
1377 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1378 srcref.offrange[0].to_shwi (),
1379 srcref.offrange[1].to_shwi ());
1381 if (ovloff[0] == ovloff[1] || !ovloff[1])
1382 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1383 else
1384 sprintf (offstr[2],
1385 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1386 ovloff[0], ovloff[1]);
1388 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1389 bool must_overlap = ovlsiz[0] > 0;
1391 if (ovlsiz[1] == 0)
1392 ovlsiz[1] = ovlsiz[0];
1394 if (must_overlap)
1396 /* Issue definitive "overlaps" diagnostic in this block. */
1398 if (sizrange[0] == sizrange[1])
1400 if (ovlsiz[0] == ovlsiz[1])
1401 warning_at (loc, OPT_Wrestrict,
1402 sizrange[0] == 1
1403 ? (ovlsiz[0] == 1
1404 ? G_("%G%qD accessing %wu byte at offsets %s "
1405 "and %s overlaps %wu byte at offset %s")
1406 : G_("%G%qD accessing %wu byte at offsets %s "
1407 "and %s overlaps %wu bytes at offset "
1408 "%s"))
1409 : (ovlsiz[0] == 1
1410 ? G_("%G%qD accessing %wu bytes at offsets %s "
1411 "and %s overlaps %wu byte at offset %s")
1412 : G_("%G%qD accessing %wu bytes at offsets %s "
1413 "and %s overlaps %wu bytes at offset "
1414 "%s")),
1415 call, func, sizrange[0],
1416 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1417 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1418 warning_n (loc, OPT_Wrestrict, sizrange[0],
1419 "%G%qD accessing %wu byte at offsets %s "
1420 "and %s overlaps between %wu and %wu bytes "
1421 "at offset %s",
1422 "%G%qD accessing %wu bytes at offsets %s "
1423 "and %s overlaps between %wu and %wu bytes "
1424 "at offset %s",
1425 call, func, sizrange[0], offstr[0], offstr[1],
1426 ovlsiz[0], ovlsiz[1], offstr[2]);
1427 else
1428 warning_n (loc, OPT_Wrestrict, sizrange[0],
1429 "%G%qD accessing %wu byte at offsets %s and "
1430 "%s overlaps %wu or more bytes at offset %s",
1431 "%G%qD accessing %wu bytes at offsets %s and "
1432 "%s overlaps %wu or more bytes at offset %s",
1433 call, func, sizrange[0],
1434 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1435 return true;
1438 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1440 if (ovlsiz[0] == ovlsiz[1])
1441 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1442 "%G%qD accessing between %wu and %wu bytes "
1443 "at offsets %s and %s overlaps %wu byte at "
1444 "offset %s",
1445 "%G%qD accessing between %wu and %wu bytes "
1446 "at offsets %s and %s overlaps %wu bytes "
1447 "at offset %s",
1448 call, func, sizrange[0], sizrange[1],
1449 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1450 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1451 warning_at (loc, OPT_Wrestrict,
1452 "%G%qD accessing between %wu and %wu bytes at "
1453 "offsets %s and %s overlaps between %wu and %wu "
1454 "bytes at offset %s",
1455 call, func, sizrange[0], sizrange[1],
1456 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1457 offstr[2]);
1458 else
1459 warning_at (loc, OPT_Wrestrict,
1460 "%G%qD accessing between %wu and %wu bytes at "
1461 "offsets %s and %s overlaps %wu or more bytes "
1462 "at offset %s",
1463 call, func, sizrange[0], sizrange[1],
1464 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1465 return true;
1468 if (ovlsiz[0] != ovlsiz[1])
1469 ovlsiz[1] = maxobjsize.to_shwi ();
1471 if (ovlsiz[0] == ovlsiz[1])
1472 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1473 "%G%qD accessing %wu or more bytes at offsets "
1474 "%s and %s overlaps %wu byte at offset %s",
1475 "%G%qD accessing %wu or more bytes at offsets "
1476 "%s and %s overlaps %wu bytes at offset %s",
1477 call, func, sizrange[0], offstr[0], offstr[1],
1478 ovlsiz[0], offstr[2]);
1479 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1480 warning_at (loc, OPT_Wrestrict,
1481 "%G%qD accessing %wu or more bytes at offsets %s "
1482 "and %s overlaps between %wu and %wu bytes "
1483 "at offset %s",
1484 call, func, sizrange[0], offstr[0], offstr[1],
1485 ovlsiz[0], ovlsiz[1], offstr[2]);
1486 else
1487 warning_at (loc, OPT_Wrestrict,
1488 "%G%qD accessing %wu or more bytes at offsets %s "
1489 "and %s overlaps %wu or more bytes at offset %s",
1490 call, func, sizrange[0], offstr[0], offstr[1],
1491 ovlsiz[0], offstr[2]);
1492 return true;
1495 /* Use more concise wording when one of the offsets is unbounded
1496 to avoid confusing the user with large and mostly meaningless
1497 numbers. */
1498 bool open_range;
1499 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1500 open_range = ((dstref.offrange[0] == 0
1501 && dstref.offrange[1] == maxobjsize)
1502 || (srcref.offrange[0] == 0
1503 && srcref.offrange[1] == maxobjsize));
1504 else
1505 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1506 && dstref.offrange[1] == maxobjsize)
1507 || (srcref.offrange[0] == -maxobjsize - 1
1508 && srcref.offrange[1] == maxobjsize));
1510 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1512 if (ovlsiz[1] == 1)
1514 if (open_range)
1515 warning_n (loc, OPT_Wrestrict, sizrange[1],
1516 "%G%qD accessing %wu byte may overlap "
1517 "%wu byte",
1518 "%G%qD accessing %wu bytes may overlap "
1519 "%wu byte",
1520 call, func, sizrange[1], ovlsiz[1]);
1521 else
1522 warning_n (loc, OPT_Wrestrict, sizrange[1],
1523 "%G%qD accessing %wu byte at offsets %s "
1524 "and %s may overlap %wu byte at offset %s",
1525 "%G%qD accessing %wu bytes at offsets %s "
1526 "and %s may overlap %wu byte at offset %s",
1527 call, func, sizrange[1], offstr[0], offstr[1],
1528 ovlsiz[1], offstr[2]);
1529 return true;
1532 if (open_range)
1533 warning_n (loc, OPT_Wrestrict, sizrange[1],
1534 "%G%qD accessing %wu byte may overlap "
1535 "up to %wu bytes",
1536 "%G%qD accessing %wu bytes may overlap "
1537 "up to %wu bytes",
1538 call, func, sizrange[1], ovlsiz[1]);
1539 else
1540 warning_n (loc, OPT_Wrestrict, sizrange[1],
1541 "%G%qD accessing %wu byte at offsets %s and "
1542 "%s may overlap up to %wu bytes at offset %s",
1543 "%G%qD accessing %wu bytes at offsets %s and "
1544 "%s may overlap up to %wu bytes at offset %s",
1545 call, func, sizrange[1], offstr[0], offstr[1],
1546 ovlsiz[1], offstr[2]);
1547 return true;
1550 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1552 if (open_range)
1553 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1554 "%G%qD accessing between %wu and %wu bytes "
1555 "may overlap %wu byte",
1556 "%G%qD accessing between %wu and %wu bytes "
1557 "may overlap up to %wu bytes",
1558 call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1559 else
1560 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1561 "%G%qD accessing between %wu and %wu bytes "
1562 "at offsets %s and %s may overlap %wu byte "
1563 "at offset %s",
1564 "%G%qD accessing between %wu and %wu bytes "
1565 "at offsets %s and %s may overlap up to %wu "
1566 "bytes at offset %s",
1567 call, func, sizrange[0], sizrange[1],
1568 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1569 return true;
1572 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1573 "%G%qD accessing %wu or more bytes at offsets %s "
1574 "and %s may overlap %wu byte at offset %s",
1575 "%G%qD accessing %wu or more bytes at offsets %s "
1576 "and %s may overlap up to %wu bytes at offset %s",
1577 call, func, sizrange[0], offstr[0], offstr[1],
1578 ovlsiz[1], offstr[2]);
1580 return true;
1583 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1584 to a built-in function FUNC to make sure they are within the bounds
1585 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1586 Both initial values of the offsets and their final value computed by
1587 the function by incrementing the initial value by the size are
1588 validated. Return true if the offsets are not valid and a diagnostic
1589 has been issued. */
1591 static bool
1592 maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
1593 tree expr, const builtin_memref &ref)
1595 if (!warn_array_bounds)
1596 return false;
1598 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1] };
1599 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1600 if (!oobref)
1601 return false;
1603 if (EXPR_HAS_LOCATION (expr))
1604 loc = EXPR_LOCATION (expr);
1606 loc = expansion_point_location_if_in_system_header (loc);
1608 tree type;
1610 char rangestr[2][64];
1611 if (ooboff[0] == ooboff[1]
1612 || (ooboff[0] != ref.offrange[0]
1613 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1614 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1615 else
1616 sprintf (rangestr[0], "[%lli, %lli]",
1617 (long long) ooboff[0].to_shwi (),
1618 (long long) ooboff[1].to_shwi ());
1620 if (oobref == error_mark_node)
1622 if (ref.sizrange[0] == ref.sizrange[1])
1623 sprintf (rangestr[1], "%lli", (long long) ref.sizrange[0].to_shwi ());
1624 else
1625 sprintf (rangestr[1], "[%lli, %lli]",
1626 (long long) ref.sizrange[0].to_shwi (),
1627 (long long) ref.sizrange[1].to_shwi ());
1629 if (DECL_P (ref.base)
1630 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1632 if (warning_at (loc, OPT_Warray_bounds,
1633 "%G%qD pointer overflow between offset %s "
1634 "and size %s accessing array %qD with type %qT",
1635 call, func, rangestr[0], rangestr[1], ref.base, type))
1636 inform (DECL_SOURCE_LOCATION (ref.base),
1637 "array %qD declared here", ref.base);
1638 else
1639 warning_at (loc, OPT_Warray_bounds,
1640 "%G%qD pointer overflow between offset %s "
1641 "and size %s",
1642 call, func, rangestr[0], rangestr[1]);
1644 else
1645 warning_at (loc, OPT_Warray_bounds,
1646 "%G%qD pointer overflow between offset %s "
1647 "and size %s",
1648 call, func, rangestr[0], rangestr[1]);
1650 else if (oobref == ref.base)
1652 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1654 /* True when the offset formed by an access to the reference
1655 is out of bounds, rather than the initial offset wich is
1656 in bounds. This implies access past the end. */
1657 bool form = ooboff[0] != ref.offrange[0];
1659 if (DECL_P (ref.base))
1661 if ((ref.basesize < maxobjsize
1662 && warning_at (loc, OPT_Warray_bounds,
1663 form
1664 ? G_("%G%qD forming offset %s is out of "
1665 "the bounds [0, %wu] of object %qD with "
1666 "type %qT")
1667 : G_("%G%qD offset %s is out of the bounds "
1668 "[0, %wu] of object %qD with type %qT"),
1669 call, func, rangestr[0], ref.basesize.to_uhwi (),
1670 ref.base, TREE_TYPE (ref.base)))
1671 || warning_at (loc, OPT_Warray_bounds,
1672 form
1673 ? G_("%G%qD forming offset %s is out of "
1674 "the bounds of object %qD with type %qT")
1675 : G_("%G%qD offset %s is out of the bounds "
1676 "of object %qD with type %qT"),
1677 call, func, rangestr[0],
1678 ref.base, TREE_TYPE (ref.base)))
1679 inform (DECL_SOURCE_LOCATION (ref.base),
1680 "%qD declared here", ref.base);
1682 else if (ref.basesize < maxobjsize)
1683 warning_at (loc, OPT_Warray_bounds,
1684 form
1685 ? G_("%G%qD forming offset %s is out of the bounds "
1686 "[0, %wu]")
1687 : G_("%G%qD offset %s is out of the bounds [0, %wu]"),
1688 call, func, rangestr[0], ref.basesize.to_uhwi ());
1689 else
1690 warning_at (loc, OPT_Warray_bounds,
1691 form
1692 ? G_("%G%qD forming offset %s is out of bounds")
1693 : G_("%G%qD offset %s is out of bounds"),
1694 call, func, rangestr[0]);
1696 else if (TREE_CODE (ref.ref) == MEM_REF)
1698 tree type = TREE_TYPE (TREE_OPERAND (ref.ref, 0));
1699 if (POINTER_TYPE_P (type))
1700 type = TREE_TYPE (type);
1701 type = TYPE_MAIN_VARIANT (type);
1703 warning_at (loc, OPT_Warray_bounds,
1704 "%G%qD offset %s from the object at %qE is out "
1705 "of the bounds of %qT",
1706 call, func, rangestr[0], ref.base, type);
1708 else
1710 type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1712 warning_at (loc, OPT_Warray_bounds,
1713 "%G%qD offset %s from the object at %qE is out "
1714 "of the bounds of referenced subobject %qD with type %qT "
1715 "at offset %wu",
1716 call, func, rangestr[0], ref.base, TREE_OPERAND (ref.ref, 1),
1717 type, ref.refoff.to_uhwi ());
1720 return true;
1723 /* Check a CALL statement for restrict-violations and issue warnings
1724 if/when appropriate. */
1726 void
1727 wrestrict_dom_walker::check_call (gcall *call)
1729 /* Avoid checking the call if it has already been diagnosed for
1730 some reason. */
1731 if (gimple_no_warning_p (call))
1732 return;
1734 tree func = gimple_call_fndecl (call);
1735 if (!func || DECL_BUILT_IN_CLASS (func) != BUILT_IN_NORMAL)
1736 return;
1738 bool with_bounds = gimple_call_with_bounds_p (call);
1740 /* Argument number to extract from the call (depends on the built-in
1741 and its kind). */
1742 unsigned dst_idx = -1;
1743 unsigned src_idx = -1;
1744 unsigned bnd_idx = -1;
1746 /* Is this CALL to a string function (as opposed to one to a raw
1747 memory function). */
1748 bool strfun = true;
1750 switch (DECL_FUNCTION_CODE (func))
1752 case BUILT_IN_MEMCPY:
1753 case BUILT_IN_MEMCPY_CHK:
1754 case BUILT_IN_MEMCPY_CHKP:
1755 case BUILT_IN_MEMCPY_CHK_CHKP:
1756 case BUILT_IN_MEMPCPY:
1757 case BUILT_IN_MEMPCPY_CHK:
1758 case BUILT_IN_MEMPCPY_CHKP:
1759 case BUILT_IN_MEMPCPY_CHK_CHKP:
1760 case BUILT_IN_MEMMOVE:
1761 case BUILT_IN_MEMMOVE_CHK:
1762 case BUILT_IN_MEMMOVE_CHKP:
1763 case BUILT_IN_MEMMOVE_CHK_CHKP:
1764 strfun = false;
1765 /* Fall through. */
1767 case BUILT_IN_STPNCPY:
1768 case BUILT_IN_STPNCPY_CHK:
1769 case BUILT_IN_STRNCAT:
1770 case BUILT_IN_STRNCAT_CHK:
1771 case BUILT_IN_STRNCPY:
1772 case BUILT_IN_STRNCPY_CHK:
1773 dst_idx = 0;
1774 src_idx = 1 + with_bounds;
1775 bnd_idx = 2 + 2 * with_bounds;
1776 break;
1778 case BUILT_IN_STPCPY:
1779 case BUILT_IN_STPCPY_CHK:
1780 case BUILT_IN_STPCPY_CHKP:
1781 case BUILT_IN_STPCPY_CHK_CHKP:
1782 case BUILT_IN_STRCPY:
1783 case BUILT_IN_STRCPY_CHK:
1784 case BUILT_IN_STRCPY_CHKP:
1785 case BUILT_IN_STRCPY_CHK_CHKP:
1786 case BUILT_IN_STRCAT:
1787 case BUILT_IN_STRCAT_CHK:
1788 case BUILT_IN_STRCAT_CHKP:
1789 case BUILT_IN_STRCAT_CHK_CHKP:
1790 dst_idx = 0;
1791 src_idx = 1 + with_bounds;
1792 break;
1794 default:
1795 /* Handle other string functions here whose access may need
1796 to be validated for in-bounds offsets and non-overlapping
1797 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
1798 macros so they need to be handled here.) */
1799 return;
1802 unsigned nargs = gimple_call_num_args (call);
1804 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1805 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1806 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1808 /* For string functions with an unspecified or unknown bound,
1809 assume the size of the access is one. */
1810 if (!dstwr && strfun)
1811 dstwr = size_one_node;
1813 /* DST and SRC can be null for a call with an insufficient number
1814 of arguments to a built-in function declared without a protype. */
1815 if (!dst || !src)
1816 return;
1818 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1819 a function declared without a prototype. Avoid checking such
1820 invalid calls. */
1821 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1822 || TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
1823 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1824 return;
1826 if (check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
1827 return;
1829 /* Avoid diagnosing the call again. */
1830 gimple_set_no_warning (call, true);
1833 } /* anonymous namespace */
1835 /* Attempt to detect and diagnose invalid offset bounds and (except for
1836 memmove) overlapping copy in a call expression EXPR from SRC to DST
1837 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1838 SRCSIZE may be NULL. Return false when one or the other has been
1839 detected and diagnosed, true otherwise. */
1841 bool
1842 check_bounds_or_overlap (gcall *call, tree dst, tree src, tree dstsize,
1843 tree srcsize, bool bounds_only /* = false */)
1845 location_t loc = gimple_location (call);
1847 if (tree block = gimple_block (call))
1848 if (location_t *pbloc = block_nonartificial_location (block))
1849 loc = *pbloc;
1851 loc = expansion_point_location_if_in_system_header (loc);
1853 tree func = gimple_call_fndecl (call);
1855 builtin_memref dstref (dst, dstsize);
1856 builtin_memref srcref (src, srcsize);
1858 builtin_access acs (call, dstref, srcref);
1860 /* Set STRICT to the value of the -Warray-bounds=N argument for
1861 string functions or when N > 1. */
1862 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
1864 /* Validate offsets first to make sure they are within the bounds
1865 of the destination object if its size is known, or PTRDIFF_MAX
1866 otherwise. */
1867 if (maybe_diag_offset_bounds (loc, call, func, strict, dst, dstref)
1868 || maybe_diag_offset_bounds (loc, call, func, strict, src, srcref))
1870 gimple_set_no_warning (call, true);
1871 return false;
1874 bool check_overlap
1875 = (warn_restrict
1876 && (bounds_only
1877 || (DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE
1878 && DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE_CHK)));
1880 if (!check_overlap)
1881 return true;
1883 if (operand_equal_p (dst, src, 0))
1885 /* Issue -Wrestrict unless the pointers are null (those do
1886 not point to objects and so do not indicate an overlap;
1887 such calls could be the result of sanitization and jump
1888 threading). */
1889 if (!integer_zerop (dst) && !gimple_no_warning_p (call))
1891 warning_at (loc, OPT_Wrestrict,
1892 "%G%qD source argument is the same as destination",
1893 call, func);
1894 gimple_set_no_warning (call, true);
1895 return false;
1898 return true;
1901 /* Return false when overlap has been detected. */
1902 if (maybe_diag_overlap (loc, call, acs))
1904 gimple_set_no_warning (call, true);
1905 return false;
1908 return true;
1911 gimple_opt_pass *
1912 make_pass_warn_restrict (gcc::context *ctxt)
1914 return new pass_wrestrict (ctxt);