PR middle-end/84095 - false-positive -Wrestrict warnings for memcpy within array
[official-gcc.git] / gcc / gimple-ssa-warn-restrict.c
blob9d5c6e043701cbee9eb0aa7f32658f82f6438326
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_at (loc, OPT_Wrestrict,
1403 sizrange[0] == 1
1404 ? G_("%G%qD accessing %wu byte at offsets %s "
1405 "and %s overlaps between %wu and %wu bytes "
1406 "at offset %s")
1407 : G_("%G%qD accessing %wu bytes at offsets %s "
1408 "and %s overlaps between %wu and %wu bytes "
1409 "at offset %s"),
1410 call, func, sizrange[0],
1411 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1412 offstr[2]);
1413 else
1414 warning_at (loc, OPT_Wrestrict,
1415 sizrange[0] == 1
1416 ? G_("%G%qD accessing %wu byte at offsets %s and "
1417 "%s overlaps %wu or more bytes at offset %s")
1418 : G_("%G%qD accessing %wu bytes at offsets %s and "
1419 "%s overlaps %wu or more bytes at offset %s"),
1420 call, func, sizrange[0],
1421 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1422 return true;
1425 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1427 if (ovlsiz[0] == ovlsiz[1])
1428 warning_at (loc, OPT_Wrestrict,
1429 ovlsiz[0] == 1
1430 ? G_("%G%qD accessing between %wu and %wu bytes "
1431 "at offsets %s and %s overlaps %wu byte at "
1432 "offset %s")
1433 : G_("%G%qD accessing between %wu and %wu bytes "
1434 "at offsets %s and %s overlaps %wu bytes "
1435 "at offset %s"),
1436 call, func, sizrange[0], sizrange[1],
1437 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1438 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1439 warning_at (loc, OPT_Wrestrict,
1440 "%G%qD accessing between %wu and %wu bytes at "
1441 "offsets %s and %s overlaps between %wu and %wu "
1442 "bytes at offset %s",
1443 call, func, sizrange[0], sizrange[1],
1444 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1445 offstr[2]);
1446 else
1447 warning_at (loc, OPT_Wrestrict,
1448 "%G%qD accessing between %wu and %wu bytes at "
1449 "offsets %s and %s overlaps %wu or more bytes "
1450 "at offset %s",
1451 call, func, sizrange[0], sizrange[1],
1452 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1453 return true;
1456 if (ovlsiz[0] != ovlsiz[1])
1457 ovlsiz[1] = maxobjsize.to_shwi ();
1459 if (ovlsiz[0] == ovlsiz[1])
1460 warning_at (loc, OPT_Wrestrict,
1461 ovlsiz[0] == 1
1462 ? G_("%G%qD accessing %wu or more bytes at offsets "
1463 "%s and %s overlaps %wu byte at offset %s")
1464 : G_("%G%qD accessing %wu or more bytes at offsets "
1465 "%s and %s overlaps %wu bytes at offset %s"),
1466 call, func, sizrange[0], offstr[0], offstr[1],
1467 ovlsiz[0], offstr[2]);
1468 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1469 warning_at (loc, OPT_Wrestrict,
1470 "%G%qD accessing %wu or more bytes at offsets %s "
1471 "and %s overlaps between %wu and %wu bytes "
1472 "at offset %s",
1473 call, func, sizrange[0], offstr[0], offstr[1],
1474 ovlsiz[0], ovlsiz[1], offstr[2]);
1475 else
1476 warning_at (loc, OPT_Wrestrict,
1477 "%G%qD accessing %wu or more bytes at offsets %s "
1478 "and %s overlaps %wu or more bytes at offset %s",
1479 call, func, sizrange[0], offstr[0], offstr[1],
1480 ovlsiz[0], offstr[2]);
1481 return true;
1484 /* Use more concise wording when one of the offsets is unbounded
1485 to avoid confusing the user with large and mostly meaningless
1486 numbers. */
1487 bool open_range;
1488 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1489 open_range = ((dstref.offrange[0] == 0
1490 && dstref.offrange[1] == maxobjsize)
1491 || (srcref.offrange[0] == 0
1492 && srcref.offrange[1] == maxobjsize));
1493 else
1494 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1495 && dstref.offrange[1] == maxobjsize)
1496 || (srcref.offrange[0] == -maxobjsize - 1
1497 && srcref.offrange[1] == maxobjsize));
1499 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1501 if (ovlsiz[1] == 1)
1503 if (open_range)
1504 warning_at (loc, OPT_Wrestrict,
1505 sizrange[1] == 1
1506 ? G_("%G%qD accessing %wu byte may overlap "
1507 "%wu byte")
1508 : G_("%G%qD accessing %wu bytes may overlap "
1509 "%wu byte"),
1510 call, func, sizrange[1], ovlsiz[1]);
1511 else
1512 warning_at (loc, OPT_Wrestrict,
1513 sizrange[1] == 1
1514 ? G_("%G%qD accessing %wu byte at offsets %s "
1515 "and %s may overlap %wu byte at offset %s")
1516 : G_("%G%qD accessing %wu bytes at offsets %s "
1517 "and %s may overlap %wu byte at offset %s"),
1518 call, func, sizrange[1], offstr[0], offstr[1],
1519 ovlsiz[1], offstr[2]);
1520 return true;
1523 if (open_range)
1524 warning_at (loc, OPT_Wrestrict,
1525 sizrange[1] == 1
1526 ? G_("%G%qD accessing %wu byte may overlap "
1527 "up to %wu bytes")
1528 : G_("%G%qD accessing %wu bytes may overlap "
1529 "up to %wu bytes"),
1530 call, func, sizrange[1], ovlsiz[1]);
1531 else
1532 warning_at (loc, OPT_Wrestrict,
1533 sizrange[1] == 1
1534 ? G_("%G%qD accessing %wu byte at offsets %s and "
1535 "%s may overlap up to %wu bytes at offset %s")
1536 : G_("%G%qD accessing %wu bytes at offsets %s and "
1537 "%s may overlap up to %wu bytes at offset %s"),
1538 call, func, sizrange[1], offstr[0], offstr[1],
1539 ovlsiz[1], offstr[2]);
1540 return true;
1543 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1545 if (open_range)
1546 warning_at (loc, OPT_Wrestrict,
1547 ovlsiz[1] == 1
1548 ? G_("%G%qD accessing between %wu and %wu bytes "
1549 "may overlap %wu byte")
1550 : G_("%G%qD accessing between %wu and %wu bytes "
1551 "may overlap up to %wu bytes"),
1552 call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1553 else
1554 warning_at (loc, OPT_Wrestrict,
1555 ovlsiz[1] == 1
1556 ? G_("%G%qD accessing between %wu and %wu bytes "
1557 "at offsets %s and %s may overlap %wu byte "
1558 "at offset %s")
1559 : G_("%G%qD accessing between %wu and %wu bytes "
1560 "at offsets %s and %s may overlap up to %wu "
1561 "bytes at offset %s"),
1562 call, func, sizrange[0], sizrange[1],
1563 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1564 return true;
1567 warning_at (loc, OPT_Wrestrict,
1568 ovlsiz[1] == 1
1569 ? G_("%G%qD accessing %wu or more bytes at offsets %s "
1570 "and %s may overlap %wu byte at offset %s")
1571 : G_("%G%qD accessing %wu or more bytes at offsets %s "
1572 "and %s may overlap up to %wu bytes at offset %s"),
1573 call, func, sizrange[0], offstr[0], offstr[1],
1574 ovlsiz[1], offstr[2]);
1576 return true;
1579 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1580 to a built-in function FUNC to make sure they are within the bounds
1581 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1582 Both initial values of the offsets and their final value computed by
1583 the function by incrementing the initial value by the size are
1584 validated. Return true if the offsets are not valid and a diagnostic
1585 has been issued. */
1587 static bool
1588 maybe_diag_offset_bounds (location_t loc, gcall *call, tree func, int strict,
1589 tree expr, const builtin_memref &ref)
1591 if (!warn_array_bounds)
1592 return false;
1594 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1] };
1595 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1596 if (!oobref)
1597 return false;
1599 if (EXPR_HAS_LOCATION (expr))
1600 loc = EXPR_LOCATION (expr);
1602 loc = expansion_point_location_if_in_system_header (loc);
1604 tree type;
1606 char rangestr[2][64];
1607 if (ooboff[0] == ooboff[1]
1608 || (ooboff[0] != ref.offrange[0]
1609 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1610 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1611 else
1612 sprintf (rangestr[0], "[%lli, %lli]",
1613 (long long) ooboff[0].to_shwi (),
1614 (long long) ooboff[1].to_shwi ());
1616 if (oobref == error_mark_node)
1618 if (ref.sizrange[0] == ref.sizrange[1])
1619 sprintf (rangestr[1], "%lli", (long long) ref.sizrange[0].to_shwi ());
1620 else
1621 sprintf (rangestr[1], "[%lli, %lli]",
1622 (long long) ref.sizrange[0].to_shwi (),
1623 (long long) ref.sizrange[1].to_shwi ());
1625 if (DECL_P (ref.base)
1626 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1628 if (warning_at (loc, OPT_Warray_bounds,
1629 "%G%qD pointer overflow between offset %s "
1630 "and size %s accessing array %qD with type %qT",
1631 call, func, rangestr[0], rangestr[1], ref.base, type))
1632 inform (DECL_SOURCE_LOCATION (ref.base),
1633 "array %qD declared here", ref.base);
1634 else
1635 warning_at (loc, OPT_Warray_bounds,
1636 "%G%qD pointer overflow between offset %s "
1637 "and size %s",
1638 call, func, rangestr[0], rangestr[1]);
1640 else
1641 warning_at (loc, OPT_Warray_bounds,
1642 "%G%qD pointer overflow between offset %s "
1643 "and size %s",
1644 call, func, rangestr[0], rangestr[1]);
1646 else if (oobref == ref.base)
1648 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1650 /* True when the offset formed by an access to the reference
1651 is out of bounds, rather than the initial offset wich is
1652 in bounds. This implies access past the end. */
1653 bool form = ooboff[0] != ref.offrange[0];
1655 if (DECL_P (ref.base))
1657 if ((ref.basesize < maxobjsize
1658 && warning_at (loc, OPT_Warray_bounds,
1659 form
1660 ? G_("%G%qD forming offset %s is out of "
1661 "the bounds [0, %wu] of object %qD with "
1662 "type %qT")
1663 : G_("%G%qD offset %s is out of the bounds "
1664 "[0, %wu] of object %qD with type %qT"),
1665 call, func, rangestr[0], ref.basesize.to_uhwi (),
1666 ref.base, TREE_TYPE (ref.base)))
1667 || warning_at (loc, OPT_Warray_bounds,
1668 form
1669 ? G_("%G%qD forming offset %s is out of "
1670 "the bounds of object %qD with type %qT")
1671 : G_("%G%qD offset %s is out of the bounds "
1672 "of object %qD with type %qT"),
1673 call, func, rangestr[0],
1674 ref.base, TREE_TYPE (ref.base)))
1675 inform (DECL_SOURCE_LOCATION (ref.base),
1676 "%qD declared here", ref.base);
1678 else if (ref.basesize < maxobjsize)
1679 warning_at (loc, OPT_Warray_bounds,
1680 form
1681 ? G_("%G%qD forming offset %s is out of the bounds "
1682 "[0, %wu]")
1683 : G_("%G%qD offset %s is out of the bounds [0, %wu]"),
1684 call, func, rangestr[0], ref.basesize.to_uhwi ());
1685 else
1686 warning_at (loc, OPT_Warray_bounds,
1687 form
1688 ? G_("%G%qD forming offset %s is out of bounds")
1689 : G_("%G%qD offset %s is out of bounds"),
1690 call, func, rangestr[0]);
1692 else if (TREE_CODE (ref.ref) == MEM_REF)
1694 tree type = TREE_TYPE (TREE_OPERAND (ref.ref, 0));
1695 if (POINTER_TYPE_P (type))
1696 type = TREE_TYPE (type);
1697 type = TYPE_MAIN_VARIANT (type);
1699 warning_at (loc, OPT_Warray_bounds,
1700 "%G%qD offset %s from the object at %qE is out "
1701 "of the bounds of %qT",
1702 call, func, rangestr[0], ref.base, type);
1704 else
1706 type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1708 warning_at (loc, OPT_Warray_bounds,
1709 "%G%qD offset %s from the object at %qE is out "
1710 "of the bounds of referenced subobject %qD with type %qT "
1711 "at offset %wu",
1712 call, func, rangestr[0], ref.base, TREE_OPERAND (ref.ref, 1),
1713 type, ref.refoff.to_uhwi ());
1716 return true;
1719 /* Check a CALL statement for restrict-violations and issue warnings
1720 if/when appropriate. */
1722 void
1723 wrestrict_dom_walker::check_call (gcall *call)
1725 /* Avoid checking the call if it has already been diagnosed for
1726 some reason. */
1727 if (gimple_no_warning_p (call))
1728 return;
1730 tree func = gimple_call_fndecl (call);
1731 if (!func || DECL_BUILT_IN_CLASS (func) != BUILT_IN_NORMAL)
1732 return;
1734 bool with_bounds = gimple_call_with_bounds_p (call);
1736 /* Argument number to extract from the call (depends on the built-in
1737 and its kind). */
1738 unsigned dst_idx = -1;
1739 unsigned src_idx = -1;
1740 unsigned bnd_idx = -1;
1742 /* Is this CALL to a string function (as opposed to one to a raw
1743 memory function). */
1744 bool strfun = true;
1746 switch (DECL_FUNCTION_CODE (func))
1748 case BUILT_IN_MEMCPY:
1749 case BUILT_IN_MEMCPY_CHK:
1750 case BUILT_IN_MEMCPY_CHKP:
1751 case BUILT_IN_MEMCPY_CHK_CHKP:
1752 case BUILT_IN_MEMPCPY:
1753 case BUILT_IN_MEMPCPY_CHK:
1754 case BUILT_IN_MEMPCPY_CHKP:
1755 case BUILT_IN_MEMPCPY_CHK_CHKP:
1756 case BUILT_IN_MEMMOVE:
1757 case BUILT_IN_MEMMOVE_CHK:
1758 case BUILT_IN_MEMMOVE_CHKP:
1759 case BUILT_IN_MEMMOVE_CHK_CHKP:
1760 strfun = false;
1761 /* Fall through. */
1763 case BUILT_IN_STPNCPY:
1764 case BUILT_IN_STPNCPY_CHK:
1765 case BUILT_IN_STRNCAT:
1766 case BUILT_IN_STRNCAT_CHK:
1767 case BUILT_IN_STRNCPY:
1768 case BUILT_IN_STRNCPY_CHK:
1769 dst_idx = 0;
1770 src_idx = 1 + with_bounds;
1771 bnd_idx = 2 + 2 * with_bounds;
1772 break;
1774 case BUILT_IN_STPCPY:
1775 case BUILT_IN_STPCPY_CHK:
1776 case BUILT_IN_STPCPY_CHKP:
1777 case BUILT_IN_STPCPY_CHK_CHKP:
1778 case BUILT_IN_STRCPY:
1779 case BUILT_IN_STRCPY_CHK:
1780 case BUILT_IN_STRCPY_CHKP:
1781 case BUILT_IN_STRCPY_CHK_CHKP:
1782 case BUILT_IN_STRCAT:
1783 case BUILT_IN_STRCAT_CHK:
1784 case BUILT_IN_STRCAT_CHKP:
1785 case BUILT_IN_STRCAT_CHK_CHKP:
1786 dst_idx = 0;
1787 src_idx = 1 + with_bounds;
1788 break;
1790 default:
1791 /* Handle other string functions here whose access may need
1792 to be validated for in-bounds offsets and non-overlapping
1793 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
1794 macros so they need to be handled here.) */
1795 return;
1798 unsigned nargs = gimple_call_num_args (call);
1800 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1801 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1802 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1804 /* For string functions with an unspecified or unknown bound,
1805 assume the size of the access is one. */
1806 if (!dstwr && strfun)
1807 dstwr = size_one_node;
1809 /* DST and SRC can be null for a call with an insufficient number
1810 of arguments to a built-in function declared without a protype. */
1811 if (!dst || !src)
1812 return;
1814 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1815 a function declared without a prototype. Avoid checking such
1816 invalid calls. */
1817 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1818 || TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
1819 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1820 return;
1822 if (check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
1823 return;
1825 /* Avoid diagnosing the call again. */
1826 gimple_set_no_warning (call, true);
1829 } /* anonymous namespace */
1831 /* Attempt to detect and diagnose invalid offset bounds and (except for
1832 memmove) overlapping copy in a call expression EXPR from SRC to DST
1833 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1834 SRCSIZE may be NULL. Return false when one or the other has been
1835 detected and diagnosed, true otherwise. */
1837 bool
1838 check_bounds_or_overlap (gcall *call, tree dst, tree src, tree dstsize,
1839 tree srcsize, bool bounds_only /* = false */)
1841 location_t loc = gimple_location (call);
1843 if (tree block = gimple_block (call))
1844 if (location_t *pbloc = block_nonartificial_location (block))
1845 loc = *pbloc;
1847 loc = expansion_point_location_if_in_system_header (loc);
1849 tree func = gimple_call_fndecl (call);
1851 builtin_memref dstref (dst, dstsize);
1852 builtin_memref srcref (src, srcsize);
1854 builtin_access acs (call, dstref, srcref);
1856 /* Set STRICT to the value of the -Warray-bounds=N argument for
1857 string functions or when N > 1. */
1858 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
1860 /* Validate offsets first to make sure they are within the bounds
1861 of the destination object if its size is known, or PTRDIFF_MAX
1862 otherwise. */
1863 if (maybe_diag_offset_bounds (loc, call, func, strict, dst, dstref)
1864 || maybe_diag_offset_bounds (loc, call, func, strict, src, srcref))
1866 gimple_set_no_warning (call, true);
1867 return false;
1870 bool check_overlap
1871 = (warn_restrict
1872 && (bounds_only
1873 || (DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE
1874 && DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE_CHK)));
1876 if (!check_overlap)
1877 return true;
1879 if (operand_equal_p (dst, src, 0))
1881 warning_at (loc, OPT_Wrestrict,
1882 "%G%qD source argument is the same as destination",
1883 call, func);
1884 gimple_set_no_warning (call, true);
1885 return false;
1888 /* Return false when overlap has been detected. */
1889 if (maybe_diag_overlap (loc, call, acs))
1891 gimple_set_no_warning (call, true);
1892 return false;
1895 return true;
1898 gimple_opt_pass *
1899 make_pass_warn_restrict (gcc::context *ctxt)
1901 return new pass_wrestrict (ctxt);