MAINTAINERS: Add myself as arc port maintainer
[official-gcc.git] / gcc / gimple-ssa-warn-restrict.c
blob3a79e7240f9562e18fdb3e3bf1e7634bacf3628f
1 /* Pass to detect and issue warnings for violations of the restrict
2 qualifier.
3 Copyright (C) 2017-2020 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 "tree-pass.h"
29 #include "builtins.h"
30 #include "ssa.h"
31 #include "gimple-pretty-print.h"
32 #include "gimple-ssa-warn-restrict.h"
33 #include "diagnostic-core.h"
34 #include "fold-const.h"
35 #include "gimple-iterator.h"
36 #include "tree-dfa.h"
37 #include "tree-ssa.h"
38 #include "tree-cfg.h"
39 #include "tree-object-size.h"
40 #include "calls.h"
41 #include "cfgloop.h"
42 #include "intl.h"
43 #include "gimple-range.h"
45 namespace {
47 const pass_data pass_data_wrestrict = {
48 GIMPLE_PASS,
49 "wrestrict",
50 OPTGROUP_NONE,
51 TV_NONE,
52 PROP_cfg, /* Properties_required. */
53 0, /* properties_provided. */
54 0, /* properties_destroyed. */
55 0, /* properties_start */
56 0, /* properties_finish */
59 /* Pass to detect violations of strict aliasing requirements in calls
60 to built-in string and raw memory functions. */
61 class pass_wrestrict : public gimple_opt_pass
63 public:
64 pass_wrestrict (gcc::context *ctxt)
65 : gimple_opt_pass (pass_data_wrestrict, ctxt)
66 { }
68 opt_pass *clone () { return new pass_wrestrict (m_ctxt); }
70 virtual bool gate (function *);
71 virtual unsigned int execute (function *);
74 bool
75 pass_wrestrict::gate (function *fun ATTRIBUTE_UNUSED)
77 return warn_array_bounds || warn_restrict || warn_stringop_overflow;
80 static void check_call (range_query *, gimple *);
82 static void
83 wrestrict_walk (range_query *query, basic_block bb)
85 /* Iterate over statements, looking for function calls. */
86 for (gimple_stmt_iterator si = gsi_start_bb (bb); !gsi_end_p (si);
87 gsi_next (&si))
89 gimple *stmt = gsi_stmt (si);
90 if (!is_gimple_call (stmt))
91 continue;
93 check_call (query, stmt);
97 unsigned
98 pass_wrestrict::execute (function *fun)
100 gimple_ranger ranger;
101 basic_block bb;
102 FOR_EACH_BB_FN (bb, fun)
103 wrestrict_walk (&ranger, bb);
105 return 0;
108 /* Description of a memory reference by a built-in function. This
109 is similar to ao_ref but made especially suitable for -Wrestrict
110 and not for optimization. */
111 class builtin_memref
113 public:
114 /* The original pointer argument to the built-in function. */
115 tree ptr;
116 /* The referenced subobject or NULL if not available, and the base
117 object of the memory reference or NULL. */
118 tree ref;
119 tree base;
121 /* The size of the BASE object, PTRDIFF_MAX if indeterminate,
122 and negative until (possibly lazily) initialized. */
123 offset_int basesize;
124 /* Same for the subobject. */
125 offset_int refsize;
127 /* The non-negative offset of the referenced subobject. Used to avoid
128 warnings for (apparently) possibly but not definitively overlapping
129 accesses to member arrays. Negative when unknown/invalid. */
130 offset_int refoff;
132 /* The offset range relative to the base. */
133 offset_int offrange[2];
134 /* The size range of the access to this reference. */
135 offset_int sizrange[2];
137 /* Cached result of get_max_objsize(). */
138 const offset_int maxobjsize;
140 /* True for "bounded" string functions like strncat, and strncpy
141 and their variants that specify either an exact or upper bound
142 on the size of the accesses they perform. For strncat both
143 the source and destination references are bounded. For strncpy
144 only the destination reference is. */
145 bool strbounded_p;
147 builtin_memref (range_query *, gimple *, tree, tree);
149 tree offset_out_of_bounds (int, offset_int[3]) const;
151 private:
152 /* Call statement to the built-in. */
153 gimple *stmt;
155 range_query *query;
157 /* Ctor helper to set or extend OFFRANGE based on argument. */
158 void extend_offset_range (tree);
160 /* Ctor helper to determine BASE and OFFRANGE from argument. */
161 void set_base_and_offset (tree);
164 /* Description of a memory access by a raw memory or string built-in
165 function involving a pair of builtin_memref's. */
166 class builtin_access
168 public:
169 /* Destination and source memory reference. */
170 builtin_memref* const dstref;
171 builtin_memref* const srcref;
172 /* The size range of the access. It's the greater of the accesses
173 to the two references. */
174 HOST_WIDE_INT sizrange[2];
176 /* The minimum and maximum offset of an overlap of the access
177 (if it does, in fact, overlap), and the size of the overlap. */
178 HOST_WIDE_INT ovloff[2];
179 HOST_WIDE_INT ovlsiz[2];
181 /* True to consider valid only accesses to the smallest subobject
182 and false for raw memory functions. */
183 bool strict () const
185 return (detect_overlap != &builtin_access::generic_overlap
186 && detect_overlap != &builtin_access::no_overlap);
189 builtin_access (range_query *, gimple *, builtin_memref &, builtin_memref &);
191 /* Entry point to determine overlap. */
192 bool overlap ();
194 offset_int write_off (tree) const;
196 void dump (FILE *) const;
198 private:
199 /* Implementation functions used to determine overlap. */
200 bool generic_overlap ();
201 bool strcat_overlap ();
202 bool strcpy_overlap ();
204 bool no_overlap ()
206 return false;
209 offset_int overlap_size (const offset_int [2], const offset_int[2],
210 offset_int [2]);
212 private:
213 /* Temporaries used to compute the final result. */
214 offset_int dstoff[2];
215 offset_int srcoff[2];
216 offset_int dstsiz[2];
217 offset_int srcsiz[2];
219 /* Pointer to a member function to call to determine overlap. */
220 bool (builtin_access::*detect_overlap) ();
223 /* Initialize a memory reference representation from a pointer EXPR and
224 a size SIZE in bytes. If SIZE is NULL_TREE then the size is assumed
225 to be unknown. STMT is the statement in which expr appears in. */
227 builtin_memref::builtin_memref (range_query *query, gimple *stmt, tree expr,
228 tree size)
229 : ptr (expr),
230 ref (),
231 base (),
232 basesize (-1),
233 refsize (-1),
234 refoff (HOST_WIDE_INT_MIN),
235 offrange (),
236 sizrange (),
237 maxobjsize (tree_to_shwi (max_object_size ())),
238 strbounded_p (),
239 stmt (stmt),
240 query (query)
242 /* Unfortunately, wide_int default ctor is a no-op so array members
243 of the type must be set individually. */
244 offrange[0] = offrange[1] = 0;
245 sizrange[0] = sizrange[1] = 0;
247 if (!expr)
248 return;
250 /* Find the BASE object or pointer referenced by EXPR and set
251 the offset range OFFRANGE in the process. */
252 set_base_and_offset (expr);
254 if (size)
256 tree range[2];
257 /* Determine the size range, allowing for the result to be [0, 0]
258 for SIZE in the anti-range ~[0, N] where N >= PTRDIFF_MAX. */
259 get_size_range (query, size, stmt, range, SR_ALLOW_ZERO);
260 sizrange[0] = wi::to_offset (range[0]);
261 sizrange[1] = wi::to_offset (range[1]);
262 /* get_size_range returns SIZE_MAX for the maximum size.
263 Constrain it to the real maximum of PTRDIFF_MAX. */
264 if (sizrange[0] <= maxobjsize && sizrange[1] > maxobjsize)
265 sizrange[1] = maxobjsize;
267 else
268 sizrange[1] = maxobjsize;
270 if (!DECL_P (base))
271 return;
273 /* If the offset could be in the range of the referenced object
274 constrain its bounds so neither exceeds those of the object. */
275 if (offrange[0] < 0 && offrange[1] > 0)
276 offrange[0] = 0;
278 offset_int maxoff = maxobjsize;
279 tree basetype = TREE_TYPE (base);
280 if (TREE_CODE (basetype) == ARRAY_TYPE)
282 if (ref && array_at_struct_end_p (ref))
283 ; /* Use the maximum possible offset for last member arrays. */
284 else if (tree basesize = TYPE_SIZE_UNIT (basetype))
285 if (TREE_CODE (basesize) == INTEGER_CST)
286 /* Size could be non-constant for a variable-length type such
287 as a struct with a VLA member (a GCC extension). */
288 maxoff = wi::to_offset (basesize);
291 if (offrange[0] >= 0)
293 if (offrange[1] < 0)
294 offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
295 else if (offrange[0] <= maxoff && offrange[1] > maxoff)
296 offrange[1] = maxoff;
300 /* Based on the initial length of the destination STARTLEN, returns
301 the offset of the first write access from the beginning of
302 the destination. Nonzero only for strcat-type of calls. */
304 offset_int builtin_access::write_off (tree startlen) const
306 if (detect_overlap != &builtin_access::strcat_overlap
307 || !startlen || TREE_CODE (startlen) != INTEGER_CST)
308 return 0;
310 return wi::to_offset (startlen);
313 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument.
314 Pointer offsets are represented as unsigned sizetype but must be
315 treated as signed. */
317 void
318 builtin_memref::extend_offset_range (tree offset)
320 if (TREE_CODE (offset) == INTEGER_CST)
322 offset_int off = int_cst_value (offset);
323 if (off != 0)
325 offrange[0] += off;
326 offrange[1] += off;
328 return;
331 if (TREE_CODE (offset) == SSA_NAME)
333 /* A pointer offset is represented as sizetype but treated
334 as signed. */
335 wide_int min, max;
336 value_range_kind rng;
337 value_range vr;
338 if (query && query->range_of_expr (vr, offset, stmt))
340 rng = vr.kind ();
341 if (!vr.undefined_p ())
343 min = wi::to_wide (vr.min ());
344 max = wi::to_wide (vr.max ());
347 else
349 /* There is a global version here because
350 check_bounds_or_overlap may be called from gimple
351 fold during gimple lowering. */
352 rng = get_range_info (offset, &min, &max);
354 if (rng == VR_ANTI_RANGE && wi::lts_p (max, min))
356 /* Convert an anti-range whose upper bound is less than
357 its lower bound to a signed range. */
358 offrange[0] += offset_int::from (max + 1, SIGNED);
359 offrange[1] += offset_int::from (min - 1, SIGNED);
360 return;
363 if (rng == VR_RANGE
364 && (DECL_P (base) || wi::lts_p (min, max)))
366 /* Preserve the bounds of the range for an offset into
367 a known object (it may be adjusted later relative to
368 a constant offset from its beginning). Otherwise use
369 the bounds only when they are ascending when treated
370 as signed. */
371 offrange[0] += offset_int::from (min, SIGNED);
372 offrange[1] += offset_int::from (max, SIGNED);
373 return;
376 /* Handle an anti-range the same as no range at all. */
377 gimple *stmt = SSA_NAME_DEF_STMT (offset);
378 tree type;
379 if (is_gimple_assign (stmt)
380 && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
381 && INTEGRAL_TYPE_P (type))
383 tree_code code = gimple_assign_rhs_code (stmt);
384 if (code == NOP_EXPR)
386 /* Use the bounds of the type of the NOP_EXPR operand
387 even if it's signed. The result doesn't trigger
388 warnings but makes their output more readable. */
389 offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
390 offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
391 return;
396 const offset_int maxoff = tree_to_shwi (max_object_size ()) >> 1;
397 const offset_int minoff = -maxoff - 1;
399 offrange[0] += minoff;
400 offrange[1] += maxoff;
403 /* Determines the base object or pointer of the reference EXPR
404 and the offset range from the beginning of the base. */
406 void
407 builtin_memref::set_base_and_offset (tree expr)
409 tree offset = NULL_TREE;
411 if (TREE_CODE (expr) == SSA_NAME)
413 /* Try to tease the offset out of the pointer. */
414 gimple *stmt = SSA_NAME_DEF_STMT (expr);
415 if (!base
416 && gimple_assign_single_p (stmt)
417 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
418 expr = gimple_assign_rhs1 (stmt);
419 else if (is_gimple_assign (stmt))
421 tree_code code = gimple_assign_rhs_code (stmt);
422 if (code == NOP_EXPR)
424 tree rhs = gimple_assign_rhs1 (stmt);
425 if (POINTER_TYPE_P (TREE_TYPE (rhs)))
426 expr = gimple_assign_rhs1 (stmt);
427 else
429 base = expr;
430 return;
433 else if (code == POINTER_PLUS_EXPR)
435 expr = gimple_assign_rhs1 (stmt);
436 offset = gimple_assign_rhs2 (stmt);
438 else
440 base = expr;
441 return;
444 else
446 /* FIXME: Handle PHI nodes in case like:
447 _12 = &MEM[(void *)&a + 2B] + _10;
449 <bb> [local count: 1073741824]:
450 # prephitmp_13 = PHI <_12, &MEM[(void *)&a + 2B]>
451 memcpy (prephitmp_13, p_7(D), 6); */
452 base = expr;
453 return;
457 if (TREE_CODE (expr) == ADDR_EXPR)
458 expr = TREE_OPERAND (expr, 0);
460 /* Stash the reference for offset validation. */
461 ref = expr;
463 poly_int64 bitsize, bitpos;
464 tree var_off;
465 machine_mode mode;
466 int sign, reverse, vol;
468 /* Determine the base object or pointer of the reference and
469 the constant bit offset from the beginning of the base.
470 If the offset has a non-constant component, it will be in
471 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
472 unused here. */
473 base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
474 &mode, &sign, &reverse, &vol);
476 /* get_inner_reference is not expected to return null. */
477 gcc_assert (base != NULL);
479 if (offset)
480 extend_offset_range (offset);
482 poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
484 /* Convert the poly_int64 offset to offset_int. The offset
485 should be constant but be prepared for it not to be just in
486 case. */
487 offset_int cstoff;
488 if (bytepos.is_constant (&cstoff))
490 offrange[0] += cstoff;
491 offrange[1] += cstoff;
493 /* Besides the reference saved above, also stash the offset
494 for validation. */
495 if (TREE_CODE (expr) == COMPONENT_REF)
496 refoff = cstoff;
498 else
499 offrange[1] += maxobjsize;
501 if (var_off)
503 if (TREE_CODE (var_off) == INTEGER_CST)
505 cstoff = wi::to_offset (var_off);
506 offrange[0] += cstoff;
507 offrange[1] += cstoff;
509 else
510 offrange[1] += maxobjsize;
513 if (TREE_CODE (base) == MEM_REF)
515 tree memrefoff = fold_convert (ptrdiff_type_node, TREE_OPERAND (base, 1));
516 extend_offset_range (memrefoff);
517 base = TREE_OPERAND (base, 0);
519 if (refoff != HOST_WIDE_INT_MIN
520 && TREE_CODE (expr) == COMPONENT_REF)
522 /* Bump up the offset of the referenced subobject to reflect
523 the offset to the enclosing object. For example, so that
525 struct S { char a, b[3]; } s[2];
526 strcpy (s[1].b, "1234");
527 REFOFF is set to s[1].b - (char*)s. */
528 offset_int off = tree_to_shwi (memrefoff);
529 refoff += off;
532 if (!integer_zerop (memrefoff))
533 /* A non-zero offset into an array of struct with flexible array
534 members implies that the array is empty because there is no
535 way to initialize such a member when it belongs to an array.
536 This must be some sort of a bug. */
537 refsize = 0;
540 if (TREE_CODE (ref) == COMPONENT_REF)
541 if (tree size = component_ref_size (ref))
542 if (TREE_CODE (size) == INTEGER_CST)
543 refsize = wi::to_offset (size);
545 if (TREE_CODE (base) == SSA_NAME)
546 set_base_and_offset (base);
549 /* Return error_mark_node if the signed offset exceeds the bounds
550 of the address space (PTRDIFF_MAX). Otherwise, return either BASE
551 or REF when the offset exceeds the bounds of the BASE or REF object,
552 and set OOBOFF to the past-the-end offset formed by the reference,
553 including its size. OOBOFF is initially setto the range of offsets,
554 and OOBOFF[2] to the offset of the first write access (nonzero for
555 the strcat family). When STRICT is nonzero use REF size, when
556 available, otherwise use BASE size. When STRICT is greater than 1,
557 use the size of the last array member as the bound, otherwise treat
558 such a member as a flexible array member. Return NULL when the offset
559 is in bounds. */
561 tree
562 builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[3]) const
564 if (!ptr)
565 return NULL_TREE;
567 /* The offset of the first write access or zero. */
568 offset_int wroff = ooboff[2];
570 /* A temporary, possibly adjusted, copy of the offset range. */
571 offset_int offrng[2] = { ooboff[0], ooboff[1] };
573 if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
575 /* Check for offset in an anti-range with a negative lower bound.
576 For such a range, consider only the non-negative subrange. */
577 if (offrng[1] < offrng[0] && offrng[1] < 0)
578 offrng[1] = maxobjsize;
581 /* Conservative offset of the last byte of the referenced object. */
582 offset_int endoff;
584 /* The bounds need not be ordered. Set HIB to use as the index
585 of the larger of the bounds and LOB as the opposite. */
586 bool hib = wi::les_p (offrng[0], offrng[1]);
587 bool lob = !hib;
589 /* Set to the size remaining in the object after subtracting
590 REFOFF. It may become negative as a result of negative indices
591 into the enclosing object, such as in:
592 extern struct S { char a[4], b[3], c[1]; } *p;
593 strcpy (p[-3].b, "123"); */
594 offset_int size = basesize;
595 tree obj = base;
597 const bool decl_p = DECL_P (obj);
599 if (basesize < 0)
601 endoff = offrng[lob] + (sizrange[0] - wroff);
603 /* For a reference through a pointer to an object of unknown size
604 all initial offsets are considered valid, positive as well as
605 negative, since the pointer itself can point past the beginning
606 of the object. However, the sum of the lower bound of the offset
607 and that of the size must be less than or equal than PTRDIFF_MAX. */
608 if (endoff > maxobjsize)
609 return error_mark_node;
611 /* When the referenced subobject is known, the end offset must be
612 within its bounds. Otherwise there is nothing to do. */
613 if (strict
614 && !decl_p
615 && ref
616 && refsize >= 0
617 && TREE_CODE (ref) == COMPONENT_REF)
619 /* If REFOFF is negative, SIZE will become negative here. */
620 size = refoff + refsize;
621 obj = ref;
623 else
624 return NULL_TREE;
627 /* A reference to an object of known size must be within the bounds
628 of either the base object or the subobject (see above for when
629 a subobject can be used). */
630 if ((decl_p && offrng[hib] < 0) || offrng[lob] > size)
631 return obj;
633 /* The extent of the reference must also be within the bounds of
634 the base object (if known) or the subobject or the maximum object
635 size otherwise. */
636 endoff = offrng[lob] + sizrange[0];
637 if (endoff > maxobjsize)
638 return error_mark_node;
640 if (strict
641 && decl_p
642 && ref
643 && refsize >= 0
644 && TREE_CODE (ref) == COMPONENT_REF)
646 /* If the reference is to a member subobject of a declared object,
647 the offset must be within the bounds of the subobject. */
648 size = refoff + refsize;
649 obj = ref;
652 if (endoff <= size)
653 return NULL_TREE;
655 /* Set the out-of-bounds offset range to be one greater than
656 that delimited by the reference including its size. */
657 ooboff[lob] = size;
659 if (endoff > ooboff[lob])
660 ooboff[hib] = endoff - 1;
661 else
662 ooboff[hib] = offrng[lob] + sizrange[1];
664 return obj;
667 /* Create an association between the memory references DST and SRC
668 for access by a call EXPR to a memory or string built-in funtion. */
670 builtin_access::builtin_access (range_query *query, gimple *call,
671 builtin_memref &dst,
672 builtin_memref &src)
673 : dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
674 dstoff (), srcoff (), dstsiz (), srcsiz ()
676 dstoff[0] = dst.offrange[0];
677 dstoff[1] = dst.offrange[1];
679 /* Zero out since the offset_int ctors invoked above are no-op. */
680 srcoff[0] = srcoff[1] = 0;
681 dstsiz[0] = dstsiz[1] = 0;
682 srcsiz[0] = srcsiz[1] = 0;
684 /* Object Size Type to use to determine the size of the destination
685 and source objects. Overridden below for raw memory functions. */
686 int ostype = 1;
688 /* True when the size of one reference depends on the offset of
689 itself or the other. */
690 bool depends_p = true;
692 /* True when the size of the destination reference DSTREF has been
693 determined from SRCREF and so needs to be adjusted by the latter's
694 offset. Only meaningful for bounded string functions like strncpy. */
695 bool dstadjust_p = false;
697 /* The size argument number (depends on the built-in). */
698 unsigned sizeargno = 2;
700 tree func = gimple_call_fndecl (call);
701 switch (DECL_FUNCTION_CODE (func))
703 case BUILT_IN_MEMCPY:
704 case BUILT_IN_MEMCPY_CHK:
705 case BUILT_IN_MEMPCPY:
706 case BUILT_IN_MEMPCPY_CHK:
707 ostype = 0;
708 depends_p = false;
709 detect_overlap = &builtin_access::generic_overlap;
710 break;
712 case BUILT_IN_MEMMOVE:
713 case BUILT_IN_MEMMOVE_CHK:
714 /* For memmove there is never any overlap to check for. */
715 ostype = 0;
716 depends_p = false;
717 detect_overlap = &builtin_access::no_overlap;
718 break;
720 case BUILT_IN_MEMSET:
721 case BUILT_IN_MEMSET_CHK:
722 /* For memset there is never any overlap to check for. */
723 ostype = 0;
724 depends_p = false;
725 detect_overlap = &builtin_access::no_overlap;
726 break;
728 case BUILT_IN_STPNCPY:
729 case BUILT_IN_STPNCPY_CHK:
730 case BUILT_IN_STRNCPY:
731 case BUILT_IN_STRNCPY_CHK:
732 dstref->strbounded_p = true;
733 detect_overlap = &builtin_access::strcpy_overlap;
734 break;
736 case BUILT_IN_STPCPY:
737 case BUILT_IN_STPCPY_CHK:
738 case BUILT_IN_STRCPY:
739 case BUILT_IN_STRCPY_CHK:
740 detect_overlap = &builtin_access::strcpy_overlap;
741 break;
743 case BUILT_IN_STRCAT:
744 case BUILT_IN_STRCAT_CHK:
745 detect_overlap = &builtin_access::strcat_overlap;
746 break;
748 case BUILT_IN_STRNCAT:
749 case BUILT_IN_STRNCAT_CHK:
750 dstref->strbounded_p = true;
751 srcref->strbounded_p = true;
752 detect_overlap = &builtin_access::strcat_overlap;
753 break;
755 default:
756 /* Handle other string functions here whose access may need
757 to be validated for in-bounds offsets and non-overlapping
758 copies. */
759 return;
762 const offset_int maxobjsize = dst.maxobjsize;
764 /* Try to determine the size of the base object. compute_objsize
765 expects a pointer so create one if BASE is a non-pointer object. */
766 tree addr;
767 if (dst.basesize < 0)
769 addr = dst.base;
770 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
771 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
773 if (tree dstsize = compute_objsize (addr, ostype))
774 dst.basesize = wi::to_offset (dstsize);
775 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
776 dst.basesize = HOST_WIDE_INT_MIN;
777 else
778 dst.basesize = maxobjsize;
781 if (src.base && src.basesize < 0)
783 addr = src.base;
784 if (!POINTER_TYPE_P (TREE_TYPE (addr)))
785 addr = build1 (ADDR_EXPR, (TREE_TYPE (addr)), addr);
787 if (tree srcsize = compute_objsize (addr, ostype))
788 src.basesize = wi::to_offset (srcsize);
789 else if (POINTER_TYPE_P (TREE_TYPE (addr)))
790 src.basesize = HOST_WIDE_INT_MIN;
791 else
792 src.basesize = maxobjsize;
795 /* Make adjustments for references to the same object by string
796 built-in functions to reflect the constraints imposed by
797 the function. */
799 /* For bounded string functions determine the range of the bound
800 on the access. For others, the range stays unbounded. */
801 offset_int bounds[2] = { maxobjsize, maxobjsize };
802 if (dstref->strbounded_p)
804 unsigned nargs = gimple_call_num_args (call);
805 if (nargs <= sizeargno)
806 return;
808 tree size = gimple_call_arg (call, sizeargno);
809 tree range[2];
810 if (get_size_range (query, size, call, range, true))
812 bounds[0] = wi::to_offset (range[0]);
813 bounds[1] = wi::to_offset (range[1]);
816 /* If both references' size ranges are indeterminate use the last
817 (size) argument from the function call as a substitute. This
818 may only be necessary for strncpy (but not for memcpy where
819 the size range would have been already determined this way). */
820 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
821 && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
823 dstref->sizrange[0] = bounds[0];
824 dstref->sizrange[1] = bounds[1];
828 bool dstsize_set = false;
829 /* The size range of one reference involving the same base object
830 can be determined from the size range of the other reference.
831 This makes it possible to compute accurate offsets for warnings
832 involving functions like strcpy where the length of just one of
833 the two arguments is known (determined by tree-ssa-strlen). */
834 if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
836 /* When the destination size is unknown set it to the size of
837 the source. */
838 dstref->sizrange[0] = srcref->sizrange[0];
839 dstref->sizrange[1] = srcref->sizrange[1];
840 dstsize_set = true;
842 else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
844 /* When the size of the source access is unknown set it to the size
845 of the destination first and adjust it later if necessary. */
846 srcref->sizrange[0] = dstref->sizrange[0];
847 srcref->sizrange[1] = dstref->sizrange[1];
849 if (depends_p)
851 if (dstref->strbounded_p)
853 /* Read access by strncpy is constrained by the third
854 argument but except for a zero bound is at least one. */
855 srcref->sizrange[0] = bounds[1] > 0 ? 1 : 0;
856 offset_int bound = wi::umin (srcref->basesize, bounds[1]);
857 if (bound < srcref->sizrange[1])
858 srcref->sizrange[1] = bound;
860 /* For string functions, adjust the size range of the source
861 reference by the inverse boundaries of the offset (because
862 the higher the offset into the string the shorter its
863 length). */
864 if (srcref->offrange[1] >= 0
865 && srcref->offrange[1] < srcref->sizrange[0])
866 srcref->sizrange[0] -= srcref->offrange[1];
867 else
868 srcref->sizrange[0] = 1;
870 if (srcref->offrange[0] > 0)
872 if (srcref->offrange[0] < srcref->sizrange[1])
873 srcref->sizrange[1] -= srcref->offrange[0];
874 else
875 srcref->sizrange[1] = 0;
878 dstadjust_p = true;
882 if (detect_overlap == &builtin_access::generic_overlap)
884 if (dstref->strbounded_p)
886 dstref->sizrange[0] = bounds[0];
887 dstref->sizrange[1] = bounds[1];
889 if (dstref->sizrange[0] < srcref->sizrange[0])
890 srcref->sizrange[0] = dstref->sizrange[0];
892 if (dstref->sizrange[1] < srcref->sizrange[1])
893 srcref->sizrange[1] = dstref->sizrange[1];
896 else if (detect_overlap == &builtin_access::strcpy_overlap)
898 if (!dstref->strbounded_p)
900 /* For strcpy, adjust the destination size range to match that
901 of the source computed above. */
902 if (depends_p && dstadjust_p)
904 dstref->sizrange[0] = srcref->sizrange[0];
905 dstref->sizrange[1] = srcref->sizrange[1];
909 else if (!dstsize_set && detect_overlap == &builtin_access::strcat_overlap)
911 dstref->sizrange[0] += srcref->sizrange[0] - 1;
912 dstref->sizrange[1] += srcref->sizrange[1] - 1;
915 if (dstref->strbounded_p)
917 /* For strncpy, adjust the destination size range to match that
918 of the source computed above. */
919 dstref->sizrange[0] = bounds[0];
920 dstref->sizrange[1] = bounds[1];
922 if (bounds[0] < srcref->sizrange[0])
923 srcref->sizrange[0] = bounds[0];
925 if (bounds[1] < srcref->sizrange[1])
926 srcref->sizrange[1] = bounds[1];
930 offset_int
931 builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
932 offset_int *off)
934 const offset_int *p = a;
935 const offset_int *q = b;
937 /* Point P at the bigger of the two ranges and Q at the smaller. */
938 if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
940 p = b;
941 q = a;
944 if (p[0] < q[0])
946 if (p[1] < q[0])
947 return 0;
949 *off = q[0];
950 return wi::smin (p[1], q[1]) - q[0];
953 if (q[1] < p[0])
954 return 0;
956 off[0] = p[0];
957 return q[1] - p[0];
960 /* Return true if the bounded mempry (memcpy amd similar) or string function
961 access (strncpy and similar) ACS overlaps. */
963 bool
964 builtin_access::generic_overlap ()
966 builtin_access &acs = *this;
967 const builtin_memref *dstref = acs.dstref;
968 const builtin_memref *srcref = acs.srcref;
970 gcc_assert (dstref->base == srcref->base);
972 const offset_int maxobjsize = acs.dstref->maxobjsize;
974 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
976 /* Adjust the larger bounds of the offsets (which may be the first
977 element if the lower bound is larger than the upper bound) to
978 make them valid for the smallest access (if possible) but no smaller
979 than the smaller bounds. */
980 gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));
982 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
983 acs.dstoff[1] = maxsize - acs.dstsiz[0];
984 if (acs.dstoff[1] < acs.dstoff[0])
985 acs.dstoff[1] = acs.dstoff[0];
987 gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));
989 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
990 acs.srcoff[1] = maxsize - acs.srcsiz[0];
991 if (acs.srcoff[1] < acs.srcoff[0])
992 acs.srcoff[1] = acs.srcoff[0];
994 /* Determine the minimum and maximum space for the access given
995 the offsets. */
996 offset_int space[2];
997 space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
998 space[1] = space[0];
1000 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1001 if (acs.srcsiz[0] > 0)
1003 if (d < space[0])
1004 space[0] = d;
1006 if (space[1] < d)
1007 space[1] = d;
1009 else
1010 space[1] = acs.dstsiz[1];
1012 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1013 if (d < space[0])
1014 space[0] = d;
1016 if (space[1] < d)
1017 space[1] = d;
1019 /* Treat raw memory functions both of whose references are bounded
1020 as special and permit uncertain overlaps to go undetected. For
1021 all kinds of constant offset and constant size accesses, if
1022 overlap isn't certain it is not possible. */
1023 bool overlap_possible = space[0] < acs.dstsiz[1];
1024 if (!overlap_possible)
1025 return false;
1027 bool overlap_certain = space[1] < acs.dstsiz[0];
1029 /* True when the size of one reference depends on the offset of
1030 the other. */
1031 bool depends_p = detect_overlap != &builtin_access::generic_overlap;
1033 if (!overlap_certain)
1035 if (!dstref->strbounded_p && !depends_p)
1036 /* Memcpy only considers certain overlap. */
1037 return false;
1039 /* There's no way to distinguish an access to the same member
1040 of a structure from one to two distinct members of the same
1041 structure. Give up to avoid excessive false positives. */
1042 tree basetype = TREE_TYPE (dstref->base);
1044 if (POINTER_TYPE_P (basetype))
1045 basetype = TREE_TYPE (basetype);
1046 else
1047 while (TREE_CODE (basetype) == ARRAY_TYPE)
1048 basetype = TREE_TYPE (basetype);
1050 if (RECORD_OR_UNION_TYPE_P (basetype))
1051 return false;
1054 /* True for stpcpy and strcpy. */
1055 bool stxcpy_p = (!dstref->strbounded_p
1056 && detect_overlap == &builtin_access::strcpy_overlap);
1058 if (dstref->refoff >= 0
1059 && srcref->refoff >= 0
1060 && dstref->refoff != srcref->refoff
1061 && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
1062 return false;
1064 offset_int siz[2] = { maxobjsize + 1, 0 };
1066 ovloff[0] = HOST_WIDE_INT_MAX;
1067 ovloff[1] = HOST_WIDE_INT_MIN;
1069 if (stxcpy_p)
1071 /* Iterate over the extreme locations (on the horizontal axis formed
1072 by their offsets) and sizes of two regions and find their smallest
1073 and largest overlap and the corresponding offsets. */
1074 for (unsigned i = 0; i != 2; ++i)
1076 const offset_int a[2] = {
1077 acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
1080 const offset_int b[2] = {
1081 acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
1084 offset_int off;
1085 offset_int sz = overlap_size (a, b, &off);
1086 if (sz < siz[0])
1087 siz[0] = sz;
1089 if (siz[1] <= sz)
1090 siz[1] = sz;
1092 if (sz != 0)
1094 if (wi::lts_p (off, ovloff[0]))
1095 ovloff[0] = off.to_shwi ();
1096 if (wi::lts_p (ovloff[1], off))
1097 ovloff[1] = off.to_shwi ();
1101 else
1103 /* Iterate over the extreme locations (on the horizontal axis
1104 formed by their offsets) and sizes of the two regions and
1105 find their smallest and largest overlap and the corresponding
1106 offsets. */
1108 for (unsigned io = 0; io != 2; ++io)
1109 for (unsigned is = 0; is != 2; ++is)
1111 const offset_int a[2] = {
1112 acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
1115 for (unsigned jo = 0; jo != 2; ++jo)
1116 for (unsigned js = 0; js != 2; ++js)
1118 const offset_int b[2] = {
1119 acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
1122 offset_int off;
1123 offset_int sz = overlap_size (a, b, &off);
1124 if (sz < siz[0])
1125 siz[0] = sz;
1127 if (siz[1] <= sz)
1128 siz[1] = sz;
1130 if (sz != 0)
1132 if (wi::lts_p (off, ovloff[0]))
1133 ovloff[0] = off.to_shwi ();
1134 if (wi::lts_p (ovloff[1], off))
1135 ovloff[1] = off.to_shwi ();
1141 ovlsiz[0] = siz[0].to_shwi ();
1142 ovlsiz[1] = siz[1].to_shwi ();
1144 /* Adjust the overlap offset range to reflect the overlap size range. */
1145 if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
1146 ovloff[1] = ovloff[0] + ovlsiz[1] - 1;
1148 return true;
1151 /* Return true if the strcat-like access overlaps. */
1153 bool
1154 builtin_access::strcat_overlap ()
1156 builtin_access &acs = *this;
1157 const builtin_memref *dstref = acs.dstref;
1158 const builtin_memref *srcref = acs.srcref;
1160 gcc_assert (dstref->base == srcref->base);
1162 const offset_int maxobjsize = acs.dstref->maxobjsize;
1164 gcc_assert (dstref->base && dstref->base == srcref->base);
1166 /* Adjust for strcat-like accesses. */
1168 /* As a special case for strcat, set the DSTREF offsets to the length
1169 of the destination string since the function starts writing over
1170 its terminating nul, and set the destination size to 1 for the length
1171 of the nul. */
1172 acs.dstoff[0] += dstsiz[0] - srcref->sizrange[0];
1173 acs.dstoff[1] += dstsiz[1] - srcref->sizrange[1];
1175 bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;
1177 /* The lower bound is zero when the size is unknown because then
1178 overlap is not certain. */
1179 acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
1180 acs.dstsiz[1] = 1;
1182 offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;
1184 /* For references to the same base object, determine if there's a pair
1185 of valid offsets into the two references such that access between
1186 them doesn't overlap. Adjust both upper bounds to be valid for
1187 the smaller size (i.e., at most MAXSIZE - SIZE). */
1189 if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
1190 acs.dstoff[1] = maxsize - acs.dstsiz[0];
1192 if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
1193 acs.srcoff[1] = maxsize - acs.srcsiz[0];
1195 /* Check to see if there's enough space for both accesses without
1196 overlap. Determine the optimistic (maximum) amount of available
1197 space. */
1198 offset_int space;
1199 if (acs.dstoff[0] <= acs.srcoff[0])
1201 if (acs.dstoff[1] < acs.srcoff[1])
1202 space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
1203 else
1204 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1206 else
1207 space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
1209 /* Overlap is certain if the distance between the farthest offsets
1210 of the opposite accesses is less than the sum of the lower bounds
1211 of the sizes of the two accesses. */
1212 bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];
1214 /* For a constant-offset, constant size access, consider the largest
1215 distance between the offset bounds and the lower bound of the access
1216 size. If the overlap isn't certain return success. */
1217 if (!overlap_certain
1218 && acs.dstoff[0] == acs.dstoff[1]
1219 && acs.srcoff[0] == acs.srcoff[1]
1220 && acs.dstsiz[0] == acs.dstsiz[1]
1221 && acs.srcsiz[0] == acs.srcsiz[1])
1222 return false;
1224 /* Overlap is not certain but may be possible. */
1226 offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];
1228 /* Determine the conservative (minimum) amount of space. */
1229 space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
1230 offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
1231 if (d < space)
1232 space = d;
1233 d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
1234 if (d < space)
1235 space = d;
1237 /* For a strict test (used for strcpy and similar with unknown or
1238 variable bounds or sizes), consider the smallest distance between
1239 the offset bounds and either the upper bound of the access size
1240 if known, or the lower bound otherwise. */
1241 if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
1242 return false;
1244 /* When strcat overlap is certain it is always a single byte:
1245 the terminating NUL, regardless of offsets and sizes. When
1246 overlap is only possible its range is [0, 1]. */
1247 acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
1248 acs.ovlsiz[1] = 1;
1250 offset_int endoff
1251 = dstref->offrange[0] + (dstref->sizrange[0] - srcref->sizrange[0]);
1252 if (endoff <= srcref->offrange[0])
1253 acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
1254 else
1255 acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();
1257 acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
1258 srcref->sizrange[0]).to_shwi ();
1259 if (dstref->offrange[0] == dstref->offrange[1])
1261 if (srcref->offrange[0] == srcref->offrange[1])
1262 acs.ovloff[1] = acs.ovloff[0];
1263 else
1264 acs.ovloff[1]
1265 = wi::smin (maxobjsize,
1266 srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
1268 else
1269 acs.ovloff[1]
1270 = wi::smin (maxobjsize,
1271 dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();
1273 if (acs.sizrange[0] == 0)
1274 acs.sizrange[0] = 1;
1275 acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1276 return true;
1279 /* Return true if the strcpy-like access overlaps. */
1281 bool
1282 builtin_access::strcpy_overlap ()
1284 return generic_overlap ();
1287 /* For a BASE of array type, clamp REFOFF to at most [0, BASE_SIZE]
1288 if known, or [0, MAXOBJSIZE] otherwise. */
1290 static void
1291 clamp_offset (tree base, offset_int refoff[2], offset_int maxobjsize)
1293 if (!base || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
1294 return;
1296 if (refoff[0] < 0 && refoff[1] >= 0)
1297 refoff[0] = 0;
1299 if (refoff[1] < refoff[0])
1301 offset_int maxsize = maxobjsize;
1302 if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (base)))
1303 maxsize = wi::to_offset (size);
1305 refoff[1] = wi::umin (refoff[1], maxsize);
1309 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1310 one another or that, in order not to overlap, would imply that the size
1311 of the referenced object(s) exceeds the maximum size of an object. Set
1312 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1313 they may overlap in a way that's not apparent from the available data),
1314 return false. */
1316 bool
1317 builtin_access::overlap ()
1319 builtin_access &acs = *this;
1321 const offset_int maxobjsize = dstref->maxobjsize;
1323 acs.sizrange[0] = wi::smax (dstref->sizrange[0],
1324 srcref->sizrange[0]).to_shwi ();
1325 acs.sizrange[1] = wi::smax (dstref->sizrange[1],
1326 srcref->sizrange[1]).to_shwi ();
1328 /* Check to see if the two references refer to regions that are
1329 too large not to overlap in the address space (whose maximum
1330 size is PTRDIFF_MAX). */
1331 offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
1332 if (maxobjsize < size)
1334 acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
1335 acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
1336 return true;
1339 /* If both base objects aren't known return the maximum possible
1340 offset that would make them not overlap. */
1341 if (!dstref->base || !srcref->base)
1342 return false;
1344 /* If the base object is an array adjust the bounds of the offset
1345 to be non-negative and within the bounds of the array if possible. */
1346 clamp_offset (dstref->base, acs.dstoff, maxobjsize);
1348 acs.srcoff[0] = srcref->offrange[0];
1349 acs.srcoff[1] = srcref->offrange[1];
1351 clamp_offset (srcref->base, acs.srcoff, maxobjsize);
1353 /* When the upper bound of the offset is less than the lower bound
1354 the former is the result of a negative offset being represented
1355 as a large positive value or vice versa. The resulting range is
1356 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1357 a union is not representable using the current data structure
1358 replace it with the full range of offsets. */
1359 if (acs.dstoff[1] < acs.dstoff[0])
1361 acs.dstoff[0] = -maxobjsize - 1;
1362 acs.dstoff[1] = maxobjsize;
1365 /* Validate the offset and size of each reference on its own first.
1366 This is independent of whether or not the base objects are the
1367 same. Normally, this would have already been detected and
1368 diagnosed by -Warray-bounds, unless it has been disabled. */
1369 offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
1370 if (maxobjsize < maxoff)
1372 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1373 acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
1374 return true;
1377 /* Repeat the same as above but for the source offsets. */
1378 if (acs.srcoff[1] < acs.srcoff[0])
1380 acs.srcoff[0] = -maxobjsize - 1;
1381 acs.srcoff[1] = maxobjsize;
1384 maxoff = acs.srcoff[0] + srcref->sizrange[0];
1385 if (maxobjsize < maxoff)
1387 acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
1388 acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
1389 - maxobjsize).to_shwi ();
1390 acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
1391 return true;
1394 if (dstref->base != srcref->base)
1395 return false;
1397 acs.dstsiz[0] = dstref->sizrange[0];
1398 acs.dstsiz[1] = dstref->sizrange[1];
1400 acs.srcsiz[0] = srcref->sizrange[0];
1401 acs.srcsiz[1] = srcref->sizrange[1];
1403 /* Call the appropriate function to determine the overlap. */
1404 if ((this->*detect_overlap) ())
1406 if (!sizrange[1])
1408 /* Unless the access size range has already been set, do so here. */
1409 sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
1410 sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
1412 return true;
1415 return false;
1418 /* Attempt to detect and diagnose an overlapping copy in a call expression
1419 EXPR involving an access ACS to a built-in memory or string function.
1420 Return true when one has been detected, false otherwise. */
1422 static bool
1423 maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
1425 if (!acs.overlap ())
1426 return false;
1428 if (gimple_no_warning_p (call))
1429 return true;
1431 /* For convenience. */
1432 const builtin_memref &dstref = *acs.dstref;
1433 const builtin_memref &srcref = *acs.srcref;
1435 /* Determine the range of offsets and sizes of the overlap if it
1436 exists and issue diagnostics. */
1437 HOST_WIDE_INT *ovloff = acs.ovloff;
1438 HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
1439 HOST_WIDE_INT *sizrange = acs.sizrange;
1441 tree func = gimple_call_fndecl (call);
1443 /* To avoid a combinatorial explosion of diagnostics format the offsets
1444 or their ranges as strings and use them in the warning calls below. */
1445 char offstr[3][64];
1447 if (dstref.offrange[0] == dstref.offrange[1]
1448 || dstref.offrange[1] > HOST_WIDE_INT_MAX)
1449 sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
1450 dstref.offrange[0].to_shwi ());
1451 else
1452 sprintf (offstr[0],
1453 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1454 dstref.offrange[0].to_shwi (),
1455 dstref.offrange[1].to_shwi ());
1457 if (srcref.offrange[0] == srcref.offrange[1]
1458 || srcref.offrange[1] > HOST_WIDE_INT_MAX)
1459 sprintf (offstr[1],
1460 HOST_WIDE_INT_PRINT_DEC,
1461 srcref.offrange[0].to_shwi ());
1462 else
1463 sprintf (offstr[1],
1464 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1465 srcref.offrange[0].to_shwi (),
1466 srcref.offrange[1].to_shwi ());
1468 if (ovloff[0] == ovloff[1] || !ovloff[1])
1469 sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
1470 else
1471 sprintf (offstr[2],
1472 "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
1473 ovloff[0], ovloff[1]);
1475 const offset_int maxobjsize = dstref.maxobjsize;
1476 bool must_overlap = ovlsiz[0] > 0;
1478 if (ovlsiz[1] == 0)
1479 ovlsiz[1] = ovlsiz[0];
1481 if (must_overlap)
1483 /* Issue definitive "overlaps" diagnostic in this block. */
1485 if (sizrange[0] == sizrange[1])
1487 if (ovlsiz[0] == ovlsiz[1])
1488 warning_at (loc, OPT_Wrestrict,
1489 sizrange[0] == 1
1490 ? (ovlsiz[0] == 1
1491 ? G_("%G%qD accessing %wu byte at offsets %s "
1492 "and %s overlaps %wu byte at offset %s")
1493 : G_("%G%qD accessing %wu byte at offsets %s "
1494 "and %s overlaps %wu bytes at offset "
1495 "%s"))
1496 : (ovlsiz[0] == 1
1497 ? G_("%G%qD accessing %wu bytes at offsets %s "
1498 "and %s overlaps %wu byte at offset %s")
1499 : G_("%G%qD accessing %wu bytes at offsets %s "
1500 "and %s overlaps %wu bytes at offset "
1501 "%s")),
1502 call, func, sizrange[0],
1503 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1504 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1505 warning_n (loc, OPT_Wrestrict, sizrange[0],
1506 "%G%qD accessing %wu byte at offsets %s "
1507 "and %s overlaps between %wu and %wu bytes "
1508 "at offset %s",
1509 "%G%qD accessing %wu bytes at offsets %s "
1510 "and %s overlaps between %wu and %wu bytes "
1511 "at offset %s",
1512 call, func, sizrange[0], offstr[0], offstr[1],
1513 ovlsiz[0], ovlsiz[1], offstr[2]);
1514 else
1515 warning_n (loc, OPT_Wrestrict, sizrange[0],
1516 "%G%qD accessing %wu byte at offsets %s and "
1517 "%s overlaps %wu or more bytes at offset %s",
1518 "%G%qD accessing %wu bytes at offsets %s and "
1519 "%s overlaps %wu or more bytes at offset %s",
1520 call, func, sizrange[0],
1521 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1522 return true;
1525 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1527 if (ovlsiz[0] == ovlsiz[1])
1528 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1529 "%G%qD accessing between %wu and %wu bytes "
1530 "at offsets %s and %s overlaps %wu byte at "
1531 "offset %s",
1532 "%G%qD accessing between %wu and %wu bytes "
1533 "at offsets %s and %s overlaps %wu bytes "
1534 "at offset %s",
1535 call, func, sizrange[0], sizrange[1],
1536 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1537 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1538 warning_at (loc, OPT_Wrestrict,
1539 "%G%qD accessing between %wu and %wu bytes at "
1540 "offsets %s and %s overlaps between %wu and %wu "
1541 "bytes at offset %s",
1542 call, func, sizrange[0], sizrange[1],
1543 offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
1544 offstr[2]);
1545 else
1546 warning_at (loc, OPT_Wrestrict,
1547 "%G%qD accessing between %wu and %wu bytes at "
1548 "offsets %s and %s overlaps %wu or more bytes "
1549 "at offset %s",
1550 call, func, sizrange[0], sizrange[1],
1551 offstr[0], offstr[1], ovlsiz[0], offstr[2]);
1552 return true;
1555 if (ovlsiz[0] != ovlsiz[1])
1556 ovlsiz[1] = maxobjsize.to_shwi ();
1558 if (ovlsiz[0] == ovlsiz[1])
1559 warning_n (loc, OPT_Wrestrict, ovlsiz[0],
1560 "%G%qD accessing %wu or more bytes at offsets "
1561 "%s and %s overlaps %wu byte at offset %s",
1562 "%G%qD accessing %wu or more bytes at offsets "
1563 "%s and %s overlaps %wu bytes at offset %s",
1564 call, func, sizrange[0], offstr[0], offstr[1],
1565 ovlsiz[0], offstr[2]);
1566 else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
1567 warning_at (loc, OPT_Wrestrict,
1568 "%G%qD accessing %wu or more bytes at offsets %s "
1569 "and %s overlaps between %wu and %wu bytes "
1570 "at offset %s",
1571 call, func, sizrange[0], offstr[0], offstr[1],
1572 ovlsiz[0], ovlsiz[1], offstr[2]);
1573 else
1574 warning_at (loc, OPT_Wrestrict,
1575 "%G%qD accessing %wu or more bytes at offsets %s "
1576 "and %s overlaps %wu or more bytes at offset %s",
1577 call, func, sizrange[0], offstr[0], offstr[1],
1578 ovlsiz[0], offstr[2]);
1579 return true;
1582 /* Use more concise wording when one of the offsets is unbounded
1583 to avoid confusing the user with large and mostly meaningless
1584 numbers. */
1585 bool open_range;
1586 if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
1587 open_range = ((dstref.offrange[0] == 0
1588 && dstref.offrange[1] == maxobjsize)
1589 || (srcref.offrange[0] == 0
1590 && srcref.offrange[1] == maxobjsize));
1591 else
1592 open_range = ((dstref.offrange[0] == -maxobjsize - 1
1593 && dstref.offrange[1] == maxobjsize)
1594 || (srcref.offrange[0] == -maxobjsize - 1
1595 && srcref.offrange[1] == maxobjsize));
1597 if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
1599 if (ovlsiz[1] == 1)
1601 if (open_range)
1602 warning_n (loc, OPT_Wrestrict, sizrange[1],
1603 "%G%qD accessing %wu byte may overlap "
1604 "%wu byte",
1605 "%G%qD accessing %wu bytes may overlap "
1606 "%wu byte",
1607 call, func, sizrange[1], ovlsiz[1]);
1608 else
1609 warning_n (loc, OPT_Wrestrict, sizrange[1],
1610 "%G%qD accessing %wu byte at offsets %s "
1611 "and %s may overlap %wu byte at offset %s",
1612 "%G%qD accessing %wu bytes at offsets %s "
1613 "and %s may overlap %wu byte at offset %s",
1614 call, func, sizrange[1], offstr[0], offstr[1],
1615 ovlsiz[1], offstr[2]);
1616 return true;
1619 if (open_range)
1620 warning_n (loc, OPT_Wrestrict, sizrange[1],
1621 "%G%qD accessing %wu byte may overlap "
1622 "up to %wu bytes",
1623 "%G%qD accessing %wu bytes may overlap "
1624 "up to %wu bytes",
1625 call, func, sizrange[1], ovlsiz[1]);
1626 else
1627 warning_n (loc, OPT_Wrestrict, sizrange[1],
1628 "%G%qD accessing %wu byte at offsets %s and "
1629 "%s may overlap up to %wu bytes at offset %s",
1630 "%G%qD accessing %wu bytes at offsets %s and "
1631 "%s may overlap up to %wu bytes at offset %s",
1632 call, func, sizrange[1], offstr[0], offstr[1],
1633 ovlsiz[1], offstr[2]);
1634 return true;
1637 if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
1639 if (open_range)
1640 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1641 "%G%qD accessing between %wu and %wu bytes "
1642 "may overlap %wu byte",
1643 "%G%qD accessing between %wu and %wu bytes "
1644 "may overlap up to %wu bytes",
1645 call, func, sizrange[0], sizrange[1], ovlsiz[1]);
1646 else
1647 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1648 "%G%qD accessing between %wu and %wu bytes "
1649 "at offsets %s and %s may overlap %wu byte "
1650 "at offset %s",
1651 "%G%qD accessing between %wu and %wu bytes "
1652 "at offsets %s and %s may overlap up to %wu "
1653 "bytes at offset %s",
1654 call, func, sizrange[0], sizrange[1],
1655 offstr[0], offstr[1], ovlsiz[1], offstr[2]);
1656 return true;
1659 warning_n (loc, OPT_Wrestrict, ovlsiz[1],
1660 "%G%qD accessing %wu or more bytes at offsets %s "
1661 "and %s may overlap %wu byte at offset %s",
1662 "%G%qD accessing %wu or more bytes at offsets %s "
1663 "and %s may overlap up to %wu bytes at offset %s",
1664 call, func, sizrange[0], offstr[0], offstr[1],
1665 ovlsiz[1], offstr[2]);
1667 return true;
1670 /* Validate REF size and offsets in an expression passed as an argument
1671 to a CALL to a built-in function FUNC to make sure they are within
1672 the bounds of the referenced object if its size is known, or
1673 PTRDIFF_MAX otherwise. DO_WARN is true when a diagnostic should
1674 be issued, false otherwise.
1675 Both initial values of the offsets and their final value computed
1676 by the function by incrementing the initial value by the size are
1677 validated. Return true if the offsets are not valid and a diagnostic
1678 has been issued, or would have been issued if DO_WARN had been true. */
1680 static bool
1681 maybe_diag_access_bounds (gimple *call, tree func, int strict,
1682 const builtin_memref &ref, offset_int wroff,
1683 bool do_warn)
1685 location_t loc = gimple_or_expr_nonartificial_location (call, ref.ptr);
1686 const offset_int maxobjsize = ref.maxobjsize;
1688 /* Check for excessive size first and regardless of warning options
1689 since the result is used to make codegen decisions. */
1690 if (ref.sizrange[0] > maxobjsize)
1692 /* Return true without issuing a warning. */
1693 if (!do_warn)
1694 return true;
1696 if (ref.ref && TREE_NO_WARNING (ref.ref))
1697 return false;
1699 if (warn_stringop_overflow)
1701 if (ref.sizrange[0] == ref.sizrange[1])
1702 return warning_at (loc, OPT_Wstringop_overflow_,
1703 "%G%qD specified bound %wu "
1704 "exceeds maximum object size %wu",
1705 call, func, ref.sizrange[0].to_uhwi (),
1706 maxobjsize.to_uhwi ());
1708 return warning_at (loc, OPT_Wstringop_overflow_,
1709 "%G%qD specified bound between %wu and %wu "
1710 "exceeds maximum object size %wu",
1711 call, func, ref.sizrange[0].to_uhwi (),
1712 ref.sizrange[1].to_uhwi (),
1713 maxobjsize.to_uhwi ());
1717 /* Check for out-bounds pointers regardless of warning options since
1718 the result is used to make codegen decisions. An excessive WROFF
1719 can only come up as a result of an invalid strncat bound and is
1720 diagnosed separately using a more meaningful warning. */
1721 if (maxobjsize < wroff)
1722 wroff = 0;
1723 offset_int ooboff[] = { ref.offrange[0], ref.offrange[1], wroff };
1724 tree oobref = ref.offset_out_of_bounds (strict, ooboff);
1725 if (!oobref)
1726 return false;
1728 /* Return true without issuing a warning. */
1729 if (!do_warn)
1730 return true;
1732 if (!warn_array_bounds)
1733 return false;
1735 if (TREE_NO_WARNING (ref.ptr)
1736 || (ref.ref && TREE_NO_WARNING (ref.ref)))
1737 return false;
1739 char rangestr[2][64];
1740 if (ooboff[0] == ooboff[1]
1741 || (ooboff[0] != ref.offrange[0]
1742 && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
1743 sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
1744 else
1745 sprintf (rangestr[0], "[%lli, %lli]",
1746 (long long) ooboff[0].to_shwi (),
1747 (long long) ooboff[1].to_shwi ());
1749 bool warned = false;
1751 if (oobref == error_mark_node)
1753 if (ref.sizrange[0] == ref.sizrange[1])
1754 sprintf (rangestr[1], "%llu",
1755 (unsigned long long) ref.sizrange[0].to_shwi ());
1756 else
1757 sprintf (rangestr[1], "[%lli, %lli]",
1758 (unsigned long long) ref.sizrange[0].to_uhwi (),
1759 (unsigned long long) ref.sizrange[1].to_uhwi ());
1761 tree type;
1763 if (DECL_P (ref.base)
1764 && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
1766 auto_diagnostic_group d;
1767 if (warning_at (loc, OPT_Warray_bounds,
1768 "%G%qD pointer overflow between offset %s "
1769 "and size %s accessing array %qD with type %qT",
1770 call, func, rangestr[0], rangestr[1], ref.base, type))
1772 inform (DECL_SOURCE_LOCATION (ref.base),
1773 "array %qD declared here", ref.base);
1774 warned = true;
1776 else
1777 warned = warning_at (loc, OPT_Warray_bounds,
1778 "%G%qD pointer overflow between offset %s "
1779 "and size %s",
1780 call, func, rangestr[0], rangestr[1]);
1782 else
1783 warned = warning_at (loc, OPT_Warray_bounds,
1784 "%G%qD pointer overflow between offset %s "
1785 "and size %s",
1786 call, func, rangestr[0], rangestr[1]);
1788 else if (oobref == ref.base)
1790 /* True when the offset formed by an access to the reference
1791 is out of bounds, rather than the initial offset wich is
1792 in bounds. This implies access past the end. */
1793 bool form = ooboff[0] != ref.offrange[0];
1795 if (DECL_P (ref.base))
1797 auto_diagnostic_group d;
1798 if ((ref.basesize < maxobjsize
1799 && warning_at (loc, OPT_Warray_bounds,
1800 form
1801 ? G_("%G%qD forming offset %s is out of "
1802 "the bounds [0, %wu] of object %qD with "
1803 "type %qT")
1804 : G_("%G%qD offset %s is out of the bounds "
1805 "[0, %wu] of object %qD with type %qT"),
1806 call, func, rangestr[0], ref.basesize.to_uhwi (),
1807 ref.base, TREE_TYPE (ref.base)))
1808 || warning_at (loc, OPT_Warray_bounds,
1809 form
1810 ? G_("%G%qD forming offset %s is out of "
1811 "the bounds of object %qD with type %qT")
1812 : G_("%G%qD offset %s is out of the bounds "
1813 "of object %qD with type %qT"),
1814 call, func, rangestr[0],
1815 ref.base, TREE_TYPE (ref.base)))
1817 inform (DECL_SOURCE_LOCATION (ref.base),
1818 "%qD declared here", ref.base);
1819 warned = true;
1822 else if (ref.basesize < maxobjsize)
1823 warned = warning_at (loc, OPT_Warray_bounds,
1824 form
1825 ? G_("%G%qD forming offset %s is out "
1826 "of the bounds [0, %wu]")
1827 : G_("%G%qD offset %s is out "
1828 "of the bounds [0, %wu]"),
1829 call, func, rangestr[0], ref.basesize.to_uhwi ());
1830 else
1831 warned = warning_at (loc, OPT_Warray_bounds,
1832 form
1833 ? G_("%G%qD forming offset %s is out of bounds")
1834 : G_("%G%qD offset %s is out of bounds"),
1835 call, func, rangestr[0]);
1837 else if (TREE_CODE (ref.ref) == MEM_REF)
1839 tree refop = TREE_OPERAND (ref.ref, 0);
1840 tree type = TREE_TYPE (refop);
1841 if (POINTER_TYPE_P (type))
1842 type = TREE_TYPE (type);
1843 type = TYPE_MAIN_VARIANT (type);
1845 if (warning_at (loc, OPT_Warray_bounds,
1846 "%G%qD offset %s from the object at %qE is out "
1847 "of the bounds of %qT",
1848 call, func, rangestr[0], ref.base, type))
1850 if (TREE_CODE (ref.ref) == COMPONENT_REF)
1851 refop = TREE_OPERAND (ref.ref, 1);
1852 if (DECL_P (refop))
1853 inform (DECL_SOURCE_LOCATION (refop),
1854 "subobject %qD declared here", refop);
1855 warned = true;
1858 else
1860 tree refop = TREE_OPERAND (ref.ref, 0);
1861 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));
1863 if (warning_at (loc, OPT_Warray_bounds,
1864 "%G%qD offset %s from the object at %qE is out "
1865 "of the bounds of referenced subobject %qD with "
1866 "type %qT at offset %wi",
1867 call, func, rangestr[0], ref.base,
1868 TREE_OPERAND (ref.ref, 1), type,
1869 ref.refoff.to_shwi ()))
1871 if (TREE_CODE (ref.ref) == COMPONENT_REF)
1872 refop = TREE_OPERAND (ref.ref, 1);
1873 if (DECL_P (refop))
1874 inform (DECL_SOURCE_LOCATION (refop),
1875 "subobject %qD declared here", refop);
1876 warned = true;
1880 return warned;
1883 /* Check a CALL statement for restrict-violations and issue warnings
1884 if/when appropriate. */
1886 static void
1887 check_call (range_query *query, gimple *call)
1889 /* Avoid checking the call if it has already been diagnosed for
1890 some reason. */
1891 if (gimple_no_warning_p (call))
1892 return;
1894 tree func = gimple_call_fndecl (call);
1895 if (!func || !fndecl_built_in_p (func, BUILT_IN_NORMAL))
1896 return;
1898 /* Argument number to extract from the call (depends on the built-in
1899 and its kind). */
1900 unsigned dst_idx = -1;
1901 unsigned src_idx = -1;
1902 unsigned bnd_idx = -1;
1904 /* Is this CALL to a string function (as opposed to one to a raw
1905 memory function). */
1906 bool strfun = true;
1908 switch (DECL_FUNCTION_CODE (func))
1910 case BUILT_IN_MEMCPY:
1911 case BUILT_IN_MEMCPY_CHK:
1912 case BUILT_IN_MEMPCPY:
1913 case BUILT_IN_MEMPCPY_CHK:
1914 case BUILT_IN_MEMMOVE:
1915 case BUILT_IN_MEMMOVE_CHK:
1916 strfun = false;
1917 /* Fall through. */
1919 case BUILT_IN_STPNCPY:
1920 case BUILT_IN_STPNCPY_CHK:
1921 case BUILT_IN_STRNCAT:
1922 case BUILT_IN_STRNCAT_CHK:
1923 case BUILT_IN_STRNCPY:
1924 case BUILT_IN_STRNCPY_CHK:
1925 dst_idx = 0;
1926 src_idx = 1;
1927 bnd_idx = 2;
1928 break;
1930 case BUILT_IN_MEMSET:
1931 case BUILT_IN_MEMSET_CHK:
1932 dst_idx = 0;
1933 bnd_idx = 2;
1934 break;
1936 case BUILT_IN_STPCPY:
1937 case BUILT_IN_STPCPY_CHK:
1938 case BUILT_IN_STRCPY:
1939 case BUILT_IN_STRCPY_CHK:
1940 case BUILT_IN_STRCAT:
1941 case BUILT_IN_STRCAT_CHK:
1942 dst_idx = 0;
1943 src_idx = 1;
1944 break;
1946 default:
1947 /* Handle other string functions here whose access may need
1948 to be validated for in-bounds offsets and non-overlapping
1949 copies. */
1950 return;
1953 unsigned nargs = gimple_call_num_args (call);
1955 tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
1956 tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
1957 tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;
1959 /* For string functions with an unspecified or unknown bound,
1960 assume the size of the access is one. */
1961 if (!dstwr && strfun)
1962 dstwr = size_one_node;
1964 /* DST and SRC can be null for a call with an insufficient number
1965 of arguments to a built-in function declared without a protype. */
1966 if (!dst || (src_idx < nargs && !src))
1967 return;
1969 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1970 a function declared without a prototype. Avoid checking such
1971 invalid calls. */
1972 if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
1973 || (src && TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE)
1974 || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
1975 return;
1977 if (!check_bounds_or_overlap (query, call, dst, src, dstwr, NULL_TREE))
1978 return;
1980 /* Avoid diagnosing the call again. */
1981 gimple_set_no_warning (call, true);
1984 } /* anonymous namespace */
1986 /* Attempt to detect and diagnose invalid offset bounds and (except for
1987 memmove) overlapping copy in a call expression EXPR from SRC to DST
1988 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1989 SRCSIZE may be NULL. DO_WARN is false to detect either problem
1990 without issue a warning. Return the OPT_Wxxx constant corresponding
1991 to the warning if one has been detected and zero otherwise. */
1994 check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
1995 tree srcsize, bool bounds_only /* = false */,
1996 bool do_warn /* = true */)
1998 return check_bounds_or_overlap (/*range_query=*/NULL,
1999 call, dst, src, dstsize, srcsize,
2000 bounds_only, do_warn);
2004 check_bounds_or_overlap (range_query *query,
2005 gimple *call, tree dst, tree src, tree dstsize,
2006 tree srcsize, bool bounds_only /* = false */,
2007 bool do_warn /* = true */)
2009 tree func = gimple_call_fndecl (call);
2011 builtin_memref dstref (query, call, dst, dstsize);
2012 builtin_memref srcref (query, call, src, srcsize);
2014 /* Create a descriptor of the access. This may adjust both DSTREF
2015 and SRCREF based on one another and the kind of the access. */
2016 builtin_access acs (query, call, dstref, srcref);
2018 /* Set STRICT to the value of the -Warray-bounds=N argument for
2019 string functions or when N > 1. */
2020 int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);
2022 /* The starting offset of the destination write access. Nonzero only
2023 for the strcat family of functions. */
2024 offset_int wroff = acs.write_off (dstsize);
2026 /* Validate offsets to each reference before the access first to make
2027 sure they are within the bounds of the destination object if its
2028 size is known, or PTRDIFF_MAX otherwise. */
2029 if (maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn)
2030 || maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn))
2032 if (do_warn)
2033 gimple_set_no_warning (call, true);
2034 return OPT_Warray_bounds;
2037 if (!warn_restrict || bounds_only || !src)
2038 return 0;
2040 if (!bounds_only)
2042 switch (DECL_FUNCTION_CODE (func))
2044 case BUILT_IN_MEMMOVE:
2045 case BUILT_IN_MEMMOVE_CHK:
2046 case BUILT_IN_MEMSET:
2047 case BUILT_IN_MEMSET_CHK:
2048 return 0;
2049 default:
2050 break;
2054 location_t loc = gimple_or_expr_nonartificial_location (call, dst);
2055 if (operand_equal_p (dst, src, 0))
2057 /* Issue -Wrestrict unless the pointers are null (those do
2058 not point to objects and so do not indicate an overlap;
2059 such calls could be the result of sanitization and jump
2060 threading). */
2061 if (!integer_zerop (dst) && !gimple_no_warning_p (call))
2063 warning_at (loc, OPT_Wrestrict,
2064 "%G%qD source argument is the same as destination",
2065 call, func);
2066 gimple_set_no_warning (call, true);
2067 return OPT_Wrestrict;
2070 return 0;
2073 /* Return false when overlap has been detected. */
2074 if (maybe_diag_overlap (loc, call, acs))
2076 gimple_set_no_warning (call, true);
2077 return OPT_Wrestrict;
2080 return 0;
2083 gimple_opt_pass *
2084 make_pass_warn_restrict (gcc::context *ctxt)
2086 return new pass_wrestrict (ctxt);
2089 DEBUG_FUNCTION void
2090 dump_builtin_memref (FILE *fp, const builtin_memref &ref)
2092 fprintf (fp, "\n ptr = ");
2093 print_generic_expr (fp, ref.ptr, TDF_LINENO);
2094 fprintf (fp, "\n ref = ");
2095 if (ref.ref)
2096 print_generic_expr (fp, ref.ref, TDF_LINENO);
2097 else
2098 fputs ("null", fp);
2099 fprintf (fp, "\n base = ");
2100 print_generic_expr (fp, ref.base, TDF_LINENO);
2101 fprintf (fp,
2102 "\n basesize = %lli"
2103 "\n refsize = %lli"
2104 "\n refoff = %lli"
2105 "\n offrange = [%lli, %lli]"
2106 "\n sizrange = [%lli, %lli]"
2107 "\n strbounded_p = %s\n",
2108 (long long)ref.basesize.to_shwi (),
2109 (long long)ref.refsize.to_shwi (),
2110 (long long)ref.refoff.to_shwi (),
2111 (long long)ref.offrange[0].to_shwi (),
2112 (long long)ref.offrange[1].to_shwi (),
2113 (long long)ref.sizrange[0].to_shwi (),
2114 (long long)ref.sizrange[1].to_shwi (),
2115 ref.strbounded_p ? "true" : "false");
2118 void
2119 builtin_access::dump (FILE *fp) const
2121 fprintf (fp, " dstref:");
2122 dump_builtin_memref (fp, *dstref);
2123 fprintf (fp, "\n srcref:");
2124 dump_builtin_memref (fp, *srcref);
2126 fprintf (fp,
2127 " sizrange = [%lli, %lli]\n"
2128 " ovloff = [%lli, %lli]\n"
2129 " ovlsiz = [%lli, %lli]\n"
2130 " dstoff = [%lli, %lli]\n"
2131 " dstsiz = [%lli, %lli]\n"
2132 " srcoff = [%lli, %lli]\n"
2133 " srcsiz = [%lli, %lli]\n",
2134 (long long)sizrange[0], (long long)sizrange[1],
2135 (long long)ovloff[0], (long long)ovloff[1],
2136 (long long)ovlsiz[0], (long long)ovlsiz[1],
2137 (long long)dstoff[0].to_shwi (), (long long)dstoff[1].to_shwi (),
2138 (long long)dstsiz[0].to_shwi (), (long long)dstsiz[1].to_shwi (),
2139 (long long)srcoff[0].to_shwi (), (long long)srcoff[1].to_shwi (),
2140 (long long)srcsiz[0].to_shwi (), (long long)srcsiz[1].to_shwi ());
2143 DEBUG_FUNCTION void
2144 dump_builtin_access (FILE *fp, gimple *stmt, const builtin_access &acs)
2146 if (stmt)
2148 fprintf (fp, "\nDumping builtin_access for ");
2149 print_gimple_expr (fp, stmt, TDF_LINENO);
2150 fputs (":\n", fp);
2153 acs.dump (fp);
2156 DEBUG_FUNCTION void
2157 debug (gimple *stmt, const builtin_access &acs)
2159 dump_builtin_access (stdout, stmt, acs);