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