Remove nfs bogon
[official-gcc.git] / gcc / gimple-ssa-warn-restrict.c
blob01503d6091247a888ce692588051496f83a422f0
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 (gimple *);
94 edge
95 wrestrict_dom_walker::before_dom_children (basic_block bb)
97 /* Iterate over statements, looking for function calls. */
98 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
99 gsi_next (&si))
101 gimple *stmt = gsi_stmt (si);
102 if (!is_gimple_call (stmt))
103 continue;
105 check_call (stmt);
108 return NULL;
111 /* Execute the pass for function FUN, walking in dominator order. */
113 unsigned
114 pass_wrestrict::execute (function *fun)
116 calculate_dominance_info (CDI_DOMINATORS);
118 wrestrict_dom_walker walker;
119 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
121 return 0;
124 /* Description of a memory reference by a built-in function. This
125 is similar to ao_ref but made especially suitable for -Wrestrict
126 and not for optimization. */
127 struct builtin_memref
129 /* The original pointer argument to the built-in function. */
130 tree ptr;
131 /* The referenced subobject or NULL if not available, and the base
132 object of the memory reference or NULL. */
133 tree ref;
134 tree base;
136 /* The size of the BASE object, PTRDIFF_MAX if indeterminate,
137 and negative until (possibly lazily) initialized. */
138 offset_int basesize;
140 /* The non-negative offset of the referenced subobject. Used to avoid
141 warnings for (apparently) possibly but not definitively overlapping
142 accesses to member arrays. Negative when unknown/invalid. */
143 offset_int refoff;
145 /* The offset range relative to the base. */
146 offset_int offrange[2];
147 /* The size range of the access to this reference. */
148 offset_int sizrange[2];
150 /* True for "bounded" string functions like strncat, and strncpy
151 and their variants that specify either an exact or upper bound
152 on the size of the accesses they perform. For strncat both
153 the source and destination references are bounded. For strncpy
154 only the destination reference is. */
155 bool strbounded_p;
157 builtin_memref (tree, tree);
159 tree offset_out_of_bounds (int, offset_int[2]) const;
161 private:
163 /* Ctor helper to set or extend OFFRANGE based on argument. */
164 void extend_offset_range (tree);
166 /* Ctor helper to determine BASE and OFFRANGE from argument. */
167 void set_base_and_offset (tree);
170 /* Description of a memory access by a raw memory or string built-in
171 function involving a pair of builtin_memref's. */
172 class builtin_access
174 public:
175 /* Destination and source memory reference. */
176 builtin_memref* const dstref;
177 builtin_memref* const srcref;
178 /* The size range of the access. It's the greater of the accesses
179 to the two references. */
180 HOST_WIDE_INT sizrange[2];
182 /* The minimum and maximum offset of an overlap of the access
183 (if it does, in fact, overlap), and the size of the overlap. */
184 HOST_WIDE_INT ovloff[2];
185 HOST_WIDE_INT ovlsiz[2];
187 /* True to consider valid only accesses to the smallest subobject
188 and false for raw memory functions. */
189 bool strict () const
191 return detect_overlap != &builtin_access::generic_overlap;
194 builtin_access (gimple *, builtin_memref &, builtin_memref &);
196 /* Entry point to determine overlap. */
197 bool overlap ();
199 private:
200 /* Implementation functions used to determine overlap. */
201 bool generic_overlap ();
202 bool strcat_overlap ();
203 bool strcpy_overlap ();
205 bool no_overlap ()
207 return false;
210 offset_int overlap_size (const offset_int [2], const offset_int[2],
211 offset_int [2]);
213 private:
214 /* Temporaries used to compute the final result. */
215 offset_int dstoff[2];
216 offset_int srcoff[2];
217 offset_int dstsiz[2];
218 offset_int srcsiz[2];
220 /* Pointer to a member function to call to determine overlap. */
221 bool (builtin_access::*detect_overlap) ();
224 /* Initialize a memory reference representation from a pointer EXPR and
225 a size SIZE in bytes. If SIZE is NULL_TREE then the size is assumed
226 to be unknown. */
228 builtin_memref::builtin_memref (tree expr, tree size)
229 : ptr (expr),
230 ref (),
231 base (),
232 basesize (-1),
233 refoff (HOST_WIDE_INT_MIN),
234 offrange (),
235 sizrange (),
236 strbounded_p ()
238 /* Unfortunately, wide_int default ctor is a no-op so array members
239 of the type must be set individually. */
240 offrange[0] = offrange[1] = 0;
241 sizrange[0] = sizrange[1] = 0;
243 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
245 /* Find the BASE object or pointer referenced by EXPR and set
246 the offset range OFFRANGE in the process. */
247 set_base_and_offset (expr);
249 if (size)
251 tree range[2];
252 /* Determine the size range, allowing for the result to be [0, 0]
253 for SIZE in the anti-range ~[0, N] where N >= PTRDIFF_MAX. */
254 get_size_range (size, range, true);
255 sizrange[0] = wi::to_offset (range[0]);
256 sizrange[1] = wi::to_offset (range[1]);
257 /* get_size_range returns SIZE_MAX for the maximum size.
258 Constrain it to the real maximum of PTRDIFF_MAX. */
259 if (sizrange[1] > maxobjsize)
260 sizrange[1] = maxobjsize;
262 else
263 sizrange[1] = maxobjsize;
265 if (!DECL_P (base))
266 return;
268 /* If the offset could be in the range of the referenced object
269 constrain its bounds so neither exceeds those of the object. */
270 if (offrange[0] < 0 && offrange[1] > 0)
271 offrange[0] = 0;
273 offset_int maxoff = maxobjsize;
274 tree basetype = TREE_TYPE (base);
275 if (TREE_CODE (basetype) == ARRAY_TYPE
276 && ref
277 && array_at_struct_end_p (ref))
278 ; /* Use the maximum possible offset for last member arrays. */
279 else if (tree basesize = TYPE_SIZE_UNIT (basetype))
280 if (TREE_CODE (basesize) == INTEGER_CST)
281 /* Size could be non-constant for a variable-length type such
282 as a struct with a VLA member (a GCC extension). */
283 maxoff = wi::to_offset (basesize);
285 if (offrange[0] >= 0)
287 if (offrange[1] < 0)
288 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
289 else if (offrange[0] <= maxoff && offrange[1] > maxoff)
290 offrange[1] = maxoff;
294 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. */
296 void
297 builtin_memref::extend_offset_range (tree offset)
299 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
301 if (TREE_CODE (offset) == INTEGER_CST)
303 offset_int off = int_cst_value (offset);
304 if (off != 0)
306 offrange[0] += off;
307 offrange[1] += off;
309 return;
312 if (TREE_CODE (offset) == SSA_NAME)
314 wide_int min, max;
315 value_range_type rng = get_range_info (offset, &min, &max);
316 if (rng == VR_RANGE)
318 offrange[0] += offset_int::from (min, SIGNED);
319 offrange[1] += offset_int::from (max, SIGNED);
321 else if (rng == VR_ANTI_RANGE)
323 offrange[0] += offset_int::from (max + 1, SIGNED);
324 offrange[1] += offset_int::from (min - 1, SIGNED);
326 else
328 gimple *stmt = SSA_NAME_DEF_STMT (offset);
329 tree type;
330 if (is_gimple_assign (stmt)
331 && gimple_assign_rhs_code (stmt) == NOP_EXPR
332 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
333 && INTEGRAL_TYPE_P (type))
335 /* Use the bounds of the type of the NOP_EXPR operand
336 even if it's signed. The result doesn't trigger
337 warnings but makes their output more readable. */
338 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
339 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
341 else
342 offrange[1] += maxobjsize;
344 return;
347 offrange[1] += maxobjsize;
350 /* Determines the base object or pointer of the reference EXPR
351 and the offset range from the beginning of the base. */
353 void
354 builtin_memref::set_base_and_offset (tree expr)
356 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
358 if (TREE_CODE (expr) == SSA_NAME)
360 /* Try to tease the offset out of the pointer. */
361 gimple *stmt = SSA_NAME_DEF_STMT (expr);
362 if (!base
363 && gimple_assign_single_p (stmt)
364 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
365 expr = gimple_assign_rhs1 (stmt);
366 else if (is_gimple_assign (stmt))
368 tree_code code = gimple_assign_rhs_code (stmt);
369 if (code == NOP_EXPR)
371 tree rhs = gimple_assign_rhs1 (stmt);
372 if (POINTER_TYPE_P (TREE_TYPE (rhs)))
373 expr = gimple_assign_rhs1 (stmt);
374 else
376 base = expr;
377 return;
380 else if (code == POINTER_PLUS_EXPR)
382 expr = gimple_assign_rhs1 (stmt);
384 tree offset = gimple_assign_rhs2 (stmt);
385 extend_offset_range (offset);
387 else
389 base = expr;
390 return;
393 else
395 base = expr;
396 return;
400 if (TREE_CODE (expr) == ADDR_EXPR)
401 expr = TREE_OPERAND (expr, 0);
403 /* Stash the reference for offset validation. */
404 ref = expr;
406 poly_int64 bitsize, bitpos;
407 tree var_off;
408 machine_mode mode;
409 int sign, reverse, vol;
411 /* Determine the base object or pointer of the reference and
412 the constant bit offset from the beginning of the base.
413 If the offset has a non-constant component, it will be in
414 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
415 unused here. */
416 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
417 &mode, &sign, &reverse, &vol);
419 /* get_inner_reference is not expected to return null. */
420 gcc_assert (base != NULL);
422 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
424 /* Convert the poly_int64 offset to offset_int. The offset
425 should be constant but be prepared for it not to be just in
426 case. */
427 offset_int cstoff;
428 if (bytepos.is_constant (&cstoff))
430 offrange[0] += cstoff;
431 offrange[1] += cstoff;
433 /* Besides the reference saved above, also stash the offset
434 for validation. */
435 if (TREE_CODE (expr) == COMPONENT_REF)
436 refoff = cstoff;
438 else
439 offrange[1] += maxobjsize;
441 if (var_off)
443 if (TREE_CODE (var_off) == INTEGER_CST)
445 cstoff = wi::to_offset (var_off);
446 offrange[0] += cstoff;
447 offrange[1] += cstoff;
449 else
450 offrange[1] += maxobjsize;
453 if (TREE_CODE (base) == MEM_REF)
455 tree memrefoff = TREE_OPERAND (base, 1);
456 extend_offset_range (memrefoff);
457 base = TREE_OPERAND (base, 0);
460 if (TREE_CODE (base) == SSA_NAME)
461 set_base_and_offset (base);
464 /* Return error_mark_node if the signed offset exceeds the bounds
465 of the address space (PTRDIFF_MAX). Otherwise, return either
466 BASE or REF when the offset exceeds the bounds of the BASE or
467 REF object, and set OOBOFF to the past-the-end offset formed
468 by the reference, including its size. When STRICT is non-zero
469 use REF size, when available, otherwise use BASE size. When
470 STRICT is greater than 1, use the size of the last array member
471 as the bound, otherwise treat such a member as a flexible array
472 member. Return NULL when the offset is in bounds. */
474 tree
475 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[2]) const
477 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
479 /* A temporary, possibly adjusted, copy of the offset range. */
480 offset_int offrng[2] = { offrange[0], offrange[1] };
482 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
484 /* Check for offset in an anti-range with a negative lower bound.
485 For such a range, consider only the non-negative subrange. */
486 if (offrng[1] < offrng[0] && offrng[1] < 0)
487 offrng[1] = maxobjsize;
490 /* Conservative offset of the last byte of the referenced object. */
491 offset_int endoff;
493 /* The bounds need not be ordered. Set HIB to use as the index
494 of the larger of the bounds and LOB as the opposite. */
495 bool hib = wi::les_p (offrng[0], offrng[1]);
496 bool lob = !hib;
498 if (basesize < 0)
500 endoff = offrng[lob] + sizrange[0];
502 /* For a reference through a pointer to an object of unknown size
503 all initial offsets are considered valid, positive as well as
504 negative, since the pointer itself can point past the beginning
505 of the object. However, the sum of the lower bound of the offset
506 and that of the size must be less than or equal than PTRDIFF_MAX. */
507 if (endoff > maxobjsize)
508 return error_mark_node;
510 return NULL_TREE;
513 /* A reference to an object of known size must be within the bounds
514 of the base object. */
515 if (offrng[hib] < 0 || offrng[lob] > basesize)
516 return base;
518 /* The extent of the reference must also be within the bounds of
519 the base object (if known) or the maximum object size otherwise. */
520 endoff = wi::smax (offrng[lob], 0) + sizrange[0];
521 if (endoff > maxobjsize)
522 return error_mark_node;
524 offset_int size = basesize;
525 tree obj = base;
527 if (strict
528 && DECL_P (obj)
529 && ref
530 && refoff >= 0
531 && TREE_CODE (ref) == COMPONENT_REF
532 && (strict > 1
533 || !array_at_struct_end_p (ref)))
535 /* If the reference is to a member subobject, the offset must
536 be within the bounds of the subobject. */
537 tree field = TREE_OPERAND (ref, 1);
538 tree type = TREE_TYPE (field);
539 if (tree sz = TYPE_SIZE_UNIT (type))
540 if (TREE_CODE (sz) == INTEGER_CST)
542 size = refoff + wi::to_offset (sz);
543 obj = ref;
547 if (endoff <= size)
548 return NULL_TREE;
550 /* Set the out-of-bounds offset range to be one greater than
551 that delimited by the reference including its size. */
552 ooboff[lob] = size + 1;
554 if (endoff > ooboff[lob])
555 ooboff[hib] = endoff;
556 else
557 ooboff[hib] = wi::smax (offrng[lob], 0) + sizrange[1];
559 return obj;
562 /* Create an association between the memory references DST and SRC
563 for access by a call EXPR to a memory or string built-in funtion. */
565 builtin_access::builtin_access (gimple *call, builtin_memref &dst,
566 builtin_memref &src)
567 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
568 dstoff (), srcoff (), dstsiz (), srcsiz ()
570 /* Zero out since the offset_int ctors invoked above are no-op. */
571 dstoff[0] = dstoff[1] = 0;
572 srcoff[0] = srcoff[1] = 0;
573 dstsiz[0] = dstsiz[1] = 0;
574 srcsiz[0] = srcsiz[1] = 0;
576 /* Object Size Type to use to determine the size of the destination
577 and source objects. Overridden below for raw memory functions. */
578 int ostype = 1;
580 /* True when the size of one reference depends on the offset of
581 itself or the other. */
582 bool depends_p = true;
584 /* True when the size of the destination reference DSTREF has been
585 determined from SRCREF and so needs to be adjusted by the latter's
586 offset. Only meaningful for bounded string functions like strncpy. */
587 bool dstadjust_p = false;
589 /* The size argument number (depends on the built-in). */
590 unsigned sizeargno = 2;
592 tree func = gimple_call_fndecl (call);
593 switch (DECL_FUNCTION_CODE (func))
595 case BUILT_IN_MEMCPY:
596 case BUILT_IN_MEMCPY_CHK:
597 case BUILT_IN_MEMPCPY:
598 case BUILT_IN_MEMPCPY_CHK:
599 ostype = 0;
600 depends_p = false;
601 detect_overlap = &builtin_access::generic_overlap;
602 break;
604 case BUILT_IN_MEMMOVE:
605 case BUILT_IN_MEMMOVE_CHK:
606 /* For memmove there is never any overlap to check for. */
607 ostype = 0;
608 depends_p = false;
609 detect_overlap = &builtin_access::no_overlap;
610 break;
612 case BUILT_IN_STPNCPY:
613 case BUILT_IN_STPNCPY_CHK:
614 case BUILT_IN_STRNCPY:
615 case BUILT_IN_STRNCPY_CHK:
616 dstref->strbounded_p = true;
617 detect_overlap = &builtin_access::strcpy_overlap;
618 break;
620 case BUILT_IN_STPCPY:
621 case BUILT_IN_STPCPY_CHK:
622 case BUILT_IN_STRCPY:
623 case BUILT_IN_STRCPY_CHK:
624 detect_overlap = &builtin_access::strcpy_overlap;
625 break;
627 case BUILT_IN_STRCAT:
628 case BUILT_IN_STRCAT_CHK:
629 detect_overlap = &builtin_access::strcat_overlap;
630 break;
632 case BUILT_IN_STRNCAT:
633 case BUILT_IN_STRNCAT_CHK:
634 dstref->strbounded_p = true;
635 srcref->strbounded_p = true;
636 detect_overlap = &builtin_access::strcat_overlap;
637 break;
639 default:
640 /* Handle other string functions here whose access may need
641 to be validated for in-bounds offsets and non-overlapping
642 copies. */
643 return;
646 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
648 /* Try to determine the size of the base object. compute_objsize
649 expects a pointer so create one if BASE is a non-pointer object. */
650 tree addr;
651 if (dst.basesize < 0)
653 addr = dst.base;
654 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
655 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
657 if (tree dstsize = compute_objsize (addr, ostype))
658 dst.basesize = wi::to_offset (dstsize);
659 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
660 dst.basesize = HOST_WIDE_INT_MIN;
661 else
662 dst.basesize = maxobjsize;
665 if (src.basesize < 0)
667 addr = src.base;
668 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
669 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
671 if (tree srcsize = compute_objsize (addr, ostype))
672 src.basesize = wi::to_offset (srcsize);
673 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
674 src.basesize = HOST_WIDE_INT_MIN;
675 else
676 src.basesize = maxobjsize;
679 /* If there is no dependency between the references or the base
680 objects of the two references aren't the same there's nothing
681 else to do. */
682 if (depends_p && dstref->base != srcref->base)
683 return;
685 /* ...otherwise, make adjustments for references to the same object
686 by string built-in functions to reflect the constraints imposed
687 by the function. */
689 /* For bounded string functions determine the range of the bound
690 on the access. For others, the range stays unbounded. */
691 offset_int bounds[2] = { maxobjsize, maxobjsize };
692 if (dstref->strbounded_p)
694 tree size = gimple_call_arg (call, sizeargno);
695 tree range[2];
696 if (get_size_range (size, range, true))
698 bounds[0] = wi::to_offset (range[0]);
699 bounds[1] = wi::to_offset (range[1]);
702 /* If both references' size ranges are indeterminate use the last
703 (size) argument from the function call as a substitute. This
704 may only be necessary for strncpy (but not for memcpy where
705 the size range would have been already determined this way). */
706 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
707 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
709 dstref->sizrange[0] = bounds[0];
710 dstref->sizrange[1] = bounds[1];
714 /* The size range of one reference involving the same base object
715 can be determined from the size range of the other reference.
716 This makes it possible to compute accurate offsets for warnings
717 involving functions like strcpy where the length of just one of
718 the two arguments is known (determined by tree-ssa-strlen). */
719 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
721 /* When the destination size is unknown set it to the size of
722 the source. */
723 dstref->sizrange[0] = srcref->sizrange[0];
724 dstref->sizrange[1] = srcref->sizrange[1];
726 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
728 /* When the source size is unknown set it to the size of
729 the destination. */
730 srcref->sizrange[0] = dstref->sizrange[0];
731 srcref->sizrange[1] = dstref->sizrange[1];
733 if (depends_p)
735 if (dstref->strbounded_p)
737 /* Read access by strncpy is bounded. */
738 if (bounds[0] < srcref->sizrange[0])
739 srcref->sizrange[0] = bounds[0];
740 if (bounds[1] < srcref->sizrange[1])
741 srcref->sizrange[1] = bounds[1];
744 /* For string functions, adjust the size range of the source
745 reference by the inverse boundaries of the offset (because
746 the higher the offset into the string the shorter its
747 length). */
748 if (srcref->offrange[1] >= 0
749 && srcref->offrange[1] < srcref->sizrange[0])
750 srcref->sizrange[0] -= srcref->offrange[1];
751 else
752 srcref->sizrange[0] = 0;
754 if (srcref->offrange[0] > 0)
756 if (srcref->offrange[0] < srcref->sizrange[1])
757 srcref->sizrange[1] -= srcref->offrange[0];
758 else
759 srcref->sizrange[1] = 0;
762 dstadjust_p = true;
766 if (detect_overlap == &builtin_access::generic_overlap)
768 if (dstref->strbounded_p)
770 dstref->sizrange[0] = bounds[0];
771 dstref->sizrange[1] = bounds[1];
773 if (dstref->sizrange[0] < srcref->sizrange[0])
774 srcref->sizrange[0] = dstref->sizrange[0];
776 if (dstref->sizrange[1] < srcref->sizrange[1])
777 srcref->sizrange[1] = dstref->sizrange[1];
780 else if (detect_overlap == &builtin_access::strcpy_overlap)
782 if (!dstref->strbounded_p)
784 /* For strcpy, adjust the destination size range to match that
785 of the source computed above. */
786 if (depends_p && dstadjust_p)
788 dstref->sizrange[0] = srcref->sizrange[0];
789 dstref->sizrange[1] = srcref->sizrange[1];
794 if (dstref->strbounded_p)
796 /* For strncpy, adjust the destination size range to match that
797 of the source computed above. */
798 dstref->sizrange[0] = bounds[0];
799 dstref->sizrange[1] = bounds[1];
801 if (bounds[0] < srcref->sizrange[0])
802 srcref->sizrange[0] = bounds[0];
804 if (bounds[1] < srcref->sizrange[1])
805 srcref->sizrange[1] = bounds[1];
809 offset_int
810 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
811 offset_int *off)
813 const offset_int *p = a;
814 const offset_int *q = b;
816 /* Point P at the bigger of the two ranges and Q at the smaller. */
817 if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
819 p = b;
820 q = a;
823 if (p[0] < q[0])
825 if (p[1] < q[0])
826 return 0;
828 *off = q[0];
829 return wi::smin (p[1], q[1]) - q[0];
832 if (q[1] < p[0])
833 return 0;
835 off[0] = p[0];
836 return q[1] - p[0];
839 /* Return true if the bounded mempry (memcpy amd similar) or string function
840 access (strncpy and similar) ACS overlaps. */
842 bool
843 builtin_access::generic_overlap ()
845 builtin_access &acs = *this;
846 const builtin_memref *dstref = acs.dstref;
847 const builtin_memref *srcref = acs.srcref;
849 gcc_assert (dstref->base == srcref->base);
851 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
853 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
854 gcc_assert (maxsize <= maxobjsize);
856 /* Adjust the larger bounds of the offsets (which may be the first
857 element if the lower bound is larger than the upper bound) to
858 make them valid for the smallest access (if possible) but no smaller
859 than the smaller bounds. */
860 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
862 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
863 acs.dstoff[1] = maxsize - acs.dstsiz[0];
864 if (acs.dstoff[1] < acs.dstoff[0])
865 acs.dstoff[1] = acs.dstoff[0];
867 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
869 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
870 acs.srcoff[1] = maxsize - acs.srcsiz[0];
871 if (acs.srcoff[1] < acs.srcoff[0])
872 acs.srcoff[1] = acs.srcoff[0];
874 /* Determine the minimum and maximum space for the access given
875 the offsets. */
876 offset_int space[2];
877 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
878 space[1] = space[0];
880 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
881 if (acs.srcsiz[0] > 0)
883 if (d < space[0])
884 space[0] = d;
886 if (space[1] < d)
887 space[1] = d;
889 else
890 space[1] = acs.dstsiz[1];
892 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
893 if (d < space[0])
894 space[0] = d;
896 if (space[1] < d)
897 space[1] = d;
899 /* Treat raw memory functions both of whose references are bounded
900 as special and permit uncertain overlaps to go undetected. For
901 all kinds of constant offset and constant size accesses, if
902 overlap isn't certain it is not possible. */
903 bool overlap_possible = space[0] < acs.dstsiz[1];
904 if (!overlap_possible)
905 return false;
907 bool overlap_certain = space[1] < acs.dstsiz[0];
909 /* True when the size of one reference depends on the offset of
910 the other. */
911 bool depends_p = detect_overlap != &builtin_access::generic_overlap;
913 if (!overlap_certain)
915 if (!dstref->strbounded_p && !depends_p)
916 /* Memcpy only considers certain overlap. */
917 return false;
919 /* There's no way to distinguish an access to the same member
920 of a structure from one to two distinct members of the same
921 structure. Give up to avoid excessive false positives. */
922 tree basetype = TREE_TYPE (dstref->base);
924 if (POINTER_TYPE_P (basetype))
925 basetype = TREE_TYPE (basetype);
926 else
927 while (TREE_CODE (basetype) == ARRAY_TYPE)
928 basetype = TREE_TYPE (basetype);
930 if (RECORD_OR_UNION_TYPE_P (basetype))
931 return false;
934 /* True for stpcpy and strcpy. */
935 bool stxcpy_p = (!dstref->strbounded_p
936 && detect_overlap == &builtin_access::strcpy_overlap);
938 if (dstref->refoff >= 0
939 && srcref->refoff >= 0
940 && dstref->refoff != srcref->refoff
941 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
942 return false;
944 offset_int siz[2] = { maxobjsize + 1, 0 };
946 ovloff[0] = HOST_WIDE_INT_MAX;
947 ovloff[1] = HOST_WIDE_INT_MIN;
949 /* Adjustment to the lower bound of the offset of the overlap to
950 account for a subset of unbounded string calls where the size
951 of the destination string depends on the length of the source
952 which in turn depends on the offset into it. */
953 bool sub1;
955 if (stxcpy_p)
957 sub1 = acs.dstoff[0] <= acs.srcoff[0];
959 /* Iterate over the extreme locations (on the horizontal axis formed
960 by their offsets) and sizes of two regions and find their smallest
961 and largest overlap and the corresponding offsets. */
962 for (unsigned i = 0; i != 2; ++i)
964 const offset_int a[2] = {
965 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
968 const offset_int b[2] = {
969 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
972 offset_int off;
973 offset_int sz = overlap_size (a, b, &off);
974 if (sz < siz[0])
975 siz[0] = sz;
977 if (siz[1] <= sz)
978 siz[1] = sz;
980 if (sz != 0)
982 if (wi::lts_p (off, ovloff[0]))
983 ovloff[0] = off.to_shwi ();
984 if (wi::lts_p (ovloff[1], off))
985 ovloff[1] = off.to_shwi ();
989 else
991 sub1 = !depends_p;
993 /* Iterate over the extreme locations (on the horizontal axis
994 formed by their offsets) and sizes of two regions and find
995 their smallest and largest overlap and the corresponding
996 offsets. */
998 for (unsigned io = 0; io != 2; ++io)
999 for (unsigned is = 0; is != 2; ++is)
1001 const offset_int a[2] = {
1002 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1005 for (unsigned jo = 0; jo != 2; ++jo)
1006 for (unsigned js = 0; js != 2; ++js)
1008 if (depends_p)
1010 /* For st{p,r}ncpy the size of the source sequence
1011 depends on the offset into it. */
1012 if (js)
1013 break;
1014 js = !jo;
1017 const offset_int b[2] = {
1018 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1021 offset_int off;
1022 offset_int sz = overlap_size (a, b, &off);
1023 if (sz < siz[0])
1024 siz[0] = sz;
1026 if (siz[1] <= sz)
1027 siz[1] = sz;
1029 if (sz != 0)
1031 if (wi::lts_p (off, ovloff[0]))
1032 ovloff[0] = off.to_shwi ();
1033 if (wi::lts_p (ovloff[1], off))
1034 ovloff[1] = off.to_shwi ();
1040 ovlsiz[0] = siz[0].to_shwi ();
1041 ovlsiz[1] = siz[1].to_shwi ();
1043 if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1044 ovloff[0] = ovloff[1] + ovlsiz[1] - 1 - sub1;
1046 return true;
1049 /* Return true if the strcat-like access overlaps. */
1051 bool
1052 builtin_access::strcat_overlap ()
1054 builtin_access &acs = *this;
1055 const builtin_memref *dstref = acs.dstref;
1056 const builtin_memref *srcref = acs.srcref;
1058 gcc_assert (dstref->base == srcref->base);
1060 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1062 gcc_assert (dstref->base && dstref->base == srcref->base);
1064 /* Adjust for strcat-like accesses. */
1066 /* As a special case for strcat, set the DSTREF offsets to the length
1067 of the source string since the function starts writing at the first
1068 nul, and set the size to 1 for the length of the nul. */
1069 acs.dstoff[0] += acs.dstsiz[0];
1070 acs.dstoff[1] += acs.dstsiz[1];
1072 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1074 /* The lower bound is zero when the size is unknown because then
1075 overlap is not certain. */
1076 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1077 acs.dstsiz[1] = 1;
1079 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1080 gcc_assert (maxsize <= maxobjsize);
1082 /* For references to the same base object, determine if there's a pair
1083 of valid offsets into the two references such that access between
1084 them doesn't overlap. Adjust both upper bounds to be valid for
1085 the smaller size (i.e., at most MAXSIZE - SIZE). */
1087 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1088 acs.dstoff[1] = maxsize - acs.dstsiz[0];
1090 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1091 acs.srcoff[1] = maxsize - acs.srcsiz[0];
1093 /* Check to see if there's enough space for both accesses without
1094 overlap. Determine the optimistic (maximum) amount of available
1095 space. */
1096 offset_int space;
1097 if (acs.dstoff[0] <= acs.srcoff[0])
1099 if (acs.dstoff[1] < acs.srcoff[1])
1100 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1101 else
1102 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1104 else
1105 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1107 /* Overlap is certain if the distance between the farthest offsets
1108 of the opposite accesses is less than the sum of the lower bounds
1109 of the sizes of the two accesses. */
1110 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1112 /* For a constant-offset, constant size access, consider the largest
1113 distance between the offset bounds and the lower bound of the access
1114 size. If the overlap isn't certain return success. */
1115 if (!overlap_certain
1116 && acs.dstoff[0] == acs.dstoff[1]
1117 && acs.srcoff[0] == acs.srcoff[1]
1118 && acs.dstsiz[0] == acs.dstsiz[1]
1119 && acs.srcsiz[0] == acs.srcsiz[1])
1120 return false;
1122 /* Overlap is not certain but may be possible. */
1124 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1126 /* Determine the conservative (minimum) amount of space. */
1127 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1128 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1129 if (d < space)
1130 space = d;
1131 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1132 if (d < space)
1133 space = d;
1135 /* For a strict test (used for strcpy and similar with unknown or
1136 variable bounds or sizes), consider the smallest distance between
1137 the offset bounds and either the upper bound of the access size
1138 if known, or the lower bound otherwise. */
1139 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1140 return false;
1142 /* When strcat overlap is certain it is always a single byte:
1143 the terminating NUL, regardless of offsets and sizes. When
1144 overlap is only possible its range is [0, 1]. */
1145 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1146 acs.ovlsiz[1] = 1;
1148 offset_int endoff = dstref->offrange[0] + dstref->sizrange[0];
1149 if (endoff <= srcref->offrange[0])
1150 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1151 else
1152 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1154 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1155 srcref->sizrange[0]).to_shwi ();
1156 if (dstref->offrange[0] == dstref->offrange[1])
1158 if (srcref->offrange[0] == srcref->offrange[1])
1159 acs.ovloff[1] = acs.ovloff[0];
1160 else
1161 acs.ovloff[1]
1162 = wi::smin (maxobjsize,
1163 srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1165 else
1166 acs.ovloff[1]
1167 = wi::smin (maxobjsize,
1168 dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1170 if (acs.sizrange[0] == 0)
1171 acs.sizrange[0] = 1;
1172 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1173 return true;
1176 /* Return true if the strcpy-like access overlaps. */
1178 bool
1179 builtin_access::strcpy_overlap ()
1181 return generic_overlap ();
1185 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1186 one another or that, in order not to overlap, would imply that the size
1187 of the referenced object(s) exceeds the maximum size of an object. Set
1188 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1189 they may overlap in a way that's not apparent from the available data),
1190 return false. */
1192 bool
1193 builtin_access::overlap ()
1195 builtin_access &acs = *this;
1197 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1199 acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1200 srcref->sizrange[0]).to_shwi ();
1201 acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1202 srcref->sizrange[1]).to_shwi ();
1204 /* Check to see if the two references refer to regions that are
1205 too large not to overlap in the address space (whose maximum
1206 size is PTRDIFF_MAX). */
1207 offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1208 if (maxobjsize < size)
1210 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1211 acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1212 return true;
1215 /* If both base objects aren't known return the maximum possible
1216 offset that would make them not overlap. */
1217 if (!dstref->base || !srcref->base)
1218 return false;
1220 /* Set the access offsets. */
1221 acs.dstoff[0] = dstref->offrange[0];
1222 acs.dstoff[1] = dstref->offrange[1];
1224 /* If the base object is an array adjust the bounds of the offset
1225 to be non-negative and within the bounds of the array if possible. */
1226 if (dstref->base
1227 && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE)
1229 if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0)
1230 acs.dstoff[0] = 0;
1232 if (acs.dstoff[1] < acs.dstoff[0])
1234 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base)))
1235 acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size));
1236 else
1237 acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize);
1241 acs.srcoff[0] = srcref->offrange[0];
1242 acs.srcoff[1] = srcref->offrange[1];
1244 if (srcref->base
1245 && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE)
1247 if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0)
1248 acs.srcoff[0] = 0;
1250 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base)))
1251 acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size));
1252 else if (acs.srcoff[1] < acs.srcoff[0])
1253 acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize);
1256 /* When the upper bound of the offset is less than the lower bound
1257 the former is the result of a negative offset being represented
1258 as a large positive value or vice versa. The resulting range is
1259 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1260 a union is not representable using the current data structure
1261 replace it with the full range of offsets. */
1262 if (acs.dstoff[1] < acs.dstoff[0])
1264 acs.dstoff[0] = -maxobjsize - 1;
1265 acs.dstoff[1] = maxobjsize;
1268 /* Validate the offset and size of each reference on its own first.
1269 This is independent of whether or not the base objects are the
1270 same. Normally, this would have already been detected and
1271 diagnosed by -Warray-bounds, unless it has been disabled. */
1272 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1273 if (maxobjsize < maxoff)
1275 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1276 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1277 return true;
1280 /* Repeat the same as above but for the source offsets. */
1281 if (acs.srcoff[1] < acs.srcoff[0])
1283 acs.srcoff[0] = -maxobjsize - 1;
1284 acs.srcoff[1] = maxobjsize;
1287 maxoff = acs.srcoff[0] + srcref->sizrange[0];
1288 if (maxobjsize < maxoff)
1290 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1291 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1292 - maxobjsize).to_shwi ();
1293 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1294 return true;
1297 if (dstref->base != srcref->base)
1298 return false;
1300 acs.dstsiz[0] = dstref->sizrange[0];
1301 acs.dstsiz[1] = dstref->sizrange[1];
1303 acs.srcsiz[0] = srcref->sizrange[0];
1304 acs.srcsiz[1] = srcref->sizrange[1];
1306 /* Call the appropriate function to determine the overlap. */
1307 if ((this->*detect_overlap) ())
1309 if (!sizrange[1])
1311 /* Unless the access size range has already been set, do so here. */
1312 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1313 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1315 return true;
1318 return false;
1321 /* Attempt to detect and diagnose an overlapping copy in a call expression
1322 EXPR involving an an access ACS to a built-in memory or string function.
1323 Return true when one has been detected, false otherwise. */
1325 static bool
1326 maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
1328 if (!acs.overlap ())
1329 return false;
1331 /* For convenience. */
1332 const builtin_memref &dstref = *acs.dstref;
1333 const builtin_memref &srcref = *acs.srcref;
1335 /* Determine the range of offsets and sizes of the overlap if it
1336 exists and issue diagnostics. */
1337 HOST_WIDE_INT *ovloff = acs.ovloff;
1338 HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1339 HOST_WIDE_INT *sizrange = acs.sizrange;
1341 tree func = gimple_call_fndecl (call);
1343 /* To avoid a combinatorial explosion of diagnostics format the offsets
1344 or their ranges as strings and use them in the warning calls below. */
1345 char offstr[3][64];
1347 if (dstref.offrange[0] == dstref.offrange[1]
1348 || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1349 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1350 dstref.offrange[0].to_shwi ());
1351 else
1352 sprintf (offstr[0],
1353 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1354 dstref.offrange[0].to_shwi (),
1355 dstref.offrange[1].to_shwi ());
1357 if (srcref.offrange[0] == srcref.offrange[1]
1358 || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1359 sprintf (offstr[1],
1360 HOST_WIDE_INT_PRINT_DEC,
1361 srcref.offrange[0].to_shwi ());
1362 else
1363 sprintf (offstr[1],
1364 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1365 srcref.offrange[0].to_shwi (),
1366 srcref.offrange[1].to_shwi ());
1368 if (ovloff[0] == ovloff[1] || !ovloff[1])
1369 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1370 else
1371 sprintf (offstr[2],
1372 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1373 ovloff[0], ovloff[1]);
1375 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1376 bool must_overlap = ovlsiz[0] > 0;
1378 if (ovlsiz[1] == 0)
1379 ovlsiz[1] = ovlsiz[0];
1381 if (must_overlap)
1383 /* Issue definitive "overlaps" diagnostic in this block. */
1385 if (sizrange[0] == sizrange[1])
1387 if (ovlsiz[0] == ovlsiz[1])
1388 warning_at (loc, OPT_Wrestrict,
1389 sizrange[0] == 1
1390 ? (ovlsiz[0] == 1
1391 ? G_("%G%qD accessing %wu byte at offsets %s "
1392 "and %s overlaps %wu byte at offset %s")
1393 : G_("%G%qD accessing %wu byte at offsets %s "
1394 "and %s overlaps %wu bytes at offset "
1395 "%s"))
1396 : (ovlsiz[0] == 1
1397 ? G_("%G%qD accessing %wu bytes at offsets %s "
1398 "and %s overlaps %wu byte at offset %s")
1399 : G_("%G%qD accessing %wu bytes at offsets %s "
1400 "and %s overlaps %wu bytes at offset "
1401 "%s")),
1402 call, func, sizrange[0],
1403 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1404 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1405 warning_n (loc, OPT_Wrestrict, sizrange[0],
1406 "%G%qD accessing %wu byte at offsets %s "
1407 "and %s overlaps between %wu and %wu bytes "
1408 "at offset %s",
1409 "%G%qD accessing %wu bytes at offsets %s "
1410 "and %s overlaps between %wu and %wu bytes "
1411 "at offset %s",
1412 call, func, sizrange[0], offstr[0], offstr[1],
1413 ovlsiz[0], ovlsiz[1], offstr[2]);
1414 else
1415 warning_n (loc, OPT_Wrestrict, sizrange[0],
1416 "%G%qD accessing %wu byte at offsets %s and "
1417 "%s overlaps %wu or more bytes at offset %s",
1418 "%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_n (loc, OPT_Wrestrict, ovlsiz[0],
1429 "%G%qD accessing between %wu and %wu bytes "
1430 "at offsets %s and %s overlaps %wu byte at "
1431 "offset %s",
1432 "%G%qD accessing between %wu and %wu bytes "
1433 "at offsets %s and %s overlaps %wu bytes "
1434 "at offset %s",
1435 call, func, sizrange[0], sizrange[1],
1436 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1437 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1438 warning_at (loc, OPT_Wrestrict,
1439 "%G%qD accessing between %wu and %wu bytes at "
1440 "offsets %s and %s overlaps between %wu and %wu "
1441 "bytes at offset %s",
1442 call, func, sizrange[0], sizrange[1],
1443 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1444 offstr[2]);
1445 else
1446 warning_at (loc, OPT_Wrestrict,
1447 "%G%qD accessing between %wu and %wu bytes at "
1448 "offsets %s and %s overlaps %wu or more bytes "
1449 "at offset %s",
1450 call, func, sizrange[0], sizrange[1],
1451 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1452 return true;
1455 if (ovlsiz[0] != ovlsiz[1])
1456 ovlsiz[1] = maxobjsize.to_shwi ();
1458 if (ovlsiz[0] == ovlsiz[1])
1459 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1460 "%G%qD accessing %wu or more bytes at offsets "
1461 "%s and %s overlaps %wu byte at offset %s",
1462 "%G%qD accessing %wu or more bytes at offsets "
1463 "%s and %s overlaps %wu bytes at offset %s",
1464 call, func, sizrange[0], offstr[0], offstr[1],
1465 ovlsiz[0], offstr[2]);
1466 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1467 warning_at (loc, OPT_Wrestrict,
1468 "%G%qD accessing %wu or more bytes at offsets %s "
1469 "and %s overlaps between %wu and %wu bytes "
1470 "at offset %s",
1471 call, func, sizrange[0], offstr[0], offstr[1],
1472 ovlsiz[0], ovlsiz[1], offstr[2]);
1473 else
1474 warning_at (loc, OPT_Wrestrict,
1475 "%G%qD accessing %wu or more bytes at offsets %s "
1476 "and %s overlaps %wu or more bytes at offset %s",
1477 call, func, sizrange[0], offstr[0], offstr[1],
1478 ovlsiz[0], offstr[2]);
1479 return true;
1482 /* Use more concise wording when one of the offsets is unbounded
1483 to avoid confusing the user with large and mostly meaningless
1484 numbers. */
1485 bool open_range;
1486 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1487 open_range = ((dstref.offrange[0] == 0
1488 && dstref.offrange[1] == maxobjsize)
1489 || (srcref.offrange[0] == 0
1490 && srcref.offrange[1] == maxobjsize));
1491 else
1492 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1493 && dstref.offrange[1] == maxobjsize)
1494 || (srcref.offrange[0] == -maxobjsize - 1
1495 && srcref.offrange[1] == maxobjsize));
1497 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1499 if (ovlsiz[1] == 1)
1501 if (open_range)
1502 warning_n (loc, OPT_Wrestrict, sizrange[1],
1503 "%G%qD accessing %wu byte may overlap "
1504 "%wu byte",
1505 "%G%qD accessing %wu bytes may overlap "
1506 "%wu byte",
1507 call, func, sizrange[1], ovlsiz[1]);
1508 else
1509 warning_n (loc, OPT_Wrestrict, sizrange[1],
1510 "%G%qD accessing %wu byte at offsets %s "
1511 "and %s may overlap %wu byte at offset %s",
1512 "%G%qD accessing %wu bytes at offsets %s "
1513 "and %s may overlap %wu byte at offset %s",
1514 call, func, sizrange[1], offstr[0], offstr[1],
1515 ovlsiz[1], offstr[2]);
1516 return true;
1519 if (open_range)
1520 warning_n (loc, OPT_Wrestrict, sizrange[1],
1521 "%G%qD accessing %wu byte may overlap "
1522 "up to %wu bytes",
1523 "%G%qD accessing %wu bytes may overlap "
1524 "up to %wu bytes",
1525 call, func, sizrange[1], ovlsiz[1]);
1526 else
1527 warning_n (loc, OPT_Wrestrict, sizrange[1],
1528 "%G%qD accessing %wu byte at offsets %s and "
1529 "%s may overlap up to %wu bytes at offset %s",
1530 "%G%qD accessing %wu bytes at offsets %s and "
1531 "%s may overlap up to %wu bytes at offset %s",
1532 call, func, sizrange[1], offstr[0], offstr[1],
1533 ovlsiz[1], offstr[2]);
1534 return true;
1537 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1539 if (open_range)
1540 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1541 "%G%qD accessing between %wu and %wu bytes "
1542 "may overlap %wu byte",
1543 "%G%qD accessing between %wu and %wu bytes "
1544 "may overlap up to %wu bytes",
1545 call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1546 else
1547 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1548 "%G%qD accessing between %wu and %wu bytes "
1549 "at offsets %s and %s may overlap %wu byte "
1550 "at offset %s",
1551 "%G%qD accessing between %wu and %wu bytes "
1552 "at offsets %s and %s may overlap up to %wu "
1553 "bytes at offset %s",
1554 call, func, sizrange[0], sizrange[1],
1555 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1556 return true;
1559 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1560 "%G%qD accessing %wu or more bytes at offsets %s "
1561 "and %s may overlap %wu byte at offset %s",
1562 "%G%qD accessing %wu or more bytes at offsets %s "
1563 "and %s may overlap up to %wu bytes at offset %s",
1564 call, func, sizrange[0], offstr[0], offstr[1],
1565 ovlsiz[1], offstr[2]);
1567 return true;
1570 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1571 to a built-in function FUNC to make sure they are within the bounds
1572 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1573 Both initial values of the offsets and their final value computed by
1574 the function by incrementing the initial value by the size are
1575 validated. Return true if the offsets are not valid and a diagnostic
1576 has been issued. */
1578 static bool
1579 maybe_diag_offset_bounds (location_t loc, gimple *call, tree func, int strict,
1580 tree expr, const builtin_memref &ref)
1582 if (!warn_array_bounds)
1583 return false;
1585 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1] };
1586 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1587 if (!oobref)
1588 return false;
1590 if (EXPR_HAS_LOCATION (expr))
1591 loc = EXPR_LOCATION (expr);
1593 loc = expansion_point_location_if_in_system_header (loc);
1595 char rangestr[2][64];
1596 if (ooboff[0] == ooboff[1]
1597 || (ooboff[0] != ref.offrange[0]
1598 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1599 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1600 else
1601 sprintf (rangestr[0], "[%lli, %lli]",
1602 (long long) ooboff[0].to_shwi (),
1603 (long long) ooboff[1].to_shwi ());
1605 bool warned = false;
1607 if (oobref == error_mark_node)
1609 if (ref.sizrange[0] == ref.sizrange[1])
1610 sprintf (rangestr[1], "%lli", (long long) ref.sizrange[0].to_shwi ());
1611 else
1612 sprintf (rangestr[1], "[%lli, %lli]",
1613 (long long) ref.sizrange[0].to_shwi (),
1614 (long long) ref.sizrange[1].to_shwi ());
1616 tree type;
1618 if (DECL_P (ref.base)
1619 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1621 if (warning_at (loc, OPT_Warray_bounds,
1622 "%G%qD pointer overflow between offset %s "
1623 "and size %s accessing array %qD with type %qT",
1624 call, func, rangestr[0], rangestr[1], ref.base, type))
1626 inform (DECL_SOURCE_LOCATION (ref.base),
1627 "array %qD declared here", ref.base);
1628 warned = true;
1630 else
1631 warned = warning_at (loc, OPT_Warray_bounds,
1632 "%G%qD pointer overflow between offset %s "
1633 "and size %s",
1634 call, func, rangestr[0], rangestr[1]);
1636 else
1637 warned = warning_at (loc, OPT_Warray_bounds,
1638 "%G%qD pointer overflow between offset %s "
1639 "and size %s",
1640 call, func, rangestr[0], rangestr[1]);
1642 else if (oobref == ref.base)
1644 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1646 /* True when the offset formed by an access to the reference
1647 is out of bounds, rather than the initial offset wich is
1648 in bounds. This implies access past the end. */
1649 bool form = ooboff[0] != ref.offrange[0];
1651 if (DECL_P (ref.base))
1653 if ((ref.basesize < maxobjsize
1654 && warning_at (loc, OPT_Warray_bounds,
1655 form
1656 ? G_("%G%qD forming offset %s is out of "
1657 "the bounds [0, %wu] of object %qD with "
1658 "type %qT")
1659 : G_("%G%qD offset %s is out of the bounds "
1660 "[0, %wu] of object %qD with type %qT"),
1661 call, func, rangestr[0], ref.basesize.to_uhwi (),
1662 ref.base, TREE_TYPE (ref.base)))
1663 || warning_at (loc, OPT_Warray_bounds,
1664 form
1665 ? G_("%G%qD forming offset %s is out of "
1666 "the bounds of object %qD with type %qT")
1667 : G_("%G%qD offset %s is out of the bounds "
1668 "of object %qD with type %qT"),
1669 call, func, rangestr[0],
1670 ref.base, TREE_TYPE (ref.base)))
1672 inform (DECL_SOURCE_LOCATION (ref.base),
1673 "%qD declared here", ref.base);
1674 warned = true;
1677 else if (ref.basesize < maxobjsize)
1678 warned = warning_at (loc, OPT_Warray_bounds,
1679 form
1680 ? G_("%G%qD forming offset %s is out "
1681 "of the bounds [0, %wu]")
1682 : G_("%G%qD offset %s is out "
1683 "of the bounds [0, %wu]"),
1684 call, func, rangestr[0], ref.basesize.to_uhwi ());
1685 else
1686 warned = 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 warned = 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 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1708 warned = 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 "
1711 "type %qT at offset %wu",
1712 call, func, rangestr[0], ref.base,
1713 TREE_OPERAND (ref.ref, 1), type,
1714 ref.refoff.to_uhwi ());
1717 return warned;
1720 /* Check a CALL statement for restrict-violations and issue warnings
1721 if/when appropriate. */
1723 void
1724 wrestrict_dom_walker::check_call (gimple *call)
1726 /* Avoid checking the call if it has already been diagnosed for
1727 some reason. */
1728 if (gimple_no_warning_p (call))
1729 return;
1731 tree func = gimple_call_fndecl (call);
1732 if (!func || DECL_BUILT_IN_CLASS (func) != BUILT_IN_NORMAL)
1733 return;
1735 /* Argument number to extract from the call (depends on the built-in
1736 and its kind). */
1737 unsigned dst_idx = -1;
1738 unsigned src_idx = -1;
1739 unsigned bnd_idx = -1;
1741 /* Is this CALL to a string function (as opposed to one to a raw
1742 memory function). */
1743 bool strfun = true;
1745 switch (DECL_FUNCTION_CODE (func))
1747 case BUILT_IN_MEMCPY:
1748 case BUILT_IN_MEMCPY_CHK:
1749 case BUILT_IN_MEMPCPY:
1750 case BUILT_IN_MEMPCPY_CHK:
1751 case BUILT_IN_MEMMOVE:
1752 case BUILT_IN_MEMMOVE_CHK:
1753 strfun = false;
1754 /* Fall through. */
1756 case BUILT_IN_STPNCPY:
1757 case BUILT_IN_STPNCPY_CHK:
1758 case BUILT_IN_STRNCAT:
1759 case BUILT_IN_STRNCAT_CHK:
1760 case BUILT_IN_STRNCPY:
1761 case BUILT_IN_STRNCPY_CHK:
1762 dst_idx = 0;
1763 src_idx = 1;
1764 bnd_idx = 2;
1765 break;
1767 case BUILT_IN_STPCPY:
1768 case BUILT_IN_STPCPY_CHK:
1769 case BUILT_IN_STRCPY:
1770 case BUILT_IN_STRCPY_CHK:
1771 case BUILT_IN_STRCAT:
1772 case BUILT_IN_STRCAT_CHK:
1773 dst_idx = 0;
1774 src_idx = 1;
1775 break;
1777 default:
1778 /* Handle other string functions here whose access may need
1779 to be validated for in-bounds offsets and non-overlapping
1780 copies. */
1781 return;
1784 unsigned nargs = gimple_call_num_args (call);
1786 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1787 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1788 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1790 /* For string functions with an unspecified or unknown bound,
1791 assume the size of the access is one. */
1792 if (!dstwr && strfun)
1793 dstwr = size_one_node;
1795 /* DST and SRC can be null for a call with an insufficient number
1796 of arguments to a built-in function declared without a protype. */
1797 if (!dst || !src)
1798 return;
1800 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1801 a function declared without a prototype. Avoid checking such
1802 invalid calls. */
1803 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1804 || TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
1805 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1806 return;
1808 if (check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
1809 return;
1811 /* Avoid diagnosing the call again. */
1812 gimple_set_no_warning (call, true);
1815 } /* anonymous namespace */
1817 /* Attempt to detect and diagnose invalid offset bounds and (except for
1818 memmove) overlapping copy in a call expression EXPR from SRC to DST
1819 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1820 SRCSIZE may be NULL. Return false when one or the other has been
1821 detected and diagnosed, true otherwise. */
1823 bool
1824 check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
1825 tree srcsize, bool bounds_only /* = false */)
1827 location_t loc = gimple_nonartificial_location (call);
1828 loc = expansion_point_location_if_in_system_header (loc);
1830 tree func = gimple_call_fndecl (call);
1832 builtin_memref dstref (dst, dstsize);
1833 builtin_memref srcref (src, srcsize);
1835 builtin_access acs (call, dstref, srcref);
1837 /* Set STRICT to the value of the -Warray-bounds=N argument for
1838 string functions or when N > 1. */
1839 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
1841 /* Validate offsets first to make sure they are within the bounds
1842 of the destination object if its size is known, or PTRDIFF_MAX
1843 otherwise. */
1844 if (maybe_diag_offset_bounds (loc, call, func, strict, dst, dstref)
1845 || maybe_diag_offset_bounds (loc, call, func, strict, src, srcref))
1847 gimple_set_no_warning (call, true);
1848 return false;
1851 bool check_overlap
1852 = (warn_restrict
1853 && (bounds_only
1854 || (DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE
1855 && DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE_CHK)));
1857 if (!check_overlap)
1858 return true;
1860 if (operand_equal_p (dst, src, 0))
1862 /* Issue -Wrestrict unless the pointers are null (those do
1863 not point to objects and so do not indicate an overlap;
1864 such calls could be the result of sanitization and jump
1865 threading). */
1866 if (!integer_zerop (dst) && !gimple_no_warning_p (call))
1868 warning_at (loc, OPT_Wrestrict,
1869 "%G%qD source argument is the same as destination",
1870 call, func);
1871 gimple_set_no_warning (call, true);
1872 return false;
1875 return true;
1878 /* Return false when overlap has been detected. */
1879 if (maybe_diag_overlap (loc, call, acs))
1881 gimple_set_no_warning (call, true);
1882 return false;
1885 return true;
1888 gimple_opt_pass *
1889 make_pass_warn_restrict (gcc::context *ctxt)
1891 return new pass_wrestrict (ctxt);