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
;
266 tree basetype
= TREE_TYPE (base
);
267 if (DECL_P (base
) && TREE_CODE (basetype
) == ARRAY_TYPE
)
269 /* If the offset could be in range of the referenced object
270 constrain its bounds so neither exceeds those of the object. */
271 if (offrange
[0] < 0 && offrange
[1] > 0)
274 offset_int maxoff
= maxobjsize
;
275 if (ref
&& array_at_struct_end_p (ref
))
276 ; /* Use the maximum possible offset for last member arrays. */
277 else if (tree basesize
= TYPE_SIZE_UNIT (basetype
))
278 maxoff
= wi::to_offset (basesize
);
280 if (offrange
[0] >= 0)
283 offrange
[1] = offrange
[0] <= maxoff
? maxoff
: maxobjsize
;
284 else if (offrange
[0] <= maxoff
&& offrange
[1] > maxoff
)
285 offrange
[1] = maxoff
;
290 /* Ctor helper to set or extend OFFRANGE based on the OFFSET argument. */
293 builtin_memref::extend_offset_range (tree offset
)
295 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
297 if (TREE_CODE (offset
) == INTEGER_CST
)
299 offset_int off
= int_cst_value (offset
);
308 if (TREE_CODE (offset
) == SSA_NAME
)
311 value_range_type rng
= get_range_info (offset
, &min
, &max
);
314 offrange
[0] += offset_int::from (min
, SIGNED
);
315 offrange
[1] += offset_int::from (max
, SIGNED
);
317 else if (rng
== VR_ANTI_RANGE
)
319 offrange
[0] += offset_int::from (max
+ 1, SIGNED
);
320 offrange
[1] += offset_int::from (min
- 1, SIGNED
);
324 gimple
*stmt
= SSA_NAME_DEF_STMT (offset
);
326 if (is_gimple_assign (stmt
)
327 && gimple_assign_rhs_code (stmt
) == NOP_EXPR
328 && (type
= TREE_TYPE (gimple_assign_rhs1 (stmt
)))
329 && INTEGRAL_TYPE_P (type
))
331 /* Use the bounds of the type of the NOP_EXPR operand
332 even if it's signed. The result doesn't trigger
333 warnings but makes their output more readable. */
334 offrange
[0] += wi::to_offset (TYPE_MIN_VALUE (type
));
335 offrange
[1] += wi::to_offset (TYPE_MAX_VALUE (type
));
338 offrange
[1] += maxobjsize
;
343 offrange
[1] += maxobjsize
;
346 /* Determines the base object or pointer of the reference EXPR
347 and the offset range from the beginning of the base. */
350 builtin_memref::set_base_and_offset (tree expr
)
352 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
354 if (TREE_CODE (expr
) == SSA_NAME
)
356 /* Try to tease the offset out of the pointer. */
357 gimple
*stmt
= SSA_NAME_DEF_STMT (expr
);
359 && gimple_assign_single_p (stmt
)
360 && gimple_assign_rhs_code (stmt
) == ADDR_EXPR
)
361 expr
= gimple_assign_rhs1 (stmt
);
362 else if (is_gimple_assign (stmt
))
364 tree_code code
= gimple_assign_rhs_code (stmt
);
365 if (code
== NOP_EXPR
)
367 tree rhs
= gimple_assign_rhs1 (stmt
);
368 if (POINTER_TYPE_P (TREE_TYPE (rhs
)))
369 expr
= gimple_assign_rhs1 (stmt
);
376 else if (code
== POINTER_PLUS_EXPR
)
378 expr
= gimple_assign_rhs1 (stmt
);
380 tree offset
= gimple_assign_rhs2 (stmt
);
381 extend_offset_range (offset
);
396 if (TREE_CODE (expr
) == ADDR_EXPR
)
397 expr
= TREE_OPERAND (expr
, 0);
399 /* Stash the reference for offset validation. */
402 poly_int64 bitsize
, bitpos
;
405 int sign
, reverse
, vol
;
407 /* Determine the base object or pointer of the reference and
408 the constant bit offset from the beginning of the base.
409 If the offset has a non-constant component, it will be in
410 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
412 base
= get_inner_reference (expr
, &bitsize
, &bitpos
, &var_off
,
413 &mode
, &sign
, &reverse
, &vol
);
415 /* get_inner_reference is not expected to return null. */
416 gcc_assert (base
!= NULL
);
418 poly_int64 bytepos
= exact_div (bitpos
, BITS_PER_UNIT
);
420 /* Convert the poly_int64 offset to offset_int. The offset
421 should be constant but be prepared for it not to be just in
424 if (bytepos
.is_constant (&cstoff
))
426 offrange
[0] += cstoff
;
427 offrange
[1] += cstoff
;
429 /* Besides the reference saved above, also stash the offset
431 if (TREE_CODE (expr
) == COMPONENT_REF
)
435 offrange
[1] += maxobjsize
;
439 if (TREE_CODE (var_off
) == INTEGER_CST
)
441 cstoff
= wi::to_offset (var_off
);
442 offrange
[0] += cstoff
;
443 offrange
[1] += cstoff
;
446 offrange
[1] += maxobjsize
;
449 if (TREE_CODE (base
) == MEM_REF
)
451 tree memrefoff
= TREE_OPERAND (base
, 1);
452 extend_offset_range (memrefoff
);
453 base
= TREE_OPERAND (base
, 0);
456 if (TREE_CODE (base
) == SSA_NAME
)
457 set_base_and_offset (base
);
460 /* Return error_mark_node if the signed offset exceeds the bounds
461 of the address space (PTRDIFF_MAX). Otherwise, return either
462 BASE or REF when the offset exceeds the bounds of the BASE or
463 REF object, and set OOBOFF to the past-the-end offset formed
464 by the reference, including its size. When STRICT is non-zero
465 use REF size, when available, otherwise use BASE size. When
466 STRICT is greater than 1, use the size of the last array member
467 as the bound, otherwise treat such a member as a flexible array
468 member. Return NULL when the offset is in bounds. */
471 builtin_memref::offset_out_of_bounds (int strict
, offset_int ooboff
[2]) const
473 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
475 /* A temporary, possibly adjusted, copy of the offset range. */
476 offset_int offrng
[2] = { offrange
[0], offrange
[1] };
478 if (DECL_P (base
) && TREE_CODE (TREE_TYPE (base
)) == ARRAY_TYPE
)
480 /* Check for offset in an anti-range with a negative lower bound.
481 For such a range, consider only the non-negative subrange. */
482 if (offrng
[1] < offrng
[0] && offrng
[1] < 0)
483 offrng
[1] = maxobjsize
;
486 /* Conservative offset of the last byte of the referenced object. */
489 /* The bounds need not be ordered. Set HIB to use as the index
490 of the larger of the bounds and LOB as the opposite. */
491 bool hib
= wi::les_p (offrng
[0], offrng
[1]);
496 endoff
= offrng
[lob
] + sizrange
[0];
498 /* For a reference through a pointer to an object of unknown size
499 all initial offsets are considered valid, positive as well as
500 negative, since the pointer itself can point past the beginning
501 of the object. However, the sum of the lower bound of the offset
502 and that of the size must be less than or equal than PTRDIFF_MAX. */
503 if (endoff
> maxobjsize
)
504 return error_mark_node
;
509 /* A reference to an object of known size must be within the bounds
510 of the base object. */
511 if (offrng
[hib
] < 0 || offrng
[lob
] > basesize
)
514 /* The extent of the reference must also be within the bounds of
515 the base object (if known) or the maximum object size otherwise. */
516 endoff
= wi::smax (offrng
[lob
], 0) + sizrange
[0];
517 if (endoff
> maxobjsize
)
518 return error_mark_node
;
520 offset_int size
= basesize
;
527 && TREE_CODE (ref
) == COMPONENT_REF
529 || !array_at_struct_end_p (ref
)))
531 /* If the reference is to a member subobject, the offset must
532 be within the bounds of the subobject. */
533 tree field
= TREE_OPERAND (ref
, 1);
534 tree type
= TREE_TYPE (field
);
535 if (tree sz
= TYPE_SIZE_UNIT (type
))
536 if (TREE_CODE (sz
) == INTEGER_CST
)
538 size
= refoff
+ wi::to_offset (sz
);
546 /* Set the out-of-bounds offset range to be one greater than
547 that delimited by the reference including its size. */
548 ooboff
[lob
] = size
+ 1;
550 if (endoff
> ooboff
[lob
])
551 ooboff
[hib
] = endoff
;
553 ooboff
[hib
] = wi::smax (offrng
[lob
], 0) + sizrange
[1];
558 /* Create an association between the memory references DST and SRC
559 for access by a call EXPR to a memory or string built-in funtion. */
561 builtin_access::builtin_access (gcall
*call
, builtin_memref
&dst
,
563 : dstref (&dst
), srcref (&src
), sizrange (), ovloff (), ovlsiz (),
564 dstoff (), srcoff (), dstsiz (), srcsiz ()
566 /* Zero out since the offset_int ctors invoked above are no-op. */
567 dstoff
[0] = dstoff
[1] = 0;
568 srcoff
[0] = srcoff
[1] = 0;
569 dstsiz
[0] = dstsiz
[1] = 0;
570 srcsiz
[0] = srcsiz
[1] = 0;
572 /* Object Size Type to use to determine the size of the destination
573 and source objects. Overridden below for raw memory functions. */
576 /* True when the size of one reference depends on the offset of
577 itself or the other. */
578 bool depends_p
= true;
580 /* True when the size of the destination reference DSTREF has been
581 determined from SRCREF and so needs to be adjusted by the latter's
582 offset. Only meaningful for bounded string functions like strncpy. */
583 bool dstadjust_p
= false;
585 /* The size argument number (depends on the built-in). */
586 unsigned sizeargno
= 2;
587 if (gimple_call_with_bounds_p (call
))
590 tree func
= gimple_call_fndecl (call
);
591 switch (DECL_FUNCTION_CODE (func
))
593 case BUILT_IN_MEMCPY
:
594 case BUILT_IN_MEMCPY_CHK
:
595 case BUILT_IN_MEMCPY_CHKP
:
596 case BUILT_IN_MEMCPY_CHK_CHKP
:
597 case BUILT_IN_MEMPCPY
:
598 case BUILT_IN_MEMPCPY_CHK
:
599 case BUILT_IN_MEMPCPY_CHKP
:
600 case BUILT_IN_MEMPCPY_CHK_CHKP
:
603 detect_overlap
= &builtin_access::generic_overlap
;
606 case BUILT_IN_MEMMOVE
:
607 case BUILT_IN_MEMMOVE_CHK
:
608 case BUILT_IN_MEMMOVE_CHKP
:
609 case BUILT_IN_MEMMOVE_CHK_CHKP
:
610 /* For memmove there is never any overlap to check for. */
613 detect_overlap
= &builtin_access::no_overlap
;
616 case BUILT_IN_STPNCPY
:
617 case BUILT_IN_STPNCPY_CHK
:
618 case BUILT_IN_STRNCPY
:
619 case BUILT_IN_STRNCPY_CHK
:
620 dstref
->strbounded_p
= true;
621 detect_overlap
= &builtin_access::strcpy_overlap
;
624 case BUILT_IN_STPCPY
:
625 case BUILT_IN_STPCPY_CHK
:
626 case BUILT_IN_STPCPY_CHKP
:
627 case BUILT_IN_STPCPY_CHK_CHKP
:
628 case BUILT_IN_STRCPY
:
629 case BUILT_IN_STRCPY_CHK
:
630 case BUILT_IN_STRCPY_CHKP
:
631 case BUILT_IN_STRCPY_CHK_CHKP
:
632 detect_overlap
= &builtin_access::strcpy_overlap
;
635 case BUILT_IN_STRCAT
:
636 case BUILT_IN_STRCAT_CHK
:
637 case BUILT_IN_STRCAT_CHKP
:
638 case BUILT_IN_STRCAT_CHK_CHKP
:
639 detect_overlap
= &builtin_access::strcat_overlap
;
642 case BUILT_IN_STRNCAT
:
643 case BUILT_IN_STRNCAT_CHK
:
644 dstref
->strbounded_p
= true;
645 srcref
->strbounded_p
= true;
646 detect_overlap
= &builtin_access::strcat_overlap
;
650 /* Handle other string functions here whose access may need
651 to be validated for in-bounds offsets and non-overlapping
652 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
653 macros so they need to be handled here.) */
657 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
659 /* Try to determine the size of the base object. compute_objsize
660 expects a pointer so create one if BASE is a non-pointer object. */
662 if (dst
.basesize
< 0)
665 if (!POINTER_TYPE_P (TREE_TYPE (addr
)))
666 addr
= build1 (ADDR_EXPR
, (TREE_TYPE (addr
)), addr
);
668 if (tree dstsize
= compute_objsize (addr
, ostype
))
669 dst
.basesize
= wi::to_offset (dstsize
);
670 else if (POINTER_TYPE_P (TREE_TYPE (addr
)))
671 dst
.basesize
= HOST_WIDE_INT_MIN
;
673 dst
.basesize
= maxobjsize
;
676 if (src
.basesize
< 0)
679 if (!POINTER_TYPE_P (TREE_TYPE (addr
)))
680 addr
= build1 (ADDR_EXPR
, (TREE_TYPE (addr
)), addr
);
682 if (tree srcsize
= compute_objsize (addr
, ostype
))
683 src
.basesize
= wi::to_offset (srcsize
);
684 else if (POINTER_TYPE_P (TREE_TYPE (addr
)))
685 src
.basesize
= HOST_WIDE_INT_MIN
;
687 src
.basesize
= maxobjsize
;
690 /* If there is no dependency between the references or the base
691 objects of the two references aren't the same there's nothing
693 if (depends_p
&& dstref
->base
!= srcref
->base
)
696 /* ...otherwise, make adjustments for references to the same object
697 by string built-in functions to reflect the constraints imposed
700 /* For bounded string functions determine the range of the bound
701 on the access. For others, the range stays unbounded. */
702 offset_int bounds
[2] = { maxobjsize
, maxobjsize
};
703 if (dstref
->strbounded_p
)
705 tree size
= gimple_call_arg (call
, sizeargno
);
707 if (get_size_range (size
, range
, true))
709 bounds
[0] = wi::to_offset (range
[0]);
710 bounds
[1] = wi::to_offset (range
[1]);
713 /* If both references' size ranges are indeterminate use the last
714 (size) argument from the function call as a substitute. This
715 may only be necessary for strncpy (but not for memcpy where
716 the size range would have been already determined this way). */
717 if (dstref
->sizrange
[0] == 0 && dstref
->sizrange
[1] == maxobjsize
718 && srcref
->sizrange
[0] == 0 && srcref
->sizrange
[1] == maxobjsize
)
720 dstref
->sizrange
[0] = bounds
[0];
721 dstref
->sizrange
[1] = bounds
[1];
725 /* The size range of one reference involving the same base object
726 can be determined from the size range of the other reference.
727 This makes it possible to compute accurate offsets for warnings
728 involving functions like strcpy where the length of just one of
729 the two arguments is known (determined by tree-ssa-strlen). */
730 if (dstref
->sizrange
[0] == 0 && dstref
->sizrange
[1] == maxobjsize
)
732 /* When the destination size is unknown set it to the size of
734 dstref
->sizrange
[0] = srcref
->sizrange
[0];
735 dstref
->sizrange
[1] = srcref
->sizrange
[1];
737 else if (srcref
->sizrange
[0] == 0 && srcref
->sizrange
[1] == maxobjsize
)
739 /* When the source size is unknown set it to the size of
741 srcref
->sizrange
[0] = dstref
->sizrange
[0];
742 srcref
->sizrange
[1] = dstref
->sizrange
[1];
746 if (dstref
->strbounded_p
)
748 /* Read access by strncpy is bounded. */
749 if (bounds
[0] < srcref
->sizrange
[0])
750 srcref
->sizrange
[0] = bounds
[0];
751 if (bounds
[1] < srcref
->sizrange
[1])
752 srcref
->sizrange
[1] = bounds
[1];
755 /* For string functions, adjust the size range of the source
756 reference by the inverse boundaries of the offset (because
757 the higher the offset into the string the shorter its
759 if (srcref
->offrange
[1] >= 0
760 && srcref
->offrange
[1] < srcref
->sizrange
[0])
761 srcref
->sizrange
[0] -= srcref
->offrange
[1];
763 srcref
->sizrange
[0] = 0;
765 if (srcref
->offrange
[0] > 0)
767 if (srcref
->offrange
[0] < srcref
->sizrange
[1])
768 srcref
->sizrange
[1] -= srcref
->offrange
[0];
770 srcref
->sizrange
[1] = 0;
777 if (detect_overlap
== &builtin_access::generic_overlap
)
779 if (dstref
->strbounded_p
)
781 dstref
->sizrange
[0] = bounds
[0];
782 dstref
->sizrange
[1] = bounds
[1];
784 if (dstref
->sizrange
[0] < srcref
->sizrange
[0])
785 srcref
->sizrange
[0] = dstref
->sizrange
[0];
787 if (dstref
->sizrange
[1] < srcref
->sizrange
[1])
788 srcref
->sizrange
[1] = dstref
->sizrange
[1];
791 else if (detect_overlap
== &builtin_access::strcpy_overlap
)
793 if (!dstref
->strbounded_p
)
795 /* For strcpy, adjust the destination size range to match that
796 of the source computed above. */
797 if (depends_p
&& dstadjust_p
)
799 dstref
->sizrange
[0] = srcref
->sizrange
[0];
800 dstref
->sizrange
[1] = srcref
->sizrange
[1];
805 if (dstref
->strbounded_p
)
807 /* For strncpy, adjust the destination size range to match that
808 of the source computed above. */
809 dstref
->sizrange
[0] = bounds
[0];
810 dstref
->sizrange
[1] = bounds
[1];
812 if (bounds
[0] < srcref
->sizrange
[0])
813 srcref
->sizrange
[0] = bounds
[0];
815 if (bounds
[1] < srcref
->sizrange
[1])
816 srcref
->sizrange
[1] = bounds
[1];
821 builtin_access::overlap_size (const offset_int a
[2], const offset_int b
[2],
824 const offset_int
*p
= a
;
825 const offset_int
*q
= b
;
827 /* Point P at the bigger of the two ranges and Q at the smaller. */
828 if (wi::lts_p (a
[1] - a
[0], b
[1] - b
[0]))
840 return wi::smin (p
[1], q
[1]) - q
[0];
850 /* Return true if the bounded mempry (memcpy amd similar) or string function
851 access (strncpy and similar) ACS overlaps. */
854 builtin_access::generic_overlap ()
856 builtin_access
&acs
= *this;
857 const builtin_memref
*dstref
= acs
.dstref
;
858 const builtin_memref
*srcref
= acs
.srcref
;
860 gcc_assert (dstref
->base
== srcref
->base
);
862 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
864 offset_int maxsize
= dstref
->basesize
< 0 ? maxobjsize
: dstref
->basesize
;
865 gcc_assert (maxsize
<= maxobjsize
);
867 /* Adjust the larger bounds of the offsets (which may be the first
868 element if the lower bound is larger than the upper bound) to
869 make them valid for the smallest access (if possible) but no smaller
870 than the smaller bounds. */
871 gcc_assert (wi::les_p (acs
.dstoff
[0], acs
.dstoff
[1]));
873 if (maxsize
< acs
.dstoff
[1] + acs
.dstsiz
[0])
874 acs
.dstoff
[1] = maxsize
- acs
.dstsiz
[0];
875 if (acs
.dstoff
[1] < acs
.dstoff
[0])
876 acs
.dstoff
[1] = acs
.dstoff
[0];
878 gcc_assert (wi::les_p (acs
.srcoff
[0], acs
.srcoff
[1]));
880 if (maxsize
< acs
.srcoff
[1] + acs
.srcsiz
[0])
881 acs
.srcoff
[1] = maxsize
- acs
.srcsiz
[0];
882 if (acs
.srcoff
[1] < acs
.srcoff
[0])
883 acs
.srcoff
[1] = acs
.srcoff
[0];
885 /* Determine the minimum and maximum space for the access given
888 space
[0] = wi::abs (acs
.dstoff
[0] - acs
.srcoff
[0]);
891 offset_int d
= wi::abs (acs
.dstoff
[0] - acs
.srcoff
[1]);
892 if (acs
.srcsiz
[0] > 0)
901 space
[1] = acs
.dstsiz
[1];
903 d
= wi::abs (acs
.dstoff
[1] - acs
.srcoff
[0]);
910 /* Treat raw memory functions both of whose references are bounded
911 as special and permit uncertain overlaps to go undetected. For
912 all kinds of constant offset and constant size accesses, if
913 overlap isn't certain it is not possible. */
914 bool overlap_possible
= space
[0] < acs
.dstsiz
[1];
915 if (!overlap_possible
)
918 bool overlap_certain
= space
[1] < acs
.dstsiz
[0];
920 /* True when the size of one reference depends on the offset of
922 bool depends_p
= detect_overlap
!= &builtin_access::generic_overlap
;
924 if (!overlap_certain
)
926 if (!dstref
->strbounded_p
&& !depends_p
)
927 /* Memcpy only considers certain overlap. */
930 /* There's no way to distinguish an access to the same member
931 of a structure from one to two distinct members of the same
932 structure. Give up to avoid excessive false positives. */
933 tree basetype
= TREE_TYPE (dstref
->base
);
935 if (POINTER_TYPE_P (basetype
))
936 basetype
= TREE_TYPE (basetype
);
938 while (TREE_CODE (basetype
) == ARRAY_TYPE
)
939 basetype
= TREE_TYPE (basetype
);
941 if (RECORD_OR_UNION_TYPE_P (basetype
))
945 /* True for stpcpy and strcpy. */
946 bool stxcpy_p
= (!dstref
->strbounded_p
947 && detect_overlap
== &builtin_access::strcpy_overlap
);
949 if (dstref
->refoff
>= 0
950 && srcref
->refoff
>= 0
951 && dstref
->refoff
!= srcref
->refoff
952 && (stxcpy_p
|| dstref
->strbounded_p
|| srcref
->strbounded_p
))
955 offset_int siz
[2] = { maxobjsize
+ 1, 0 };
957 ovloff
[0] = HOST_WIDE_INT_MAX
;
958 ovloff
[1] = HOST_WIDE_INT_MIN
;
960 /* Adjustment to the lower bound of the offset of the overlap to
961 account for a subset of unbounded string calls where the size
962 of the destination string depends on the length of the source
963 which in turn depends on the offset into it. */
968 sub1
= acs
.dstoff
[0] <= acs
.srcoff
[0];
970 /* Iterate over the extreme locations (on the horizontal axis formed
971 by their offsets) and sizes of two regions and find their smallest
972 and largest overlap and the corresponding offsets. */
973 for (unsigned i
= 0; i
!= 2; ++i
)
975 const offset_int a
[2] = {
976 acs
.dstoff
[i
], acs
.dstoff
[i
] + acs
.dstsiz
[!i
]
979 const offset_int b
[2] = {
980 acs
.srcoff
[i
], acs
.srcoff
[i
] + acs
.srcsiz
[!i
]
984 offset_int sz
= overlap_size (a
, b
, &off
);
993 if (wi::lts_p (off
, ovloff
[0]))
994 ovloff
[0] = off
.to_shwi ();
995 if (wi::lts_p (ovloff
[1], off
))
996 ovloff
[1] = off
.to_shwi ();
1004 /* Iterate over the extreme locations (on the horizontal axis
1005 formed by their offsets) and sizes of two regions and find
1006 their smallest and largest overlap and the corresponding
1009 for (unsigned io
= 0; io
!= 2; ++io
)
1010 for (unsigned is
= 0; is
!= 2; ++is
)
1012 const offset_int a
[2] = {
1013 acs
.dstoff
[io
], acs
.dstoff
[io
] + acs
.dstsiz
[is
]
1016 for (unsigned jo
= 0; jo
!= 2; ++jo
)
1017 for (unsigned js
= 0; js
!= 2; ++js
)
1021 /* For st{p,r}ncpy the size of the source sequence
1022 depends on the offset into it. */
1028 const offset_int b
[2] = {
1029 acs
.srcoff
[jo
], acs
.srcoff
[jo
] + acs
.srcsiz
[js
]
1033 offset_int sz
= overlap_size (a
, b
, &off
);
1042 if (wi::lts_p (off
, ovloff
[0]))
1043 ovloff
[0] = off
.to_shwi ();
1044 if (wi::lts_p (ovloff
[1], off
))
1045 ovloff
[1] = off
.to_shwi ();
1051 ovlsiz
[0] = siz
[0].to_shwi ();
1052 ovlsiz
[1] = siz
[1].to_shwi ();
1054 if (ovlsiz
[0] == 0 && ovlsiz
[1] > 1)
1055 ovloff
[0] = ovloff
[1] + ovlsiz
[1] - 1 - sub1
;
1060 /* Return true if the strcat-like access overlaps. */
1063 builtin_access::strcat_overlap ()
1065 builtin_access
&acs
= *this;
1066 const builtin_memref
*dstref
= acs
.dstref
;
1067 const builtin_memref
*srcref
= acs
.srcref
;
1069 gcc_assert (dstref
->base
== srcref
->base
);
1071 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1073 gcc_assert (dstref
->base
&& dstref
->base
== srcref
->base
);
1075 /* Adjust for strcat-like accesses. */
1077 /* As a special case for strcat, set the DSTREF offsets to the length
1078 of the source string since the function starts writing at the first
1079 nul, and set the size to 1 for the length of the nul. */
1080 acs
.dstoff
[0] += acs
.dstsiz
[0];
1081 acs
.dstoff
[1] += acs
.dstsiz
[1];
1083 bool strfunc_unknown_args
= acs
.dstsiz
[0] == 0 && acs
.dstsiz
[1] != 0;
1085 /* The lower bound is zero when the size is unknown because then
1086 overlap is not certain. */
1087 acs
.dstsiz
[0] = strfunc_unknown_args
? 0 : 1;
1090 offset_int maxsize
= dstref
->basesize
< 0 ? maxobjsize
: dstref
->basesize
;
1091 gcc_assert (maxsize
<= maxobjsize
);
1093 /* For references to the same base object, determine if there's a pair
1094 of valid offsets into the two references such that access between
1095 them doesn't overlap. Adjust both upper bounds to be valid for
1096 the smaller size (i.e., at most MAXSIZE - SIZE). */
1098 if (maxsize
< acs
.dstoff
[1] + acs
.dstsiz
[0])
1099 acs
.dstoff
[1] = maxsize
- acs
.dstsiz
[0];
1101 if (maxsize
< acs
.srcoff
[1] + acs
.srcsiz
[0])
1102 acs
.srcoff
[1] = maxsize
- acs
.srcsiz
[0];
1104 /* Check to see if there's enough space for both accesses without
1105 overlap. Determine the optimistic (maximum) amount of available
1108 if (acs
.dstoff
[0] <= acs
.srcoff
[0])
1110 if (acs
.dstoff
[1] < acs
.srcoff
[1])
1111 space
= acs
.srcoff
[1] + acs
.srcsiz
[0] - acs
.dstoff
[0];
1113 space
= acs
.dstoff
[1] + acs
.dstsiz
[0] - acs
.srcoff
[0];
1116 space
= acs
.dstoff
[1] + acs
.dstsiz
[0] - acs
.srcoff
[0];
1118 /* Overlap is certain if the distance between the farthest offsets
1119 of the opposite accesses is less than the sum of the lower bounds
1120 of the sizes of the two accesses. */
1121 bool overlap_certain
= space
< acs
.dstsiz
[0] + acs
.srcsiz
[0];
1123 /* For a constant-offset, constant size access, consider the largest
1124 distance between the offset bounds and the lower bound of the access
1125 size. If the overlap isn't certain return success. */
1126 if (!overlap_certain
1127 && acs
.dstoff
[0] == acs
.dstoff
[1]
1128 && acs
.srcoff
[0] == acs
.srcoff
[1]
1129 && acs
.dstsiz
[0] == acs
.dstsiz
[1]
1130 && acs
.srcsiz
[0] == acs
.srcsiz
[1])
1133 /* Overlap is not certain but may be possible. */
1135 offset_int access_min
= acs
.dstsiz
[0] + acs
.srcsiz
[0];
1137 /* Determine the conservative (minimum) amount of space. */
1138 space
= wi::abs (acs
.dstoff
[0] - acs
.srcoff
[0]);
1139 offset_int d
= wi::abs (acs
.dstoff
[0] - acs
.srcoff
[1]);
1142 d
= wi::abs (acs
.dstoff
[1] - acs
.srcoff
[0]);
1146 /* For a strict test (used for strcpy and similar with unknown or
1147 variable bounds or sizes), consider the smallest distance between
1148 the offset bounds and either the upper bound of the access size
1149 if known, or the lower bound otherwise. */
1150 if (access_min
<= space
&& (access_min
!= 0 || !strfunc_unknown_args
))
1153 /* When strcat overlap is certain it is always a single byte:
1154 the terminating NUL, regardless of offsets and sizes. When
1155 overlap is only possible its range is [0, 1]. */
1156 acs
.ovlsiz
[0] = dstref
->sizrange
[0] == dstref
->sizrange
[1] ? 1 : 0;
1159 offset_int endoff
= dstref
->offrange
[0] + dstref
->sizrange
[0];
1160 if (endoff
<= srcref
->offrange
[0])
1161 acs
.ovloff
[0] = wi::smin (maxobjsize
, srcref
->offrange
[0]).to_shwi ();
1163 acs
.ovloff
[0] = wi::smin (maxobjsize
, endoff
).to_shwi ();
1165 acs
.sizrange
[0] = wi::smax (wi::abs (endoff
- srcref
->offrange
[0]) + 1,
1166 srcref
->sizrange
[0]).to_shwi ();
1167 if (dstref
->offrange
[0] == dstref
->offrange
[1])
1169 if (srcref
->offrange
[0] == srcref
->offrange
[1])
1170 acs
.ovloff
[1] = acs
.ovloff
[0];
1173 = wi::smin (maxobjsize
,
1174 srcref
->offrange
[1] + srcref
->sizrange
[1]).to_shwi ();
1178 = wi::smin (maxobjsize
,
1179 dstref
->offrange
[1] + dstref
->sizrange
[1]).to_shwi ();
1181 if (acs
.sizrange
[0] == 0)
1182 acs
.sizrange
[0] = 1;
1183 acs
.sizrange
[1] = wi::smax (acs
.dstsiz
[1], srcref
->sizrange
[1]).to_shwi ();
1187 /* Return true if the strcpy-like access overlaps. */
1190 builtin_access::strcpy_overlap ()
1192 return generic_overlap ();
1196 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1197 one another or that, in order not to overlap, would imply that the size
1198 of the referenced object(s) exceeds the maximum size of an object. Set
1199 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1200 they may overlap in a way that's not apparent from the available data),
1204 builtin_access::overlap ()
1206 builtin_access
&acs
= *this;
1208 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1210 acs
.sizrange
[0] = wi::smax (dstref
->sizrange
[0],
1211 srcref
->sizrange
[0]).to_shwi ();
1212 acs
.sizrange
[1] = wi::smax (dstref
->sizrange
[1],
1213 srcref
->sizrange
[1]).to_shwi ();
1215 /* Check to see if the two references refer to regions that are
1216 too large not to overlap in the address space (whose maximum
1217 size is PTRDIFF_MAX). */
1218 offset_int size
= dstref
->sizrange
[0] + srcref
->sizrange
[0];
1219 if (maxobjsize
< size
)
1221 acs
.ovloff
[0] = (maxobjsize
- dstref
->sizrange
[0]).to_shwi ();
1222 acs
.ovlsiz
[0] = (size
- maxobjsize
).to_shwi ();
1226 /* If both base objects aren't known return the maximum possible
1227 offset that would make them not overlap. */
1228 if (!dstref
->base
|| !srcref
->base
)
1231 /* Set the access offsets. */
1232 acs
.dstoff
[0] = dstref
->offrange
[0];
1233 acs
.dstoff
[1] = dstref
->offrange
[1];
1235 /* If the base object is an array adjust the bounds of the offset
1236 to be non-negative and within the bounds of the array if possible. */
1238 && TREE_CODE (TREE_TYPE (dstref
->base
)) == ARRAY_TYPE
)
1240 if (acs
.dstoff
[0] < 0 && acs
.dstoff
[1] >= 0)
1243 if (acs
.dstoff
[1] < acs
.dstoff
[0])
1245 if (tree size
= TYPE_SIZE_UNIT (TREE_TYPE (dstref
->base
)))
1246 acs
.dstoff
[1] = wi::umin (acs
.dstoff
[1], wi::to_offset (size
));
1248 acs
.dstoff
[1] = wi::umin (acs
.dstoff
[1], maxobjsize
);
1252 acs
.srcoff
[0] = srcref
->offrange
[0];
1253 acs
.srcoff
[1] = srcref
->offrange
[1];
1256 && TREE_CODE (TREE_TYPE (srcref
->base
)) == ARRAY_TYPE
)
1258 if (acs
.srcoff
[0] < 0 && acs
.srcoff
[1] >= 0)
1261 if (tree size
= TYPE_SIZE_UNIT (TREE_TYPE (srcref
->base
)))
1262 acs
.srcoff
[1] = wi::umin (acs
.srcoff
[1], wi::to_offset (size
));
1263 else if (acs
.srcoff
[1] < acs
.srcoff
[0])
1264 acs
.srcoff
[1] = wi::umin (acs
.srcoff
[1], maxobjsize
);
1267 /* When the upper bound of the offset is less than the lower bound
1268 the former is the result of a negative offset being represented
1269 as a large positive value or vice versa. The resulting range is
1270 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1271 a union is not representable using the current data structure
1272 replace it with the full range of offsets. */
1273 if (acs
.dstoff
[1] < acs
.dstoff
[0])
1275 acs
.dstoff
[0] = -maxobjsize
- 1;
1276 acs
.dstoff
[1] = maxobjsize
;
1279 /* Validate the offset and size of each reference on its own first.
1280 This is independent of whether or not the base objects are the
1281 same. Normally, this would have already been detected and
1282 diagnosed by -Warray-bounds, unless it has been disabled. */
1283 offset_int maxoff
= acs
.dstoff
[0] + dstref
->sizrange
[0];
1284 if (maxobjsize
< maxoff
)
1286 acs
.ovlsiz
[0] = (maxoff
- maxobjsize
).to_shwi ();
1287 acs
.ovloff
[0] = acs
.dstoff
[0].to_shwi () - acs
.ovlsiz
[0];
1291 /* Repeat the same as above but for the source offsets. */
1292 if (acs
.srcoff
[1] < acs
.srcoff
[0])
1294 acs
.srcoff
[0] = -maxobjsize
- 1;
1295 acs
.srcoff
[1] = maxobjsize
;
1298 maxoff
= acs
.srcoff
[0] + srcref
->sizrange
[0];
1299 if (maxobjsize
< maxoff
)
1301 acs
.ovlsiz
[0] = (maxoff
- maxobjsize
).to_shwi ();
1302 acs
.ovlsiz
[1] = (acs
.srcoff
[0] + srcref
->sizrange
[1]
1303 - maxobjsize
).to_shwi ();
1304 acs
.ovloff
[0] = acs
.srcoff
[0].to_shwi () - acs
.ovlsiz
[0];
1308 if (dstref
->base
!= srcref
->base
)
1311 acs
.dstsiz
[0] = dstref
->sizrange
[0];
1312 acs
.dstsiz
[1] = dstref
->sizrange
[1];
1314 acs
.srcsiz
[0] = srcref
->sizrange
[0];
1315 acs
.srcsiz
[1] = srcref
->sizrange
[1];
1317 /* Call the appropriate function to determine the overlap. */
1318 if ((this->*detect_overlap
) ())
1322 /* Unless the access size range has already been set, do so here. */
1323 sizrange
[0] = wi::smax (acs
.dstsiz
[0], srcref
->sizrange
[0]).to_shwi ();
1324 sizrange
[1] = wi::smax (acs
.dstsiz
[1], srcref
->sizrange
[1]).to_shwi ();
1332 /* Attempt to detect and diagnose an overlapping copy in a call expression
1333 EXPR involving an an access ACS to a built-in memory or string function.
1334 Return true when one has been detected, false otherwise. */
1337 maybe_diag_overlap (location_t loc
, gcall
*call
, builtin_access
&acs
)
1339 if (!acs
.overlap ())
1342 /* For convenience. */
1343 const builtin_memref
&dstref
= *acs
.dstref
;
1344 const builtin_memref
&srcref
= *acs
.srcref
;
1346 /* Determine the range of offsets and sizes of the overlap if it
1347 exists and issue diagnostics. */
1348 HOST_WIDE_INT
*ovloff
= acs
.ovloff
;
1349 HOST_WIDE_INT
*ovlsiz
= acs
.ovlsiz
;
1350 HOST_WIDE_INT
*sizrange
= acs
.sizrange
;
1352 tree func
= gimple_call_fndecl (call
);
1354 /* To avoid a combinatorial explosion of diagnostics format the offsets
1355 or their ranges as strings and use them in the warning calls below. */
1358 if (dstref
.offrange
[0] == dstref
.offrange
[1]
1359 || dstref
.offrange
[1] > HOST_WIDE_INT_MAX
)
1360 sprintf (offstr
[0], HOST_WIDE_INT_PRINT_DEC
,
1361 dstref
.offrange
[0].to_shwi ());
1364 "[" HOST_WIDE_INT_PRINT_DEC
", " HOST_WIDE_INT_PRINT_DEC
"]",
1365 dstref
.offrange
[0].to_shwi (),
1366 dstref
.offrange
[1].to_shwi ());
1368 if (srcref
.offrange
[0] == srcref
.offrange
[1]
1369 || srcref
.offrange
[1] > HOST_WIDE_INT_MAX
)
1371 HOST_WIDE_INT_PRINT_DEC
,
1372 srcref
.offrange
[0].to_shwi ());
1375 "[" HOST_WIDE_INT_PRINT_DEC
", " HOST_WIDE_INT_PRINT_DEC
"]",
1376 srcref
.offrange
[0].to_shwi (),
1377 srcref
.offrange
[1].to_shwi ());
1379 if (ovloff
[0] == ovloff
[1] || !ovloff
[1])
1380 sprintf (offstr
[2], HOST_WIDE_INT_PRINT_DEC
, ovloff
[0]);
1383 "[" HOST_WIDE_INT_PRINT_DEC
", " HOST_WIDE_INT_PRINT_DEC
"]",
1384 ovloff
[0], ovloff
[1]);
1386 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1387 bool must_overlap
= ovlsiz
[0] > 0;
1390 ovlsiz
[1] = ovlsiz
[0];
1394 /* Issue definitive "overlaps" diagnostic in this block. */
1396 if (sizrange
[0] == sizrange
[1])
1398 if (ovlsiz
[0] == ovlsiz
[1])
1399 warning_at (loc
, OPT_Wrestrict
,
1402 ? G_("%G%qD accessing %wu byte at offsets %s "
1403 "and %s overlaps %wu byte at offset %s")
1404 : G_("%G%qD accessing %wu byte at offsets %s "
1405 "and %s overlaps %wu bytes at offset "
1408 ? G_("%G%qD accessing %wu bytes at offsets %s "
1409 "and %s overlaps %wu byte at offset %s")
1410 : G_("%G%qD accessing %wu bytes at offsets %s "
1411 "and %s overlaps %wu bytes at offset "
1413 call
, func
, sizrange
[0],
1414 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1415 else if (ovlsiz
[1] >= 0 && ovlsiz
[1] < maxobjsize
.to_shwi ())
1416 warning_n (loc
, OPT_Wrestrict
, sizrange
[0],
1417 "%G%qD accessing %wu byte at offsets %s "
1418 "and %s overlaps between %wu and %wu bytes "
1420 "%G%qD accessing %wu bytes at offsets %s "
1421 "and %s overlaps between %wu and %wu bytes "
1423 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1424 ovlsiz
[0], ovlsiz
[1], offstr
[2]);
1426 warning_n (loc
, OPT_Wrestrict
, sizrange
[0],
1427 "%G%qD accessing %wu byte at offsets %s and "
1428 "%s overlaps %wu or more bytes at offset %s",
1429 "%G%qD accessing %wu bytes at offsets %s and "
1430 "%s overlaps %wu or more bytes at offset %s",
1431 call
, func
, sizrange
[0],
1432 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1436 if (sizrange
[1] >= 0 && sizrange
[1] < maxobjsize
.to_shwi ())
1438 if (ovlsiz
[0] == ovlsiz
[1])
1439 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[0],
1440 "%G%qD accessing between %wu and %wu bytes "
1441 "at offsets %s and %s overlaps %wu byte at "
1443 "%G%qD accessing between %wu and %wu bytes "
1444 "at offsets %s and %s overlaps %wu bytes "
1446 call
, func
, sizrange
[0], sizrange
[1],
1447 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1448 else if (ovlsiz
[1] >= 0 && ovlsiz
[1] < maxobjsize
.to_shwi ())
1449 warning_at (loc
, OPT_Wrestrict
,
1450 "%G%qD accessing between %wu and %wu bytes at "
1451 "offsets %s and %s overlaps between %wu and %wu "
1452 "bytes at offset %s",
1453 call
, func
, sizrange
[0], sizrange
[1],
1454 offstr
[0], offstr
[1], ovlsiz
[0], ovlsiz
[1],
1457 warning_at (loc
, OPT_Wrestrict
,
1458 "%G%qD accessing between %wu and %wu bytes at "
1459 "offsets %s and %s overlaps %wu or more bytes "
1461 call
, func
, sizrange
[0], sizrange
[1],
1462 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1466 if (ovlsiz
[0] != ovlsiz
[1])
1467 ovlsiz
[1] = maxobjsize
.to_shwi ();
1469 if (ovlsiz
[0] == ovlsiz
[1])
1470 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[0],
1471 "%G%qD accessing %wu or more bytes at offsets "
1472 "%s and %s overlaps %wu byte at offset %s",
1473 "%G%qD accessing %wu or more bytes at offsets "
1474 "%s and %s overlaps %wu bytes at offset %s",
1475 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1476 ovlsiz
[0], offstr
[2]);
1477 else if (ovlsiz
[1] >= 0 && ovlsiz
[1] < maxobjsize
.to_shwi ())
1478 warning_at (loc
, OPT_Wrestrict
,
1479 "%G%qD accessing %wu or more bytes at offsets %s "
1480 "and %s overlaps between %wu and %wu bytes "
1482 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1483 ovlsiz
[0], ovlsiz
[1], offstr
[2]);
1485 warning_at (loc
, OPT_Wrestrict
,
1486 "%G%qD accessing %wu or more bytes at offsets %s "
1487 "and %s overlaps %wu or more bytes at offset %s",
1488 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1489 ovlsiz
[0], offstr
[2]);
1493 /* Use more concise wording when one of the offsets is unbounded
1494 to avoid confusing the user with large and mostly meaningless
1497 if (DECL_P (dstref
.base
) && TREE_CODE (TREE_TYPE (dstref
.base
)) == ARRAY_TYPE
)
1498 open_range
= ((dstref
.offrange
[0] == 0
1499 && dstref
.offrange
[1] == maxobjsize
)
1500 || (srcref
.offrange
[0] == 0
1501 && srcref
.offrange
[1] == maxobjsize
));
1503 open_range
= ((dstref
.offrange
[0] == -maxobjsize
- 1
1504 && dstref
.offrange
[1] == maxobjsize
)
1505 || (srcref
.offrange
[0] == -maxobjsize
- 1
1506 && srcref
.offrange
[1] == maxobjsize
));
1508 if (sizrange
[0] == sizrange
[1] || sizrange
[1] == 1)
1513 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1514 "%G%qD accessing %wu byte may overlap "
1516 "%G%qD accessing %wu bytes may overlap "
1518 call
, func
, sizrange
[1], ovlsiz
[1]);
1520 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1521 "%G%qD accessing %wu byte at offsets %s "
1522 "and %s may overlap %wu byte at offset %s",
1523 "%G%qD accessing %wu bytes at offsets %s "
1524 "and %s may overlap %wu byte at offset %s",
1525 call
, func
, sizrange
[1], offstr
[0], offstr
[1],
1526 ovlsiz
[1], offstr
[2]);
1531 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1532 "%G%qD accessing %wu byte may overlap "
1534 "%G%qD accessing %wu bytes may overlap "
1536 call
, func
, sizrange
[1], ovlsiz
[1]);
1538 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1539 "%G%qD accessing %wu byte at offsets %s and "
1540 "%s may overlap up to %wu bytes at offset %s",
1541 "%G%qD accessing %wu bytes at offsets %s and "
1542 "%s may overlap up to %wu bytes at offset %s",
1543 call
, func
, sizrange
[1], offstr
[0], offstr
[1],
1544 ovlsiz
[1], offstr
[2]);
1548 if (sizrange
[1] >= 0 && sizrange
[1] < maxobjsize
.to_shwi ())
1551 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[1],
1552 "%G%qD accessing between %wu and %wu bytes "
1553 "may overlap %wu byte",
1554 "%G%qD accessing between %wu and %wu bytes "
1555 "may overlap up to %wu bytes",
1556 call
, func
, sizrange
[0], sizrange
[1], ovlsiz
[1]);
1558 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[1],
1559 "%G%qD accessing between %wu and %wu bytes "
1560 "at offsets %s and %s may overlap %wu byte "
1562 "%G%qD accessing between %wu and %wu bytes "
1563 "at offsets %s and %s may overlap up to %wu "
1564 "bytes at offset %s",
1565 call
, func
, sizrange
[0], sizrange
[1],
1566 offstr
[0], offstr
[1], ovlsiz
[1], offstr
[2]);
1570 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[1],
1571 "%G%qD accessing %wu or more bytes at offsets %s "
1572 "and %s may overlap %wu byte at offset %s",
1573 "%G%qD accessing %wu or more bytes at offsets %s "
1574 "and %s may overlap up to %wu bytes at offset %s",
1575 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1576 ovlsiz
[1], offstr
[2]);
1581 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1582 to a built-in function FUNC to make sure they are within the bounds
1583 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1584 Both initial values of the offsets and their final value computed by
1585 the function by incrementing the initial value by the size are
1586 validated. Return true if the offsets are not valid and a diagnostic
1590 maybe_diag_offset_bounds (location_t loc
, gcall
*call
, tree func
, int strict
,
1591 tree expr
, const builtin_memref
&ref
)
1593 if (!warn_array_bounds
)
1596 offset_int ooboff
[] = { ref
.offrange
[0], ref
.offrange
[1] };
1597 tree oobref
= ref
.offset_out_of_bounds (strict
, ooboff
);
1601 if (EXPR_HAS_LOCATION (expr
))
1602 loc
= EXPR_LOCATION (expr
);
1604 loc
= expansion_point_location_if_in_system_header (loc
);
1608 char rangestr
[2][64];
1609 if (ooboff
[0] == ooboff
[1]
1610 || (ooboff
[0] != ref
.offrange
[0]
1611 && ooboff
[0].to_shwi () >= ooboff
[1].to_shwi ()))
1612 sprintf (rangestr
[0], "%lli", (long long) ooboff
[0].to_shwi ());
1614 sprintf (rangestr
[0], "[%lli, %lli]",
1615 (long long) ooboff
[0].to_shwi (),
1616 (long long) ooboff
[1].to_shwi ());
1618 if (oobref
== error_mark_node
)
1620 if (ref
.sizrange
[0] == ref
.sizrange
[1])
1621 sprintf (rangestr
[1], "%lli", (long long) ref
.sizrange
[0].to_shwi ());
1623 sprintf (rangestr
[1], "[%lli, %lli]",
1624 (long long) ref
.sizrange
[0].to_shwi (),
1625 (long long) ref
.sizrange
[1].to_shwi ());
1627 if (DECL_P (ref
.base
)
1628 && TREE_CODE (type
= TREE_TYPE (ref
.base
)) == ARRAY_TYPE
)
1630 if (warning_at (loc
, OPT_Warray_bounds
,
1631 "%G%qD pointer overflow between offset %s "
1632 "and size %s accessing array %qD with type %qT",
1633 call
, func
, rangestr
[0], rangestr
[1], ref
.base
, type
))
1634 inform (DECL_SOURCE_LOCATION (ref
.base
),
1635 "array %qD declared here", ref
.base
);
1637 warning_at (loc
, OPT_Warray_bounds
,
1638 "%G%qD pointer overflow between offset %s "
1640 call
, func
, rangestr
[0], rangestr
[1]);
1643 warning_at (loc
, OPT_Warray_bounds
,
1644 "%G%qD pointer overflow between offset %s "
1646 call
, func
, rangestr
[0], rangestr
[1]);
1648 else if (oobref
== ref
.base
)
1650 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1652 /* True when the offset formed by an access to the reference
1653 is out of bounds, rather than the initial offset wich is
1654 in bounds. This implies access past the end. */
1655 bool form
= ooboff
[0] != ref
.offrange
[0];
1657 if (DECL_P (ref
.base
))
1659 if ((ref
.basesize
< maxobjsize
1660 && warning_at (loc
, OPT_Warray_bounds
,
1662 ? G_("%G%qD forming offset %s is out of "
1663 "the bounds [0, %wu] of object %qD with "
1665 : G_("%G%qD offset %s is out of the bounds "
1666 "[0, %wu] of object %qD with type %qT"),
1667 call
, func
, rangestr
[0], ref
.basesize
.to_uhwi (),
1668 ref
.base
, TREE_TYPE (ref
.base
)))
1669 || warning_at (loc
, OPT_Warray_bounds
,
1671 ? G_("%G%qD forming offset %s is out of "
1672 "the bounds of object %qD with type %qT")
1673 : G_("%G%qD offset %s is out of the bounds "
1674 "of object %qD with type %qT"),
1675 call
, func
, rangestr
[0],
1676 ref
.base
, TREE_TYPE (ref
.base
)))
1677 inform (DECL_SOURCE_LOCATION (ref
.base
),
1678 "%qD declared here", ref
.base
);
1680 else if (ref
.basesize
< maxobjsize
)
1681 warning_at (loc
, OPT_Warray_bounds
,
1683 ? G_("%G%qD forming offset %s is out of the bounds "
1685 : G_("%G%qD offset %s is out of the bounds [0, %wu]"),
1686 call
, func
, rangestr
[0], ref
.basesize
.to_uhwi ());
1688 warning_at (loc
, OPT_Warray_bounds
,
1690 ? G_("%G%qD forming offset %s is out of bounds")
1691 : G_("%G%qD offset %s is out of bounds"),
1692 call
, func
, rangestr
[0]);
1694 else if (TREE_CODE (ref
.ref
) == MEM_REF
)
1696 tree type
= TREE_TYPE (TREE_OPERAND (ref
.ref
, 0));
1697 if (POINTER_TYPE_P (type
))
1698 type
= TREE_TYPE (type
);
1699 type
= TYPE_MAIN_VARIANT (type
);
1701 warning_at (loc
, OPT_Warray_bounds
,
1702 "%G%qD offset %s from the object at %qE is out "
1703 "of the bounds of %qT",
1704 call
, func
, rangestr
[0], ref
.base
, type
);
1708 type
= TYPE_MAIN_VARIANT (TREE_TYPE (ref
.ref
));
1710 warning_at (loc
, OPT_Warray_bounds
,
1711 "%G%qD offset %s from the object at %qE is out "
1712 "of the bounds of referenced subobject %qD with type %qT "
1714 call
, func
, rangestr
[0], ref
.base
, TREE_OPERAND (ref
.ref
, 1),
1715 type
, ref
.refoff
.to_uhwi ());
1721 /* Check a CALL statement for restrict-violations and issue warnings
1722 if/when appropriate. */
1725 wrestrict_dom_walker::check_call (gcall
*call
)
1727 /* Avoid checking the call if it has already been diagnosed for
1729 if (gimple_no_warning_p (call
))
1732 tree func
= gimple_call_fndecl (call
);
1733 if (!func
|| DECL_BUILT_IN_CLASS (func
) != BUILT_IN_NORMAL
)
1736 bool with_bounds
= gimple_call_with_bounds_p (call
);
1738 /* Argument number to extract from the call (depends on the built-in
1740 unsigned dst_idx
= -1;
1741 unsigned src_idx
= -1;
1742 unsigned bnd_idx
= -1;
1744 /* Is this CALL to a string function (as opposed to one to a raw
1745 memory function). */
1748 switch (DECL_FUNCTION_CODE (func
))
1750 case BUILT_IN_MEMCPY
:
1751 case BUILT_IN_MEMCPY_CHK
:
1752 case BUILT_IN_MEMCPY_CHKP
:
1753 case BUILT_IN_MEMCPY_CHK_CHKP
:
1754 case BUILT_IN_MEMPCPY
:
1755 case BUILT_IN_MEMPCPY_CHK
:
1756 case BUILT_IN_MEMPCPY_CHKP
:
1757 case BUILT_IN_MEMPCPY_CHK_CHKP
:
1758 case BUILT_IN_MEMMOVE
:
1759 case BUILT_IN_MEMMOVE_CHK
:
1760 case BUILT_IN_MEMMOVE_CHKP
:
1761 case BUILT_IN_MEMMOVE_CHK_CHKP
:
1765 case BUILT_IN_STPNCPY
:
1766 case BUILT_IN_STPNCPY_CHK
:
1767 case BUILT_IN_STRNCAT
:
1768 case BUILT_IN_STRNCAT_CHK
:
1769 case BUILT_IN_STRNCPY
:
1770 case BUILT_IN_STRNCPY_CHK
:
1772 src_idx
= 1 + with_bounds
;
1773 bnd_idx
= 2 + 2 * with_bounds
;
1776 case BUILT_IN_STPCPY
:
1777 case BUILT_IN_STPCPY_CHK
:
1778 case BUILT_IN_STPCPY_CHKP
:
1779 case BUILT_IN_STPCPY_CHK_CHKP
:
1780 case BUILT_IN_STRCPY
:
1781 case BUILT_IN_STRCPY_CHK
:
1782 case BUILT_IN_STRCPY_CHKP
:
1783 case BUILT_IN_STRCPY_CHK_CHKP
:
1784 case BUILT_IN_STRCAT
:
1785 case BUILT_IN_STRCAT_CHK
:
1786 case BUILT_IN_STRCAT_CHKP
:
1787 case BUILT_IN_STRCAT_CHK_CHKP
:
1789 src_idx
= 1 + with_bounds
;
1793 /* Handle other string functions here whose access may need
1794 to be validated for in-bounds offsets and non-overlapping
1795 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
1796 macros so they need to be handled here.) */
1800 unsigned nargs
= gimple_call_num_args (call
);
1802 tree dst
= dst_idx
< nargs
? gimple_call_arg (call
, dst_idx
) : NULL_TREE
;
1803 tree src
= src_idx
< nargs
? gimple_call_arg (call
, src_idx
) : NULL_TREE
;
1804 tree dstwr
= bnd_idx
< nargs
? gimple_call_arg (call
, bnd_idx
) : NULL_TREE
;
1806 /* For string functions with an unspecified or unknown bound,
1807 assume the size of the access is one. */
1808 if (!dstwr
&& strfun
)
1809 dstwr
= size_one_node
;
1811 /* DST and SRC can be null for a call with an insufficient number
1812 of arguments to a built-in function declared without a protype. */
1816 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1817 a function declared without a prototype. Avoid checking such
1819 if (TREE_CODE (TREE_TYPE (dst
)) != POINTER_TYPE
1820 || TREE_CODE (TREE_TYPE (src
)) != POINTER_TYPE
1821 || (dstwr
&& !INTEGRAL_TYPE_P (TREE_TYPE (dstwr
))))
1824 if (check_bounds_or_overlap (call
, dst
, src
, dstwr
, NULL_TREE
))
1827 /* Avoid diagnosing the call again. */
1828 gimple_set_no_warning (call
, true);
1831 } /* anonymous namespace */
1833 /* Attempt to detect and diagnose invalid offset bounds and (except for
1834 memmove) overlapping copy in a call expression EXPR from SRC to DST
1835 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1836 SRCSIZE may be NULL. Return false when one or the other has been
1837 detected and diagnosed, true otherwise. */
1840 check_bounds_or_overlap (gcall
*call
, tree dst
, tree src
, tree dstsize
,
1841 tree srcsize
, bool bounds_only
/* = false */)
1843 location_t loc
= gimple_location (call
);
1845 if (tree block
= gimple_block (call
))
1846 if (location_t
*pbloc
= block_nonartificial_location (block
))
1849 loc
= expansion_point_location_if_in_system_header (loc
);
1851 tree func
= gimple_call_fndecl (call
);
1853 builtin_memref
dstref (dst
, dstsize
);
1854 builtin_memref
srcref (src
, srcsize
);
1856 builtin_access
acs (call
, dstref
, srcref
);
1858 /* Set STRICT to the value of the -Warray-bounds=N argument for
1859 string functions or when N > 1. */
1860 int strict
= (acs
.strict () || warn_array_bounds
> 1 ? warn_array_bounds
: 0);
1862 /* Validate offsets first to make sure they are within the bounds
1863 of the destination object if its size is known, or PTRDIFF_MAX
1865 if (maybe_diag_offset_bounds (loc
, call
, func
, strict
, dst
, dstref
)
1866 || maybe_diag_offset_bounds (loc
, call
, func
, strict
, src
, srcref
))
1868 gimple_set_no_warning (call
, true);
1875 || (DECL_FUNCTION_CODE (func
) != BUILT_IN_MEMMOVE
1876 && DECL_FUNCTION_CODE (func
) != BUILT_IN_MEMMOVE_CHK
)));
1881 if (operand_equal_p (dst
, src
, 0))
1883 warning_at (loc
, OPT_Wrestrict
,
1884 "%G%qD source argument is the same as destination",
1886 gimple_set_no_warning (call
, true);
1890 /* Return false when overlap has been detected. */
1891 if (maybe_diag_overlap (loc
, call
, acs
))
1893 gimple_set_no_warning (call
, true);
1901 make_pass_warn_restrict (gcc::context
*ctxt
)
1903 return new pass_wrestrict (ctxt
);