CWG 616, 1213 - value category of subobject references.
[official-gcc.git] / gcc / gimple-ssa-warn-restrict.c
blob637ed3cc29094e16ca33d7cfa7c077add967ef77
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 if (TREE_CODE (basesize) == INTEGER_CST)
282 /* Size could be non-constant for a variable-length type such
283 as a struct with a VLA member (a GCC extension). */
284 maxoff = wi::to_offset (basesize);
286 if (offrange[0] >= 0)
288 if (offrange[1] < 0)
289 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
290 else if (offrange[0] <= maxoff && offrange[1] > maxoff)
291 offrange[1] = maxoff;
295 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. */
297 void
298 builtin_memref::extend_offset_range (tree offset)
300 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
302 if (TREE_CODE (offset) == INTEGER_CST)
304 offset_int off = int_cst_value (offset);
305 if (off != 0)
307 offrange[0] += off;
308 offrange[1] += off;
310 return;
313 if (TREE_CODE (offset) == SSA_NAME)
315 wide_int min, max;
316 value_range_type rng = get_range_info (offset, &min, &max);
317 if (rng == VR_RANGE)
319 offrange[0] += offset_int::from (min, SIGNED);
320 offrange[1] += offset_int::from (max, SIGNED);
322 else if (rng == VR_ANTI_RANGE)
324 offrange[0] += offset_int::from (max + 1, SIGNED);
325 offrange[1] += offset_int::from (min - 1, SIGNED);
327 else
329 gimple *stmt = SSA_NAME_DEF_STMT (offset);
330 tree type;
331 if (is_gimple_assign (stmt)
332 && gimple_assign_rhs_code (stmt) == NOP_EXPR
333 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
334 && INTEGRAL_TYPE_P (type))
336 /* Use the bounds of the type of the NOP_EXPR operand
337 even if it's signed. The result doesn't trigger
338 warnings but makes their output more readable. */
339 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
340 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
342 else
343 offrange[1] += maxobjsize;
345 return;
348 offrange[1] += maxobjsize;
351 /* Determines the base object or pointer of the reference EXPR
352 and the offset range from the beginning of the base. */
354 void
355 builtin_memref::set_base_and_offset (tree expr)
357 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
359 if (TREE_CODE (expr) == SSA_NAME)
361 /* Try to tease the offset out of the pointer. */
362 gimple *stmt = SSA_NAME_DEF_STMT (expr);
363 if (!base
364 && gimple_assign_single_p (stmt)
365 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
366 expr = gimple_assign_rhs1 (stmt);
367 else if (is_gimple_assign (stmt))
369 tree_code code = gimple_assign_rhs_code (stmt);
370 if (code == NOP_EXPR)
372 tree rhs = gimple_assign_rhs1 (stmt);
373 if (POINTER_TYPE_P (TREE_TYPE (rhs)))
374 expr = gimple_assign_rhs1 (stmt);
375 else
377 base = expr;
378 return;
381 else if (code == POINTER_PLUS_EXPR)
383 expr = gimple_assign_rhs1 (stmt);
385 tree offset = gimple_assign_rhs2 (stmt);
386 extend_offset_range (offset);
388 else
390 base = expr;
391 return;
394 else
396 base = expr;
397 return;
401 if (TREE_CODE (expr) == ADDR_EXPR)
402 expr = TREE_OPERAND (expr, 0);
404 /* Stash the reference for offset validation. */
405 ref = expr;
407 poly_int64 bitsize, bitpos;
408 tree var_off;
409 machine_mode mode;
410 int sign, reverse, vol;
412 /* Determine the base object or pointer of the reference and
413 the constant bit offset from the beginning of the base.
414 If the offset has a non-constant component, it will be in
415 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
416 unused here. */
417 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
418 &mode, &sign, &reverse, &vol);
420 /* get_inner_reference is not expected to return null. */
421 gcc_assert (base != NULL);
423 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
425 /* Convert the poly_int64 offset to offset_int. The offset
426 should be constant but be prepared for it not to be just in
427 case. */
428 offset_int cstoff;
429 if (bytepos.is_constant (&cstoff))
431 offrange[0] += cstoff;
432 offrange[1] += cstoff;
434 /* Besides the reference saved above, also stash the offset
435 for validation. */
436 if (TREE_CODE (expr) == COMPONENT_REF)
437 refoff = cstoff;
439 else
440 offrange[1] += maxobjsize;
442 if (var_off)
444 if (TREE_CODE (var_off) == INTEGER_CST)
446 cstoff = wi::to_offset (var_off);
447 offrange[0] += cstoff;
448 offrange[1] += cstoff;
450 else
451 offrange[1] += maxobjsize;
454 if (TREE_CODE (base) == MEM_REF)
456 tree memrefoff = TREE_OPERAND (base, 1);
457 extend_offset_range (memrefoff);
458 base = TREE_OPERAND (base, 0);
461 if (TREE_CODE (base) == SSA_NAME)
462 set_base_and_offset (base);
465 /* Return error_mark_node if the signed offset exceeds the bounds
466 of the address space (PTRDIFF_MAX). Otherwise, return either
467 BASE or REF when the offset exceeds the bounds of the BASE or
468 REF object, and set OOBOFF to the past-the-end offset formed
469 by the reference, including its size. When STRICT is non-zero
470 use REF size, when available, otherwise use BASE size. When
471 STRICT is greater than 1, use the size of the last array member
472 as the bound, otherwise treat such a member as a flexible array
473 member. Return NULL when the offset is in bounds. */
475 tree
476 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[2]) const
478 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
480 /* A temporary, possibly adjusted, copy of the offset range. */
481 offset_int offrng[2] = { offrange[0], offrange[1] };
483 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
485 /* Check for offset in an anti-range with a negative lower bound.
486 For such a range, consider only the non-negative subrange. */
487 if (offrng[1] < offrng[0] && offrng[1] < 0)
488 offrng[1] = maxobjsize;
491 /* Conservative offset of the last byte of the referenced object. */
492 offset_int endoff;
494 /* The bounds need not be ordered. Set HIB to use as the index
495 of the larger of the bounds and LOB as the opposite. */
496 bool hib = wi::les_p (offrng[0], offrng[1]);
497 bool lob = !hib;
499 if (basesize < 0)
501 endoff = offrng[lob] + sizrange[0];
503 /* For a reference through a pointer to an object of unknown size
504 all initial offsets are considered valid, positive as well as
505 negative, since the pointer itself can point past the beginning
506 of the object. However, the sum of the lower bound of the offset
507 and that of the size must be less than or equal than PTRDIFF_MAX. */
508 if (endoff > maxobjsize)
509 return error_mark_node;
511 return NULL_TREE;
514 /* A reference to an object of known size must be within the bounds
515 of the base object. */
516 if (offrng[hib] < 0 || offrng[lob] > basesize)
517 return base;
519 /* The extent of the reference must also be within the bounds of
520 the base object (if known) or the maximum object size otherwise. */
521 endoff = wi::smax (offrng[lob], 0) + sizrange[0];
522 if (endoff > maxobjsize)
523 return error_mark_node;
525 offset_int size = basesize;
526 tree obj = base;
528 if (strict
529 && DECL_P (obj)
530 && ref
531 && refoff >= 0
532 && TREE_CODE (ref) == COMPONENT_REF
533 && (strict > 1
534 || !array_at_struct_end_p (ref)))
536 /* If the reference is to a member subobject, the offset must
537 be within the bounds of the subobject. */
538 tree field = TREE_OPERAND (ref, 1);
539 tree type = TREE_TYPE (field);
540 if (tree sz = TYPE_SIZE_UNIT (type))
541 if (TREE_CODE (sz) == INTEGER_CST)
543 size = refoff + wi::to_offset (sz);
544 obj = ref;
548 if (endoff <= size)
549 return NULL_TREE;
551 /* Set the out-of-bounds offset range to be one greater than
552 that delimited by the reference including its size. */
553 ooboff[lob] = size + 1;
555 if (endoff > ooboff[lob])
556 ooboff[hib] = endoff;
557 else
558 ooboff[hib] = wi::smax (offrng[lob], 0) + sizrange[1];
560 return obj;
563 /* Create an association between the memory references DST and SRC
564 for access by a call EXPR to a memory or string built-in funtion. */
566 builtin_access::builtin_access (gcall *call, builtin_memref &dst,
567 builtin_memref &src)
568 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
569 dstoff (), srcoff (), dstsiz (), srcsiz ()
571 /* Zero out since the offset_int ctors invoked above are no-op. */
572 dstoff[0] = dstoff[1] = 0;
573 srcoff[0] = srcoff[1] = 0;
574 dstsiz[0] = dstsiz[1] = 0;
575 srcsiz[0] = srcsiz[1] = 0;
577 /* Object Size Type to use to determine the size of the destination
578 and source objects. Overridden below for raw memory functions. */
579 int ostype = 1;
581 /* True when the size of one reference depends on the offset of
582 itself or the other. */
583 bool depends_p = true;
585 /* True when the size of the destination reference DSTREF has been
586 determined from SRCREF and so needs to be adjusted by the latter's
587 offset. Only meaningful for bounded string functions like strncpy. */
588 bool dstadjust_p = false;
590 /* The size argument number (depends on the built-in). */
591 unsigned sizeargno = 2;
592 if (gimple_call_with_bounds_p (call))
593 sizeargno += 2;
595 tree func = gimple_call_fndecl (call);
596 switch (DECL_FUNCTION_CODE (func))
598 case BUILT_IN_MEMCPY:
599 case BUILT_IN_MEMCPY_CHK:
600 case BUILT_IN_MEMCPY_CHKP:
601 case BUILT_IN_MEMCPY_CHK_CHKP:
602 case BUILT_IN_MEMPCPY:
603 case BUILT_IN_MEMPCPY_CHK:
604 case BUILT_IN_MEMPCPY_CHKP:
605 case BUILT_IN_MEMPCPY_CHK_CHKP:
606 ostype = 0;
607 depends_p = false;
608 detect_overlap = &builtin_access::generic_overlap;
609 break;
611 case BUILT_IN_MEMMOVE:
612 case BUILT_IN_MEMMOVE_CHK:
613 case BUILT_IN_MEMMOVE_CHKP:
614 case BUILT_IN_MEMMOVE_CHK_CHKP:
615 /* For memmove there is never any overlap to check for. */
616 ostype = 0;
617 depends_p = false;
618 detect_overlap = &builtin_access::no_overlap;
619 break;
621 case BUILT_IN_STPNCPY:
622 case BUILT_IN_STPNCPY_CHK:
623 case BUILT_IN_STRNCPY:
624 case BUILT_IN_STRNCPY_CHK:
625 dstref->strbounded_p = true;
626 detect_overlap = &builtin_access::strcpy_overlap;
627 break;
629 case BUILT_IN_STPCPY:
630 case BUILT_IN_STPCPY_CHK:
631 case BUILT_IN_STPCPY_CHKP:
632 case BUILT_IN_STPCPY_CHK_CHKP:
633 case BUILT_IN_STRCPY:
634 case BUILT_IN_STRCPY_CHK:
635 case BUILT_IN_STRCPY_CHKP:
636 case BUILT_IN_STRCPY_CHK_CHKP:
637 detect_overlap = &builtin_access::strcpy_overlap;
638 break;
640 case BUILT_IN_STRCAT:
641 case BUILT_IN_STRCAT_CHK:
642 case BUILT_IN_STRCAT_CHKP:
643 case BUILT_IN_STRCAT_CHK_CHKP:
644 detect_overlap = &builtin_access::strcat_overlap;
645 break;
647 case BUILT_IN_STRNCAT:
648 case BUILT_IN_STRNCAT_CHK:
649 dstref->strbounded_p = true;
650 srcref->strbounded_p = true;
651 detect_overlap = &builtin_access::strcat_overlap;
652 break;
654 default:
655 /* Handle other string functions here whose access may need
656 to be validated for in-bounds offsets and non-overlapping
657 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
658 macros so they need to be handled here.) */
659 return;
662 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
664 /* Try to determine the size of the base object. compute_objsize
665 expects a pointer so create one if BASE is a non-pointer object. */
666 tree addr;
667 if (dst.basesize < 0)
669 addr = dst.base;
670 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
671 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
673 if (tree dstsize = compute_objsize (addr, ostype))
674 dst.basesize = wi::to_offset (dstsize);
675 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
676 dst.basesize = HOST_WIDE_INT_MIN;
677 else
678 dst.basesize = maxobjsize;
681 if (src.basesize < 0)
683 addr = src.base;
684 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
685 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
687 if (tree srcsize = compute_objsize (addr, ostype))
688 src.basesize = wi::to_offset (srcsize);
689 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
690 src.basesize = HOST_WIDE_INT_MIN;
691 else
692 src.basesize = maxobjsize;
695 /* If there is no dependency between the references or the base
696 objects of the two references aren't the same there's nothing
697 else to do. */
698 if (depends_p && dstref->base != srcref->base)
699 return;
701 /* ...otherwise, make adjustments for references to the same object
702 by string built-in functions to reflect the constraints imposed
703 by the function. */
705 /* For bounded string functions determine the range of the bound
706 on the access. For others, the range stays unbounded. */
707 offset_int bounds[2] = { maxobjsize, maxobjsize };
708 if (dstref->strbounded_p)
710 tree size = gimple_call_arg (call, sizeargno);
711 tree range[2];
712 if (get_size_range (size, range, true))
714 bounds[0] = wi::to_offset (range[0]);
715 bounds[1] = wi::to_offset (range[1]);
718 /* If both references' size ranges are indeterminate use the last
719 (size) argument from the function call as a substitute. This
720 may only be necessary for strncpy (but not for memcpy where
721 the size range would have been already determined this way). */
722 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
723 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
725 dstref->sizrange[0] = bounds[0];
726 dstref->sizrange[1] = bounds[1];
730 /* The size range of one reference involving the same base object
731 can be determined from the size range of the other reference.
732 This makes it possible to compute accurate offsets for warnings
733 involving functions like strcpy where the length of just one of
734 the two arguments is known (determined by tree-ssa-strlen). */
735 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
737 /* When the destination size is unknown set it to the size of
738 the source. */
739 dstref->sizrange[0] = srcref->sizrange[0];
740 dstref->sizrange[1] = srcref->sizrange[1];
742 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
744 /* When the source size is unknown set it to the size of
745 the destination. */
746 srcref->sizrange[0] = dstref->sizrange[0];
747 srcref->sizrange[1] = dstref->sizrange[1];
749 if (depends_p)
751 if (dstref->strbounded_p)
753 /* Read access by strncpy is bounded. */
754 if (bounds[0] < srcref->sizrange[0])
755 srcref->sizrange[0] = bounds[0];
756 if (bounds[1] < srcref->sizrange[1])
757 srcref->sizrange[1] = bounds[1];
760 /* For string functions, adjust the size range of the source
761 reference by the inverse boundaries of the offset (because
762 the higher the offset into the string the shorter its
763 length). */
764 if (srcref->offrange[1] >= 0
765 && srcref->offrange[1] < srcref->sizrange[0])
766 srcref->sizrange[0] -= srcref->offrange[1];
767 else
768 srcref->sizrange[0] = 0;
770 if (srcref->offrange[0] > 0)
772 if (srcref->offrange[0] < srcref->sizrange[1])
773 srcref->sizrange[1] -= srcref->offrange[0];
774 else
775 srcref->sizrange[1] = 0;
778 dstadjust_p = true;
782 if (detect_overlap == &builtin_access::generic_overlap)
784 if (dstref->strbounded_p)
786 dstref->sizrange[0] = bounds[0];
787 dstref->sizrange[1] = bounds[1];
789 if (dstref->sizrange[0] < srcref->sizrange[0])
790 srcref->sizrange[0] = dstref->sizrange[0];
792 if (dstref->sizrange[1] < srcref->sizrange[1])
793 srcref->sizrange[1] = dstref->sizrange[1];
796 else if (detect_overlap == &builtin_access::strcpy_overlap)
798 if (!dstref->strbounded_p)
800 /* For strcpy, adjust the destination size range to match that
801 of the source computed above. */
802 if (depends_p && dstadjust_p)
804 dstref->sizrange[0] = srcref->sizrange[0];
805 dstref->sizrange[1] = srcref->sizrange[1];
810 if (dstref->strbounded_p)
812 /* For strncpy, adjust the destination size range to match that
813 of the source computed above. */
814 dstref->sizrange[0] = bounds[0];
815 dstref->sizrange[1] = bounds[1];
817 if (bounds[0] < srcref->sizrange[0])
818 srcref->sizrange[0] = bounds[0];
820 if (bounds[1] < srcref->sizrange[1])
821 srcref->sizrange[1] = bounds[1];
825 offset_int
826 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
827 offset_int *off)
829 const offset_int *p = a;
830 const offset_int *q = b;
832 /* Point P at the bigger of the two ranges and Q at the smaller. */
833 if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
835 p = b;
836 q = a;
839 if (p[0] < q[0])
841 if (p[1] < q[0])
842 return 0;
844 *off = q[0];
845 return wi::smin (p[1], q[1]) - q[0];
848 if (q[1] < p[0])
849 return 0;
851 off[0] = p[0];
852 return q[1] - p[0];
855 /* Return true if the bounded mempry (memcpy amd similar) or string function
856 access (strncpy and similar) ACS overlaps. */
858 bool
859 builtin_access::generic_overlap ()
861 builtin_access &acs = *this;
862 const builtin_memref *dstref = acs.dstref;
863 const builtin_memref *srcref = acs.srcref;
865 gcc_assert (dstref->base == srcref->base);
867 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
869 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
870 gcc_assert (maxsize <= maxobjsize);
872 /* Adjust the larger bounds of the offsets (which may be the first
873 element if the lower bound is larger than the upper bound) to
874 make them valid for the smallest access (if possible) but no smaller
875 than the smaller bounds. */
876 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
878 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
879 acs.dstoff[1] = maxsize - acs.dstsiz[0];
880 if (acs.dstoff[1] < acs.dstoff[0])
881 acs.dstoff[1] = acs.dstoff[0];
883 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
885 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
886 acs.srcoff[1] = maxsize - acs.srcsiz[0];
887 if (acs.srcoff[1] < acs.srcoff[0])
888 acs.srcoff[1] = acs.srcoff[0];
890 /* Determine the minimum and maximum space for the access given
891 the offsets. */
892 offset_int space[2];
893 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
894 space[1] = space[0];
896 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
897 if (acs.srcsiz[0] > 0)
899 if (d < space[0])
900 space[0] = d;
902 if (space[1] < d)
903 space[1] = d;
905 else
906 space[1] = acs.dstsiz[1];
908 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
909 if (d < space[0])
910 space[0] = d;
912 if (space[1] < d)
913 space[1] = d;
915 /* Treat raw memory functions both of whose references are bounded
916 as special and permit uncertain overlaps to go undetected. For
917 all kinds of constant offset and constant size accesses, if
918 overlap isn't certain it is not possible. */
919 bool overlap_possible = space[0] < acs.dstsiz[1];
920 if (!overlap_possible)
921 return false;
923 bool overlap_certain = space[1] < acs.dstsiz[0];
925 /* True when the size of one reference depends on the offset of
926 the other. */
927 bool depends_p = detect_overlap != &builtin_access::generic_overlap;
929 if (!overlap_certain)
931 if (!dstref->strbounded_p && !depends_p)
932 /* Memcpy only considers certain overlap. */
933 return false;
935 /* There's no way to distinguish an access to the same member
936 of a structure from one to two distinct members of the same
937 structure. Give up to avoid excessive false positives. */
938 tree basetype = TREE_TYPE (dstref->base);
940 if (POINTER_TYPE_P (basetype))
941 basetype = TREE_TYPE (basetype);
942 else
943 while (TREE_CODE (basetype) == ARRAY_TYPE)
944 basetype = TREE_TYPE (basetype);
946 if (RECORD_OR_UNION_TYPE_P (basetype))
947 return false;
950 /* True for stpcpy and strcpy. */
951 bool stxcpy_p = (!dstref->strbounded_p
952 && detect_overlap == &builtin_access::strcpy_overlap);
954 if (dstref->refoff >= 0
955 && srcref->refoff >= 0
956 && dstref->refoff != srcref->refoff
957 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
958 return false;
960 offset_int siz[2] = { maxobjsize + 1, 0 };
962 ovloff[0] = HOST_WIDE_INT_MAX;
963 ovloff[1] = HOST_WIDE_INT_MIN;
965 /* Adjustment to the lower bound of the offset of the overlap to
966 account for a subset of unbounded string calls where the size
967 of the destination string depends on the length of the source
968 which in turn depends on the offset into it. */
969 bool sub1;
971 if (stxcpy_p)
973 sub1 = acs.dstoff[0] <= acs.srcoff[0];
975 /* Iterate over the extreme locations (on the horizontal axis formed
976 by their offsets) and sizes of two regions and find their smallest
977 and largest overlap and the corresponding offsets. */
978 for (unsigned i = 0; i != 2; ++i)
980 const offset_int a[2] = {
981 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
984 const offset_int b[2] = {
985 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
988 offset_int off;
989 offset_int sz = overlap_size (a, b, &off);
990 if (sz < siz[0])
991 siz[0] = sz;
993 if (siz[1] <= sz)
994 siz[1] = sz;
996 if (sz != 0)
998 if (wi::lts_p (off, ovloff[0]))
999 ovloff[0] = off.to_shwi ();
1000 if (wi::lts_p (ovloff[1], off))
1001 ovloff[1] = off.to_shwi ();
1005 else
1007 sub1 = !depends_p;
1009 /* Iterate over the extreme locations (on the horizontal axis
1010 formed by their offsets) and sizes of two regions and find
1011 their smallest and largest overlap and the corresponding
1012 offsets. */
1014 for (unsigned io = 0; io != 2; ++io)
1015 for (unsigned is = 0; is != 2; ++is)
1017 const offset_int a[2] = {
1018 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1021 for (unsigned jo = 0; jo != 2; ++jo)
1022 for (unsigned js = 0; js != 2; ++js)
1024 if (depends_p)
1026 /* For st{p,r}ncpy the size of the source sequence
1027 depends on the offset into it. */
1028 if (js)
1029 break;
1030 js = !jo;
1033 const offset_int b[2] = {
1034 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1037 offset_int off;
1038 offset_int sz = overlap_size (a, b, &off);
1039 if (sz < siz[0])
1040 siz[0] = sz;
1042 if (siz[1] <= sz)
1043 siz[1] = sz;
1045 if (sz != 0)
1047 if (wi::lts_p (off, ovloff[0]))
1048 ovloff[0] = off.to_shwi ();
1049 if (wi::lts_p (ovloff[1], off))
1050 ovloff[1] = off.to_shwi ();
1056 ovlsiz[0] = siz[0].to_shwi ();
1057 ovlsiz[1] = siz[1].to_shwi ();
1059 if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1060 ovloff[0] = ovloff[1] + ovlsiz[1] - 1 - sub1;
1062 return true;
1065 /* Return true if the strcat-like access overlaps. */
1067 bool
1068 builtin_access::strcat_overlap ()
1070 builtin_access &acs = *this;
1071 const builtin_memref *dstref = acs.dstref;
1072 const builtin_memref *srcref = acs.srcref;
1074 gcc_assert (dstref->base == srcref->base);
1076 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1078 gcc_assert (dstref->base && dstref->base == srcref->base);
1080 /* Adjust for strcat-like accesses. */
1082 /* As a special case for strcat, set the DSTREF offsets to the length
1083 of the source string since the function starts writing at the first
1084 nul, and set the size to 1 for the length of the nul. */
1085 acs.dstoff[0] += acs.dstsiz[0];
1086 acs.dstoff[1] += acs.dstsiz[1];
1088 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1090 /* The lower bound is zero when the size is unknown because then
1091 overlap is not certain. */
1092 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1093 acs.dstsiz[1] = 1;
1095 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1096 gcc_assert (maxsize <= maxobjsize);
1098 /* For references to the same base object, determine if there's a pair
1099 of valid offsets into the two references such that access between
1100 them doesn't overlap. Adjust both upper bounds to be valid for
1101 the smaller size (i.e., at most MAXSIZE - SIZE). */
1103 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1104 acs.dstoff[1] = maxsize - acs.dstsiz[0];
1106 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1107 acs.srcoff[1] = maxsize - acs.srcsiz[0];
1109 /* Check to see if there's enough space for both accesses without
1110 overlap. Determine the optimistic (maximum) amount of available
1111 space. */
1112 offset_int space;
1113 if (acs.dstoff[0] <= acs.srcoff[0])
1115 if (acs.dstoff[1] < acs.srcoff[1])
1116 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1117 else
1118 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1120 else
1121 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1123 /* Overlap is certain if the distance between the farthest offsets
1124 of the opposite accesses is less than the sum of the lower bounds
1125 of the sizes of the two accesses. */
1126 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1128 /* For a constant-offset, constant size access, consider the largest
1129 distance between the offset bounds and the lower bound of the access
1130 size. If the overlap isn't certain return success. */
1131 if (!overlap_certain
1132 && acs.dstoff[0] == acs.dstoff[1]
1133 && acs.srcoff[0] == acs.srcoff[1]
1134 && acs.dstsiz[0] == acs.dstsiz[1]
1135 && acs.srcsiz[0] == acs.srcsiz[1])
1136 return false;
1138 /* Overlap is not certain but may be possible. */
1140 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1142 /* Determine the conservative (minimum) amount of space. */
1143 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1144 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1145 if (d < space)
1146 space = d;
1147 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1148 if (d < space)
1149 space = d;
1151 /* For a strict test (used for strcpy and similar with unknown or
1152 variable bounds or sizes), consider the smallest distance between
1153 the offset bounds and either the upper bound of the access size
1154 if known, or the lower bound otherwise. */
1155 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1156 return false;
1158 /* When strcat overlap is certain it is always a single byte:
1159 the terminating NUL, regardless of offsets and sizes. When
1160 overlap is only possible its range is [0, 1]. */
1161 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1162 acs.ovlsiz[1] = 1;
1164 offset_int endoff = dstref->offrange[0] + dstref->sizrange[0];
1165 if (endoff <= srcref->offrange[0])
1166 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1167 else
1168 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1170 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1171 srcref->sizrange[0]).to_shwi ();
1172 if (dstref->offrange[0] == dstref->offrange[1])
1174 if (srcref->offrange[0] == srcref->offrange[1])
1175 acs.ovloff[1] = acs.ovloff[0];
1176 else
1177 acs.ovloff[1]
1178 = wi::smin (maxobjsize,
1179 srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1181 else
1182 acs.ovloff[1]
1183 = wi::smin (maxobjsize,
1184 dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1186 if (acs.sizrange[0] == 0)
1187 acs.sizrange[0] = 1;
1188 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1189 return true;
1192 /* Return true if the strcpy-like access overlaps. */
1194 bool
1195 builtin_access::strcpy_overlap ()
1197 return generic_overlap ();
1201 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1202 one another or that, in order not to overlap, would imply that the size
1203 of the referenced object(s) exceeds the maximum size of an object. Set
1204 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1205 they may overlap in a way that's not apparent from the available data),
1206 return false. */
1208 bool
1209 builtin_access::overlap ()
1211 builtin_access &acs = *this;
1213 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1215 acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1216 srcref->sizrange[0]).to_shwi ();
1217 acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1218 srcref->sizrange[1]).to_shwi ();
1220 /* Check to see if the two references refer to regions that are
1221 too large not to overlap in the address space (whose maximum
1222 size is PTRDIFF_MAX). */
1223 offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1224 if (maxobjsize < size)
1226 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1227 acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1228 return true;
1231 /* If both base objects aren't known return the maximum possible
1232 offset that would make them not overlap. */
1233 if (!dstref->base || !srcref->base)
1234 return false;
1236 /* Set the access offsets. */
1237 acs.dstoff[0] = dstref->offrange[0];
1238 acs.dstoff[1] = dstref->offrange[1];
1240 /* If the base object is an array adjust the bounds of the offset
1241 to be non-negative and within the bounds of the array if possible. */
1242 if (dstref->base
1243 && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE)
1245 if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0)
1246 acs.dstoff[0] = 0;
1248 if (acs.dstoff[1] < acs.dstoff[0])
1250 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base)))
1251 acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size));
1252 else
1253 acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize);
1257 acs.srcoff[0] = srcref->offrange[0];
1258 acs.srcoff[1] = srcref->offrange[1];
1260 if (srcref->base
1261 && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE)
1263 if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0)
1264 acs.srcoff[0] = 0;
1266 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base)))
1267 acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size));
1268 else if (acs.srcoff[1] < acs.srcoff[0])
1269 acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize);
1272 /* When the upper bound of the offset is less than the lower bound
1273 the former is the result of a negative offset being represented
1274 as a large positive value or vice versa. The resulting range is
1275 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1276 a union is not representable using the current data structure
1277 replace it with the full range of offsets. */
1278 if (acs.dstoff[1] < acs.dstoff[0])
1280 acs.dstoff[0] = -maxobjsize - 1;
1281 acs.dstoff[1] = maxobjsize;
1284 /* Validate the offset and size of each reference on its own first.
1285 This is independent of whether or not the base objects are the
1286 same. Normally, this would have already been detected and
1287 diagnosed by -Warray-bounds, unless it has been disabled. */
1288 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1289 if (maxobjsize < maxoff)
1291 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1292 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1293 return true;
1296 /* Repeat the same as above but for the source offsets. */
1297 if (acs.srcoff[1] < acs.srcoff[0])
1299 acs.srcoff[0] = -maxobjsize - 1;
1300 acs.srcoff[1] = maxobjsize;
1303 maxoff = acs.srcoff[0] + srcref->sizrange[0];
1304 if (maxobjsize < maxoff)
1306 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1307 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1308 - maxobjsize).to_shwi ();
1309 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1310 return true;
1313 if (dstref->base != srcref->base)
1314 return false;
1316 acs.dstsiz[0] = dstref->sizrange[0];
1317 acs.dstsiz[1] = dstref->sizrange[1];
1319 acs.srcsiz[0] = srcref->sizrange[0];
1320 acs.srcsiz[1] = srcref->sizrange[1];
1322 /* Call the appropriate function to determine the overlap. */
1323 if ((this->*detect_overlap) ())
1325 if (!sizrange[1])
1327 /* Unless the access size range has already been set, do so here. */
1328 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1329 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1331 return true;
1334 return false;
1337 /* Attempt to detect and diagnose an overlapping copy in a call expression
1338 EXPR involving an an access ACS to a built-in memory or string function.
1339 Return true when one has been detected, false otherwise. */
1341 static bool
1342 maybe_diag_overlap (location_t loc, gcall *call, builtin_access &acs)
1344 if (!acs.overlap ())
1345 return false;
1347 /* For convenience. */
1348 const builtin_memref &dstref = *acs.dstref;
1349 const builtin_memref &srcref = *acs.srcref;
1351 /* Determine the range of offsets and sizes of the overlap if it
1352 exists and issue diagnostics. */
1353 HOST_WIDE_INT *ovloff = acs.ovloff;
1354 HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1355 HOST_WIDE_INT *sizrange = acs.sizrange;
1357 tree func = gimple_call_fndecl (call);
1359 /* To avoid a combinatorial explosion of diagnostics format the offsets
1360 or their ranges as strings and use them in the warning calls below. */
1361 char offstr[3][64];
1363 if (dstref.offrange[0] == dstref.offrange[1]
1364 || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1365 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1366 dstref.offrange[0].to_shwi ());
1367 else
1368 sprintf (offstr[0],
1369 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1370 dstref.offrange[0].to_shwi (),
1371 dstref.offrange[1].to_shwi ());
1373 if (srcref.offrange[0] == srcref.offrange[1]
1374 || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1375 sprintf (offstr[1],
1376 HOST_WIDE_INT_PRINT_DEC,
1377 srcref.offrange[0].to_shwi ());
1378 else
1379 sprintf (offstr[1],
1380 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1381 srcref.offrange[0].to_shwi (),
1382 srcref.offrange[1].to_shwi ());
1384 if (ovloff[0] == ovloff[1] || !ovloff[1])
1385 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1386 else
1387 sprintf (offstr[2],
1388 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1389 ovloff[0], ovloff[1]);
1391 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1392 bool must_overlap = ovlsiz[0] > 0;
1394 if (ovlsiz[1] == 0)
1395 ovlsiz[1] = ovlsiz[0];
1397 if (must_overlap)
1399 /* Issue definitive "overlaps" diagnostic in this block. */
1401 if (sizrange[0] == sizrange[1])
1403 if (ovlsiz[0] == ovlsiz[1])
1404 warning_at (loc, OPT_Wrestrict,
1405 sizrange[0] == 1
1406 ? (ovlsiz[0] == 1
1407 ? G_("%G%qD accessing %wu byte at offsets %s "
1408 "and %s overlaps %wu byte at offset %s")
1409 : G_("%G%qD accessing %wu byte at offsets %s "
1410 "and %s overlaps %wu bytes at offset "
1411 "%s"))
1412 : (ovlsiz[0] == 1
1413 ? G_("%G%qD accessing %wu bytes at offsets %s "
1414 "and %s overlaps %wu byte at offset %s")
1415 : G_("%G%qD accessing %wu bytes at offsets %s "
1416 "and %s overlaps %wu bytes at offset "
1417 "%s")),
1418 call, func, sizrange[0],
1419 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1420 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1421 warning_n (loc, OPT_Wrestrict, sizrange[0],
1422 "%G%qD accessing %wu byte at offsets %s "
1423 "and %s overlaps between %wu and %wu bytes "
1424 "at offset %s",
1425 "%G%qD accessing %wu bytes at offsets %s "
1426 "and %s overlaps between %wu and %wu bytes "
1427 "at offset %s",
1428 call, func, sizrange[0], offstr[0], offstr[1],
1429 ovlsiz[0], ovlsiz[1], offstr[2]);
1430 else
1431 warning_n (loc, OPT_Wrestrict, sizrange[0],
1432 "%G%qD accessing %wu byte at offsets %s and "
1433 "%s overlaps %wu or more bytes at offset %s",
1434 "%G%qD accessing %wu bytes at offsets %s and "
1435 "%s overlaps %wu or more bytes at offset %s",
1436 call, func, sizrange[0],
1437 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1438 return true;
1441 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1443 if (ovlsiz[0] == ovlsiz[1])
1444 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1445 "%G%qD accessing between %wu and %wu bytes "
1446 "at offsets %s and %s overlaps %wu byte at "
1447 "offset %s",
1448 "%G%qD accessing between %wu and %wu bytes "
1449 "at offsets %s and %s overlaps %wu bytes "
1450 "at offset %s",
1451 call, func, sizrange[0], sizrange[1],
1452 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1453 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1454 warning_at (loc, OPT_Wrestrict,
1455 "%G%qD accessing between %wu and %wu bytes at "
1456 "offsets %s and %s overlaps between %wu and %wu "
1457 "bytes at offset %s",
1458 call, func, sizrange[0], sizrange[1],
1459 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1460 offstr[2]);
1461 else
1462 warning_at (loc, OPT_Wrestrict,
1463 "%G%qD accessing between %wu and %wu bytes at "
1464 "offsets %s and %s overlaps %wu or more bytes "
1465 "at offset %s",
1466 call, func, sizrange[0], sizrange[1],
1467 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1468 return true;
1471 if (ovlsiz[0] != ovlsiz[1])
1472 ovlsiz[1] = maxobjsize.to_shwi ();
1474 if (ovlsiz[0] == ovlsiz[1])
1475 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1476 "%G%qD accessing %wu or more bytes at offsets "
1477 "%s and %s overlaps %wu byte at offset %s",
1478 "%G%qD accessing %wu or more bytes at offsets "
1479 "%s and %s overlaps %wu bytes at offset %s",
1480 call, func, sizrange[0], offstr[0], offstr[1],
1481 ovlsiz[0], offstr[2]);
1482 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1483 warning_at (loc, OPT_Wrestrict,
1484 "%G%qD accessing %wu or more bytes at offsets %s "
1485 "and %s overlaps between %wu and %wu bytes "
1486 "at offset %s",
1487 call, func, sizrange[0], offstr[0], offstr[1],
1488 ovlsiz[0], ovlsiz[1], offstr[2]);
1489 else
1490 warning_at (loc, OPT_Wrestrict,
1491 "%G%qD accessing %wu or more bytes at offsets %s "
1492 "and %s overlaps %wu or more bytes at offset %s",
1493 call, func, sizrange[0], offstr[0], offstr[1],
1494 ovlsiz[0], offstr[2]);
1495 return true;
1498 /* Use more concise wording when one of the offsets is unbounded
1499 to avoid confusing the user with large and mostly meaningless
1500 numbers. */
1501 bool open_range;
1502 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1503 open_range = ((dstref.offrange[0] == 0
1504 && dstref.offrange[1] == maxobjsize)
1505 || (srcref.offrange[0] == 0
1506 && srcref.offrange[1] == maxobjsize));
1507 else
1508 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1509 && dstref.offrange[1] == maxobjsize)
1510 || (srcref.offrange[0] == -maxobjsize - 1
1511 && srcref.offrange[1] == maxobjsize));
1513 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1515 if (ovlsiz[1] == 1)
1517 if (open_range)
1518 warning_n (loc, OPT_Wrestrict, sizrange[1],
1519 "%G%qD accessing %wu byte may overlap "
1520 "%wu byte",
1521 "%G%qD accessing %wu bytes may overlap "
1522 "%wu byte",
1523 call, func, sizrange[1], ovlsiz[1]);
1524 else
1525 warning_n (loc, OPT_Wrestrict, sizrange[1],
1526 "%G%qD accessing %wu byte at offsets %s "
1527 "and %s may overlap %wu byte at offset %s",
1528 "%G%qD accessing %wu bytes at offsets %s "
1529 "and %s may overlap %wu byte at offset %s",
1530 call, func, sizrange[1], offstr[0], offstr[1],
1531 ovlsiz[1], offstr[2]);
1532 return true;
1535 if (open_range)
1536 warning_n (loc, OPT_Wrestrict, sizrange[1],
1537 "%G%qD accessing %wu byte may overlap "
1538 "up to %wu bytes",
1539 "%G%qD accessing %wu bytes may overlap "
1540 "up to %wu bytes",
1541 call, func, sizrange[1], ovlsiz[1]);
1542 else
1543 warning_n (loc, OPT_Wrestrict, sizrange[1],
1544 "%G%qD accessing %wu byte at offsets %s and "
1545 "%s may overlap up to %wu bytes at offset %s",
1546 "%G%qD accessing %wu bytes at offsets %s and "
1547 "%s may overlap up to %wu bytes at offset %s",
1548 call, func, sizrange[1], offstr[0], offstr[1],
1549 ovlsiz[1], offstr[2]);
1550 return true;
1553 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1555 if (open_range)
1556 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1557 "%G%qD accessing between %wu and %wu bytes "
1558 "may overlap %wu byte",
1559 "%G%qD accessing between %wu and %wu bytes "
1560 "may overlap up to %wu bytes",
1561 call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1562 else
1563 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1564 "%G%qD accessing between %wu and %wu bytes "
1565 "at offsets %s and %s may overlap %wu byte "
1566 "at offset %s",
1567 "%G%qD accessing between %wu and %wu bytes "
1568 "at offsets %s and %s may overlap up to %wu "
1569 "bytes at offset %s",
1570 call, func, sizrange[0], sizrange[1],
1571 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1572 return true;
1575 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1576 "%G%qD accessing %wu or more bytes at offsets %s "
1577 "and %s may overlap %wu byte at offset %s",
1578 "%G%qD accessing %wu or more bytes at offsets %s "
1579 "and %s may overlap up to %wu bytes at offset %s",
1580 call, func, sizrange[0], offstr[0], offstr[1],
1581 ovlsiz[1], offstr[2]);
1583 return true;
1586 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1587 to a built-in function FUNC to make sure they are within the bounds
1588 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1589 Both initial values of the offsets and their final value computed by
1590 the function by incrementing the initial value by the size are
1591 validated. Return true if the offsets are not valid and a diagnostic
1592 has been issued. */
1594 static bool
1595 maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
1596 tree expr, const builtin_memref &ref)
1598 if (!warn_array_bounds)
1599 return false;
1601 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1] };
1602 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1603 if (!oobref)
1604 return false;
1606 if (EXPR_HAS_LOCATION (expr))
1607 loc = EXPR_LOCATION (expr);
1609 loc = expansion_point_location_if_in_system_header (loc);
1611 tree type;
1613 char rangestr[2][64];
1614 if (ooboff[0] == ooboff[1]
1615 || (ooboff[0] != ref.offrange[0]
1616 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1617 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1618 else
1619 sprintf (rangestr[0], "[%lli, %lli]",
1620 (long long) ooboff[0].to_shwi (),
1621 (long long) ooboff[1].to_shwi ());
1623 if (oobref == error_mark_node)
1625 if (ref.sizrange[0] == ref.sizrange[1])
1626 sprintf (rangestr[1], "%lli", (long long) ref.sizrange[0].to_shwi ());
1627 else
1628 sprintf (rangestr[1], "[%lli, %lli]",
1629 (long long) ref.sizrange[0].to_shwi (),
1630 (long long) ref.sizrange[1].to_shwi ());
1632 if (DECL_P (ref.base)
1633 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1635 if (warning_at (loc, OPT_Warray_bounds,
1636 "%G%qD pointer overflow between offset %s "
1637 "and size %s accessing array %qD with type %qT",
1638 call, func, rangestr[0], rangestr[1], ref.base, type))
1639 inform (DECL_SOURCE_LOCATION (ref.base),
1640 "array %qD declared here", ref.base);
1641 else
1642 warning_at (loc, OPT_Warray_bounds,
1643 "%G%qD pointer overflow between offset %s "
1644 "and size %s",
1645 call, func, rangestr[0], rangestr[1]);
1647 else
1648 warning_at (loc, OPT_Warray_bounds,
1649 "%G%qD pointer overflow between offset %s "
1650 "and size %s",
1651 call, func, rangestr[0], rangestr[1]);
1653 else if (oobref == ref.base)
1655 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1657 /* True when the offset formed by an access to the reference
1658 is out of bounds, rather than the initial offset wich is
1659 in bounds. This implies access past the end. */
1660 bool form = ooboff[0] != ref.offrange[0];
1662 if (DECL_P (ref.base))
1664 if ((ref.basesize < maxobjsize
1665 && warning_at (loc, OPT_Warray_bounds,
1666 form
1667 ? G_("%G%qD forming offset %s is out of "
1668 "the bounds [0, %wu] of object %qD with "
1669 "type %qT")
1670 : G_("%G%qD offset %s is out of the bounds "
1671 "[0, %wu] of object %qD with type %qT"),
1672 call, func, rangestr[0], ref.basesize.to_uhwi (),
1673 ref.base, TREE_TYPE (ref.base)))
1674 || warning_at (loc, OPT_Warray_bounds,
1675 form
1676 ? G_("%G%qD forming offset %s is out of "
1677 "the bounds of object %qD with type %qT")
1678 : G_("%G%qD offset %s is out of the bounds "
1679 "of object %qD with type %qT"),
1680 call, func, rangestr[0],
1681 ref.base, TREE_TYPE (ref.base)))
1682 inform (DECL_SOURCE_LOCATION (ref.base),
1683 "%qD declared here", ref.base);
1685 else if (ref.basesize < maxobjsize)
1686 warning_at (loc, OPT_Warray_bounds,
1687 form
1688 ? G_("%G%qD forming offset %s is out of the bounds "
1689 "[0, %wu]")
1690 : G_("%G%qD offset %s is out of the bounds [0, %wu]"),
1691 call, func, rangestr[0], ref.basesize.to_uhwi ());
1692 else
1693 warning_at (loc, OPT_Warray_bounds,
1694 form
1695 ? G_("%G%qD forming offset %s is out of bounds")
1696 : G_("%G%qD offset %s is out of bounds"),
1697 call, func, rangestr[0]);
1699 else if (TREE_CODE (ref.ref) == MEM_REF)
1701 tree type = TREE_TYPE (TREE_OPERAND (ref.ref, 0));
1702 if (POINTER_TYPE_P (type))
1703 type = TREE_TYPE (type);
1704 type = TYPE_MAIN_VARIANT (type);
1706 warning_at (loc, OPT_Warray_bounds,
1707 "%G%qD offset %s from the object at %qE is out "
1708 "of the bounds of %qT",
1709 call, func, rangestr[0], ref.base, type);
1711 else
1713 type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1715 warning_at (loc, OPT_Warray_bounds,
1716 "%G%qD offset %s from the object at %qE is out "
1717 "of the bounds of referenced subobject %qD with type %qT "
1718 "at offset %wu",
1719 call, func, rangestr[0], ref.base, TREE_OPERAND (ref.ref, 1),
1720 type, ref.refoff.to_uhwi ());
1723 return true;
1726 /* Check a CALL statement for restrict-violations and issue warnings
1727 if/when appropriate. */
1729 void
1730 wrestrict_dom_walker::check_call (gcall *call)
1732 /* Avoid checking the call if it has already been diagnosed for
1733 some reason. */
1734 if (gimple_no_warning_p (call))
1735 return;
1737 tree func = gimple_call_fndecl (call);
1738 if (!func || DECL_BUILT_IN_CLASS (func) != BUILT_IN_NORMAL)
1739 return;
1741 bool with_bounds = gimple_call_with_bounds_p (call);
1743 /* Argument number to extract from the call (depends on the built-in
1744 and its kind). */
1745 unsigned dst_idx = -1;
1746 unsigned src_idx = -1;
1747 unsigned bnd_idx = -1;
1749 /* Is this CALL to a string function (as opposed to one to a raw
1750 memory function). */
1751 bool strfun = true;
1753 switch (DECL_FUNCTION_CODE (func))
1755 case BUILT_IN_MEMCPY:
1756 case BUILT_IN_MEMCPY_CHK:
1757 case BUILT_IN_MEMCPY_CHKP:
1758 case BUILT_IN_MEMCPY_CHK_CHKP:
1759 case BUILT_IN_MEMPCPY:
1760 case BUILT_IN_MEMPCPY_CHK:
1761 case BUILT_IN_MEMPCPY_CHKP:
1762 case BUILT_IN_MEMPCPY_CHK_CHKP:
1763 case BUILT_IN_MEMMOVE:
1764 case BUILT_IN_MEMMOVE_CHK:
1765 case BUILT_IN_MEMMOVE_CHKP:
1766 case BUILT_IN_MEMMOVE_CHK_CHKP:
1767 strfun = false;
1768 /* Fall through. */
1770 case BUILT_IN_STPNCPY:
1771 case BUILT_IN_STPNCPY_CHK:
1772 case BUILT_IN_STRNCAT:
1773 case BUILT_IN_STRNCAT_CHK:
1774 case BUILT_IN_STRNCPY:
1775 case BUILT_IN_STRNCPY_CHK:
1776 dst_idx = 0;
1777 src_idx = 1 + with_bounds;
1778 bnd_idx = 2 + 2 * with_bounds;
1779 break;
1781 case BUILT_IN_STPCPY:
1782 case BUILT_IN_STPCPY_CHK:
1783 case BUILT_IN_STPCPY_CHKP:
1784 case BUILT_IN_STPCPY_CHK_CHKP:
1785 case BUILT_IN_STRCPY:
1786 case BUILT_IN_STRCPY_CHK:
1787 case BUILT_IN_STRCPY_CHKP:
1788 case BUILT_IN_STRCPY_CHK_CHKP:
1789 case BUILT_IN_STRCAT:
1790 case BUILT_IN_STRCAT_CHK:
1791 case BUILT_IN_STRCAT_CHKP:
1792 case BUILT_IN_STRCAT_CHK_CHKP:
1793 dst_idx = 0;
1794 src_idx = 1 + with_bounds;
1795 break;
1797 default:
1798 /* Handle other string functions here whose access may need
1799 to be validated for in-bounds offsets and non-overlapping
1800 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
1801 macros so they need to be handled here.) */
1802 return;
1805 unsigned nargs = gimple_call_num_args (call);
1807 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1808 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1809 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1811 /* For string functions with an unspecified or unknown bound,
1812 assume the size of the access is one. */
1813 if (!dstwr && strfun)
1814 dstwr = size_one_node;
1816 /* DST and SRC can be null for a call with an insufficient number
1817 of arguments to a built-in function declared without a protype. */
1818 if (!dst || !src)
1819 return;
1821 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1822 a function declared without a prototype. Avoid checking such
1823 invalid calls. */
1824 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1825 || TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
1826 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1827 return;
1829 if (check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
1830 return;
1832 /* Avoid diagnosing the call again. */
1833 gimple_set_no_warning (call, true);
1836 } /* anonymous namespace */
1838 /* Attempt to detect and diagnose invalid offset bounds and (except for
1839 memmove) overlapping copy in a call expression EXPR from SRC to DST
1840 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1841 SRCSIZE may be NULL. Return false when one or the other has been
1842 detected and diagnosed, true otherwise. */
1844 bool
1845 check_bounds_or_overlap (gcall *call, tree dst, tree src, tree dstsize,
1846 tree srcsize, bool bounds_only /* = false */)
1848 location_t loc = gimple_location (call);
1850 if (tree block = gimple_block (call))
1851 if (location_t *pbloc = block_nonartificial_location (block))
1852 loc = *pbloc;
1854 loc = expansion_point_location_if_in_system_header (loc);
1856 tree func = gimple_call_fndecl (call);
1858 builtin_memref dstref (dst, dstsize);
1859 builtin_memref srcref (src, srcsize);
1861 builtin_access acs (call, dstref, srcref);
1863 /* Set STRICT to the value of the -Warray-bounds=N argument for
1864 string functions or when N > 1. */
1865 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
1867 /* Validate offsets first to make sure they are within the bounds
1868 of the destination object if its size is known, or PTRDIFF_MAX
1869 otherwise. */
1870 if (maybe_diag_offset_bounds (loc, call, func, strict, dst, dstref)
1871 || maybe_diag_offset_bounds (loc, call, func, strict, src, srcref))
1873 gimple_set_no_warning (call, true);
1874 return false;
1877 bool check_overlap
1878 = (warn_restrict
1879 && (bounds_only
1880 || (DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE
1881 && DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE_CHK)));
1883 if (!check_overlap)
1884 return true;
1886 if (operand_equal_p (dst, src, 0))
1888 /* Issue -Wrestrict unless the pointers are null (those do
1889 not point to objects and so do not indicate an overlap;
1890 such calls could be the result of sanitization and jump
1891 threading). */
1892 if (!integer_zerop (dst) && !gimple_no_warning_p (call))
1894 warning_at (loc, OPT_Wrestrict,
1895 "%G%qD source argument is the same as destination",
1896 call, func);
1897 gimple_set_no_warning (call, true);
1898 return false;
1901 return true;
1904 /* Return false when overlap has been detected. */
1905 if (maybe_diag_overlap (loc, call, acs))
1907 gimple_set_no_warning (call, true);
1908 return false;
1911 return true;
1914 gimple_opt_pass *
1915 make_pass_warn_restrict (gcc::context *ctxt)
1917 return new pass_wrestrict (ctxt);