re PR fortran/88376 (ICE in is_illegal_recursion, at fortran/resolve.c:1689)
[official-gcc.git] / gcc / gimple-ssa-warn-restrict.c
blob6eb393dc8e109fbd76047886dfecd7e741b3a803
1 /* Pass to detect and issue warnings for violations of the restrict
2 qualifier.
3 Copyright (C) 2017-2019 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)
277 if (ref && 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);
286 if (offrange[0] >= 0)
288 if (offrange[1] < 0)
289 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
290 else if (offrange[0] <= maxoff && offrange[1] > maxoff)
291 offrange[1] = maxoff;
295 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. */
297 void
298 builtin_memref::extend_offset_range (tree offset)
300 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
302 if (TREE_CODE (offset) == INTEGER_CST)
304 offset_int off = int_cst_value (offset);
305 if (off != 0)
307 offrange[0] += off;
308 offrange[1] += off;
310 return;
313 if (TREE_CODE (offset) == SSA_NAME)
315 wide_int min, max;
316 value_range_kind rng = get_range_info (offset, &min, &max);
317 if (rng == VR_RANGE)
319 offrange[0] += offset_int::from (min, SIGNED);
320 offrange[1] += offset_int::from (max, SIGNED);
322 else if (rng == VR_ANTI_RANGE)
324 offrange[0] += offset_int::from (max + 1, SIGNED);
325 offrange[1] += offset_int::from (min - 1, SIGNED);
327 else
329 gimple *stmt = SSA_NAME_DEF_STMT (offset);
330 tree type;
331 if (is_gimple_assign (stmt)
332 && gimple_assign_rhs_code (stmt) == NOP_EXPR
333 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
334 && INTEGRAL_TYPE_P (type))
336 /* Use the bounds of the type of the NOP_EXPR operand
337 even if it's signed. The result doesn't trigger
338 warnings but makes their output more readable. */
339 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
340 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
342 else
343 offrange[1] += maxobjsize;
345 return;
348 offrange[1] += maxobjsize;
351 /* Determines the base object or pointer of the reference EXPR
352 and the offset range from the beginning of the base. */
354 void
355 builtin_memref::set_base_and_offset (tree expr)
357 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
359 if (TREE_CODE (expr) == SSA_NAME)
361 /* Try to tease the offset out of the pointer. */
362 gimple *stmt = SSA_NAME_DEF_STMT (expr);
363 if (!base
364 && gimple_assign_single_p (stmt)
365 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
366 expr = gimple_assign_rhs1 (stmt);
367 else if (is_gimple_assign (stmt))
369 tree_code code = gimple_assign_rhs_code (stmt);
370 if (code == NOP_EXPR)
372 tree rhs = gimple_assign_rhs1 (stmt);
373 if (POINTER_TYPE_P (TREE_TYPE (rhs)))
374 expr = gimple_assign_rhs1 (stmt);
375 else
377 base = expr;
378 return;
381 else if (code == POINTER_PLUS_EXPR)
383 expr = gimple_assign_rhs1 (stmt);
385 tree offset = gimple_assign_rhs2 (stmt);
386 extend_offset_range (offset);
388 else
390 base = expr;
391 return;
394 else
396 base = expr;
397 return;
401 if (TREE_CODE (expr) == ADDR_EXPR)
402 expr = TREE_OPERAND (expr, 0);
404 /* Stash the reference for offset validation. */
405 ref = expr;
407 poly_int64 bitsize, bitpos;
408 tree var_off;
409 machine_mode mode;
410 int sign, reverse, vol;
412 /* Determine the base object or pointer of the reference and
413 the constant bit offset from the beginning of the base.
414 If the offset has a non-constant component, it will be in
415 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
416 unused here. */
417 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
418 &mode, &sign, &reverse, &vol);
420 /* get_inner_reference is not expected to return null. */
421 gcc_assert (base != NULL);
423 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
425 /* Convert the poly_int64 offset to offset_int. The offset
426 should be constant but be prepared for it not to be just in
427 case. */
428 offset_int cstoff;
429 if (bytepos.is_constant (&cstoff))
431 offrange[0] += cstoff;
432 offrange[1] += cstoff;
434 /* Besides the reference saved above, also stash the offset
435 for validation. */
436 if (TREE_CODE (expr) == COMPONENT_REF)
437 refoff = cstoff;
439 else
440 offrange[1] += maxobjsize;
442 if (var_off)
444 if (TREE_CODE (var_off) == INTEGER_CST)
446 cstoff = wi::to_offset (var_off);
447 offrange[0] += cstoff;
448 offrange[1] += cstoff;
450 else
451 offrange[1] += maxobjsize;
454 if (TREE_CODE (base) == MEM_REF)
456 tree memrefoff = TREE_OPERAND (base, 1);
457 extend_offset_range (memrefoff);
458 base = TREE_OPERAND (base, 0);
461 if (TREE_CODE (base) == SSA_NAME)
462 set_base_and_offset (base);
465 /* Return error_mark_node if the signed offset exceeds the bounds
466 of the address space (PTRDIFF_MAX). Otherwise, return either
467 BASE or REF when the offset exceeds the bounds of the BASE or
468 REF object, and set OOBOFF to the past-the-end offset formed
469 by the reference, including its size. When STRICT is non-zero
470 use REF size, when available, otherwise use BASE size. When
471 STRICT is greater than 1, use the size of the last array member
472 as the bound, otherwise treat such a member as a flexible array
473 member. Return NULL when the offset is in bounds. */
475 tree
476 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[2]) const
478 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
480 /* A temporary, possibly adjusted, copy of the offset range. */
481 offset_int offrng[2] = { offrange[0], offrange[1] };
483 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
485 /* Check for offset in an anti-range with a negative lower bound.
486 For such a range, consider only the non-negative subrange. */
487 if (offrng[1] < offrng[0] && offrng[1] < 0)
488 offrng[1] = maxobjsize;
491 /* Conservative offset of the last byte of the referenced object. */
492 offset_int endoff;
494 /* The bounds need not be ordered. Set HIB to use as the index
495 of the larger of the bounds and LOB as the opposite. */
496 bool hib = wi::les_p (offrng[0], offrng[1]);
497 bool lob = !hib;
499 if (basesize < 0)
501 endoff = offrng[lob] + sizrange[0];
503 /* For a reference through a pointer to an object of unknown size
504 all initial offsets are considered valid, positive as well as
505 negative, since the pointer itself can point past the beginning
506 of the object. However, the sum of the lower bound of the offset
507 and that of the size must be less than or equal than PTRDIFF_MAX. */
508 if (endoff > maxobjsize)
509 return error_mark_node;
511 return NULL_TREE;
514 /* A reference to an object of known size must be within the bounds
515 of the base object. */
516 if (offrng[hib] < 0 || offrng[lob] > basesize)
517 return base;
519 /* The extent of the reference must also be within the bounds of
520 the base object (if known) or the maximum object size otherwise. */
521 endoff = wi::smax (offrng[lob], 0) + sizrange[0];
522 if (endoff > maxobjsize)
523 return error_mark_node;
525 offset_int size = basesize;
526 tree obj = base;
528 if (strict
529 && DECL_P (obj)
530 && ref
531 && refoff >= 0
532 && TREE_CODE (ref) == COMPONENT_REF
533 && (strict > 1
534 || !array_at_struct_end_p (ref)))
536 /* If the reference is to a member subobject, the offset must
537 be within the bounds of the subobject. */
538 tree field = TREE_OPERAND (ref, 1);
539 tree type = TREE_TYPE (field);
540 if (tree sz = TYPE_SIZE_UNIT (type))
541 if (TREE_CODE (sz) == INTEGER_CST)
543 size = refoff + wi::to_offset (sz);
544 obj = ref;
548 if (endoff <= size)
549 return NULL_TREE;
551 /* Set the out-of-bounds offset range to be one greater than
552 that delimited by the reference including its size. */
553 ooboff[lob] = size + 1;
555 if (endoff > ooboff[lob])
556 ooboff[hib] = endoff;
557 else
558 ooboff[hib] = wi::smax (offrng[lob], 0) + sizrange[1];
560 return obj;
563 /* Create an association between the memory references DST and SRC
564 for access by a call EXPR to a memory or string built-in funtion. */
566 builtin_access::builtin_access (gimple *call, builtin_memref &dst,
567 builtin_memref &src)
568 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
569 dstoff (), srcoff (), dstsiz (), srcsiz ()
571 /* Zero out since the offset_int ctors invoked above are no-op. */
572 dstoff[0] = dstoff[1] = 0;
573 srcoff[0] = srcoff[1] = 0;
574 dstsiz[0] = dstsiz[1] = 0;
575 srcsiz[0] = srcsiz[1] = 0;
577 /* Object Size Type to use to determine the size of the destination
578 and source objects. Overridden below for raw memory functions. */
579 int ostype = 1;
581 /* True when the size of one reference depends on the offset of
582 itself or the other. */
583 bool depends_p = true;
585 /* True when the size of the destination reference DSTREF has been
586 determined from SRCREF and so needs to be adjusted by the latter's
587 offset. Only meaningful for bounded string functions like strncpy. */
588 bool dstadjust_p = false;
590 /* The size argument number (depends on the built-in). */
591 unsigned sizeargno = 2;
593 tree func = gimple_call_fndecl (call);
594 switch (DECL_FUNCTION_CODE (func))
596 case BUILT_IN_MEMCPY:
597 case BUILT_IN_MEMCPY_CHK:
598 case BUILT_IN_MEMPCPY:
599 case BUILT_IN_MEMPCPY_CHK:
600 ostype = 0;
601 depends_p = false;
602 detect_overlap = &builtin_access::generic_overlap;
603 break;
605 case BUILT_IN_MEMMOVE:
606 case BUILT_IN_MEMMOVE_CHK:
607 /* For memmove there is never any overlap to check for. */
608 ostype = 0;
609 depends_p = false;
610 detect_overlap = &builtin_access::no_overlap;
611 break;
613 case BUILT_IN_STPNCPY:
614 case BUILT_IN_STPNCPY_CHK:
615 case BUILT_IN_STRNCPY:
616 case BUILT_IN_STRNCPY_CHK:
617 dstref->strbounded_p = true;
618 detect_overlap = &builtin_access::strcpy_overlap;
619 break;
621 case BUILT_IN_STPCPY:
622 case BUILT_IN_STPCPY_CHK:
623 case BUILT_IN_STRCPY:
624 case BUILT_IN_STRCPY_CHK:
625 detect_overlap = &builtin_access::strcpy_overlap;
626 break;
628 case BUILT_IN_STRCAT:
629 case BUILT_IN_STRCAT_CHK:
630 detect_overlap = &builtin_access::strcat_overlap;
631 break;
633 case BUILT_IN_STRNCAT:
634 case BUILT_IN_STRNCAT_CHK:
635 dstref->strbounded_p = true;
636 srcref->strbounded_p = true;
637 detect_overlap = &builtin_access::strcat_overlap;
638 break;
640 default:
641 /* Handle other string functions here whose access may need
642 to be validated for in-bounds offsets and non-overlapping
643 copies. */
644 return;
647 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
649 /* Try to determine the size of the base object. compute_objsize
650 expects a pointer so create one if BASE is a non-pointer object. */
651 tree addr;
652 if (dst.basesize < 0)
654 addr = dst.base;
655 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
656 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
658 if (tree dstsize = compute_objsize (addr, ostype))
659 dst.basesize = wi::to_offset (dstsize);
660 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
661 dst.basesize = HOST_WIDE_INT_MIN;
662 else
663 dst.basesize = maxobjsize;
666 if (src.basesize < 0)
668 addr = src.base;
669 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
670 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
672 if (tree srcsize = compute_objsize (addr, ostype))
673 src.basesize = wi::to_offset (srcsize);
674 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
675 src.basesize = HOST_WIDE_INT_MIN;
676 else
677 src.basesize = maxobjsize;
680 /* If there is no dependency between the references or the base
681 objects of the two references aren't the same there's nothing
682 else to do. */
683 if (depends_p && dstref->base != srcref->base)
684 return;
686 /* ...otherwise, make adjustments for references to the same object
687 by string built-in functions to reflect the constraints imposed
688 by the function. */
690 /* For bounded string functions determine the range of the bound
691 on the access. For others, the range stays unbounded. */
692 offset_int bounds[2] = { maxobjsize, maxobjsize };
693 if (dstref->strbounded_p)
695 tree size = gimple_call_arg (call, sizeargno);
696 tree range[2];
697 if (get_size_range (size, range, true))
699 bounds[0] = wi::to_offset (range[0]);
700 bounds[1] = wi::to_offset (range[1]);
703 /* If both references' size ranges are indeterminate use the last
704 (size) argument from the function call as a substitute. This
705 may only be necessary for strncpy (but not for memcpy where
706 the size range would have been already determined this way). */
707 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
708 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
710 dstref->sizrange[0] = bounds[0];
711 dstref->sizrange[1] = bounds[1];
715 /* The size range of one reference involving the same base object
716 can be determined from the size range of the other reference.
717 This makes it possible to compute accurate offsets for warnings
718 involving functions like strcpy where the length of just one of
719 the two arguments is known (determined by tree-ssa-strlen). */
720 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
722 /* When the destination size is unknown set it to the size of
723 the source. */
724 dstref->sizrange[0] = srcref->sizrange[0];
725 dstref->sizrange[1] = srcref->sizrange[1];
727 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
729 /* When the source size is unknown set it to the size of
730 the destination. */
731 srcref->sizrange[0] = dstref->sizrange[0];
732 srcref->sizrange[1] = dstref->sizrange[1];
734 if (depends_p)
736 if (dstref->strbounded_p)
738 /* Read access by strncpy is bounded. */
739 if (bounds[0] < srcref->sizrange[0])
740 srcref->sizrange[0] = bounds[0];
741 if (bounds[1] < srcref->sizrange[1])
742 srcref->sizrange[1] = bounds[1];
745 /* For string functions, adjust the size range of the source
746 reference by the inverse boundaries of the offset (because
747 the higher the offset into the string the shorter its
748 length). */
749 if (srcref->offrange[1] >= 0
750 && srcref->offrange[1] < srcref->sizrange[0])
751 srcref->sizrange[0] -= srcref->offrange[1];
752 else
753 srcref->sizrange[0] = 0;
755 if (srcref->offrange[0] > 0)
757 if (srcref->offrange[0] < srcref->sizrange[1])
758 srcref->sizrange[1] -= srcref->offrange[0];
759 else
760 srcref->sizrange[1] = 0;
763 dstadjust_p = true;
767 if (detect_overlap == &builtin_access::generic_overlap)
769 if (dstref->strbounded_p)
771 dstref->sizrange[0] = bounds[0];
772 dstref->sizrange[1] = bounds[1];
774 if (dstref->sizrange[0] < srcref->sizrange[0])
775 srcref->sizrange[0] = dstref->sizrange[0];
777 if (dstref->sizrange[1] < srcref->sizrange[1])
778 srcref->sizrange[1] = dstref->sizrange[1];
781 else if (detect_overlap == &builtin_access::strcpy_overlap)
783 if (!dstref->strbounded_p)
785 /* For strcpy, adjust the destination size range to match that
786 of the source computed above. */
787 if (depends_p && dstadjust_p)
789 dstref->sizrange[0] = srcref->sizrange[0];
790 dstref->sizrange[1] = srcref->sizrange[1];
795 if (dstref->strbounded_p)
797 /* For strncpy, adjust the destination size range to match that
798 of the source computed above. */
799 dstref->sizrange[0] = bounds[0];
800 dstref->sizrange[1] = bounds[1];
802 if (bounds[0] < srcref->sizrange[0])
803 srcref->sizrange[0] = bounds[0];
805 if (bounds[1] < srcref->sizrange[1])
806 srcref->sizrange[1] = bounds[1];
810 offset_int
811 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
812 offset_int *off)
814 const offset_int *p = a;
815 const offset_int *q = b;
817 /* Point P at the bigger of the two ranges and Q at the smaller. */
818 if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
820 p = b;
821 q = a;
824 if (p[0] < q[0])
826 if (p[1] < q[0])
827 return 0;
829 *off = q[0];
830 return wi::smin (p[1], q[1]) - q[0];
833 if (q[1] < p[0])
834 return 0;
836 off[0] = p[0];
837 return q[1] - p[0];
840 /* Return true if the bounded mempry (memcpy amd similar) or string function
841 access (strncpy and similar) ACS overlaps. */
843 bool
844 builtin_access::generic_overlap ()
846 builtin_access &acs = *this;
847 const builtin_memref *dstref = acs.dstref;
848 const builtin_memref *srcref = acs.srcref;
850 gcc_assert (dstref->base == srcref->base);
852 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
854 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
855 gcc_assert (maxsize <= maxobjsize);
857 /* Adjust the larger bounds of the offsets (which may be the first
858 element if the lower bound is larger than the upper bound) to
859 make them valid for the smallest access (if possible) but no smaller
860 than the smaller bounds. */
861 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
863 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
864 acs.dstoff[1] = maxsize - acs.dstsiz[0];
865 if (acs.dstoff[1] < acs.dstoff[0])
866 acs.dstoff[1] = acs.dstoff[0];
868 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
870 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
871 acs.srcoff[1] = maxsize - acs.srcsiz[0];
872 if (acs.srcoff[1] < acs.srcoff[0])
873 acs.srcoff[1] = acs.srcoff[0];
875 /* Determine the minimum and maximum space for the access given
876 the offsets. */
877 offset_int space[2];
878 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
879 space[1] = space[0];
881 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
882 if (acs.srcsiz[0] > 0)
884 if (d < space[0])
885 space[0] = d;
887 if (space[1] < d)
888 space[1] = d;
890 else
891 space[1] = acs.dstsiz[1];
893 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
894 if (d < space[0])
895 space[0] = d;
897 if (space[1] < d)
898 space[1] = d;
900 /* Treat raw memory functions both of whose references are bounded
901 as special and permit uncertain overlaps to go undetected. For
902 all kinds of constant offset and constant size accesses, if
903 overlap isn't certain it is not possible. */
904 bool overlap_possible = space[0] < acs.dstsiz[1];
905 if (!overlap_possible)
906 return false;
908 bool overlap_certain = space[1] < acs.dstsiz[0];
910 /* True when the size of one reference depends on the offset of
911 the other. */
912 bool depends_p = detect_overlap != &builtin_access::generic_overlap;
914 if (!overlap_certain)
916 if (!dstref->strbounded_p && !depends_p)
917 /* Memcpy only considers certain overlap. */
918 return false;
920 /* There's no way to distinguish an access to the same member
921 of a structure from one to two distinct members of the same
922 structure. Give up to avoid excessive false positives. */
923 tree basetype = TREE_TYPE (dstref->base);
925 if (POINTER_TYPE_P (basetype))
926 basetype = TREE_TYPE (basetype);
927 else
928 while (TREE_CODE (basetype) == ARRAY_TYPE)
929 basetype = TREE_TYPE (basetype);
931 if (RECORD_OR_UNION_TYPE_P (basetype))
932 return false;
935 /* True for stpcpy and strcpy. */
936 bool stxcpy_p = (!dstref->strbounded_p
937 && detect_overlap == &builtin_access::strcpy_overlap);
939 if (dstref->refoff >= 0
940 && srcref->refoff >= 0
941 && dstref->refoff != srcref->refoff
942 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
943 return false;
945 offset_int siz[2] = { maxobjsize + 1, 0 };
947 ovloff[0] = HOST_WIDE_INT_MAX;
948 ovloff[1] = HOST_WIDE_INT_MIN;
950 /* Adjustment to the lower bound of the offset of the overlap to
951 account for a subset of unbounded string calls where the size
952 of the destination string depends on the length of the source
953 which in turn depends on the offset into it. */
954 bool sub1;
956 if (stxcpy_p)
958 sub1 = acs.dstoff[0] <= acs.srcoff[0];
960 /* Iterate over the extreme locations (on the horizontal axis formed
961 by their offsets) and sizes of two regions and find their smallest
962 and largest overlap and the corresponding offsets. */
963 for (unsigned i = 0; i != 2; ++i)
965 const offset_int a[2] = {
966 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
969 const offset_int b[2] = {
970 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
973 offset_int off;
974 offset_int sz = overlap_size (a, b, &off);
975 if (sz < siz[0])
976 siz[0] = sz;
978 if (siz[1] <= sz)
979 siz[1] = sz;
981 if (sz != 0)
983 if (wi::lts_p (off, ovloff[0]))
984 ovloff[0] = off.to_shwi ();
985 if (wi::lts_p (ovloff[1], off))
986 ovloff[1] = off.to_shwi ();
990 else
992 sub1 = !depends_p;
994 /* Iterate over the extreme locations (on the horizontal axis
995 formed by their offsets) and sizes of two regions and find
996 their smallest and largest overlap and the corresponding
997 offsets. */
999 for (unsigned io = 0; io != 2; ++io)
1000 for (unsigned is = 0; is != 2; ++is)
1002 const offset_int a[2] = {
1003 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1006 for (unsigned jo = 0; jo != 2; ++jo)
1007 for (unsigned js = 0; js != 2; ++js)
1009 if (depends_p)
1011 /* For st{p,r}ncpy the size of the source sequence
1012 depends on the offset into it. */
1013 if (js)
1014 break;
1015 js = !jo;
1018 const offset_int b[2] = {
1019 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1022 offset_int off;
1023 offset_int sz = overlap_size (a, b, &off);
1024 if (sz < siz[0])
1025 siz[0] = sz;
1027 if (siz[1] <= sz)
1028 siz[1] = sz;
1030 if (sz != 0)
1032 if (wi::lts_p (off, ovloff[0]))
1033 ovloff[0] = off.to_shwi ();
1034 if (wi::lts_p (ovloff[1], off))
1035 ovloff[1] = off.to_shwi ();
1041 ovlsiz[0] = siz[0].to_shwi ();
1042 ovlsiz[1] = siz[1].to_shwi ();
1044 if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1045 ovloff[0] = ovloff[1] + ovlsiz[1] - 1 - sub1;
1047 return true;
1050 /* Return true if the strcat-like access overlaps. */
1052 bool
1053 builtin_access::strcat_overlap ()
1055 builtin_access &acs = *this;
1056 const builtin_memref *dstref = acs.dstref;
1057 const builtin_memref *srcref = acs.srcref;
1059 gcc_assert (dstref->base == srcref->base);
1061 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1063 gcc_assert (dstref->base && dstref->base == srcref->base);
1065 /* Adjust for strcat-like accesses. */
1067 /* As a special case for strcat, set the DSTREF offsets to the length
1068 of the source string since the function starts writing at the first
1069 nul, and set the size to 1 for the length of the nul. */
1070 acs.dstoff[0] += acs.dstsiz[0];
1071 acs.dstoff[1] += acs.dstsiz[1];
1073 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1075 /* The lower bound is zero when the size is unknown because then
1076 overlap is not certain. */
1077 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1078 acs.dstsiz[1] = 1;
1080 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1081 gcc_assert (maxsize <= maxobjsize);
1083 /* For references to the same base object, determine if there's a pair
1084 of valid offsets into the two references such that access between
1085 them doesn't overlap. Adjust both upper bounds to be valid for
1086 the smaller size (i.e., at most MAXSIZE - SIZE). */
1088 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1089 acs.dstoff[1] = maxsize - acs.dstsiz[0];
1091 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1092 acs.srcoff[1] = maxsize - acs.srcsiz[0];
1094 /* Check to see if there's enough space for both accesses without
1095 overlap. Determine the optimistic (maximum) amount of available
1096 space. */
1097 offset_int space;
1098 if (acs.dstoff[0] <= acs.srcoff[0])
1100 if (acs.dstoff[1] < acs.srcoff[1])
1101 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1102 else
1103 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1105 else
1106 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1108 /* Overlap is certain if the distance between the farthest offsets
1109 of the opposite accesses is less than the sum of the lower bounds
1110 of the sizes of the two accesses. */
1111 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1113 /* For a constant-offset, constant size access, consider the largest
1114 distance between the offset bounds and the lower bound of the access
1115 size. If the overlap isn't certain return success. */
1116 if (!overlap_certain
1117 && acs.dstoff[0] == acs.dstoff[1]
1118 && acs.srcoff[0] == acs.srcoff[1]
1119 && acs.dstsiz[0] == acs.dstsiz[1]
1120 && acs.srcsiz[0] == acs.srcsiz[1])
1121 return false;
1123 /* Overlap is not certain but may be possible. */
1125 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1127 /* Determine the conservative (minimum) amount of space. */
1128 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1129 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1130 if (d < space)
1131 space = d;
1132 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1133 if (d < space)
1134 space = d;
1136 /* For a strict test (used for strcpy and similar with unknown or
1137 variable bounds or sizes), consider the smallest distance between
1138 the offset bounds and either the upper bound of the access size
1139 if known, or the lower bound otherwise. */
1140 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1141 return false;
1143 /* When strcat overlap is certain it is always a single byte:
1144 the terminating NUL, regardless of offsets and sizes. When
1145 overlap is only possible its range is [0, 1]. */
1146 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1147 acs.ovlsiz[1] = 1;
1149 offset_int endoff = dstref->offrange[0] + dstref->sizrange[0];
1150 if (endoff <= srcref->offrange[0])
1151 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1152 else
1153 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1155 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1156 srcref->sizrange[0]).to_shwi ();
1157 if (dstref->offrange[0] == dstref->offrange[1])
1159 if (srcref->offrange[0] == srcref->offrange[1])
1160 acs.ovloff[1] = acs.ovloff[0];
1161 else
1162 acs.ovloff[1]
1163 = wi::smin (maxobjsize,
1164 srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1166 else
1167 acs.ovloff[1]
1168 = wi::smin (maxobjsize,
1169 dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1171 if (acs.sizrange[0] == 0)
1172 acs.sizrange[0] = 1;
1173 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1174 return true;
1177 /* Return true if the strcpy-like access overlaps. */
1179 bool
1180 builtin_access::strcpy_overlap ()
1182 return generic_overlap ();
1186 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1187 one another or that, in order not to overlap, would imply that the size
1188 of the referenced object(s) exceeds the maximum size of an object. Set
1189 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1190 they may overlap in a way that's not apparent from the available data),
1191 return false. */
1193 bool
1194 builtin_access::overlap ()
1196 builtin_access &acs = *this;
1198 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1200 acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1201 srcref->sizrange[0]).to_shwi ();
1202 acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1203 srcref->sizrange[1]).to_shwi ();
1205 /* Check to see if the two references refer to regions that are
1206 too large not to overlap in the address space (whose maximum
1207 size is PTRDIFF_MAX). */
1208 offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1209 if (maxobjsize < size)
1211 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1212 acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1213 return true;
1216 /* If both base objects aren't known return the maximum possible
1217 offset that would make them not overlap. */
1218 if (!dstref->base || !srcref->base)
1219 return false;
1221 /* Set the access offsets. */
1222 acs.dstoff[0] = dstref->offrange[0];
1223 acs.dstoff[1] = dstref->offrange[1];
1225 /* If the base object is an array adjust the bounds of the offset
1226 to be non-negative and within the bounds of the array if possible. */
1227 if (dstref->base
1228 && TREE_CODE (TREE_TYPE (dstref->base)) == ARRAY_TYPE)
1230 if (acs.dstoff[0] < 0 && acs.dstoff[1] >= 0)
1231 acs.dstoff[0] = 0;
1233 if (acs.dstoff[1] < acs.dstoff[0])
1235 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (dstref->base)))
1236 acs.dstoff[1] = wi::umin (acs.dstoff[1], wi::to_offset (size));
1237 else
1238 acs.dstoff[1] = wi::umin (acs.dstoff[1], maxobjsize);
1242 acs.srcoff[0] = srcref->offrange[0];
1243 acs.srcoff[1] = srcref->offrange[1];
1245 if (srcref->base
1246 && TREE_CODE (TREE_TYPE (srcref->base)) == ARRAY_TYPE)
1248 if (acs.srcoff[0] < 0 && acs.srcoff[1] >= 0)
1249 acs.srcoff[0] = 0;
1251 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (srcref->base)))
1252 acs.srcoff[1] = wi::umin (acs.srcoff[1], wi::to_offset (size));
1253 else if (acs.srcoff[1] < acs.srcoff[0])
1254 acs.srcoff[1] = wi::umin (acs.srcoff[1], maxobjsize);
1257 /* When the upper bound of the offset is less than the lower bound
1258 the former is the result of a negative offset being represented
1259 as a large positive value or vice versa. The resulting range is
1260 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1261 a union is not representable using the current data structure
1262 replace it with the full range of offsets. */
1263 if (acs.dstoff[1] < acs.dstoff[0])
1265 acs.dstoff[0] = -maxobjsize - 1;
1266 acs.dstoff[1] = maxobjsize;
1269 /* Validate the offset and size of each reference on its own first.
1270 This is independent of whether or not the base objects are the
1271 same. Normally, this would have already been detected and
1272 diagnosed by -Warray-bounds, unless it has been disabled. */
1273 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1274 if (maxobjsize < maxoff)
1276 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1277 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1278 return true;
1281 /* Repeat the same as above but for the source offsets. */
1282 if (acs.srcoff[1] < acs.srcoff[0])
1284 acs.srcoff[0] = -maxobjsize - 1;
1285 acs.srcoff[1] = maxobjsize;
1288 maxoff = acs.srcoff[0] + srcref->sizrange[0];
1289 if (maxobjsize < maxoff)
1291 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1292 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1293 - maxobjsize).to_shwi ();
1294 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1295 return true;
1298 if (dstref->base != srcref->base)
1299 return false;
1301 acs.dstsiz[0] = dstref->sizrange[0];
1302 acs.dstsiz[1] = dstref->sizrange[1];
1304 acs.srcsiz[0] = srcref->sizrange[0];
1305 acs.srcsiz[1] = srcref->sizrange[1];
1307 /* Call the appropriate function to determine the overlap. */
1308 if ((this->*detect_overlap) ())
1310 if (!sizrange[1])
1312 /* Unless the access size range has already been set, do so here. */
1313 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1314 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1316 return true;
1319 return false;
1322 /* Attempt to detect and diagnose an overlapping copy in a call expression
1323 EXPR involving an an access ACS to a built-in memory or string function.
1324 Return true when one has been detected, false otherwise. */
1326 static bool
1327 maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
1329 if (!acs.overlap ())
1330 return false;
1332 /* For convenience. */
1333 const builtin_memref &dstref = *acs.dstref;
1334 const builtin_memref &srcref = *acs.srcref;
1336 /* Determine the range of offsets and sizes of the overlap if it
1337 exists and issue diagnostics. */
1338 HOST_WIDE_INT *ovloff = acs.ovloff;
1339 HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1340 HOST_WIDE_INT *sizrange = acs.sizrange;
1342 tree func = gimple_call_fndecl (call);
1344 /* To avoid a combinatorial explosion of diagnostics format the offsets
1345 or their ranges as strings and use them in the warning calls below. */
1346 char offstr[3][64];
1348 if (dstref.offrange[0] == dstref.offrange[1]
1349 || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1350 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1351 dstref.offrange[0].to_shwi ());
1352 else
1353 sprintf (offstr[0],
1354 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1355 dstref.offrange[0].to_shwi (),
1356 dstref.offrange[1].to_shwi ());
1358 if (srcref.offrange[0] == srcref.offrange[1]
1359 || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1360 sprintf (offstr[1],
1361 HOST_WIDE_INT_PRINT_DEC,
1362 srcref.offrange[0].to_shwi ());
1363 else
1364 sprintf (offstr[1],
1365 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1366 srcref.offrange[0].to_shwi (),
1367 srcref.offrange[1].to_shwi ());
1369 if (ovloff[0] == ovloff[1] || !ovloff[1])
1370 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1371 else
1372 sprintf (offstr[2],
1373 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1374 ovloff[0], ovloff[1]);
1376 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1377 bool must_overlap = ovlsiz[0] > 0;
1379 if (ovlsiz[1] == 0)
1380 ovlsiz[1] = ovlsiz[0];
1382 if (must_overlap)
1384 /* Issue definitive "overlaps" diagnostic in this block. */
1386 if (sizrange[0] == sizrange[1])
1388 if (ovlsiz[0] == ovlsiz[1])
1389 warning_at (loc, OPT_Wrestrict,
1390 sizrange[0] == 1
1391 ? (ovlsiz[0] == 1
1392 ? G_("%G%qD accessing %wu byte at offsets %s "
1393 "and %s overlaps %wu byte at offset %s")
1394 : G_("%G%qD accessing %wu byte at offsets %s "
1395 "and %s overlaps %wu bytes at offset "
1396 "%s"))
1397 : (ovlsiz[0] == 1
1398 ? G_("%G%qD accessing %wu bytes at offsets %s "
1399 "and %s overlaps %wu byte at offset %s")
1400 : G_("%G%qD accessing %wu bytes at offsets %s "
1401 "and %s overlaps %wu bytes at offset "
1402 "%s")),
1403 call, func, sizrange[0],
1404 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1405 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1406 warning_n (loc, OPT_Wrestrict, sizrange[0],
1407 "%G%qD accessing %wu byte at offsets %s "
1408 "and %s overlaps between %wu and %wu bytes "
1409 "at offset %s",
1410 "%G%qD accessing %wu bytes at offsets %s "
1411 "and %s overlaps between %wu and %wu bytes "
1412 "at offset %s",
1413 call, func, sizrange[0], offstr[0], offstr[1],
1414 ovlsiz[0], ovlsiz[1], offstr[2]);
1415 else
1416 warning_n (loc, OPT_Wrestrict, sizrange[0],
1417 "%G%qD accessing %wu byte at offsets %s and "
1418 "%s overlaps %wu or more bytes at offset %s",
1419 "%G%qD accessing %wu bytes at offsets %s and "
1420 "%s overlaps %wu or more bytes at offset %s",
1421 call, func, sizrange[0],
1422 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1423 return true;
1426 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1428 if (ovlsiz[0] == ovlsiz[1])
1429 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1430 "%G%qD accessing between %wu and %wu bytes "
1431 "at offsets %s and %s overlaps %wu byte at "
1432 "offset %s",
1433 "%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_n (loc, OPT_Wrestrict, ovlsiz[0],
1461 "%G%qD accessing %wu or more bytes at offsets "
1462 "%s and %s overlaps %wu byte at offset %s",
1463 "%G%qD accessing %wu or more bytes at offsets "
1464 "%s and %s overlaps %wu bytes at offset %s",
1465 call, func, sizrange[0], offstr[0], offstr[1],
1466 ovlsiz[0], offstr[2]);
1467 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1468 warning_at (loc, OPT_Wrestrict,
1469 "%G%qD accessing %wu or more bytes at offsets %s "
1470 "and %s overlaps between %wu and %wu bytes "
1471 "at offset %s",
1472 call, func, sizrange[0], offstr[0], offstr[1],
1473 ovlsiz[0], ovlsiz[1], offstr[2]);
1474 else
1475 warning_at (loc, OPT_Wrestrict,
1476 "%G%qD accessing %wu or more bytes at offsets %s "
1477 "and %s overlaps %wu or more bytes at offset %s",
1478 call, func, sizrange[0], offstr[0], offstr[1],
1479 ovlsiz[0], offstr[2]);
1480 return true;
1483 /* Use more concise wording when one of the offsets is unbounded
1484 to avoid confusing the user with large and mostly meaningless
1485 numbers. */
1486 bool open_range;
1487 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1488 open_range = ((dstref.offrange[0] == 0
1489 && dstref.offrange[1] == maxobjsize)
1490 || (srcref.offrange[0] == 0
1491 && srcref.offrange[1] == maxobjsize));
1492 else
1493 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1494 && dstref.offrange[1] == maxobjsize)
1495 || (srcref.offrange[0] == -maxobjsize - 1
1496 && srcref.offrange[1] == maxobjsize));
1498 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1500 if (ovlsiz[1] == 1)
1502 if (open_range)
1503 warning_n (loc, OPT_Wrestrict, sizrange[1],
1504 "%G%qD accessing %wu byte may overlap "
1505 "%wu byte",
1506 "%G%qD accessing %wu bytes may overlap "
1507 "%wu byte",
1508 call, func, sizrange[1], ovlsiz[1]);
1509 else
1510 warning_n (loc, OPT_Wrestrict, sizrange[1],
1511 "%G%qD accessing %wu byte at offsets %s "
1512 "and %s may overlap %wu byte at offset %s",
1513 "%G%qD accessing %wu bytes at offsets %s "
1514 "and %s may overlap %wu byte at offset %s",
1515 call, func, sizrange[1], offstr[0], offstr[1],
1516 ovlsiz[1], offstr[2]);
1517 return true;
1520 if (open_range)
1521 warning_n (loc, OPT_Wrestrict, sizrange[1],
1522 "%G%qD accessing %wu byte may overlap "
1523 "up to %wu bytes",
1524 "%G%qD accessing %wu bytes may overlap "
1525 "up to %wu bytes",
1526 call, func, sizrange[1], ovlsiz[1]);
1527 else
1528 warning_n (loc, OPT_Wrestrict, sizrange[1],
1529 "%G%qD accessing %wu byte at offsets %s and "
1530 "%s may overlap up to %wu bytes at offset %s",
1531 "%G%qD accessing %wu bytes at offsets %s and "
1532 "%s may overlap up to %wu bytes at offset %s",
1533 call, func, sizrange[1], offstr[0], offstr[1],
1534 ovlsiz[1], offstr[2]);
1535 return true;
1538 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1540 if (open_range)
1541 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1542 "%G%qD accessing between %wu and %wu bytes "
1543 "may overlap %wu byte",
1544 "%G%qD accessing between %wu and %wu bytes "
1545 "may overlap up to %wu bytes",
1546 call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1547 else
1548 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1549 "%G%qD accessing between %wu and %wu bytes "
1550 "at offsets %s and %s may overlap %wu byte "
1551 "at offset %s",
1552 "%G%qD accessing between %wu and %wu bytes "
1553 "at offsets %s and %s may overlap up to %wu "
1554 "bytes at offset %s",
1555 call, func, sizrange[0], sizrange[1],
1556 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1557 return true;
1560 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1561 "%G%qD accessing %wu or more bytes at offsets %s "
1562 "and %s may overlap %wu byte at offset %s",
1563 "%G%qD accessing %wu or more bytes at offsets %s "
1564 "and %s may overlap up to %wu bytes at offset %s",
1565 call, func, sizrange[0], offstr[0], offstr[1],
1566 ovlsiz[1], offstr[2]);
1568 return true;
1571 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1572 to a built-in function FUNC to make sure they are within the bounds
1573 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1574 Both initial values of the offsets and their final value computed by
1575 the function by incrementing the initial value by the size are
1576 validated. Return true if the offsets are not valid and a diagnostic
1577 has been issued. */
1579 static bool
1580 maybe_diag_offset_bounds (location_t loc, gimple *call, tree func, int strict,
1581 tree expr, const builtin_memref &ref)
1583 if (!warn_array_bounds)
1584 return false;
1586 if (ref.ref && TREE_NO_WARNING (ref.ref))
1587 return false;
1589 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1] };
1590 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1591 if (!oobref)
1592 return false;
1594 if (EXPR_HAS_LOCATION (expr))
1595 loc = EXPR_LOCATION (expr);
1597 loc = expansion_point_location_if_in_system_header (loc);
1599 char rangestr[2][64];
1600 if (ooboff[0] == ooboff[1]
1601 || (ooboff[0] != ref.offrange[0]
1602 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1603 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1604 else
1605 sprintf (rangestr[0], "[%lli, %lli]",
1606 (long long) ooboff[0].to_shwi (),
1607 (long long) ooboff[1].to_shwi ());
1609 bool warned = false;
1611 if (oobref == error_mark_node)
1613 if (ref.sizrange[0] == ref.sizrange[1])
1614 sprintf (rangestr[1], "%lli", (long long) ref.sizrange[0].to_shwi ());
1615 else
1616 sprintf (rangestr[1], "[%lli, %lli]",
1617 (long long) ref.sizrange[0].to_shwi (),
1618 (long long) ref.sizrange[1].to_shwi ());
1620 tree type;
1622 if (DECL_P (ref.base)
1623 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1625 auto_diagnostic_group d;
1626 if (warning_at (loc, OPT_Warray_bounds,
1627 "%G%qD pointer overflow between offset %s "
1628 "and size %s accessing array %qD with type %qT",
1629 call, func, rangestr[0], rangestr[1], ref.base, type))
1631 inform (DECL_SOURCE_LOCATION (ref.base),
1632 "array %qD declared here", ref.base);
1633 warned = true;
1635 else
1636 warned = warning_at (loc, OPT_Warray_bounds,
1637 "%G%qD pointer overflow between offset %s "
1638 "and size %s",
1639 call, func, rangestr[0], rangestr[1]);
1641 else
1642 warned = warning_at (loc, OPT_Warray_bounds,
1643 "%G%qD pointer overflow between offset %s "
1644 "and size %s",
1645 call, func, rangestr[0], rangestr[1]);
1647 else if (oobref == ref.base)
1649 const offset_int maxobjsize = tree_to_shwi (max_object_size ());
1651 /* True when the offset formed by an access to the reference
1652 is out of bounds, rather than the initial offset wich is
1653 in bounds. This implies access past the end. */
1654 bool form = ooboff[0] != ref.offrange[0];
1656 if (DECL_P (ref.base))
1658 auto_diagnostic_group d;
1659 if ((ref.basesize < maxobjsize
1660 && warning_at (loc, OPT_Warray_bounds,
1661 form
1662 ? G_("%G%qD forming offset %s is out of "
1663 "the bounds [0, %wu] of object %qD with "
1664 "type %qT")
1665 : G_("%G%qD offset %s is out of the bounds "
1666 "[0, %wu] of object %qD with type %qT"),
1667 call, func, rangestr[0], ref.basesize.to_uhwi (),
1668 ref.base, TREE_TYPE (ref.base)))
1669 || warning_at (loc, OPT_Warray_bounds,
1670 form
1671 ? G_("%G%qD forming offset %s is out of "
1672 "the bounds of object %qD with type %qT")
1673 : G_("%G%qD offset %s is out of the bounds "
1674 "of object %qD with type %qT"),
1675 call, func, rangestr[0],
1676 ref.base, TREE_TYPE (ref.base)))
1678 inform (DECL_SOURCE_LOCATION (ref.base),
1679 "%qD declared here", ref.base);
1680 warned = true;
1683 else if (ref.basesize < maxobjsize)
1684 warned = warning_at (loc, OPT_Warray_bounds,
1685 form
1686 ? G_("%G%qD forming offset %s is out "
1687 "of the bounds [0, %wu]")
1688 : G_("%G%qD offset %s is out "
1689 "of the bounds [0, %wu]"),
1690 call, func, rangestr[0], ref.basesize.to_uhwi ());
1691 else
1692 warned = warning_at (loc, OPT_Warray_bounds,
1693 form
1694 ? G_("%G%qD forming offset %s is out of bounds")
1695 : G_("%G%qD offset %s is out of bounds"),
1696 call, func, rangestr[0]);
1698 else if (TREE_CODE (ref.ref) == MEM_REF)
1700 tree type = TREE_TYPE (TREE_OPERAND (ref.ref, 0));
1701 if (POINTER_TYPE_P (type))
1702 type = TREE_TYPE (type);
1703 type = TYPE_MAIN_VARIANT (type);
1705 warned = warning_at (loc, OPT_Warray_bounds,
1706 "%G%qD offset %s from the object at %qE is out "
1707 "of the bounds of %qT",
1708 call, func, rangestr[0], ref.base, type);
1710 else
1712 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1714 warned = warning_at (loc, OPT_Warray_bounds,
1715 "%G%qD offset %s from the object at %qE is out "
1716 "of the bounds of referenced subobject %qD with "
1717 "type %qT at offset %wu",
1718 call, func, rangestr[0], ref.base,
1719 TREE_OPERAND (ref.ref, 1), type,
1720 ref.refoff.to_uhwi ());
1723 return warned;
1726 /* Check a CALL statement for restrict-violations and issue warnings
1727 if/when appropriate. */
1729 void
1730 wrestrict_dom_walker::check_call (gimple *call)
1732 /* Avoid checking the call if it has already been diagnosed for
1733 some reason. */
1734 if (gimple_no_warning_p (call))
1735 return;
1737 tree func = gimple_call_fndecl (call);
1738 if (!func || !fndecl_built_in_p (func, BUILT_IN_NORMAL))
1739 return;
1741 /* Argument number to extract from the call (depends on the built-in
1742 and its kind). */
1743 unsigned dst_idx = -1;
1744 unsigned src_idx = -1;
1745 unsigned bnd_idx = -1;
1747 /* Is this CALL to a string function (as opposed to one to a raw
1748 memory function). */
1749 bool strfun = true;
1751 switch (DECL_FUNCTION_CODE (func))
1753 case BUILT_IN_MEMCPY:
1754 case BUILT_IN_MEMCPY_CHK:
1755 case BUILT_IN_MEMPCPY:
1756 case BUILT_IN_MEMPCPY_CHK:
1757 case BUILT_IN_MEMMOVE:
1758 case BUILT_IN_MEMMOVE_CHK:
1759 strfun = false;
1760 /* Fall through. */
1762 case BUILT_IN_STPNCPY:
1763 case BUILT_IN_STPNCPY_CHK:
1764 case BUILT_IN_STRNCAT:
1765 case BUILT_IN_STRNCAT_CHK:
1766 case BUILT_IN_STRNCPY:
1767 case BUILT_IN_STRNCPY_CHK:
1768 dst_idx = 0;
1769 src_idx = 1;
1770 bnd_idx = 2;
1771 break;
1773 case BUILT_IN_STPCPY:
1774 case BUILT_IN_STPCPY_CHK:
1775 case BUILT_IN_STRCPY:
1776 case BUILT_IN_STRCPY_CHK:
1777 case BUILT_IN_STRCAT:
1778 case BUILT_IN_STRCAT_CHK:
1779 dst_idx = 0;
1780 src_idx = 1;
1781 break;
1783 default:
1784 /* Handle other string functions here whose access may need
1785 to be validated for in-bounds offsets and non-overlapping
1786 copies. */
1787 return;
1790 unsigned nargs = gimple_call_num_args (call);
1792 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1793 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1794 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1796 /* For string functions with an unspecified or unknown bound,
1797 assume the size of the access is one. */
1798 if (!dstwr && strfun)
1799 dstwr = size_one_node;
1801 /* DST and SRC can be null for a call with an insufficient number
1802 of arguments to a built-in function declared without a protype. */
1803 if (!dst || !src)
1804 return;
1806 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1807 a function declared without a prototype. Avoid checking such
1808 invalid calls. */
1809 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1810 || TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
1811 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1812 return;
1814 if (check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
1815 return;
1817 /* Avoid diagnosing the call again. */
1818 gimple_set_no_warning (call, true);
1821 } /* anonymous namespace */
1823 /* Attempt to detect and diagnose invalid offset bounds and (except for
1824 memmove) overlapping copy in a call expression EXPR from SRC to DST
1825 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1826 SRCSIZE may be NULL. Return false when one or the other has been
1827 detected and diagnosed, true otherwise. */
1829 bool
1830 check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
1831 tree srcsize, bool bounds_only /* = false */)
1833 location_t loc = gimple_nonartificial_location (call);
1834 loc = expansion_point_location_if_in_system_header (loc);
1836 tree func = gimple_call_fndecl (call);
1838 builtin_memref dstref (dst, dstsize);
1839 builtin_memref srcref (src, srcsize);
1841 builtin_access acs (call, dstref, srcref);
1843 /* Set STRICT to the value of the -Warray-bounds=N argument for
1844 string functions or when N > 1. */
1845 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
1847 /* Validate offsets first to make sure they are within the bounds
1848 of the destination object if its size is known, or PTRDIFF_MAX
1849 otherwise. */
1850 if (maybe_diag_offset_bounds (loc, call, func, strict, dst, dstref)
1851 || maybe_diag_offset_bounds (loc, call, func, strict, src, srcref))
1853 gimple_set_no_warning (call, true);
1854 return false;
1857 bool check_overlap
1858 = (warn_restrict
1859 && (bounds_only
1860 || (DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE
1861 && DECL_FUNCTION_CODE (func) != BUILT_IN_MEMMOVE_CHK)));
1863 if (!check_overlap)
1864 return true;
1866 if (operand_equal_p (dst, src, 0))
1868 /* Issue -Wrestrict unless the pointers are null (those do
1869 not point to objects and so do not indicate an overlap;
1870 such calls could be the result of sanitization and jump
1871 threading). */
1872 if (!integer_zerop (dst) && !gimple_no_warning_p (call))
1874 warning_at (loc, OPT_Wrestrict,
1875 "%G%qD source argument is the same as destination",
1876 call, func);
1877 gimple_set_no_warning (call, true);
1878 return false;
1881 return true;
1884 /* Return false when overlap has been detected. */
1885 if (maybe_diag_overlap (loc, call, acs))
1887 gimple_set_no_warning (call, true);
1888 return false;
1891 return true;
1894 gimple_opt_pass *
1895 make_pass_warn_restrict (gcc::context *ctxt)
1897 return new pass_wrestrict (ctxt);