PR tree-optimization/84740
[official-gcc.git] / gcc / gimple-ssa-warn-restrict.c
blobdf775062758fcd355f96afac8e433266120a5629
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 tree basetype = TREE_TYPE (base);
267 if (DECL_P (base) && TREE_CODE (basetype) == ARRAY_TYPE)
269 /* If the offset could be in 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 if (ref && array_at_struct_end_p (ref))
276 ; /* Use the maximum possible offset for last member arrays. */
277 else if (tree basesize = TYPE_SIZE_UNIT (basetype))
278 maxoff = wi::to_offset (basesize);
280 if (offrange[0] >= 0)
282 if (offrange[1] < 0)
283 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
284 else if (offrange[0] <= maxoff && offrange[1] > maxoff)
285 offrange[1] = maxoff;
290 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. */
292 void
293 builtin_memref::extend_offset_range (tree offset)
295 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
297 if (TREE_CODE (offset) == INTEGER_CST)
299 offset_int off = int_cst_value (offset);
300 if (off != 0)
302 offrange[0] += off;
303 offrange[1] += off;
305 return;
308 if (TREE_CODE (offset) == SSA_NAME)
310 wide_int min, max;
311 value_range_type rng = get_range_info (offset, &min, &max);
312 if (rng == VR_RANGE)
314 offrange[0] += offset_int::from (min, SIGNED);
315 offrange[1] += offset_int::from (max, SIGNED);
317 else if (rng == VR_ANTI_RANGE)
319 offrange[0] += offset_int::from (max + 1, SIGNED);
320 offrange[1] += offset_int::from (min - 1, SIGNED);
322 else
324 gimple *stmt = SSA_NAME_DEF_STMT (offset);
325 tree type;
326 if (is_gimple_assign (stmt)
327 && gimple_assign_rhs_code (stmt) == NOP_EXPR
328 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
329 && INTEGRAL_TYPE_P (type))
331 /* Use the bounds of the type of the NOP_EXPR operand
332 even if it's signed. The result doesn't trigger
333 warnings but makes their output more readable. */
334 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
335 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
337 else
338 offrange[1] += maxobjsize;
340 return;
343 offrange[1] += maxobjsize;
346 /* Determines the base object or pointer of the reference EXPR
347 and the offset range from the beginning of the base. */
349 void
350 builtin_memref::set_base_and_offset (tree expr)
352 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
354 if (TREE_CODE (expr) == SSA_NAME)
356 /* Try to tease the offset out of the pointer. */
357 gimple *stmt = SSA_NAME_DEF_STMT (expr);
358 if (!base
359 && gimple_assign_single_p (stmt)
360 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
361 expr = gimple_assign_rhs1 (stmt);
362 else if (is_gimple_assign (stmt))
364 tree_code code = gimple_assign_rhs_code (stmt);
365 if (code == NOP_EXPR)
367 tree rhs = gimple_assign_rhs1 (stmt);
368 if (POINTER_TYPE_P (TREE_TYPE (rhs)))
369 expr = gimple_assign_rhs1 (stmt);
370 else
372 base = expr;
373 return;
376 else if (code == POINTER_PLUS_EXPR)
378 expr = gimple_assign_rhs1 (stmt);
380 tree offset = gimple_assign_rhs2 (stmt);
381 extend_offset_range (offset);
383 else
385 base = expr;
386 return;
389 else
391 base = expr;
392 return;
396 if (TREE_CODE (expr) == ADDR_EXPR)
397 expr = TREE_OPERAND (expr, 0);
399 poly_int64 bitsize, bitpos;
400 tree var_off;
401 machine_mode mode;
402 int sign, reverse, vol;
404 /* Determine the base object or pointer of the reference and
405 the constant bit offset from the beginning of the base.
406 If the offset has a non-constant component, it will be in
407 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
408 unused here. */
409 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
410 &mode, &sign, &reverse, &vol);
412 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
414 HOST_WIDE_INT const_off;
415 if (!base || !bytepos.is_constant (&const_off))
417 base = get_base_address (TREE_OPERAND (expr, 0));
418 return;
421 offrange[0] += const_off;
422 offrange[1] += const_off;
424 if (var_off)
426 if (TREE_CODE (var_off) == INTEGER_CST)
428 offset_int cstoff = wi::to_offset (var_off);
429 offrange[0] += cstoff;
430 offrange[1] += cstoff;
432 else
433 offrange[1] += maxobjsize;
436 /* Stash the reference for offset validation. */
437 ref = expr;
439 /* Also stash the constant offset for offset validation. */
440 if (TREE_CODE (expr) == COMPONENT_REF)
441 refoff = const_off;
443 if (TREE_CODE (base) == MEM_REF)
445 tree memrefoff = TREE_OPERAND (base, 1);
446 extend_offset_range (memrefoff);
447 base = TREE_OPERAND (base, 0);
450 if (TREE_CODE (base) == SSA_NAME)
451 set_base_and_offset (base);
454 /* Return error_mark_node if the signed offset exceeds the bounds
455 of the address space (PTRDIFF_MAX). Otherwise, return either
456 BASE or REF when the offset exceeds the bounds of the BASE or
457 REF object, and set OOBOFF to the past-the-end offset formed
458 by the reference, including its size. When STRICT is non-zero
459 use REF size, when available, otherwise use BASE size. When
460 STRICT is greater than 1, use the size of the last array member
461 as the bound, otherwise treat such a member as a flexible array
462 member. Return NULL when the offset is in bounds. */
464 tree
465 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[2]) const
467 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
469 /* A temporary, possibly adjusted, copy of the offset range. */
470 offset_int offrng[2] = { offrange[0], offrange[1] };
472 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
474 /* Check for offset in an anti-range with a negative lower bound.
475 For such a range, consider only the non-negative subrange. */
476 if (offrng[1] < offrng[0] && offrng[1] < 0)
477 offrng[1] = maxobjsize;
480 /* Conservative offset of the last byte of the referenced object. */
481 offset_int endoff;
483 /* The bounds need not be ordered. Set HIB to use as the index
484 of the larger of the bounds and LOB as the opposite. */
485 bool hib = wi::les_p (offrng[0], offrng[1]);
486 bool lob = !hib;
488 if (basesize < 0)
490 endoff = offrng[lob] + sizrange[0];
492 /* For a reference through a pointer to an object of unknown size
493 all initial offsets are considered valid, positive as well as
494 negative, since the pointer itself can point past the beginning
495 of the object. However, the sum of the lower bound of the offset
496 and that of the size must be less than or equal than PTRDIFF_MAX. */
497 if (endoff > maxobjsize)
498 return error_mark_node;
500 return NULL_TREE;
503 /* A reference to an object of known size must be within the bounds
504 of the base object. */
505 if (offrng[hib] < 0 || offrng[lob] > basesize)
506 return base;
508 /* The extent of the reference must also be within the bounds of
509 the base object (if known) or the maximum object size otherwise. */
510 endoff = wi::smax (offrng[lob], 0) + sizrange[0];
511 if (endoff > maxobjsize)
512 return error_mark_node;
514 offset_int size = basesize;
515 tree obj = base;
517 if (strict
518 && DECL_P (obj)
519 && ref
520 && refoff >= 0
521 && TREE_CODE (ref) == COMPONENT_REF
522 && (strict > 1
523 || !array_at_struct_end_p (ref)))
525 /* If the reference is to a member subobject, the offset must
526 be within the bounds of the subobject. */
527 tree field = TREE_OPERAND (ref, 1);
528 tree type = TREE_TYPE (field);
529 if (tree sz = TYPE_SIZE_UNIT (type))
530 if (TREE_CODE (sz) == INTEGER_CST)
532 size = refoff + wi::to_offset (sz);
533 obj = ref;
537 if (endoff <= size)
538 return NULL_TREE;
540 /* Set the out-of-bounds offset range to be one greater than
541 that delimited by the reference including its size. */
542 ooboff[lob] = size + 1;
544 if (endoff > ooboff[lob])
545 ooboff[hib] = endoff;
546 else
547 ooboff[hib] = wi::smax (offrng[lob], 0) + sizrange[1];
549 return obj;
552 /* Create an association between the memory references DST and SRC
553 for access by a call EXPR to a memory or string built-in funtion. */
555 builtin_access::builtin_access (gcall *call, builtin_memref &dst,
556 builtin_memref &src)
557 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
558 dstoff (), srcoff (), dstsiz (), srcsiz ()
560 /* Zero out since the offset_int ctors invoked above are no-op. */
561 dstoff[0] = dstoff[1] = 0;
562 srcoff[0] = srcoff[1] = 0;
563 dstsiz[0] = dstsiz[1] = 0;
564 srcsiz[0] = srcsiz[1] = 0;
566 /* Object Size Type to use to determine the size of the destination
567 and source objects. Overridden below for raw memory functions. */
568 int ostype = 1;
570 /* True when the size of one reference depends on the offset of
571 itself or the other. */
572 bool depends_p = true;
574 /* True when the size of the destination reference DSTREF has been
575 determined from SRCREF and so needs to be adjusted by the latter's
576 offset. Only meaningful for bounded string functions like strncpy. */
577 bool dstadjust_p = false;
579 /* The size argument number (depends on the built-in). */
580 unsigned sizeargno = 2;
581 if (gimple_call_with_bounds_p (call))
582 sizeargno += 2;
584 tree func = gimple_call_fndecl (call);
585 switch (DECL_FUNCTION_CODE (func))
587 case BUILT_IN_MEMCPY:
588 case BUILT_IN_MEMCPY_CHK:
589 case BUILT_IN_MEMCPY_CHKP:
590 case BUILT_IN_MEMCPY_CHK_CHKP:
591 case BUILT_IN_MEMPCPY:
592 case BUILT_IN_MEMPCPY_CHK:
593 case BUILT_IN_MEMPCPY_CHKP:
594 case BUILT_IN_MEMPCPY_CHK_CHKP:
595 ostype = 0;
596 depends_p = false;
597 detect_overlap = &builtin_access::generic_overlap;
598 break;
600 case BUILT_IN_MEMMOVE:
601 case BUILT_IN_MEMMOVE_CHK:
602 case BUILT_IN_MEMMOVE_CHKP:
603 case BUILT_IN_MEMMOVE_CHK_CHKP:
604 /* For memmove there is never any overlap to check for. */
605 ostype = 0;
606 depends_p = false;
607 detect_overlap = &builtin_access::no_overlap;
608 break;
610 case BUILT_IN_STPNCPY:
611 case BUILT_IN_STPNCPY_CHK:
612 case BUILT_IN_STRNCPY:
613 case BUILT_IN_STRNCPY_CHK:
614 dstref->strbounded_p = true;
615 detect_overlap = &builtin_access::strcpy_overlap;
616 break;
618 case BUILT_IN_STPCPY:
619 case BUILT_IN_STPCPY_CHK:
620 case BUILT_IN_STPCPY_CHKP:
621 case BUILT_IN_STPCPY_CHK_CHKP:
622 case BUILT_IN_STRCPY:
623 case BUILT_IN_STRCPY_CHK:
624 case BUILT_IN_STRCPY_CHKP:
625 case BUILT_IN_STRCPY_CHK_CHKP:
626 detect_overlap = &builtin_access::strcpy_overlap;
627 break;
629 case BUILT_IN_STRCAT:
630 case BUILT_IN_STRCAT_CHK:
631 case BUILT_IN_STRCAT_CHKP:
632 case BUILT_IN_STRCAT_CHK_CHKP:
633 detect_overlap = &builtin_access::strcat_overlap;
634 break;
636 case BUILT_IN_STRNCAT:
637 case BUILT_IN_STRNCAT_CHK:
638 dstref->strbounded_p = true;
639 srcref->strbounded_p = true;
640 detect_overlap = &builtin_access::strcat_overlap;
641 break;
643 default:
644 /* Handle other string functions here whose access may need
645 to be validated for in-bounds offsets and non-overlapping
646 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
647 macros so they need to be handled here.) */
648 return;
651 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
653 /* Try to determine the size of the base object. compute_objsize
654 expects a pointer so create one if BASE is a non-pointer object. */
655 tree addr;
656 if (dst.basesize < 0)
658 addr = dst.base;
659 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
660 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
662 if (tree dstsize = compute_objsize (addr, ostype))
663 dst.basesize = wi::to_offset (dstsize);
664 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
665 dst.basesize = HOST_WIDE_INT_MIN;
666 else
667 dst.basesize = maxobjsize;
670 if (src.basesize < 0)
672 addr = src.base;
673 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
674 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
676 if (tree srcsize = compute_objsize (addr, ostype))
677 src.basesize = wi::to_offset (srcsize);
678 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
679 src.basesize = HOST_WIDE_INT_MIN;
680 else
681 src.basesize = maxobjsize;
684 /* If there is no dependency between the references or the base
685 objects of the two references aren't the same there's nothing
686 else to do. */
687 if (depends_p && dstref->base != srcref->base)
688 return;
690 /* ...otherwise, make adjustments for references to the same object
691 by string built-in functions to reflect the constraints imposed
692 by the function. */
694 /* For bounded string functions determine the range of the bound
695 on the access. For others, the range stays unbounded. */
696 offset_int bounds[2] = { maxobjsize, maxobjsize };
697 if (dstref->strbounded_p)
699 tree size = gimple_call_arg (call, sizeargno);
700 tree range[2];
701 if (get_size_range (size, range, true))
703 bounds[0] = wi::to_offset (range[0]);
704 bounds[1] = wi::to_offset (range[1]);
707 /* If both references' size ranges are indeterminate use the last
708 (size) argument from the function call as a substitute. This
709 may only be necessary for strncpy (but not for memcpy where
710 the size range would have been already determined this way). */
711 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
712 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
714 dstref->sizrange[0] = bounds[0];
715 dstref->sizrange[1] = bounds[1];
719 /* The size range of one reference involving the same base object
720 can be determined from the size range of the other reference.
721 This makes it possible to compute accurate offsets for warnings
722 involving functions like strcpy where the length of just one of
723 the two arguments is known (determined by tree-ssa-strlen). */
724 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
726 /* When the destination size is unknown set it to the size of
727 the source. */
728 dstref->sizrange[0] = srcref->sizrange[0];
729 dstref->sizrange[1] = srcref->sizrange[1];
731 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
733 /* When the source size is unknown set it to the size of
734 the destination. */
735 srcref->sizrange[0] = dstref->sizrange[0];
736 srcref->sizrange[1] = dstref->sizrange[1];
738 if (depends_p)
740 if (dstref->strbounded_p)
742 /* Read access by strncpy is bounded. */
743 if (bounds[0] < srcref->sizrange[0])
744 srcref->sizrange[0] = bounds[0];
745 if (bounds[1] < srcref->sizrange[1])
746 srcref->sizrange[1] = bounds[1];
749 /* For string functions, adjust the size range of the source
750 reference by the inverse boundaries of the offset (because
751 the higher the offset into the string the shorter its
752 length). */
753 if (srcref->offrange[1] >= 0
754 && srcref->offrange[1] < srcref->sizrange[0])
755 srcref->sizrange[0] -= srcref->offrange[1];
756 else
757 srcref->sizrange[0] = 0;
759 if (srcref->offrange[0] > 0)
761 if (srcref->offrange[0] < srcref->sizrange[1])
762 srcref->sizrange[1] -= srcref->offrange[0];
763 else
764 srcref->sizrange[1] = 0;
767 dstadjust_p = true;
771 if (detect_overlap == &builtin_access::generic_overlap)
773 if (dstref->strbounded_p)
775 dstref->sizrange[0] = bounds[0];
776 dstref->sizrange[1] = bounds[1];
778 if (dstref->sizrange[0] < srcref->sizrange[0])
779 srcref->sizrange[0] = dstref->sizrange[0];
781 if (dstref->sizrange[1] < srcref->sizrange[1])
782 srcref->sizrange[1] = dstref->sizrange[1];
785 else if (detect_overlap == &builtin_access::strcpy_overlap)
787 if (!dstref->strbounded_p)
789 /* For strcpy, adjust the destination size range to match that
790 of the source computed above. */
791 if (depends_p && dstadjust_p)
793 dstref->sizrange[0] = srcref->sizrange[0];
794 dstref->sizrange[1] = srcref->sizrange[1];
799 if (dstref->strbounded_p)
801 /* For strncpy, adjust the destination size range to match that
802 of the source computed above. */
803 dstref->sizrange[0] = bounds[0];
804 dstref->sizrange[1] = bounds[1];
806 if (bounds[0] < srcref->sizrange[0])
807 srcref->sizrange[0] = bounds[0];
809 if (bounds[1] < srcref->sizrange[1])
810 srcref->sizrange[1] = bounds[1];
814 offset_int
815 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
816 offset_int *off)
818 const offset_int *p = a;
819 const offset_int *q = b;
821 /* Point P at the bigger of the two ranges and Q at the smaller. */
822 if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
824 p = b;
825 q = a;
828 if (p[0] < q[0])
830 if (p[1] < q[0])
831 return 0;
833 *off = q[0];
834 return wi::smin (p[1], q[1]) - q[0];
837 if (q[1] < p[0])
838 return 0;
840 off[0] = p[0];
841 return q[1] - p[0];
844 /* Return true if the bounded mempry (memcpy amd similar) or string function
845 access (strncpy and similar) ACS overlaps. */
847 bool
848 builtin_access::generic_overlap ()
850 builtin_access &acs = *this;
851 const builtin_memref *dstref = acs.dstref;
852 const builtin_memref *srcref = acs.srcref;
854 gcc_assert (dstref->base == srcref->base);
856 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
858 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
859 gcc_assert (maxsize <= maxobjsize);
861 /* Adjust the larger bounds of the offsets (which may be the first
862 element if the lower bound is larger than the upper bound) to
863 make them valid for the smallest access (if possible) but no smaller
864 than the smaller bounds. */
865 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
867 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
868 acs.dstoff[1] = maxsize - acs.dstsiz[0];
869 if (acs.dstoff[1] < acs.dstoff[0])
870 acs.dstoff[1] = acs.dstoff[0];
872 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
874 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
875 acs.srcoff[1] = maxsize - acs.srcsiz[0];
876 if (acs.srcoff[1] < acs.srcoff[0])
877 acs.srcoff[1] = acs.srcoff[0];
879 /* Determine the minimum and maximum space for the access given
880 the offsets. */
881 offset_int space[2];
882 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
883 space[1] = space[0];
885 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
886 if (acs.srcsiz[0] > 0)
888 if (d < space[0])
889 space[0] = d;
891 if (space[1] < d)
892 space[1] = d;
894 else
895 space[1] = acs.dstsiz[1];
897 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
898 if (d < space[0])
899 space[0] = d;
901 if (space[1] < d)
902 space[1] = d;
904 /* Treat raw memory functions both of whose references are bounded
905 as special and permit uncertain overlaps to go undetected. For
906 all kinds of constant offset and constant size accesses, if
907 overlap isn't certain it is not possible. */
908 bool overlap_possible = space[0] < acs.dstsiz[1];
909 if (!overlap_possible)
910 return false;
912 bool overlap_certain = space[1] < acs.dstsiz[0];
914 /* True when the size of one reference depends on the offset of
915 the other. */
916 bool depends_p = detect_overlap != &builtin_access::generic_overlap;
918 if (!overlap_certain)
920 if (!dstref->strbounded_p && !depends_p)
921 return false;
923 /* There's no way to distinguish an access to the same member
924 of a structure from one to two distinct members of the same
925 structure. Give up to avoid excessive false positives. */
926 tree basetype = TREE_TYPE (TREE_TYPE (dstref->base));
927 if (RECORD_OR_UNION_TYPE_P (basetype))
928 return false;
931 /* True for stpcpy and strcpy. */
932 bool stxcpy_p = (!dstref->strbounded_p
933 && detect_overlap == &builtin_access::strcpy_overlap);
935 if (dstref->refoff >= 0
936 && srcref->refoff >= 0
937 && dstref->refoff != srcref->refoff
938 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
939 return false;
941 offset_int siz[2] = { maxobjsize + 1, 0 };
943 ovloff[0] = HOST_WIDE_INT_MAX;
944 ovloff[1] = HOST_WIDE_INT_MIN;
946 /* Adjustment to the lower bound of the offset of the overlap to
947 account for a subset of unbounded string calls where the size
948 of the destination string depends on the length of the source
949 which in turn depends on the offset into it. */
950 bool sub1;
952 if (stxcpy_p)
954 sub1 = acs.dstoff[0] <= acs.srcoff[0];
956 /* Iterate over the extreme locations (on the horizontal axis formed
957 by their offsets) and sizes of two regions and find their smallest
958 and largest overlap and the corresponding offsets. */
959 for (unsigned i = 0; i != 2; ++i)
961 const offset_int a[2] = {
962 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
965 const offset_int b[2] = {
966 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
969 offset_int off;
970 offset_int sz = overlap_size (a, b, &off);
971 if (sz < siz[0])
972 siz[0] = sz;
974 if (siz[1] <= sz)
975 siz[1] = sz;
977 if (sz != 0)
979 if (wi::lts_p (off, ovloff[0]))
980 ovloff[0] = off.to_shwi ();
981 if (wi::lts_p (ovloff[1], off))
982 ovloff[1] = off.to_shwi ();
986 else
988 sub1 = !depends_p;
990 /* Iterate over the extreme locations (on the horizontal axis
991 formed by their offsets) and sizes of two regions and find
992 their smallest and largest overlap and the corresponding
993 offsets. */
995 for (unsigned io = 0; io != 2; ++io)
996 for (unsigned is = 0; is != 2; ++is)
998 const offset_int a[2] = {
999 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1002 for (unsigned jo = 0; jo != 2; ++jo)
1003 for (unsigned js = 0; js != 2; ++js)
1005 if (depends_p)
1007 /* For st{p,r}ncpy the size of the source sequence
1008 depends on the offset into it. */
1009 if (js)
1010 break;
1011 js = !jo;
1014 const offset_int b[2] = {
1015 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1018 offset_int off;
1019 offset_int sz = overlap_size (a, b, &off);
1020 if (sz < siz[0])
1021 siz[0] = sz;
1023 if (siz[1] <= sz)
1024 siz[1] = sz;
1026 if (sz != 0)
1028 if (wi::lts_p (off, ovloff[0]))
1029 ovloff[0] = off.to_shwi ();
1030 if (wi::lts_p (ovloff[1], off))
1031 ovloff[1] = off.to_shwi ();
1037 ovlsiz[0] = siz[0].to_shwi ();
1038 ovlsiz[1] = siz[1].to_shwi ();
1040 if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1041 ovloff[0] = ovloff[1] + ovlsiz[1] - 1 - sub1;
1043 return true;
1046 /* Return true if the strcat-like access overlaps. */
1048 bool
1049 builtin_access::strcat_overlap ()
1051 builtin_access &acs = *this;
1052 const builtin_memref *dstref = acs.dstref;
1053 const builtin_memref *srcref = acs.srcref;
1055 gcc_assert (dstref->base == srcref->base);
1057 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1059 gcc_assert (dstref->base && dstref->base == srcref->base);
1061 /* Adjust for strcat-like accesses. */
1063 /* As a special case for strcat, set the DSTREF offsets to the length
1064 of the source string since the function starts writing at the first
1065 nul, and set the size to 1 for the length of the nul. */
1066 acs.dstoff[0] += acs.dstsiz[0];
1067 acs.dstoff[1] += acs.dstsiz[1];
1069 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1071 /* The lower bound is zero when the size is unknown because then
1072 overlap is not certain. */
1073 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1074 acs.dstsiz[1] = 1;
1076 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1077 gcc_assert (maxsize <= maxobjsize);
1079 /* For references to the same base object, determine if there's a pair
1080 of valid offsets into the two references such that access between
1081 them doesn't overlap. Adjust both upper bounds to be valid for
1082 the smaller size (i.e., at most MAXSIZE - SIZE). */
1084 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1085 acs.dstoff[1] = maxsize - acs.dstsiz[0];
1087 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1088 acs.srcoff[1] = maxsize - acs.srcsiz[0];
1090 /* Check to see if there's enough space for both accesses without
1091 overlap. Determine the optimistic (maximum) amount of available
1092 space. */
1093 offset_int space;
1094 if (acs.dstoff[0] <= acs.srcoff[0])
1096 if (acs.dstoff[1] < acs.srcoff[1])
1097 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1098 else
1099 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1101 else
1102 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1104 /* Overlap is certain if the distance between the farthest offsets
1105 of the opposite accesses is less than the sum of the lower bounds
1106 of the sizes of the two accesses. */
1107 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1109 /* For a constant-offset, constant size access, consider the largest
1110 distance between the offset bounds and the lower bound of the access
1111 size. If the overlap isn't certain return success. */
1112 if (!overlap_certain
1113 && acs.dstoff[0] == acs.dstoff[1]
1114 && acs.srcoff[0] == acs.srcoff[1]
1115 && acs.dstsiz[0] == acs.dstsiz[1]
1116 && acs.srcsiz[0] == acs.srcsiz[1])
1117 return false;
1119 /* Overlap is not certain but may be possible. */
1121 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1123 /* Determine the conservative (minimum) amount of space. */
1124 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1125 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1126 if (d < space)
1127 space = d;
1128 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1129 if (d < space)
1130 space = d;
1132 /* For a strict test (used for strcpy and similar with unknown or
1133 variable bounds or sizes), consider the smallest distance between
1134 the offset bounds and either the upper bound of the access size
1135 if known, or the lower bound otherwise. */
1136 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1137 return false;
1139 /* When strcat overlap is certain it is always a single byte:
1140 the terminating NUL, regardless of offsets and sizes. When
1141 overlap is only possible its range is [0, 1]. */
1142 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1143 acs.ovlsiz[1] = 1;
1145 offset_int endoff = dstref->offrange[0] + dstref->sizrange[0];
1146 if (endoff <= srcref->offrange[0])
1147 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1148 else
1149 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1151 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1152 srcref->sizrange[0]).to_shwi ();
1153 if (dstref->offrange[0] == dstref->offrange[1])
1155 if (srcref->offrange[0] == srcref->offrange[1])
1156 acs.ovloff[1] = acs.ovloff[0];
1157 else
1158 acs.ovloff[1]
1159 = wi::smin (maxobjsize,
1160 srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1162 else
1163 acs.ovloff[1]
1164 = wi::smin (maxobjsize,
1165 dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1167 if (acs.sizrange[0] == 0)
1168 acs.sizrange[0] = 1;
1169 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1170 return true;
1173 /* Return true if the strcpy-like access overlaps. */
1175 bool
1176 builtin_access::strcpy_overlap ()
1178 return generic_overlap ();
1182 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1183 one another or that, in order not to overlap, would imply that the size
1184 of the referenced object(s) exceeds the maximum size of an object. Set
1185 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1186 they may overlap in a way that's not apparent from the available data),
1187 return false. */
1189 bool
1190 builtin_access::overlap ()
1192 builtin_access &acs = *this;
1194 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1196 acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1197 srcref->sizrange[0]).to_shwi ();
1198 acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1199 srcref->sizrange[1]).to_shwi ();
1201 /* Check to see if the two references refer to regions that are
1202 too large not to overlap in the address space (whose maximum
1203 size is PTRDIFF_MAX). */
1204 offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1205 if (maxobjsize < size)
1207 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1208 acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1209 return true;
1212 /* If both base objects aren't known return the maximum possible
1213 offset that would make them not overlap. */
1214 if (!dstref->base || !srcref->base)
1215 return false;
1217 /* Set the access offsets. */
1218 acs.dstoff[0] = dstref->offrange[0];
1219 acs.dstoff[1] = dstref->offrange[1];
1221 /* If the base object is an array adjust the bounds of the offset
1222 to be non-negative and within the bounds of the array if possible. */
1223 if (dstref->base
1224 && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE)
1226 if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0)
1227 acs.dstoff[0] = 0;
1229 if (acs.dstoff[1] < acs.dstoff[0])
1231 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base)))
1232 acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size));
1233 else
1234 acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize);
1238 acs.srcoff[0] = srcref->offrange[0];
1239 acs.srcoff[1] = srcref->offrange[1];
1241 if (srcref->base
1242 && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE)
1244 if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0)
1245 acs.srcoff[0] = 0;
1247 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base)))
1248 acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size));
1249 else if (acs.srcoff[1] < acs.srcoff[0])
1250 acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize);
1253 /* When the upper bound of the offset is less than the lower bound
1254 the former is the result of a negative offset being represented
1255 as a large positive value or vice versa. The resulting range is
1256 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1257 a union is not representable using the current data structure
1258 replace it with the full range of offsets. */
1259 if (acs.dstoff[1] < acs.dstoff[0])
1261 acs.dstoff[0] = -maxobjsize - 1;
1262 acs.dstoff[1] = maxobjsize;
1265 /* Validate the offset and size of each reference on its own first.
1266 This is independent of whether or not the base objects are the
1267 same. Normally, this would have already been detected and
1268 diagnosed by -Warray-bounds, unless it has been disabled. */
1269 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1270 if (maxobjsize < maxoff)
1272 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1273 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1274 return true;
1277 /* Repeat the same as above but for the source offsets. */
1278 if (acs.srcoff[1] < acs.srcoff[0])
1280 acs.srcoff[0] = -maxobjsize - 1;
1281 acs.srcoff[1] = maxobjsize;
1284 maxoff = acs.srcoff[0] + srcref->sizrange[0];
1285 if (maxobjsize < maxoff)
1287 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1288 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1289 - maxobjsize).to_shwi ();
1290 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1291 return true;
1294 if (dstref->base != srcref->base)
1295 return false;
1297 acs.dstsiz[0] = dstref->sizrange[0];
1298 acs.dstsiz[1] = dstref->sizrange[1];
1300 acs.srcsiz[0] = srcref->sizrange[0];
1301 acs.srcsiz[1] = srcref->sizrange[1];
1303 /* Call the appropriate function to determine the overlap. */
1304 if ((this->*detect_overlap) ())
1306 if (!sizrange[1])
1308 /* Unless the access size range has already been set, do so here. */
1309 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1310 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1312 return true;
1315 return false;
1318 /* Attempt to detect and diagnose an overlapping copy in a call expression
1319 EXPR involving an an access ACS to a built-in memory or string function.
1320 Return true when one has been detected, false otherwise. */
1322 static bool
1323 maybe_diag_overlap (location_t loc, gcall *call, builtin_access &acs)
1325 if (!acs.overlap ())
1326 return false;
1328 /* For convenience. */
1329 const builtin_memref &dstref = *acs.dstref;
1330 const builtin_memref &srcref = *acs.srcref;
1332 /* Determine the range of offsets and sizes of the overlap if it
1333 exists and issue diagnostics. */
1334 HOST_WIDE_INT *ovloff = acs.ovloff;
1335 HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1336 HOST_WIDE_INT *sizrange = acs.sizrange;
1338 tree func = gimple_call_fndecl (call);
1340 /* To avoid a combinatorial explosion of diagnostics format the offsets
1341 or their ranges as strings and use them in the warning calls below. */
1342 char offstr[3][64];
1344 if (dstref.offrange[0] == dstref.offrange[1]
1345 || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1346 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1347 dstref.offrange[0].to_shwi ());
1348 else
1349 sprintf (offstr[0],
1350 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1351 dstref.offrange[0].to_shwi (),
1352 dstref.offrange[1].to_shwi ());
1354 if (srcref.offrange[0] == srcref.offrange[1]
1355 || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1356 sprintf (offstr[1],
1357 HOST_WIDE_INT_PRINT_DEC,
1358 srcref.offrange[0].to_shwi ());
1359 else
1360 sprintf (offstr[1],
1361 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1362 srcref.offrange[0].to_shwi (),
1363 srcref.offrange[1].to_shwi ());
1365 if (ovloff[0] == ovloff[1] || !ovloff[1])
1366 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1367 else
1368 sprintf (offstr[2],
1369 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1370 ovloff[0], ovloff[1]);
1372 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1373 bool must_overlap = ovlsiz[0] > 0;
1375 if (ovlsiz[1] == 0)
1376 ovlsiz[1] = ovlsiz[0];
1378 if (must_overlap)
1380 /* Issue definitive "overlaps" diagnostic in this block. */
1382 if (sizrange[0] == sizrange[1])
1384 if (ovlsiz[0] == ovlsiz[1])
1385 warning_at (loc, OPT_Wrestrict,
1386 sizrange[0] == 1
1387 ? (ovlsiz[0] == 1
1388 ? G_("%G%qD accessing %wu byte at offsets %s "
1389 "and %s overlaps %wu byte at offset %s")
1390 : G_("%G%qD accessing %wu byte at offsets %s "
1391 "and %s overlaps %wu bytes at offset "
1392 "%s"))
1393 : (ovlsiz[0] == 1
1394 ? G_("%G%qD accessing %wu bytes at offsets %s "
1395 "and %s overlaps %wu byte at offset %s")
1396 : G_("%G%qD accessing %wu bytes at offsets %s "
1397 "and %s overlaps %wu bytes at offset "
1398 "%s")),
1399 call, func, sizrange[0],
1400 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1401 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1402 warning_n (loc, OPT_Wrestrict, sizrange[0],
1403 "%G%qD accessing %wu byte at offsets %s "
1404 "and %s overlaps between %wu and %wu bytes "
1405 "at offset %s",
1406 "%G%qD accessing %wu bytes at offsets %s "
1407 "and %s overlaps between %wu and %wu bytes "
1408 "at offset %s",
1409 call, func, sizrange[0], offstr[0], offstr[1],
1410 ovlsiz[0], ovlsiz[1], offstr[2]);
1411 else
1412 warning_n (loc, OPT_Wrestrict, sizrange[0],
1413 "%G%qD accessing %wu byte at offsets %s and "
1414 "%s overlaps %wu or more bytes at offset %s",
1415 "%G%qD accessing %wu bytes at offsets %s and "
1416 "%s overlaps %wu or more bytes at offset %s",
1417 call, func, sizrange[0],
1418 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1419 return true;
1422 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1424 if (ovlsiz[0] == ovlsiz[1])
1425 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1426 "%G%qD accessing between %wu and %wu bytes "
1427 "at offsets %s and %s overlaps %wu byte at "
1428 "offset %s",
1429 "%G%qD accessing between %wu and %wu bytes "
1430 "at offsets %s and %s overlaps %wu bytes "
1431 "at offset %s",
1432 call, func, sizrange[0], sizrange[1],
1433 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1434 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1435 warning_at (loc, OPT_Wrestrict,
1436 "%G%qD accessing between %wu and %wu bytes at "
1437 "offsets %s and %s overlaps between %wu and %wu "
1438 "bytes at offset %s",
1439 call, func, sizrange[0], sizrange[1],
1440 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1441 offstr[2]);
1442 else
1443 warning_at (loc, OPT_Wrestrict,
1444 "%G%qD accessing between %wu and %wu bytes at "
1445 "offsets %s and %s overlaps %wu or more bytes "
1446 "at offset %s",
1447 call, func, sizrange[0], sizrange[1],
1448 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1449 return true;
1452 if (ovlsiz[0] != ovlsiz[1])
1453 ovlsiz[1] = maxobjsize.to_shwi ();
1455 if (ovlsiz[0] == ovlsiz[1])
1456 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1457 "%G%qD accessing %wu or more bytes at offsets "
1458 "%s and %s overlaps %wu byte at offset %s",
1459 "%G%qD accessing %wu or more bytes at offsets "
1460 "%s and %s overlaps %wu bytes at offset %s",
1461 call, func, sizrange[0], offstr[0], offstr[1],
1462 ovlsiz[0], offstr[2]);
1463 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1464 warning_at (loc, OPT_Wrestrict,
1465 "%G%qD accessing %wu or more bytes at offsets %s "
1466 "and %s overlaps between %wu and %wu bytes "
1467 "at offset %s",
1468 call, func, sizrange[0], offstr[0], offstr[1],
1469 ovlsiz[0], ovlsiz[1], offstr[2]);
1470 else
1471 warning_at (loc, OPT_Wrestrict,
1472 "%G%qD accessing %wu or more bytes at offsets %s "
1473 "and %s overlaps %wu or more bytes at offset %s",
1474 call, func, sizrange[0], offstr[0], offstr[1],
1475 ovlsiz[0], offstr[2]);
1476 return true;
1479 /* Use more concise wording when one of the offsets is unbounded
1480 to avoid confusing the user with large and mostly meaningless
1481 numbers. */
1482 bool open_range;
1483 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1484 open_range = ((dstref.offrange[0] == 0
1485 && dstref.offrange[1] == maxobjsize)
1486 || (srcref.offrange[0] == 0
1487 && srcref.offrange[1] == maxobjsize));
1488 else
1489 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1490 && dstref.offrange[1] == maxobjsize)
1491 || (srcref.offrange[0] == -maxobjsize - 1
1492 && srcref.offrange[1] == maxobjsize));
1494 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1496 if (ovlsiz[1] == 1)
1498 if (open_range)
1499 warning_n (loc, OPT_Wrestrict, sizrange[1],
1500 "%G%qD accessing %wu byte may overlap "
1501 "%wu byte",
1502 "%G%qD accessing %wu bytes may overlap "
1503 "%wu byte",
1504 call, func, sizrange[1], ovlsiz[1]);
1505 else
1506 warning_n (loc, OPT_Wrestrict, sizrange[1],
1507 "%G%qD accessing %wu byte at offsets %s "
1508 "and %s may overlap %wu byte at offset %s",
1509 "%G%qD accessing %wu bytes at offsets %s "
1510 "and %s may overlap %wu byte at offset %s",
1511 call, func, sizrange[1], offstr[0], offstr[1],
1512 ovlsiz[1], offstr[2]);
1513 return true;
1516 if (open_range)
1517 warning_n (loc, OPT_Wrestrict, sizrange[1],
1518 "%G%qD accessing %wu byte may overlap "
1519 "up to %wu bytes",
1520 "%G%qD accessing %wu bytes may overlap "
1521 "up to %wu bytes",
1522 call, func, sizrange[1], ovlsiz[1]);
1523 else
1524 warning_n (loc, OPT_Wrestrict, sizrange[1],
1525 "%G%qD accessing %wu byte at offsets %s and "
1526 "%s may overlap up to %wu bytes at offset %s",
1527 "%G%qD accessing %wu bytes at offsets %s and "
1528 "%s may overlap up to %wu bytes at offset %s",
1529 call, func, sizrange[1], offstr[0], offstr[1],
1530 ovlsiz[1], offstr[2]);
1531 return true;
1534 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1536 if (open_range)
1537 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1538 "%G%qD accessing between %wu and %wu bytes "
1539 "may overlap %wu byte",
1540 "%G%qD accessing between %wu and %wu bytes "
1541 "may overlap up to %wu bytes",
1542 call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1543 else
1544 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1545 "%G%qD accessing between %wu and %wu bytes "
1546 "at offsets %s and %s may overlap %wu byte "
1547 "at offset %s",
1548 "%G%qD accessing between %wu and %wu bytes "
1549 "at offsets %s and %s may overlap up to %wu "
1550 "bytes at offset %s",
1551 call, func, sizrange[0], sizrange[1],
1552 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1553 return true;
1556 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1557 "%G%qD accessing %wu or more bytes at offsets %s "
1558 "and %s may overlap %wu byte at offset %s",
1559 "%G%qD accessing %wu or more bytes at offsets %s "
1560 "and %s may overlap up to %wu bytes at offset %s",
1561 call, func, sizrange[0], offstr[0], offstr[1],
1562 ovlsiz[1], offstr[2]);
1564 return true;
1567 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1568 to a built-in function FUNC to make sure they are within the bounds
1569 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1570 Both initial values of the offsets and their final value computed by
1571 the function by incrementing the initial value by the size are
1572 validated. Return true if the offsets are not valid and a diagnostic
1573 has been issued. */
1575 static bool
1576 maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
1577 tree expr, const builtin_memref &ref)
1579 if (!warn_array_bounds)
1580 return false;
1582 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1] };
1583 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1584 if (!oobref)
1585 return false;
1587 if (EXPR_HAS_LOCATION (expr))
1588 loc = EXPR_LOCATION (expr);
1590 loc = expansion_point_location_if_in_system_header (loc);
1592 tree type;
1594 char rangestr[2][64];
1595 if (ooboff[0] == ooboff[1]
1596 || (ooboff[0] != ref.offrange[0]
1597 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1598 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1599 else
1600 sprintf (rangestr[0], "[%lli, %lli]",
1601 (long long) ooboff[0].to_shwi (),
1602 (long long) ooboff[1].to_shwi ());
1604 if (oobref == error_mark_node)
1606 if (ref.sizrange[0] == ref.sizrange[1])
1607 sprintf (rangestr[1], "%lli", (long long) ref.sizrange[0].to_shwi ());
1608 else
1609 sprintf (rangestr[1], "[%lli, %lli]",
1610 (long long) ref.sizrange[0].to_shwi (),
1611 (long long) ref.sizrange[1].to_shwi ());
1613 if (DECL_P (ref.base)
1614 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1616 if (warning_at (loc, OPT_Warray_bounds,
1617 "%G%qD pointer overflow between offset %s "
1618 "and size %s accessing array %qD with type %qT",
1619 call, func, rangestr[0], rangestr[1], ref.base, type))
1620 inform (DECL_SOURCE_LOCATION (ref.base),
1621 "array %qD declared here", ref.base);
1622 else
1623 warning_at (loc, OPT_Warray_bounds,
1624 "%G%qD pointer overflow between offset %s "
1625 "and size %s",
1626 call, func, rangestr[0], rangestr[1]);
1628 else
1629 warning_at (loc, OPT_Warray_bounds,
1630 "%G%qD pointer overflow between offset %s "
1631 "and size %s",
1632 call, func, rangestr[0], rangestr[1]);
1634 else if (oobref == ref.base)
1636 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1638 /* True when the offset formed by an access to the reference
1639 is out of bounds, rather than the initial offset wich is
1640 in bounds. This implies access past the end. */
1641 bool form = ooboff[0] != ref.offrange[0];
1643 if (DECL_P (ref.base))
1645 if ((ref.basesize < maxobjsize
1646 && warning_at (loc, OPT_Warray_bounds,
1647 form
1648 ? G_("%G%qD forming offset %s is out of "
1649 "the bounds [0, %wu] of object %qD with "
1650 "type %qT")
1651 : G_("%G%qD offset %s is out of the bounds "
1652 "[0, %wu] of object %qD with type %qT"),
1653 call, func, rangestr[0], ref.basesize.to_uhwi (),
1654 ref.base, TREE_TYPE (ref.base)))
1655 || warning_at (loc, OPT_Warray_bounds,
1656 form
1657 ? G_("%G%qD forming offset %s is out of "
1658 "the bounds of object %qD with type %qT")
1659 : G_("%G%qD offset %s is out of the bounds "
1660 "of object %qD with type %qT"),
1661 call, func, rangestr[0],
1662 ref.base, TREE_TYPE (ref.base)))
1663 inform (DECL_SOURCE_LOCATION (ref.base),
1664 "%qD declared here", ref.base);
1666 else if (ref.basesize < maxobjsize)
1667 warning_at (loc, OPT_Warray_bounds,
1668 form
1669 ? G_("%G%qD forming offset %s is out of the bounds "
1670 "[0, %wu]")
1671 : G_("%G%qD offset %s is out of the bounds [0, %wu]"),
1672 call, func, rangestr[0], ref.basesize.to_uhwi ());
1673 else
1674 warning_at (loc, OPT_Warray_bounds,
1675 form
1676 ? G_("%G%qD forming offset %s is out of bounds")
1677 : G_("%G%qD offset %s is out of bounds"),
1678 call, func, rangestr[0]);
1680 else if (TREE_CODE (ref.ref) == MEM_REF)
1682 tree type = TREE_TYPE (TREE_OPERAND (ref.ref, 0));
1683 if (POINTER_TYPE_P (type))
1684 type = TREE_TYPE (type);
1685 type = TYPE_MAIN_VARIANT (type);
1687 warning_at (loc, OPT_Warray_bounds,
1688 "%G%qD offset %s from the object at %qE is out "
1689 "of the bounds of %qT",
1690 call, func, rangestr[0], ref.base, type);
1692 else
1694 type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1696 warning_at (loc, OPT_Warray_bounds,
1697 "%G%qD offset %s from the object at %qE is out "
1698 "of the bounds of referenced subobject %qD with type %qT "
1699 "at offset %wu",
1700 call, func, rangestr[0], ref.base, TREE_OPERAND (ref.ref, 1),
1701 type, ref.refoff.to_uhwi ());
1704 return true;
1707 /* Check a CALL statement for restrict-violations and issue warnings
1708 if/when appropriate. */
1710 void
1711 wrestrict_dom_walker::check_call (gcall *call)
1713 /* Avoid checking the call if it has already been diagnosed for
1714 some reason. */
1715 if (gimple_no_warning_p (call))
1716 return;
1718 tree func = gimple_call_fndecl (call);
1719 if (!func || DECL_BUILT_IN_CLASS (func) != BUILT_IN_NORMAL)
1720 return;
1722 bool with_bounds = gimple_call_with_bounds_p (call);
1724 /* Argument number to extract from the call (depends on the built-in
1725 and its kind). */
1726 unsigned dst_idx = -1;
1727 unsigned src_idx = -1;
1728 unsigned bnd_idx = -1;
1730 /* Is this CALL to a string function (as opposed to one to a raw
1731 memory function). */
1732 bool strfun = true;
1734 switch (DECL_FUNCTION_CODE (func))
1736 case BUILT_IN_MEMCPY:
1737 case BUILT_IN_MEMCPY_CHK:
1738 case BUILT_IN_MEMCPY_CHKP:
1739 case BUILT_IN_MEMCPY_CHK_CHKP:
1740 case BUILT_IN_MEMPCPY:
1741 case BUILT_IN_MEMPCPY_CHK:
1742 case BUILT_IN_MEMPCPY_CHKP:
1743 case BUILT_IN_MEMPCPY_CHK_CHKP:
1744 case BUILT_IN_MEMMOVE:
1745 case BUILT_IN_MEMMOVE_CHK:
1746 case BUILT_IN_MEMMOVE_CHKP:
1747 case BUILT_IN_MEMMOVE_CHK_CHKP:
1748 strfun = false;
1749 /* Fall through. */
1751 case BUILT_IN_STPNCPY:
1752 case BUILT_IN_STPNCPY_CHK:
1753 case BUILT_IN_STRNCAT:
1754 case BUILT_IN_STRNCAT_CHK:
1755 case BUILT_IN_STRNCPY:
1756 case BUILT_IN_STRNCPY_CHK:
1757 dst_idx = 0;
1758 src_idx = 1 + with_bounds;
1759 bnd_idx = 2 + 2 * with_bounds;
1760 break;
1762 case BUILT_IN_STPCPY:
1763 case BUILT_IN_STPCPY_CHK:
1764 case BUILT_IN_STPCPY_CHKP:
1765 case BUILT_IN_STPCPY_CHK_CHKP:
1766 case BUILT_IN_STRCPY:
1767 case BUILT_IN_STRCPY_CHK:
1768 case BUILT_IN_STRCPY_CHKP:
1769 case BUILT_IN_STRCPY_CHK_CHKP:
1770 case BUILT_IN_STRCAT:
1771 case BUILT_IN_STRCAT_CHK:
1772 case BUILT_IN_STRCAT_CHKP:
1773 case BUILT_IN_STRCAT_CHK_CHKP:
1774 dst_idx = 0;
1775 src_idx = 1 + with_bounds;
1776 break;
1778 default:
1779 /* Handle other string functions here whose access may need
1780 to be validated for in-bounds offsets and non-overlapping
1781 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
1782 macros so they need to be handled here.) */
1783 return;
1786 unsigned nargs = gimple_call_num_args (call);
1788 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1789 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1790 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1792 /* For string functions with an unspecified or unknown bound,
1793 assume the size of the access is one. */
1794 if (!dstwr && strfun)
1795 dstwr = size_one_node;
1797 /* DST and SRC can be null for a call with an insufficient number
1798 of arguments to a built-in function declared without a protype. */
1799 if (!dst || !src)
1800 return;
1802 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1803 a function declared without a prototype. Avoid checking such
1804 invalid calls. */
1805 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1806 || TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
1807 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1808 return;
1810 if (check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
1811 return;
1813 /* Avoid diagnosing the call again. */
1814 gimple_set_no_warning (call, true);
1817 } /* anonymous namespace */
1819 /* Attempt to detect and diagnose invalid offset bounds and (except for
1820 memmove) overlapping copy in a call expression EXPR from SRC to DST
1821 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1822 SRCSIZE may be NULL. Return false when one or the other has been
1823 detected and diagnosed, true otherwise. */
1825 bool
1826 check_bounds_or_overlap (gcall *call, tree dst, tree src, tree dstsize,
1827 tree srcsize, bool bounds_only /* = false */)
1829 location_t loc = gimple_location (call);
1831 if (tree block = gimple_block (call))
1832 if (location_t *pbloc = block_nonartificial_location (block))
1833 loc = *pbloc;
1835 loc = expansion_point_location_if_in_system_header (loc);
1837 tree func = gimple_call_fndecl (call);
1839 builtin_memref dstref (dst, dstsize);
1840 builtin_memref srcref (src, srcsize);
1842 builtin_access acs (call, dstref, srcref);
1844 /* Set STRICT to the value of the -Warray-bounds=N argument for
1845 string functions or when N > 1. */
1846 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
1848 /* Validate offsets first to make sure they are within the bounds
1849 of the destination object if its size is known, or PTRDIFF_MAX
1850 otherwise. */
1851 if (maybe_diag_offset_bounds (loc, call, func, strict, dst, dstref)
1852 || maybe_diag_offset_bounds (loc, call, func, strict, src, srcref))
1854 gimple_set_no_warning (call, true);
1855 return false;
1858 bool check_overlap
1859 = (warn_restrict
1860 && (bounds_only
1861 || (DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE
1862 && DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE_CHK)));
1864 if (!check_overlap)
1865 return true;
1867 if (operand_equal_p (dst, src, 0))
1869 warning_at (loc, OPT_Wrestrict,
1870 "%G%qD source argument is the same as destination",
1871 call, func);
1872 gimple_set_no_warning (call, true);
1873 return false;
1876 /* Return false when overlap has been detected. */
1877 if (maybe_diag_overlap (loc, call, acs))
1879 gimple_set_no_warning (call, true);
1880 return false;
1883 return true;
1886 gimple_opt_pass *
1887 make_pass_warn_restrict (gcc::context *ctxt)
1889 return new pass_wrestrict (ctxt);