1 /* Pass to detect and issue warnings for violations of the restrict
3 Copyright (C) 2017-2018 Free Software Foundation, Inc.
4 Contributed by Martin Sebor <msebor@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
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
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/>. */
24 #include "coretypes.h"
29 #include "tree-pass.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"
41 #include "tree-object-size.h"
48 const pass_data pass_data_wrestrict
= {
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
65 pass_wrestrict (gcc::context
*ctxt
)
66 : gimple_opt_pass (pass_data_wrestrict
, ctxt
)
69 opt_pass
*clone () { return new pass_wrestrict (m_ctxt
); }
71 virtual bool gate (function
*);
72 virtual unsigned int execute (function
*);
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
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
*);
91 void check_call (gcall
*);
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
);
101 gimple
*stmt
= gsi_stmt (si
);
102 if (!is_gimple_call (stmt
))
105 if (gcall
*call
= as_a
<gcall
*> (stmt
))
112 /* Execute the pass for function FUN, walking in dominator order. */
115 pass_wrestrict::execute (function
*fun
)
117 calculate_dominance_info (CDI_DOMINATORS
);
119 wrestrict_dom_walker walker
;
120 walker
.walk (ENTRY_BLOCK_PTR_FOR_FN (fun
));
125 /* Description of a memory reference by a built-in function. This
126 is similar to ao_ref but made especially suitable for -Wrestrict
127 and not for optimization. */
128 struct builtin_memref
130 /* The original pointer argument to the built-in function. */
132 /* The referenced subobject or NULL if not available, and the base
133 object of the memory reference or NULL. */
137 /* The size of the BASE object, PTRDIFF_MAX if indeterminate,
138 and negative until (possibly lazily) initialized. */
141 /* The non-negative offset of the referenced subobject. Used to avoid
142 warnings for (apparently) possibly but not definitively overlapping
143 accesses to member arrays. Negative when unknown/invalid. */
146 /* The offset range relative to the base. */
147 offset_int offrange
[2];
148 /* The size range of the access to this reference. */
149 offset_int sizrange
[2];
151 /* True for "bounded" string functions like strncat, and strncpy
152 and their variants that specify either an exact or upper bound
153 on the size of the accesses they perform. For strncat both
154 the source and destination references are bounded. For strncpy
155 only the destination reference is. */
158 builtin_memref (tree
, tree
);
160 tree
offset_out_of_bounds (int, offset_int
[2]) const;
164 /* Ctor helper to set or extend OFFRANGE based on argument. */
165 void extend_offset_range (tree
);
167 /* Ctor helper to determine BASE and OFFRANGE from argument. */
168 void set_base_and_offset (tree
);
171 /* Description of a memory access by a raw memory or string built-in
172 function involving a pair of builtin_memref's. */
176 /* Destination and source memory reference. */
177 builtin_memref
* const dstref
;
178 builtin_memref
* const srcref
;
179 /* The size range of the access. It's the greater of the accesses
180 to the two references. */
181 HOST_WIDE_INT sizrange
[2];
183 /* The minimum and maximum offset of an overlap of the access
184 (if it does, in fact, overlap), and the size of the overlap. */
185 HOST_WIDE_INT ovloff
[2];
186 HOST_WIDE_INT ovlsiz
[2];
188 /* True to consider valid only accesses to the smallest subobject
189 and false for raw memory functions. */
192 return detect_overlap
!= &builtin_access::generic_overlap
;
195 builtin_access (gcall
*, builtin_memref
&, builtin_memref
&);
197 /* Entry point to determine overlap. */
201 /* Implementation functions used to determine overlap. */
202 bool generic_overlap ();
203 bool strcat_overlap ();
204 bool strcpy_overlap ();
211 offset_int
overlap_size (const offset_int
[2], const offset_int
[2],
215 /* Temporaries used to compute the final result. */
216 offset_int dstoff
[2];
217 offset_int srcoff
[2];
218 offset_int dstsiz
[2];
219 offset_int srcsiz
[2];
221 /* Pointer to a member function to call to determine overlap. */
222 bool (builtin_access::*detect_overlap
) ();
225 /* Initialize a memory reference representation from a pointer EXPR and
226 a size SIZE in bytes. If SIZE is NULL_TREE then the size is assumed
229 builtin_memref::builtin_memref (tree expr
, tree size
)
234 refoff (HOST_WIDE_INT_MIN
),
239 /* Unfortunately, wide_int default ctor is a no-op so array members
240 of the type must be set individually. */
241 offrange
[0] = offrange
[1] = 0;
242 sizrange
[0] = sizrange
[1] = 0;
244 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
246 /* Find the BASE object or pointer referenced by EXPR and set
247 the offset range OFFRANGE in the process. */
248 set_base_and_offset (expr
);
253 /* Determine the size range, allowing for the result to be [0, 0]
254 for SIZE in the anti-range ~[0, N] where N >= PTRDIFF_MAX. */
255 get_size_range (size
, range
, true);
256 sizrange
[0] = wi::to_offset (range
[0]);
257 sizrange
[1] = wi::to_offset (range
[1]);
258 /* get_size_range returns SIZE_MAX for the maximum size.
259 Constrain it to the real maximum of PTRDIFF_MAX. */
260 if (sizrange
[1] > maxobjsize
)
261 sizrange
[1] = maxobjsize
;
264 sizrange
[1] = maxobjsize
;
269 /* If the offset could be in the range of the referenced object
270 constrain its bounds so neither exceeds those of the object. */
271 if (offrange
[0] < 0 && offrange
[1] > 0)
274 offset_int maxoff
= maxobjsize
;
275 tree basetype
= TREE_TYPE (base
);
276 if (TREE_CODE (basetype
) == ARRAY_TYPE
278 && array_at_struct_end_p (ref
))
279 ; /* Use the maximum possible offset for last member arrays. */
280 else if (tree basesize
= TYPE_SIZE_UNIT (basetype
))
281 maxoff
= wi::to_offset (basesize
);
283 if (offrange
[0] >= 0)
286 offrange
[1] = offrange
[0] <= maxoff
? maxoff
: maxobjsize
;
287 else if (offrange
[0] <= maxoff
&& offrange
[1] > maxoff
)
288 offrange
[1] = maxoff
;
292 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. */
295 builtin_memref::extend_offset_range (tree offset
)
297 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
299 if (TREE_CODE (offset
) == INTEGER_CST
)
301 offset_int off
= int_cst_value (offset
);
310 if (TREE_CODE (offset
) == SSA_NAME
)
313 value_range_type rng
= get_range_info (offset
, &min
, &max
);
316 offrange
[0] += offset_int::from (min
, SIGNED
);
317 offrange
[1] += offset_int::from (max
, SIGNED
);
319 else if (rng
== VR_ANTI_RANGE
)
321 offrange
[0] += offset_int::from (max
+ 1, SIGNED
);
322 offrange
[1] += offset_int::from (min
- 1, SIGNED
);
326 gimple
*stmt
= SSA_NAME_DEF_STMT (offset
);
328 if (is_gimple_assign (stmt
)
329 && gimple_assign_rhs_code (stmt
) == NOP_EXPR
330 && (type
= TREE_TYPE (gimple_assign_rhs1 (stmt
)))
331 && INTEGRAL_TYPE_P (type
))
333 /* Use the bounds of the type of the NOP_EXPR operand
334 even if it's signed. The result doesn't trigger
335 warnings but makes their output more readable. */
336 offrange
[0] += wi::to_offset (TYPE_MIN_VALUE (type
));
337 offrange
[1] += wi::to_offset (TYPE_MAX_VALUE (type
));
340 offrange
[1] += maxobjsize
;
345 offrange
[1] += maxobjsize
;
348 /* Determines the base object or pointer of the reference EXPR
349 and the offset range from the beginning of the base. */
352 builtin_memref::set_base_and_offset (tree expr
)
354 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
356 if (TREE_CODE (expr
) == SSA_NAME
)
358 /* Try to tease the offset out of the pointer. */
359 gimple
*stmt
= SSA_NAME_DEF_STMT (expr
);
361 && gimple_assign_single_p (stmt
)
362 && gimple_assign_rhs_code (stmt
) == ADDR_EXPR
)
363 expr
= gimple_assign_rhs1 (stmt
);
364 else if (is_gimple_assign (stmt
))
366 tree_code code
= gimple_assign_rhs_code (stmt
);
367 if (code
== NOP_EXPR
)
369 tree rhs
= gimple_assign_rhs1 (stmt
);
370 if (POINTER_TYPE_P (TREE_TYPE (rhs
)))
371 expr
= gimple_assign_rhs1 (stmt
);
378 else if (code
== POINTER_PLUS_EXPR
)
380 expr
= gimple_assign_rhs1 (stmt
);
382 tree offset
= gimple_assign_rhs2 (stmt
);
383 extend_offset_range (offset
);
398 if (TREE_CODE (expr
) == ADDR_EXPR
)
399 expr
= TREE_OPERAND (expr
, 0);
401 /* Stash the reference for offset validation. */
404 poly_int64 bitsize
, bitpos
;
407 int sign
, reverse
, vol
;
409 /* Determine the base object or pointer of the reference and
410 the constant bit offset from the beginning of the base.
411 If the offset has a non-constant component, it will be in
412 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
414 base
= get_inner_reference (expr
, &bitsize
, &bitpos
, &var_off
,
415 &mode
, &sign
, &reverse
, &vol
);
417 /* get_inner_reference is not expected to return null. */
418 gcc_assert (base
!= NULL
);
420 poly_int64 bytepos
= exact_div (bitpos
, BITS_PER_UNIT
);
422 /* Convert the poly_int64 offset to offset_int. The offset
423 should be constant but be prepared for it not to be just in
426 if (bytepos
.is_constant (&cstoff
))
428 offrange
[0] += cstoff
;
429 offrange
[1] += cstoff
;
431 /* Besides the reference saved above, also stash the offset
433 if (TREE_CODE (expr
) == COMPONENT_REF
)
437 offrange
[1] += maxobjsize
;
441 if (TREE_CODE (var_off
) == INTEGER_CST
)
443 cstoff
= wi::to_offset (var_off
);
444 offrange
[0] += cstoff
;
445 offrange
[1] += cstoff
;
448 offrange
[1] += maxobjsize
;
451 if (TREE_CODE (base
) == MEM_REF
)
453 tree memrefoff
= TREE_OPERAND (base
, 1);
454 extend_offset_range (memrefoff
);
455 base
= TREE_OPERAND (base
, 0);
458 if (TREE_CODE (base
) == SSA_NAME
)
459 set_base_and_offset (base
);
462 /* Return error_mark_node if the signed offset exceeds the bounds
463 of the address space (PTRDIFF_MAX). Otherwise, return either
464 BASE or REF when the offset exceeds the bounds of the BASE or
465 REF object, and set OOBOFF to the past-the-end offset formed
466 by the reference, including its size. When STRICT is non-zero
467 use REF size, when available, otherwise use BASE size. When
468 STRICT is greater than 1, use the size of the last array member
469 as the bound, otherwise treat such a member as a flexible array
470 member. Return NULL when the offset is in bounds. */
473 builtin_memref::offset_out_of_bounds (int strict
, offset_int ooboff
[2]) const
475 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
477 /* A temporary, possibly adjusted, copy of the offset range. */
478 offset_int offrng
[2] = { offrange
[0], offrange
[1] };
480 if (DECL_P (base
) && TREE_CODE (TREE_TYPE (base
)) == ARRAY_TYPE
)
482 /* Check for offset in an anti-range with a negative lower bound.
483 For such a range, consider only the non-negative subrange. */
484 if (offrng
[1] < offrng
[0] && offrng
[1] < 0)
485 offrng
[1] = maxobjsize
;
488 /* Conservative offset of the last byte of the referenced object. */
491 /* The bounds need not be ordered. Set HIB to use as the index
492 of the larger of the bounds and LOB as the opposite. */
493 bool hib
= wi::les_p (offrng
[0], offrng
[1]);
498 endoff
= offrng
[lob
] + sizrange
[0];
500 /* For a reference through a pointer to an object of unknown size
501 all initial offsets are considered valid, positive as well as
502 negative, since the pointer itself can point past the beginning
503 of the object. However, the sum of the lower bound of the offset
504 and that of the size must be less than or equal than PTRDIFF_MAX. */
505 if (endoff
> maxobjsize
)
506 return error_mark_node
;
511 /* A reference to an object of known size must be within the bounds
512 of the base object. */
513 if (offrng
[hib
] < 0 || offrng
[lob
] > basesize
)
516 /* The extent of the reference must also be within the bounds of
517 the base object (if known) or the maximum object size otherwise. */
518 endoff
= wi::smax (offrng
[lob
], 0) + sizrange
[0];
519 if (endoff
> maxobjsize
)
520 return error_mark_node
;
522 offset_int size
= basesize
;
529 && TREE_CODE (ref
) == COMPONENT_REF
531 || !array_at_struct_end_p (ref
)))
533 /* If the reference is to a member subobject, the offset must
534 be within the bounds of the subobject. */
535 tree field
= TREE_OPERAND (ref
, 1);
536 tree type
= TREE_TYPE (field
);
537 if (tree sz
= TYPE_SIZE_UNIT (type
))
538 if (TREE_CODE (sz
) == INTEGER_CST
)
540 size
= refoff
+ wi::to_offset (sz
);
548 /* Set the out-of-bounds offset range to be one greater than
549 that delimited by the reference including its size. */
550 ooboff
[lob
] = size
+ 1;
552 if (endoff
> ooboff
[lob
])
553 ooboff
[hib
] = endoff
;
555 ooboff
[hib
] = wi::smax (offrng
[lob
], 0) + sizrange
[1];
560 /* Create an association between the memory references DST and SRC
561 for access by a call EXPR to a memory or string built-in funtion. */
563 builtin_access::builtin_access (gcall
*call
, builtin_memref
&dst
,
565 : dstref (&dst
), srcref (&src
), sizrange (), ovloff (), ovlsiz (),
566 dstoff (), srcoff (), dstsiz (), srcsiz ()
568 /* Zero out since the offset_int ctors invoked above are no-op. */
569 dstoff
[0] = dstoff
[1] = 0;
570 srcoff
[0] = srcoff
[1] = 0;
571 dstsiz
[0] = dstsiz
[1] = 0;
572 srcsiz
[0] = srcsiz
[1] = 0;
574 /* Object Size Type to use to determine the size of the destination
575 and source objects. Overridden below for raw memory functions. */
578 /* True when the size of one reference depends on the offset of
579 itself or the other. */
580 bool depends_p
= true;
582 /* True when the size of the destination reference DSTREF has been
583 determined from SRCREF and so needs to be adjusted by the latter's
584 offset. Only meaningful for bounded string functions like strncpy. */
585 bool dstadjust_p
= false;
587 /* The size argument number (depends on the built-in). */
588 unsigned sizeargno
= 2;
589 if (gimple_call_with_bounds_p (call
))
592 tree func
= gimple_call_fndecl (call
);
593 switch (DECL_FUNCTION_CODE (func
))
595 case BUILT_IN_MEMCPY
:
596 case BUILT_IN_MEMCPY_CHK
:
597 case BUILT_IN_MEMCPY_CHKP
:
598 case BUILT_IN_MEMCPY_CHK_CHKP
:
599 case BUILT_IN_MEMPCPY
:
600 case BUILT_IN_MEMPCPY_CHK
:
601 case BUILT_IN_MEMPCPY_CHKP
:
602 case BUILT_IN_MEMPCPY_CHK_CHKP
:
605 detect_overlap
= &builtin_access::generic_overlap
;
608 case BUILT_IN_MEMMOVE
:
609 case BUILT_IN_MEMMOVE_CHK
:
610 case BUILT_IN_MEMMOVE_CHKP
:
611 case BUILT_IN_MEMMOVE_CHK_CHKP
:
612 /* For memmove there is never any overlap to check for. */
615 detect_overlap
= &builtin_access::no_overlap
;
618 case BUILT_IN_STPNCPY
:
619 case BUILT_IN_STPNCPY_CHK
:
620 case BUILT_IN_STRNCPY
:
621 case BUILT_IN_STRNCPY_CHK
:
622 dstref
->strbounded_p
= true;
623 detect_overlap
= &builtin_access::strcpy_overlap
;
626 case BUILT_IN_STPCPY
:
627 case BUILT_IN_STPCPY_CHK
:
628 case BUILT_IN_STPCPY_CHKP
:
629 case BUILT_IN_STPCPY_CHK_CHKP
:
630 case BUILT_IN_STRCPY
:
631 case BUILT_IN_STRCPY_CHK
:
632 case BUILT_IN_STRCPY_CHKP
:
633 case BUILT_IN_STRCPY_CHK_CHKP
:
634 detect_overlap
= &builtin_access::strcpy_overlap
;
637 case BUILT_IN_STRCAT
:
638 case BUILT_IN_STRCAT_CHK
:
639 case BUILT_IN_STRCAT_CHKP
:
640 case BUILT_IN_STRCAT_CHK_CHKP
:
641 detect_overlap
= &builtin_access::strcat_overlap
;
644 case BUILT_IN_STRNCAT
:
645 case BUILT_IN_STRNCAT_CHK
:
646 dstref
->strbounded_p
= true;
647 srcref
->strbounded_p
= true;
648 detect_overlap
= &builtin_access::strcat_overlap
;
652 /* Handle other string functions here whose access may need
653 to be validated for in-bounds offsets and non-overlapping
654 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
655 macros so they need to be handled here.) */
659 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
661 /* Try to determine the size of the base object. compute_objsize
662 expects a pointer so create one if BASE is a non-pointer object. */
664 if (dst
.basesize
< 0)
667 if (!POINTER_TYPE_P (TREE_TYPE (addr
)))
668 addr
= build1 (ADDR_EXPR
, (TREE_TYPE (addr
)), addr
);
670 if (tree dstsize
= compute_objsize (addr
, ostype
))
671 dst
.basesize
= wi::to_offset (dstsize
);
672 else if (POINTER_TYPE_P (TREE_TYPE (addr
)))
673 dst
.basesize
= HOST_WIDE_INT_MIN
;
675 dst
.basesize
= maxobjsize
;
678 if (src
.basesize
< 0)
681 if (!POINTER_TYPE_P (TREE_TYPE (addr
)))
682 addr
= build1 (ADDR_EXPR
, (TREE_TYPE (addr
)), addr
);
684 if (tree srcsize
= compute_objsize (addr
, ostype
))
685 src
.basesize
= wi::to_offset (srcsize
);
686 else if (POINTER_TYPE_P (TREE_TYPE (addr
)))
687 src
.basesize
= HOST_WIDE_INT_MIN
;
689 src
.basesize
= maxobjsize
;
692 /* If there is no dependency between the references or the base
693 objects of the two references aren't the same there's nothing
695 if (depends_p
&& dstref
->base
!= srcref
->base
)
698 /* ...otherwise, make adjustments for references to the same object
699 by string built-in functions to reflect the constraints imposed
702 /* For bounded string functions determine the range of the bound
703 on the access. For others, the range stays unbounded. */
704 offset_int bounds
[2] = { maxobjsize
, maxobjsize
};
705 if (dstref
->strbounded_p
)
707 tree size
= gimple_call_arg (call
, sizeargno
);
709 if (get_size_range (size
, range
, true))
711 bounds
[0] = wi::to_offset (range
[0]);
712 bounds
[1] = wi::to_offset (range
[1]);
715 /* If both references' size ranges are indeterminate use the last
716 (size) argument from the function call as a substitute. This
717 may only be necessary for strncpy (but not for memcpy where
718 the size range would have been already determined this way). */
719 if (dstref
->sizrange
[0] == 0 && dstref
->sizrange
[1] == maxobjsize
720 && srcref
->sizrange
[0] == 0 && srcref
->sizrange
[1] == maxobjsize
)
722 dstref
->sizrange
[0] = bounds
[0];
723 dstref
->sizrange
[1] = bounds
[1];
727 /* The size range of one reference involving the same base object
728 can be determined from the size range of the other reference.
729 This makes it possible to compute accurate offsets for warnings
730 involving functions like strcpy where the length of just one of
731 the two arguments is known (determined by tree-ssa-strlen). */
732 if (dstref
->sizrange
[0] == 0 && dstref
->sizrange
[1] == maxobjsize
)
734 /* When the destination size is unknown set it to the size of
736 dstref
->sizrange
[0] = srcref
->sizrange
[0];
737 dstref
->sizrange
[1] = srcref
->sizrange
[1];
739 else if (srcref
->sizrange
[0] == 0 && srcref
->sizrange
[1] == maxobjsize
)
741 /* When the source size is unknown set it to the size of
743 srcref
->sizrange
[0] = dstref
->sizrange
[0];
744 srcref
->sizrange
[1] = dstref
->sizrange
[1];
748 if (dstref
->strbounded_p
)
750 /* Read access by strncpy is bounded. */
751 if (bounds
[0] < srcref
->sizrange
[0])
752 srcref
->sizrange
[0] = bounds
[0];
753 if (bounds
[1] < srcref
->sizrange
[1])
754 srcref
->sizrange
[1] = bounds
[1];
757 /* For string functions, adjust the size range of the source
758 reference by the inverse boundaries of the offset (because
759 the higher the offset into the string the shorter its
761 if (srcref
->offrange
[1] >= 0
762 && srcref
->offrange
[1] < srcref
->sizrange
[0])
763 srcref
->sizrange
[0] -= srcref
->offrange
[1];
765 srcref
->sizrange
[0] = 0;
767 if (srcref
->offrange
[0] > 0)
769 if (srcref
->offrange
[0] < srcref
->sizrange
[1])
770 srcref
->sizrange
[1] -= srcref
->offrange
[0];
772 srcref
->sizrange
[1] = 0;
779 if (detect_overlap
== &builtin_access::generic_overlap
)
781 if (dstref
->strbounded_p
)
783 dstref
->sizrange
[0] = bounds
[0];
784 dstref
->sizrange
[1] = bounds
[1];
786 if (dstref
->sizrange
[0] < srcref
->sizrange
[0])
787 srcref
->sizrange
[0] = dstref
->sizrange
[0];
789 if (dstref
->sizrange
[1] < srcref
->sizrange
[1])
790 srcref
->sizrange
[1] = dstref
->sizrange
[1];
793 else if (detect_overlap
== &builtin_access::strcpy_overlap
)
795 if (!dstref
->strbounded_p
)
797 /* For strcpy, adjust the destination size range to match that
798 of the source computed above. */
799 if (depends_p
&& dstadjust_p
)
801 dstref
->sizrange
[0] = srcref
->sizrange
[0];
802 dstref
->sizrange
[1] = srcref
->sizrange
[1];
807 if (dstref
->strbounded_p
)
809 /* For strncpy, adjust the destination size range to match that
810 of the source computed above. */
811 dstref
->sizrange
[0] = bounds
[0];
812 dstref
->sizrange
[1] = bounds
[1];
814 if (bounds
[0] < srcref
->sizrange
[0])
815 srcref
->sizrange
[0] = bounds
[0];
817 if (bounds
[1] < srcref
->sizrange
[1])
818 srcref
->sizrange
[1] = bounds
[1];
823 builtin_access::overlap_size (const offset_int a
[2], const offset_int b
[2],
826 const offset_int
*p
= a
;
827 const offset_int
*q
= b
;
829 /* Point P at the bigger of the two ranges and Q at the smaller. */
830 if (wi::lts_p (a
[1] - a
[0], b
[1] - b
[0]))
842 return wi::smin (p
[1], q
[1]) - q
[0];
852 /* Return true if the bounded mempry (memcpy amd similar) or string function
853 access (strncpy and similar) ACS overlaps. */
856 builtin_access::generic_overlap ()
858 builtin_access
&acs
= *this;
859 const builtin_memref
*dstref
= acs
.dstref
;
860 const builtin_memref
*srcref
= acs
.srcref
;
862 gcc_assert (dstref
->base
== srcref
->base
);
864 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
866 offset_int maxsize
= dstref
->basesize
< 0 ? maxobjsize
: dstref
->basesize
;
867 gcc_assert (maxsize
<= maxobjsize
);
869 /* Adjust the larger bounds of the offsets (which may be the first
870 element if the lower bound is larger than the upper bound) to
871 make them valid for the smallest access (if possible) but no smaller
872 than the smaller bounds. */
873 gcc_assert (wi::les_p (acs
.dstoff
[0], acs
.dstoff
[1]));
875 if (maxsize
< acs
.dstoff
[1] + acs
.dstsiz
[0])
876 acs
.dstoff
[1] = maxsize
- acs
.dstsiz
[0];
877 if (acs
.dstoff
[1] < acs
.dstoff
[0])
878 acs
.dstoff
[1] = acs
.dstoff
[0];
880 gcc_assert (wi::les_p (acs
.srcoff
[0], acs
.srcoff
[1]));
882 if (maxsize
< acs
.srcoff
[1] + acs
.srcsiz
[0])
883 acs
.srcoff
[1] = maxsize
- acs
.srcsiz
[0];
884 if (acs
.srcoff
[1] < acs
.srcoff
[0])
885 acs
.srcoff
[1] = acs
.srcoff
[0];
887 /* Determine the minimum and maximum space for the access given
890 space
[0] = wi::abs (acs
.dstoff
[0] - acs
.srcoff
[0]);
893 offset_int d
= wi::abs (acs
.dstoff
[0] - acs
.srcoff
[1]);
894 if (acs
.srcsiz
[0] > 0)
903 space
[1] = acs
.dstsiz
[1];
905 d
= wi::abs (acs
.dstoff
[1] - acs
.srcoff
[0]);
912 /* Treat raw memory functions both of whose references are bounded
913 as special and permit uncertain overlaps to go undetected. For
914 all kinds of constant offset and constant size accesses, if
915 overlap isn't certain it is not possible. */
916 bool overlap_possible
= space
[0] < acs
.dstsiz
[1];
917 if (!overlap_possible
)
920 bool overlap_certain
= space
[1] < acs
.dstsiz
[0];
922 /* True when the size of one reference depends on the offset of
924 bool depends_p
= detect_overlap
!= &builtin_access::generic_overlap
;
926 if (!overlap_certain
)
928 if (!dstref
->strbounded_p
&& !depends_p
)
929 /* Memcpy only considers certain overlap. */
932 /* There's no way to distinguish an access to the same member
933 of a structure from one to two distinct members of the same
934 structure. Give up to avoid excessive false positives. */
935 tree basetype
= TREE_TYPE (dstref
->base
);
937 if (POINTER_TYPE_P (basetype
))
938 basetype
= TREE_TYPE (basetype
);
940 while (TREE_CODE (basetype
) == ARRAY_TYPE
)
941 basetype
= TREE_TYPE (basetype
);
943 if (RECORD_OR_UNION_TYPE_P (basetype
))
947 /* True for stpcpy and strcpy. */
948 bool stxcpy_p
= (!dstref
->strbounded_p
949 && detect_overlap
== &builtin_access::strcpy_overlap
);
951 if (dstref
->refoff
>= 0
952 && srcref
->refoff
>= 0
953 && dstref
->refoff
!= srcref
->refoff
954 && (stxcpy_p
|| dstref
->strbounded_p
|| srcref
->strbounded_p
))
957 offset_int siz
[2] = { maxobjsize
+ 1, 0 };
959 ovloff
[0] = HOST_WIDE_INT_MAX
;
960 ovloff
[1] = HOST_WIDE_INT_MIN
;
962 /* Adjustment to the lower bound of the offset of the overlap to
963 account for a subset of unbounded string calls where the size
964 of the destination string depends on the length of the source
965 which in turn depends on the offset into it. */
970 sub1
= acs
.dstoff
[0] <= acs
.srcoff
[0];
972 /* Iterate over the extreme locations (on the horizontal axis formed
973 by their offsets) and sizes of two regions and find their smallest
974 and largest overlap and the corresponding offsets. */
975 for (unsigned i
= 0; i
!= 2; ++i
)
977 const offset_int a
[2] = {
978 acs
.dstoff
[i
], acs
.dstoff
[i
] + acs
.dstsiz
[!i
]
981 const offset_int b
[2] = {
982 acs
.srcoff
[i
], acs
.srcoff
[i
] + acs
.srcsiz
[!i
]
986 offset_int sz
= overlap_size (a
, b
, &off
);
995 if (wi::lts_p (off
, ovloff
[0]))
996 ovloff
[0] = off
.to_shwi ();
997 if (wi::lts_p (ovloff
[1], off
))
998 ovloff
[1] = off
.to_shwi ();
1006 /* Iterate over the extreme locations (on the horizontal axis
1007 formed by their offsets) and sizes of two regions and find
1008 their smallest and largest overlap and the corresponding
1011 for (unsigned io
= 0; io
!= 2; ++io
)
1012 for (unsigned is
= 0; is
!= 2; ++is
)
1014 const offset_int a
[2] = {
1015 acs
.dstoff
[io
], acs
.dstoff
[io
] + acs
.dstsiz
[is
]
1018 for (unsigned jo
= 0; jo
!= 2; ++jo
)
1019 for (unsigned js
= 0; js
!= 2; ++js
)
1023 /* For st{p,r}ncpy the size of the source sequence
1024 depends on the offset into it. */
1030 const offset_int b
[2] = {
1031 acs
.srcoff
[jo
], acs
.srcoff
[jo
] + acs
.srcsiz
[js
]
1035 offset_int sz
= overlap_size (a
, b
, &off
);
1044 if (wi::lts_p (off
, ovloff
[0]))
1045 ovloff
[0] = off
.to_shwi ();
1046 if (wi::lts_p (ovloff
[1], off
))
1047 ovloff
[1] = off
.to_shwi ();
1053 ovlsiz
[0] = siz
[0].to_shwi ();
1054 ovlsiz
[1] = siz
[1].to_shwi ();
1056 if (ovlsiz
[0] == 0 && ovlsiz
[1] > 1)
1057 ovloff
[0] = ovloff
[1] + ovlsiz
[1] - 1 - sub1
;
1062 /* Return true if the strcat-like access overlaps. */
1065 builtin_access::strcat_overlap ()
1067 builtin_access
&acs
= *this;
1068 const builtin_memref
*dstref
= acs
.dstref
;
1069 const builtin_memref
*srcref
= acs
.srcref
;
1071 gcc_assert (dstref
->base
== srcref
->base
);
1073 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1075 gcc_assert (dstref
->base
&& dstref
->base
== srcref
->base
);
1077 /* Adjust for strcat-like accesses. */
1079 /* As a special case for strcat, set the DSTREF offsets to the length
1080 of the source string since the function starts writing at the first
1081 nul, and set the size to 1 for the length of the nul. */
1082 acs
.dstoff
[0] += acs
.dstsiz
[0];
1083 acs
.dstoff
[1] += acs
.dstsiz
[1];
1085 bool strfunc_unknown_args
= acs
.dstsiz
[0] == 0 && acs
.dstsiz
[1] != 0;
1087 /* The lower bound is zero when the size is unknown because then
1088 overlap is not certain. */
1089 acs
.dstsiz
[0] = strfunc_unknown_args
? 0 : 1;
1092 offset_int maxsize
= dstref
->basesize
< 0 ? maxobjsize
: dstref
->basesize
;
1093 gcc_assert (maxsize
<= maxobjsize
);
1095 /* For references to the same base object, determine if there's a pair
1096 of valid offsets into the two references such that access between
1097 them doesn't overlap. Adjust both upper bounds to be valid for
1098 the smaller size (i.e., at most MAXSIZE - SIZE). */
1100 if (maxsize
< acs
.dstoff
[1] + acs
.dstsiz
[0])
1101 acs
.dstoff
[1] = maxsize
- acs
.dstsiz
[0];
1103 if (maxsize
< acs
.srcoff
[1] + acs
.srcsiz
[0])
1104 acs
.srcoff
[1] = maxsize
- acs
.srcsiz
[0];
1106 /* Check to see if there's enough space for both accesses without
1107 overlap. Determine the optimistic (maximum) amount of available
1110 if (acs
.dstoff
[0] <= acs
.srcoff
[0])
1112 if (acs
.dstoff
[1] < acs
.srcoff
[1])
1113 space
= acs
.srcoff
[1] + acs
.srcsiz
[0] - acs
.dstoff
[0];
1115 space
= acs
.dstoff
[1] + acs
.dstsiz
[0] - acs
.srcoff
[0];
1118 space
= acs
.dstoff
[1] + acs
.dstsiz
[0] - acs
.srcoff
[0];
1120 /* Overlap is certain if the distance between the farthest offsets
1121 of the opposite accesses is less than the sum of the lower bounds
1122 of the sizes of the two accesses. */
1123 bool overlap_certain
= space
< acs
.dstsiz
[0] + acs
.srcsiz
[0];
1125 /* For a constant-offset, constant size access, consider the largest
1126 distance between the offset bounds and the lower bound of the access
1127 size. If the overlap isn't certain return success. */
1128 if (!overlap_certain
1129 && acs
.dstoff
[0] == acs
.dstoff
[1]
1130 && acs
.srcoff
[0] == acs
.srcoff
[1]
1131 && acs
.dstsiz
[0] == acs
.dstsiz
[1]
1132 && acs
.srcsiz
[0] == acs
.srcsiz
[1])
1135 /* Overlap is not certain but may be possible. */
1137 offset_int access_min
= acs
.dstsiz
[0] + acs
.srcsiz
[0];
1139 /* Determine the conservative (minimum) amount of space. */
1140 space
= wi::abs (acs
.dstoff
[0] - acs
.srcoff
[0]);
1141 offset_int d
= wi::abs (acs
.dstoff
[0] - acs
.srcoff
[1]);
1144 d
= wi::abs (acs
.dstoff
[1] - acs
.srcoff
[0]);
1148 /* For a strict test (used for strcpy and similar with unknown or
1149 variable bounds or sizes), consider the smallest distance between
1150 the offset bounds and either the upper bound of the access size
1151 if known, or the lower bound otherwise. */
1152 if (access_min
<= space
&& (access_min
!= 0 || !strfunc_unknown_args
))
1155 /* When strcat overlap is certain it is always a single byte:
1156 the terminating NUL, regardless of offsets and sizes. When
1157 overlap is only possible its range is [0, 1]. */
1158 acs
.ovlsiz
[0] = dstref
->sizrange
[0] == dstref
->sizrange
[1] ? 1 : 0;
1161 offset_int endoff
= dstref
->offrange
[0] + dstref
->sizrange
[0];
1162 if (endoff
<= srcref
->offrange
[0])
1163 acs
.ovloff
[0] = wi::smin (maxobjsize
, srcref
->offrange
[0]).to_shwi ();
1165 acs
.ovloff
[0] = wi::smin (maxobjsize
, endoff
).to_shwi ();
1167 acs
.sizrange
[0] = wi::smax (wi::abs (endoff
- srcref
->offrange
[0]) + 1,
1168 srcref
->sizrange
[0]).to_shwi ();
1169 if (dstref
->offrange
[0] == dstref
->offrange
[1])
1171 if (srcref
->offrange
[0] == srcref
->offrange
[1])
1172 acs
.ovloff
[1] = acs
.ovloff
[0];
1175 = wi::smin (maxobjsize
,
1176 srcref
->offrange
[1] + srcref
->sizrange
[1]).to_shwi ();
1180 = wi::smin (maxobjsize
,
1181 dstref
->offrange
[1] + dstref
->sizrange
[1]).to_shwi ();
1183 if (acs
.sizrange
[0] == 0)
1184 acs
.sizrange
[0] = 1;
1185 acs
.sizrange
[1] = wi::smax (acs
.dstsiz
[1], srcref
->sizrange
[1]).to_shwi ();
1189 /* Return true if the strcpy-like access overlaps. */
1192 builtin_access::strcpy_overlap ()
1194 return generic_overlap ();
1198 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1199 one another or that, in order not to overlap, would imply that the size
1200 of the referenced object(s) exceeds the maximum size of an object. Set
1201 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1202 they may overlap in a way that's not apparent from the available data),
1206 builtin_access::overlap ()
1208 builtin_access
&acs
= *this;
1210 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1212 acs
.sizrange
[0] = wi::smax (dstref
->sizrange
[0],
1213 srcref
->sizrange
[0]).to_shwi ();
1214 acs
.sizrange
[1] = wi::smax (dstref
->sizrange
[1],
1215 srcref
->sizrange
[1]).to_shwi ();
1217 /* Check to see if the two references refer to regions that are
1218 too large not to overlap in the address space (whose maximum
1219 size is PTRDIFF_MAX). */
1220 offset_int size
= dstref
->sizrange
[0] + srcref
->sizrange
[0];
1221 if (maxobjsize
< size
)
1223 acs
.ovloff
[0] = (maxobjsize
- dstref
->sizrange
[0]).to_shwi ();
1224 acs
.ovlsiz
[0] = (size
- maxobjsize
).to_shwi ();
1228 /* If both base objects aren't known return the maximum possible
1229 offset that would make them not overlap. */
1230 if (!dstref
->base
|| !srcref
->base
)
1233 /* Set the access offsets. */
1234 acs
.dstoff
[0] = dstref
->offrange
[0];
1235 acs
.dstoff
[1] = dstref
->offrange
[1];
1237 /* If the base object is an array adjust the bounds of the offset
1238 to be non-negative and within the bounds of the array if possible. */
1240 && TREE_CODE (TREE_TYPE (dstref
->base
)) == ARRAY_TYPE
)
1242 if (acs
.dstoff
[0] < 0 && acs
.dstoff
[1] >= 0)
1245 if (acs
.dstoff
[1] < acs
.dstoff
[0])
1247 if (tree size
= TYPE_SIZE_UNIT (TREE_TYPE (dstref
->base
)))
1248 acs
.dstoff
[1] = wi::umin (acs
.dstoff
[1], wi::to_offset (size
));
1250 acs
.dstoff
[1] = wi::umin (acs
.dstoff
[1], maxobjsize
);
1254 acs
.srcoff
[0] = srcref
->offrange
[0];
1255 acs
.srcoff
[1] = srcref
->offrange
[1];
1258 && TREE_CODE (TREE_TYPE (srcref
->base
)) == ARRAY_TYPE
)
1260 if (acs
.srcoff
[0] < 0 && acs
.srcoff
[1] >= 0)
1263 if (tree size
= TYPE_SIZE_UNIT (TREE_TYPE (srcref
->base
)))
1264 acs
.srcoff
[1] = wi::umin (acs
.srcoff
[1], wi::to_offset (size
));
1265 else if (acs
.srcoff
[1] < acs
.srcoff
[0])
1266 acs
.srcoff
[1] = wi::umin (acs
.srcoff
[1], maxobjsize
);
1269 /* When the upper bound of the offset is less than the lower bound
1270 the former is the result of a negative offset being represented
1271 as a large positive value or vice versa. The resulting range is
1272 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1273 a union is not representable using the current data structure
1274 replace it with the full range of offsets. */
1275 if (acs
.dstoff
[1] < acs
.dstoff
[0])
1277 acs
.dstoff
[0] = -maxobjsize
- 1;
1278 acs
.dstoff
[1] = maxobjsize
;
1281 /* Validate the offset and size of each reference on its own first.
1282 This is independent of whether or not the base objects are the
1283 same. Normally, this would have already been detected and
1284 diagnosed by -Warray-bounds, unless it has been disabled. */
1285 offset_int maxoff
= acs
.dstoff
[0] + dstref
->sizrange
[0];
1286 if (maxobjsize
< maxoff
)
1288 acs
.ovlsiz
[0] = (maxoff
- maxobjsize
).to_shwi ();
1289 acs
.ovloff
[0] = acs
.dstoff
[0].to_shwi () - acs
.ovlsiz
[0];
1293 /* Repeat the same as above but for the source offsets. */
1294 if (acs
.srcoff
[1] < acs
.srcoff
[0])
1296 acs
.srcoff
[0] = -maxobjsize
- 1;
1297 acs
.srcoff
[1] = maxobjsize
;
1300 maxoff
= acs
.srcoff
[0] + srcref
->sizrange
[0];
1301 if (maxobjsize
< maxoff
)
1303 acs
.ovlsiz
[0] = (maxoff
- maxobjsize
).to_shwi ();
1304 acs
.ovlsiz
[1] = (acs
.srcoff
[0] + srcref
->sizrange
[1]
1305 - maxobjsize
).to_shwi ();
1306 acs
.ovloff
[0] = acs
.srcoff
[0].to_shwi () - acs
.ovlsiz
[0];
1310 if (dstref
->base
!= srcref
->base
)
1313 acs
.dstsiz
[0] = dstref
->sizrange
[0];
1314 acs
.dstsiz
[1] = dstref
->sizrange
[1];
1316 acs
.srcsiz
[0] = srcref
->sizrange
[0];
1317 acs
.srcsiz
[1] = srcref
->sizrange
[1];
1319 /* Call the appropriate function to determine the overlap. */
1320 if ((this->*detect_overlap
) ())
1324 /* Unless the access size range has already been set, do so here. */
1325 sizrange
[0] = wi::smax (acs
.dstsiz
[0], srcref
->sizrange
[0]).to_shwi ();
1326 sizrange
[1] = wi::smax (acs
.dstsiz
[1], srcref
->sizrange
[1]).to_shwi ();
1334 /* Attempt to detect and diagnose an overlapping copy in a call expression
1335 EXPR involving an an access ACS to a built-in memory or string function.
1336 Return true when one has been detected, false otherwise. */
1339 maybe_diag_overlap (location_t loc
, gcall
*call
, builtin_access
&acs
)
1341 if (!acs
.overlap ())
1344 /* For convenience. */
1345 const builtin_memref
&dstref
= *acs
.dstref
;
1346 const builtin_memref
&srcref
= *acs
.srcref
;
1348 /* Determine the range of offsets and sizes of the overlap if it
1349 exists and issue diagnostics. */
1350 HOST_WIDE_INT
*ovloff
= acs
.ovloff
;
1351 HOST_WIDE_INT
*ovlsiz
= acs
.ovlsiz
;
1352 HOST_WIDE_INT
*sizrange
= acs
.sizrange
;
1354 tree func
= gimple_call_fndecl (call
);
1356 /* To avoid a combinatorial explosion of diagnostics format the offsets
1357 or their ranges as strings and use them in the warning calls below. */
1360 if (dstref
.offrange
[0] == dstref
.offrange
[1]
1361 || dstref
.offrange
[1] > HOST_WIDE_INT_MAX
)
1362 sprintf (offstr
[0], HOST_WIDE_INT_PRINT_DEC
,
1363 dstref
.offrange
[0].to_shwi ());
1366 "[" HOST_WIDE_INT_PRINT_DEC
", " HOST_WIDE_INT_PRINT_DEC
"]",
1367 dstref
.offrange
[0].to_shwi (),
1368 dstref
.offrange
[1].to_shwi ());
1370 if (srcref
.offrange
[0] == srcref
.offrange
[1]
1371 || srcref
.offrange
[1] > HOST_WIDE_INT_MAX
)
1373 HOST_WIDE_INT_PRINT_DEC
,
1374 srcref
.offrange
[0].to_shwi ());
1377 "[" HOST_WIDE_INT_PRINT_DEC
", " HOST_WIDE_INT_PRINT_DEC
"]",
1378 srcref
.offrange
[0].to_shwi (),
1379 srcref
.offrange
[1].to_shwi ());
1381 if (ovloff
[0] == ovloff
[1] || !ovloff
[1])
1382 sprintf (offstr
[2], HOST_WIDE_INT_PRINT_DEC
, ovloff
[0]);
1385 "[" HOST_WIDE_INT_PRINT_DEC
", " HOST_WIDE_INT_PRINT_DEC
"]",
1386 ovloff
[0], ovloff
[1]);
1388 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1389 bool must_overlap
= ovlsiz
[0] > 0;
1392 ovlsiz
[1] = ovlsiz
[0];
1396 /* Issue definitive "overlaps" diagnostic in this block. */
1398 if (sizrange
[0] == sizrange
[1])
1400 if (ovlsiz
[0] == ovlsiz
[1])
1401 warning_at (loc
, OPT_Wrestrict
,
1404 ? G_("%G%qD accessing %wu byte at offsets %s "
1405 "and %s overlaps %wu byte at offset %s")
1406 : G_("%G%qD accessing %wu byte at offsets %s "
1407 "and %s overlaps %wu bytes at offset "
1410 ? G_("%G%qD accessing %wu bytes at offsets %s "
1411 "and %s overlaps %wu byte at offset %s")
1412 : G_("%G%qD accessing %wu bytes at offsets %s "
1413 "and %s overlaps %wu bytes at offset "
1415 call
, func
, sizrange
[0],
1416 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1417 else if (ovlsiz
[1] >= 0 && ovlsiz
[1] < maxobjsize
.to_shwi ())
1418 warning_n (loc
, OPT_Wrestrict
, sizrange
[0],
1419 "%G%qD accessing %wu byte at offsets %s "
1420 "and %s overlaps between %wu and %wu bytes "
1422 "%G%qD accessing %wu bytes at offsets %s "
1423 "and %s overlaps between %wu and %wu bytes "
1425 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1426 ovlsiz
[0], ovlsiz
[1], offstr
[2]);
1428 warning_n (loc
, OPT_Wrestrict
, sizrange
[0],
1429 "%G%qD accessing %wu byte at offsets %s and "
1430 "%s overlaps %wu or more bytes at offset %s",
1431 "%G%qD accessing %wu bytes at offsets %s and "
1432 "%s overlaps %wu or more bytes at offset %s",
1433 call
, func
, sizrange
[0],
1434 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1438 if (sizrange
[1] >= 0 && sizrange
[1] < maxobjsize
.to_shwi ())
1440 if (ovlsiz
[0] == ovlsiz
[1])
1441 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[0],
1442 "%G%qD accessing between %wu and %wu bytes "
1443 "at offsets %s and %s overlaps %wu byte at "
1445 "%G%qD accessing between %wu and %wu bytes "
1446 "at offsets %s and %s overlaps %wu bytes "
1448 call
, func
, sizrange
[0], sizrange
[1],
1449 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1450 else if (ovlsiz
[1] >= 0 && ovlsiz
[1] < maxobjsize
.to_shwi ())
1451 warning_at (loc
, OPT_Wrestrict
,
1452 "%G%qD accessing between %wu and %wu bytes at "
1453 "offsets %s and %s overlaps between %wu and %wu "
1454 "bytes at offset %s",
1455 call
, func
, sizrange
[0], sizrange
[1],
1456 offstr
[0], offstr
[1], ovlsiz
[0], ovlsiz
[1],
1459 warning_at (loc
, OPT_Wrestrict
,
1460 "%G%qD accessing between %wu and %wu bytes at "
1461 "offsets %s and %s overlaps %wu or more bytes "
1463 call
, func
, sizrange
[0], sizrange
[1],
1464 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1468 if (ovlsiz
[0] != ovlsiz
[1])
1469 ovlsiz
[1] = maxobjsize
.to_shwi ();
1471 if (ovlsiz
[0] == ovlsiz
[1])
1472 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[0],
1473 "%G%qD accessing %wu or more bytes at offsets "
1474 "%s and %s overlaps %wu byte at offset %s",
1475 "%G%qD accessing %wu or more bytes at offsets "
1476 "%s and %s overlaps %wu bytes at offset %s",
1477 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1478 ovlsiz
[0], offstr
[2]);
1479 else if (ovlsiz
[1] >= 0 && ovlsiz
[1] < maxobjsize
.to_shwi ())
1480 warning_at (loc
, OPT_Wrestrict
,
1481 "%G%qD accessing %wu or more bytes at offsets %s "
1482 "and %s overlaps between %wu and %wu bytes "
1484 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1485 ovlsiz
[0], ovlsiz
[1], offstr
[2]);
1487 warning_at (loc
, OPT_Wrestrict
,
1488 "%G%qD accessing %wu or more bytes at offsets %s "
1489 "and %s overlaps %wu or more bytes at offset %s",
1490 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1491 ovlsiz
[0], offstr
[2]);
1495 /* Use more concise wording when one of the offsets is unbounded
1496 to avoid confusing the user with large and mostly meaningless
1499 if (DECL_P (dstref
.base
) && TREE_CODE (TREE_TYPE (dstref
.base
)) == ARRAY_TYPE
)
1500 open_range
= ((dstref
.offrange
[0] == 0
1501 && dstref
.offrange
[1] == maxobjsize
)
1502 || (srcref
.offrange
[0] == 0
1503 && srcref
.offrange
[1] == maxobjsize
));
1505 open_range
= ((dstref
.offrange
[0] == -maxobjsize
- 1
1506 && dstref
.offrange
[1] == maxobjsize
)
1507 || (srcref
.offrange
[0] == -maxobjsize
- 1
1508 && srcref
.offrange
[1] == maxobjsize
));
1510 if (sizrange
[0] == sizrange
[1] || sizrange
[1] == 1)
1515 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1516 "%G%qD accessing %wu byte may overlap "
1518 "%G%qD accessing %wu bytes may overlap "
1520 call
, func
, sizrange
[1], ovlsiz
[1]);
1522 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1523 "%G%qD accessing %wu byte at offsets %s "
1524 "and %s may overlap %wu byte at offset %s",
1525 "%G%qD accessing %wu bytes at offsets %s "
1526 "and %s may overlap %wu byte at offset %s",
1527 call
, func
, sizrange
[1], offstr
[0], offstr
[1],
1528 ovlsiz
[1], offstr
[2]);
1533 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1534 "%G%qD accessing %wu byte may overlap "
1536 "%G%qD accessing %wu bytes may overlap "
1538 call
, func
, sizrange
[1], ovlsiz
[1]);
1540 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1541 "%G%qD accessing %wu byte at offsets %s and "
1542 "%s may overlap up to %wu bytes at offset %s",
1543 "%G%qD accessing %wu bytes at offsets %s and "
1544 "%s may overlap up to %wu bytes at offset %s",
1545 call
, func
, sizrange
[1], offstr
[0], offstr
[1],
1546 ovlsiz
[1], offstr
[2]);
1550 if (sizrange
[1] >= 0 && sizrange
[1] < maxobjsize
.to_shwi ())
1553 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[1],
1554 "%G%qD accessing between %wu and %wu bytes "
1555 "may overlap %wu byte",
1556 "%G%qD accessing between %wu and %wu bytes "
1557 "may overlap up to %wu bytes",
1558 call
, func
, sizrange
[0], sizrange
[1], ovlsiz
[1]);
1560 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[1],
1561 "%G%qD accessing between %wu and %wu bytes "
1562 "at offsets %s and %s may overlap %wu byte "
1564 "%G%qD accessing between %wu and %wu bytes "
1565 "at offsets %s and %s may overlap up to %wu "
1566 "bytes at offset %s",
1567 call
, func
, sizrange
[0], sizrange
[1],
1568 offstr
[0], offstr
[1], ovlsiz
[1], offstr
[2]);
1572 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[1],
1573 "%G%qD accessing %wu or more bytes at offsets %s "
1574 "and %s may overlap %wu byte at offset %s",
1575 "%G%qD accessing %wu or more bytes at offsets %s "
1576 "and %s may overlap up to %wu bytes at offset %s",
1577 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1578 ovlsiz
[1], offstr
[2]);
1583 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1584 to a built-in function FUNC to make sure they are within the bounds
1585 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1586 Both initial values of the offsets and their final value computed by
1587 the function by incrementing the initial value by the size are
1588 validated. Return true if the offsets are not valid and a diagnostic
1592 maybe_diag_offset_bounds (location_t loc
, gcall
*call
, tree func
, int strict
,
1593 tree expr
, const builtin_memref
&ref
)
1595 if (!warn_array_bounds
)
1598 offset_int ooboff
[] = { ref
.offrange
[0], ref
.offrange
[1] };
1599 tree oobref
= ref
.offset_out_of_bounds (strict
, ooboff
);
1603 if (EXPR_HAS_LOCATION (expr
))
1604 loc
= EXPR_LOCATION (expr
);
1606 loc
= expansion_point_location_if_in_system_header (loc
);
1610 char rangestr
[2][64];
1611 if (ooboff
[0] == ooboff
[1]
1612 || (ooboff
[0] != ref
.offrange
[0]
1613 && ooboff
[0].to_shwi () >= ooboff
[1].to_shwi ()))
1614 sprintf (rangestr
[0], "%lli", (long long) ooboff
[0].to_shwi ());
1616 sprintf (rangestr
[0], "[%lli, %lli]",
1617 (long long) ooboff
[0].to_shwi (),
1618 (long long) ooboff
[1].to_shwi ());
1620 if (oobref
== error_mark_node
)
1622 if (ref
.sizrange
[0] == ref
.sizrange
[1])
1623 sprintf (rangestr
[1], "%lli", (long long) ref
.sizrange
[0].to_shwi ());
1625 sprintf (rangestr
[1], "[%lli, %lli]",
1626 (long long) ref
.sizrange
[0].to_shwi (),
1627 (long long) ref
.sizrange
[1].to_shwi ());
1629 if (DECL_P (ref
.base
)
1630 && TREE_CODE (type
= TREE_TYPE (ref
.base
)) == ARRAY_TYPE
)
1632 if (warning_at (loc
, OPT_Warray_bounds
,
1633 "%G%qD pointer overflow between offset %s "
1634 "and size %s accessing array %qD with type %qT",
1635 call
, func
, rangestr
[0], rangestr
[1], ref
.base
, type
))
1636 inform (DECL_SOURCE_LOCATION (ref
.base
),
1637 "array %qD declared here", ref
.base
);
1639 warning_at (loc
, OPT_Warray_bounds
,
1640 "%G%qD pointer overflow between offset %s "
1642 call
, func
, rangestr
[0], rangestr
[1]);
1645 warning_at (loc
, OPT_Warray_bounds
,
1646 "%G%qD pointer overflow between offset %s "
1648 call
, func
, rangestr
[0], rangestr
[1]);
1650 else if (oobref
== ref
.base
)
1652 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1654 /* True when the offset formed by an access to the reference
1655 is out of bounds, rather than the initial offset wich is
1656 in bounds. This implies access past the end. */
1657 bool form
= ooboff
[0] != ref
.offrange
[0];
1659 if (DECL_P (ref
.base
))
1661 if ((ref
.basesize
< maxobjsize
1662 && warning_at (loc
, OPT_Warray_bounds
,
1664 ? G_("%G%qD forming offset %s is out of "
1665 "the bounds [0, %wu] of object %qD with "
1667 : G_("%G%qD offset %s is out of the bounds "
1668 "[0, %wu] of object %qD with type %qT"),
1669 call
, func
, rangestr
[0], ref
.basesize
.to_uhwi (),
1670 ref
.base
, TREE_TYPE (ref
.base
)))
1671 || warning_at (loc
, OPT_Warray_bounds
,
1673 ? G_("%G%qD forming offset %s is out of "
1674 "the bounds of object %qD with type %qT")
1675 : G_("%G%qD offset %s is out of the bounds "
1676 "of object %qD with type %qT"),
1677 call
, func
, rangestr
[0],
1678 ref
.base
, TREE_TYPE (ref
.base
)))
1679 inform (DECL_SOURCE_LOCATION (ref
.base
),
1680 "%qD declared here", ref
.base
);
1682 else if (ref
.basesize
< maxobjsize
)
1683 warning_at (loc
, OPT_Warray_bounds
,
1685 ? G_("%G%qD forming offset %s is out of the bounds "
1687 : G_("%G%qD offset %s is out of the bounds [0, %wu]"),
1688 call
, func
, rangestr
[0], ref
.basesize
.to_uhwi ());
1690 warning_at (loc
, OPT_Warray_bounds
,
1692 ? G_("%G%qD forming offset %s is out of bounds")
1693 : G_("%G%qD offset %s is out of bounds"),
1694 call
, func
, rangestr
[0]);
1696 else if (TREE_CODE (ref
.ref
) == MEM_REF
)
1698 tree type
= TREE_TYPE (TREE_OPERAND (ref
.ref
, 0));
1699 if (POINTER_TYPE_P (type
))
1700 type
= TREE_TYPE (type
);
1701 type
= TYPE_MAIN_VARIANT (type
);
1703 warning_at (loc
, OPT_Warray_bounds
,
1704 "%G%qD offset %s from the object at %qE is out "
1705 "of the bounds of %qT",
1706 call
, func
, rangestr
[0], ref
.base
, type
);
1710 type
= TYPE_MAIN_VARIANT (TREE_TYPE (ref
.ref
));
1712 warning_at (loc
, OPT_Warray_bounds
,
1713 "%G%qD offset %s from the object at %qE is out "
1714 "of the bounds of referenced subobject %qD with type %qT "
1716 call
, func
, rangestr
[0], ref
.base
, TREE_OPERAND (ref
.ref
, 1),
1717 type
, ref
.refoff
.to_uhwi ());
1723 /* Check a CALL statement for restrict-violations and issue warnings
1724 if/when appropriate. */
1727 wrestrict_dom_walker::check_call (gcall
*call
)
1729 /* Avoid checking the call if it has already been diagnosed for
1731 if (gimple_no_warning_p (call
))
1734 tree func
= gimple_call_fndecl (call
);
1735 if (!func
|| DECL_BUILT_IN_CLASS (func
) != BUILT_IN_NORMAL
)
1738 bool with_bounds
= gimple_call_with_bounds_p (call
);
1740 /* Argument number to extract from the call (depends on the built-in
1742 unsigned dst_idx
= -1;
1743 unsigned src_idx
= -1;
1744 unsigned bnd_idx
= -1;
1746 /* Is this CALL to a string function (as opposed to one to a raw
1747 memory function). */
1750 switch (DECL_FUNCTION_CODE (func
))
1752 case BUILT_IN_MEMCPY
:
1753 case BUILT_IN_MEMCPY_CHK
:
1754 case BUILT_IN_MEMCPY_CHKP
:
1755 case BUILT_IN_MEMCPY_CHK_CHKP
:
1756 case BUILT_IN_MEMPCPY
:
1757 case BUILT_IN_MEMPCPY_CHK
:
1758 case BUILT_IN_MEMPCPY_CHKP
:
1759 case BUILT_IN_MEMPCPY_CHK_CHKP
:
1760 case BUILT_IN_MEMMOVE
:
1761 case BUILT_IN_MEMMOVE_CHK
:
1762 case BUILT_IN_MEMMOVE_CHKP
:
1763 case BUILT_IN_MEMMOVE_CHK_CHKP
:
1767 case BUILT_IN_STPNCPY
:
1768 case BUILT_IN_STPNCPY_CHK
:
1769 case BUILT_IN_STRNCAT
:
1770 case BUILT_IN_STRNCAT_CHK
:
1771 case BUILT_IN_STRNCPY
:
1772 case BUILT_IN_STRNCPY_CHK
:
1774 src_idx
= 1 + with_bounds
;
1775 bnd_idx
= 2 + 2 * with_bounds
;
1778 case BUILT_IN_STPCPY
:
1779 case BUILT_IN_STPCPY_CHK
:
1780 case BUILT_IN_STPCPY_CHKP
:
1781 case BUILT_IN_STPCPY_CHK_CHKP
:
1782 case BUILT_IN_STRCPY
:
1783 case BUILT_IN_STRCPY_CHK
:
1784 case BUILT_IN_STRCPY_CHKP
:
1785 case BUILT_IN_STRCPY_CHK_CHKP
:
1786 case BUILT_IN_STRCAT
:
1787 case BUILT_IN_STRCAT_CHK
:
1788 case BUILT_IN_STRCAT_CHKP
:
1789 case BUILT_IN_STRCAT_CHK_CHKP
:
1791 src_idx
= 1 + with_bounds
;
1795 /* Handle other string functions here whose access may need
1796 to be validated for in-bounds offsets and non-overlapping
1797 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
1798 macros so they need to be handled here.) */
1802 unsigned nargs
= gimple_call_num_args (call
);
1804 tree dst
= dst_idx
< nargs
? gimple_call_arg (call
, dst_idx
) : NULL_TREE
;
1805 tree src
= src_idx
< nargs
? gimple_call_arg (call
, src_idx
) : NULL_TREE
;
1806 tree dstwr
= bnd_idx
< nargs
? gimple_call_arg (call
, bnd_idx
) : NULL_TREE
;
1808 /* For string functions with an unspecified or unknown bound,
1809 assume the size of the access is one. */
1810 if (!dstwr
&& strfun
)
1811 dstwr
= size_one_node
;
1813 /* DST and SRC can be null for a call with an insufficient number
1814 of arguments to a built-in function declared without a protype. */
1818 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1819 a function declared without a prototype. Avoid checking such
1821 if (TREE_CODE (TREE_TYPE (dst
)) != POINTER_TYPE
1822 || TREE_CODE (TREE_TYPE (src
)) != POINTER_TYPE
1823 || (dstwr
&& !INTEGRAL_TYPE_P (TREE_TYPE (dstwr
))))
1826 if (check_bounds_or_overlap (call
, dst
, src
, dstwr
, NULL_TREE
))
1829 /* Avoid diagnosing the call again. */
1830 gimple_set_no_warning (call
, true);
1833 } /* anonymous namespace */
1835 /* Attempt to detect and diagnose invalid offset bounds and (except for
1836 memmove) overlapping copy in a call expression EXPR from SRC to DST
1837 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1838 SRCSIZE may be NULL. Return false when one or the other has been
1839 detected and diagnosed, true otherwise. */
1842 check_bounds_or_overlap (gcall
*call
, tree dst
, tree src
, tree dstsize
,
1843 tree srcsize
, bool bounds_only
/* = false */)
1845 location_t loc
= gimple_location (call
);
1847 if (tree block
= gimple_block (call
))
1848 if (location_t
*pbloc
= block_nonartificial_location (block
))
1851 loc
= expansion_point_location_if_in_system_header (loc
);
1853 tree func
= gimple_call_fndecl (call
);
1855 builtin_memref
dstref (dst
, dstsize
);
1856 builtin_memref
srcref (src
, srcsize
);
1858 builtin_access
acs (call
, dstref
, srcref
);
1860 /* Set STRICT to the value of the -Warray-bounds=N argument for
1861 string functions or when N > 1. */
1862 int strict
= (acs
.strict () || warn_array_bounds
> 1 ? warn_array_bounds
: 0);
1864 /* Validate offsets first to make sure they are within the bounds
1865 of the destination object if its size is known, or PTRDIFF_MAX
1867 if (maybe_diag_offset_bounds (loc
, call
, func
, strict
, dst
, dstref
)
1868 || maybe_diag_offset_bounds (loc
, call
, func
, strict
, src
, srcref
))
1870 gimple_set_no_warning (call
, true);
1877 || (DECL_FUNCTION_CODE (func
) != BUILT_IN_MEMMOVE
1878 && DECL_FUNCTION_CODE (func
) != BUILT_IN_MEMMOVE_CHK
)));
1883 if (operand_equal_p (dst
, src
, 0))
1885 /* Issue -Wrestrict unless the pointers are null (those do
1886 not point to objects and so do not indicate an overlap;
1887 such calls could be the result of sanitization and jump
1889 if (!integer_zerop (dst
) && !gimple_no_warning_p (call
))
1891 warning_at (loc
, OPT_Wrestrict
,
1892 "%G%qD source argument is the same as destination",
1894 gimple_set_no_warning (call
, true);
1901 /* Return false when overlap has been detected. */
1902 if (maybe_diag_overlap (loc
, call
, acs
))
1904 gimple_set_no_warning (call
, true);
1912 make_pass_warn_restrict (gcc::context
*ctxt
)
1914 return new pass_wrestrict (ctxt
);