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 poly_int64 bitsize
, bitpos
;
402 int sign
, reverse
, vol
;
404 /* Determine the base object or pointer of the reference and
405 the constant bit offset from the beginning of the base.
406 If the offset has a non-constant component, it will be in
407 VAR_OFF. MODE, SIGN, REVERSE, and VOL are write only and
409 base
= get_inner_reference (expr
, &bitsize
, &bitpos
, &var_off
,
410 &mode
, &sign
, &reverse
, &vol
);
412 poly_int64 bytepos
= exact_div (bitpos
, BITS_PER_UNIT
);
414 HOST_WIDE_INT const_off
;
415 if (!base
|| !bytepos
.is_constant (&const_off
))
417 base
= get_base_address (TREE_OPERAND (expr
, 0));
421 offrange
[0] += const_off
;
422 offrange
[1] += const_off
;
426 if (TREE_CODE (var_off
) == INTEGER_CST
)
428 offset_int cstoff
= wi::to_offset (var_off
);
429 offrange
[0] += cstoff
;
430 offrange
[1] += cstoff
;
433 offrange
[1] += maxobjsize
;
436 /* Stash the reference for offset validation. */
439 /* Also stash the constant offset for offset validation. */
440 if (TREE_CODE (expr
) == COMPONENT_REF
)
443 if (TREE_CODE (base
) == MEM_REF
)
445 tree memrefoff
= TREE_OPERAND (base
, 1);
446 extend_offset_range (memrefoff
);
447 base
= TREE_OPERAND (base
, 0);
450 if (TREE_CODE (base
) == SSA_NAME
)
451 set_base_and_offset (base
);
454 /* Return error_mark_node if the signed offset exceeds the bounds
455 of the address space (PTRDIFF_MAX). Otherwise, return either
456 BASE or REF when the offset exceeds the bounds of the BASE or
457 REF object, and set OOBOFF to the past-the-end offset formed
458 by the reference, including its size. When STRICT is non-zero
459 use REF size, when available, otherwise use BASE size. When
460 STRICT is greater than 1, use the size of the last array member
461 as the bound, otherwise treat such a member as a flexible array
462 member. Return NULL when the offset is in bounds. */
465 builtin_memref::offset_out_of_bounds (int strict
, offset_int ooboff
[2]) const
467 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
469 /* A temporary, possibly adjusted, copy of the offset range. */
470 offset_int offrng
[2] = { offrange
[0], offrange
[1] };
472 if (DECL_P (base
) && TREE_CODE (TREE_TYPE (base
)) == ARRAY_TYPE
)
474 /* Check for offset in an anti-range with a negative lower bound.
475 For such a range, consider only the non-negative subrange. */
476 if (offrng
[1] < offrng
[0] && offrng
[1] < 0)
477 offrng
[1] = maxobjsize
;
480 /* Conservative offset of the last byte of the referenced object. */
483 /* The bounds need not be ordered. Set HIB to use as the index
484 of the larger of the bounds and LOB as the opposite. */
485 bool hib
= wi::les_p (offrng
[0], offrng
[1]);
490 endoff
= offrng
[lob
] + sizrange
[0];
492 /* For a reference through a pointer to an object of unknown size
493 all initial offsets are considered valid, positive as well as
494 negative, since the pointer itself can point past the beginning
495 of the object. However, the sum of the lower bound of the offset
496 and that of the size must be less than or equal than PTRDIFF_MAX. */
497 if (endoff
> maxobjsize
)
498 return error_mark_node
;
503 /* A reference to an object of known size must be within the bounds
504 of the base object. */
505 if (offrng
[hib
] < 0 || offrng
[lob
] > basesize
)
508 /* The extent of the reference must also be within the bounds of
509 the base object (if known) or the maximum object size otherwise. */
510 endoff
= wi::smax (offrng
[lob
], 0) + sizrange
[0];
511 if (endoff
> maxobjsize
)
512 return error_mark_node
;
514 offset_int size
= basesize
;
521 && TREE_CODE (ref
) == COMPONENT_REF
523 || !array_at_struct_end_p (ref
)))
525 /* If the reference is to a member subobject, the offset must
526 be within the bounds of the subobject. */
527 tree field
= TREE_OPERAND (ref
, 1);
528 tree type
= TREE_TYPE (field
);
529 if (tree sz
= TYPE_SIZE_UNIT (type
))
530 if (TREE_CODE (sz
) == INTEGER_CST
)
532 size
= refoff
+ wi::to_offset (sz
);
540 /* Set the out-of-bounds offset range to be one greater than
541 that delimited by the reference including its size. */
542 ooboff
[lob
] = size
+ 1;
544 if (endoff
> ooboff
[lob
])
545 ooboff
[hib
] = endoff
;
547 ooboff
[hib
] = wi::smax (offrng
[lob
], 0) + sizrange
[1];
552 /* Create an association between the memory references DST and SRC
553 for access by a call EXPR to a memory or string built-in funtion. */
555 builtin_access::builtin_access (gcall
*call
, builtin_memref
&dst
,
557 : dstref (&dst
), srcref (&src
), sizrange (), ovloff (), ovlsiz (),
558 dstoff (), srcoff (), dstsiz (), srcsiz ()
560 /* Zero out since the offset_int ctors invoked above are no-op. */
561 dstoff
[0] = dstoff
[1] = 0;
562 srcoff
[0] = srcoff
[1] = 0;
563 dstsiz
[0] = dstsiz
[1] = 0;
564 srcsiz
[0] = srcsiz
[1] = 0;
566 /* Object Size Type to use to determine the size of the destination
567 and source objects. Overridden below for raw memory functions. */
570 /* True when the size of one reference depends on the offset of
571 itself or the other. */
572 bool depends_p
= true;
574 /* True when the size of the destination reference DSTREF has been
575 determined from SRCREF and so needs to be adjusted by the latter's
576 offset. Only meaningful for bounded string functions like strncpy. */
577 bool dstadjust_p
= false;
579 /* The size argument number (depends on the built-in). */
580 unsigned sizeargno
= 2;
581 if (gimple_call_with_bounds_p (call
))
584 tree func
= gimple_call_fndecl (call
);
585 switch (DECL_FUNCTION_CODE (func
))
587 case BUILT_IN_MEMCPY
:
588 case BUILT_IN_MEMCPY_CHK
:
589 case BUILT_IN_MEMCPY_CHKP
:
590 case BUILT_IN_MEMCPY_CHK_CHKP
:
591 case BUILT_IN_MEMPCPY
:
592 case BUILT_IN_MEMPCPY_CHK
:
593 case BUILT_IN_MEMPCPY_CHKP
:
594 case BUILT_IN_MEMPCPY_CHK_CHKP
:
597 detect_overlap
= &builtin_access::generic_overlap
;
600 case BUILT_IN_MEMMOVE
:
601 case BUILT_IN_MEMMOVE_CHK
:
602 case BUILT_IN_MEMMOVE_CHKP
:
603 case BUILT_IN_MEMMOVE_CHK_CHKP
:
604 /* For memmove there is never any overlap to check for. */
607 detect_overlap
= &builtin_access::no_overlap
;
610 case BUILT_IN_STPNCPY
:
611 case BUILT_IN_STPNCPY_CHK
:
612 case BUILT_IN_STRNCPY
:
613 case BUILT_IN_STRNCPY_CHK
:
614 dstref
->strbounded_p
= true;
615 detect_overlap
= &builtin_access::strcpy_overlap
;
618 case BUILT_IN_STPCPY
:
619 case BUILT_IN_STPCPY_CHK
:
620 case BUILT_IN_STPCPY_CHKP
:
621 case BUILT_IN_STPCPY_CHK_CHKP
:
622 case BUILT_IN_STRCPY
:
623 case BUILT_IN_STRCPY_CHK
:
624 case BUILT_IN_STRCPY_CHKP
:
625 case BUILT_IN_STRCPY_CHK_CHKP
:
626 detect_overlap
= &builtin_access::strcpy_overlap
;
629 case BUILT_IN_STRCAT
:
630 case BUILT_IN_STRCAT_CHK
:
631 case BUILT_IN_STRCAT_CHKP
:
632 case BUILT_IN_STRCAT_CHK_CHKP
:
633 detect_overlap
= &builtin_access::strcat_overlap
;
636 case BUILT_IN_STRNCAT
:
637 case BUILT_IN_STRNCAT_CHK
:
638 dstref
->strbounded_p
= true;
639 srcref
->strbounded_p
= true;
640 detect_overlap
= &builtin_access::strcat_overlap
;
644 /* Handle other string functions here whose access may need
645 to be validated for in-bounds offsets and non-overlapping
646 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
647 macros so they need to be handled here.) */
651 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
653 /* Try to determine the size of the base object. compute_objsize
654 expects a pointer so create one if BASE is a non-pointer object. */
656 if (dst
.basesize
< 0)
659 if (!POINTER_TYPE_P (TREE_TYPE (addr
)))
660 addr
= build1 (ADDR_EXPR
, (TREE_TYPE (addr
)), addr
);
662 if (tree dstsize
= compute_objsize (addr
, ostype
))
663 dst
.basesize
= wi::to_offset (dstsize
);
664 else if (POINTER_TYPE_P (TREE_TYPE (addr
)))
665 dst
.basesize
= HOST_WIDE_INT_MIN
;
667 dst
.basesize
= maxobjsize
;
670 if (src
.basesize
< 0)
673 if (!POINTER_TYPE_P (TREE_TYPE (addr
)))
674 addr
= build1 (ADDR_EXPR
, (TREE_TYPE (addr
)), addr
);
676 if (tree srcsize
= compute_objsize (addr
, ostype
))
677 src
.basesize
= wi::to_offset (srcsize
);
678 else if (POINTER_TYPE_P (TREE_TYPE (addr
)))
679 src
.basesize
= HOST_WIDE_INT_MIN
;
681 src
.basesize
= maxobjsize
;
684 /* If there is no dependency between the references or the base
685 objects of the two references aren't the same there's nothing
687 if (depends_p
&& dstref
->base
!= srcref
->base
)
690 /* ...otherwise, make adjustments for references to the same object
691 by string built-in functions to reflect the constraints imposed
694 /* For bounded string functions determine the range of the bound
695 on the access. For others, the range stays unbounded. */
696 offset_int bounds
[2] = { maxobjsize
, maxobjsize
};
697 if (dstref
->strbounded_p
)
699 tree size
= gimple_call_arg (call
, sizeargno
);
701 if (get_size_range (size
, range
, true))
703 bounds
[0] = wi::to_offset (range
[0]);
704 bounds
[1] = wi::to_offset (range
[1]);
707 /* If both references' size ranges are indeterminate use the last
708 (size) argument from the function call as a substitute. This
709 may only be necessary for strncpy (but not for memcpy where
710 the size range would have been already determined this way). */
711 if (dstref
->sizrange
[0] == 0 && dstref
->sizrange
[1] == maxobjsize
712 && srcref
->sizrange
[0] == 0 && srcref
->sizrange
[1] == maxobjsize
)
714 dstref
->sizrange
[0] = bounds
[0];
715 dstref
->sizrange
[1] = bounds
[1];
719 /* The size range of one reference involving the same base object
720 can be determined from the size range of the other reference.
721 This makes it possible to compute accurate offsets for warnings
722 involving functions like strcpy where the length of just one of
723 the two arguments is known (determined by tree-ssa-strlen). */
724 if (dstref
->sizrange
[0] == 0 && dstref
->sizrange
[1] == maxobjsize
)
726 /* When the destination size is unknown set it to the size of
728 dstref
->sizrange
[0] = srcref
->sizrange
[0];
729 dstref
->sizrange
[1] = srcref
->sizrange
[1];
731 else if (srcref
->sizrange
[0] == 0 && srcref
->sizrange
[1] == maxobjsize
)
733 /* When the source size is unknown set it to the size of
735 srcref
->sizrange
[0] = dstref
->sizrange
[0];
736 srcref
->sizrange
[1] = dstref
->sizrange
[1];
740 if (dstref
->strbounded_p
)
742 /* Read access by strncpy is bounded. */
743 if (bounds
[0] < srcref
->sizrange
[0])
744 srcref
->sizrange
[0] = bounds
[0];
745 if (bounds
[1] < srcref
->sizrange
[1])
746 srcref
->sizrange
[1] = bounds
[1];
749 /* For string functions, adjust the size range of the source
750 reference by the inverse boundaries of the offset (because
751 the higher the offset into the string the shorter its
753 if (srcref
->offrange
[1] >= 0
754 && srcref
->offrange
[1] < srcref
->sizrange
[0])
755 srcref
->sizrange
[0] -= srcref
->offrange
[1];
757 srcref
->sizrange
[0] = 0;
759 if (srcref
->offrange
[0] > 0)
761 if (srcref
->offrange
[0] < srcref
->sizrange
[1])
762 srcref
->sizrange
[1] -= srcref
->offrange
[0];
764 srcref
->sizrange
[1] = 0;
771 if (detect_overlap
== &builtin_access::generic_overlap
)
773 if (dstref
->strbounded_p
)
775 dstref
->sizrange
[0] = bounds
[0];
776 dstref
->sizrange
[1] = bounds
[1];
778 if (dstref
->sizrange
[0] < srcref
->sizrange
[0])
779 srcref
->sizrange
[0] = dstref
->sizrange
[0];
781 if (dstref
->sizrange
[1] < srcref
->sizrange
[1])
782 srcref
->sizrange
[1] = dstref
->sizrange
[1];
785 else if (detect_overlap
== &builtin_access::strcpy_overlap
)
787 if (!dstref
->strbounded_p
)
789 /* For strcpy, adjust the destination size range to match that
790 of the source computed above. */
791 if (depends_p
&& dstadjust_p
)
793 dstref
->sizrange
[0] = srcref
->sizrange
[0];
794 dstref
->sizrange
[1] = srcref
->sizrange
[1];
799 if (dstref
->strbounded_p
)
801 /* For strncpy, adjust the destination size range to match that
802 of the source computed above. */
803 dstref
->sizrange
[0] = bounds
[0];
804 dstref
->sizrange
[1] = bounds
[1];
806 if (bounds
[0] < srcref
->sizrange
[0])
807 srcref
->sizrange
[0] = bounds
[0];
809 if (bounds
[1] < srcref
->sizrange
[1])
810 srcref
->sizrange
[1] = bounds
[1];
815 builtin_access::overlap_size (const offset_int a
[2], const offset_int b
[2],
818 const offset_int
*p
= a
;
819 const offset_int
*q
= b
;
821 /* Point P at the bigger of the two ranges and Q at the smaller. */
822 if (wi::lts_p (a
[1] - a
[0], b
[1] - b
[0]))
834 return wi::smin (p
[1], q
[1]) - q
[0];
844 /* Return true if the bounded mempry (memcpy amd similar) or string function
845 access (strncpy and similar) ACS overlaps. */
848 builtin_access::generic_overlap ()
850 builtin_access
&acs
= *this;
851 const builtin_memref
*dstref
= acs
.dstref
;
852 const builtin_memref
*srcref
= acs
.srcref
;
854 gcc_assert (dstref
->base
== srcref
->base
);
856 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
858 offset_int maxsize
= dstref
->basesize
< 0 ? maxobjsize
: dstref
->basesize
;
859 gcc_assert (maxsize
<= maxobjsize
);
861 /* Adjust the larger bounds of the offsets (which may be the first
862 element if the lower bound is larger than the upper bound) to
863 make them valid for the smallest access (if possible) but no smaller
864 than the smaller bounds. */
865 gcc_assert (wi::les_p (acs
.dstoff
[0], acs
.dstoff
[1]));
867 if (maxsize
< acs
.dstoff
[1] + acs
.dstsiz
[0])
868 acs
.dstoff
[1] = maxsize
- acs
.dstsiz
[0];
869 if (acs
.dstoff
[1] < acs
.dstoff
[0])
870 acs
.dstoff
[1] = acs
.dstoff
[0];
872 gcc_assert (wi::les_p (acs
.srcoff
[0], acs
.srcoff
[1]));
874 if (maxsize
< acs
.srcoff
[1] + acs
.srcsiz
[0])
875 acs
.srcoff
[1] = maxsize
- acs
.srcsiz
[0];
876 if (acs
.srcoff
[1] < acs
.srcoff
[0])
877 acs
.srcoff
[1] = acs
.srcoff
[0];
879 /* Determine the minimum and maximum space for the access given
882 space
[0] = wi::abs (acs
.dstoff
[0] - acs
.srcoff
[0]);
885 offset_int d
= wi::abs (acs
.dstoff
[0] - acs
.srcoff
[1]);
886 if (acs
.srcsiz
[0] > 0)
895 space
[1] = acs
.dstsiz
[1];
897 d
= wi::abs (acs
.dstoff
[1] - acs
.srcoff
[0]);
904 /* Treat raw memory functions both of whose references are bounded
905 as special and permit uncertain overlaps to go undetected. For
906 all kinds of constant offset and constant size accesses, if
907 overlap isn't certain it is not possible. */
908 bool overlap_possible
= space
[0] < acs
.dstsiz
[1];
909 if (!overlap_possible
)
912 bool overlap_certain
= space
[1] < acs
.dstsiz
[0];
914 /* True when the size of one reference depends on the offset of
916 bool depends_p
= detect_overlap
!= &builtin_access::generic_overlap
;
918 if (!overlap_certain
)
920 if (!dstref
->strbounded_p
&& !depends_p
)
923 /* There's no way to distinguish an access to the same member
924 of a structure from one to two distinct members of the same
925 structure. Give up to avoid excessive false positives. */
926 tree basetype
= TREE_TYPE (TREE_TYPE (dstref
->base
));
927 if (RECORD_OR_UNION_TYPE_P (basetype
))
931 /* True for stpcpy and strcpy. */
932 bool stxcpy_p
= (!dstref
->strbounded_p
933 && detect_overlap
== &builtin_access::strcpy_overlap
);
935 if (dstref
->refoff
>= 0
936 && srcref
->refoff
>= 0
937 && dstref
->refoff
!= srcref
->refoff
938 && (stxcpy_p
|| dstref
->strbounded_p
|| srcref
->strbounded_p
))
941 offset_int siz
[2] = { maxobjsize
+ 1, 0 };
943 ovloff
[0] = HOST_WIDE_INT_MAX
;
944 ovloff
[1] = HOST_WIDE_INT_MIN
;
946 /* Adjustment to the lower bound of the offset of the overlap to
947 account for a subset of unbounded string calls where the size
948 of the destination string depends on the length of the source
949 which in turn depends on the offset into it. */
954 sub1
= acs
.dstoff
[0] <= acs
.srcoff
[0];
956 /* Iterate over the extreme locations (on the horizontal axis formed
957 by their offsets) and sizes of two regions and find their smallest
958 and largest overlap and the corresponding offsets. */
959 for (unsigned i
= 0; i
!= 2; ++i
)
961 const offset_int a
[2] = {
962 acs
.dstoff
[i
], acs
.dstoff
[i
] + acs
.dstsiz
[!i
]
965 const offset_int b
[2] = {
966 acs
.srcoff
[i
], acs
.srcoff
[i
] + acs
.srcsiz
[!i
]
970 offset_int sz
= overlap_size (a
, b
, &off
);
979 if (wi::lts_p (off
, ovloff
[0]))
980 ovloff
[0] = off
.to_shwi ();
981 if (wi::lts_p (ovloff
[1], off
))
982 ovloff
[1] = off
.to_shwi ();
990 /* Iterate over the extreme locations (on the horizontal axis
991 formed by their offsets) and sizes of two regions and find
992 their smallest and largest overlap and the corresponding
995 for (unsigned io
= 0; io
!= 2; ++io
)
996 for (unsigned is
= 0; is
!= 2; ++is
)
998 const offset_int a
[2] = {
999 acs
.dstoff
[io
], acs
.dstoff
[io
] + acs
.dstsiz
[is
]
1002 for (unsigned jo
= 0; jo
!= 2; ++jo
)
1003 for (unsigned js
= 0; js
!= 2; ++js
)
1007 /* For st{p,r}ncpy the size of the source sequence
1008 depends on the offset into it. */
1014 const offset_int b
[2] = {
1015 acs
.srcoff
[jo
], acs
.srcoff
[jo
] + acs
.srcsiz
[js
]
1019 offset_int sz
= overlap_size (a
, b
, &off
);
1028 if (wi::lts_p (off
, ovloff
[0]))
1029 ovloff
[0] = off
.to_shwi ();
1030 if (wi::lts_p (ovloff
[1], off
))
1031 ovloff
[1] = off
.to_shwi ();
1037 ovlsiz
[0] = siz
[0].to_shwi ();
1038 ovlsiz
[1] = siz
[1].to_shwi ();
1040 if (ovlsiz
[0] == 0 && ovlsiz
[1] > 1)
1041 ovloff
[0] = ovloff
[1] + ovlsiz
[1] - 1 - sub1
;
1046 /* Return true if the strcat-like access overlaps. */
1049 builtin_access::strcat_overlap ()
1051 builtin_access
&acs
= *this;
1052 const builtin_memref
*dstref
= acs
.dstref
;
1053 const builtin_memref
*srcref
= acs
.srcref
;
1055 gcc_assert (dstref
->base
== srcref
->base
);
1057 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1059 gcc_assert (dstref
->base
&& dstref
->base
== srcref
->base
);
1061 /* Adjust for strcat-like accesses. */
1063 /* As a special case for strcat, set the DSTREF offsets to the length
1064 of the source string since the function starts writing at the first
1065 nul, and set the size to 1 for the length of the nul. */
1066 acs
.dstoff
[0] += acs
.dstsiz
[0];
1067 acs
.dstoff
[1] += acs
.dstsiz
[1];
1069 bool strfunc_unknown_args
= acs
.dstsiz
[0] == 0 && acs
.dstsiz
[1] != 0;
1071 /* The lower bound is zero when the size is unknown because then
1072 overlap is not certain. */
1073 acs
.dstsiz
[0] = strfunc_unknown_args
? 0 : 1;
1076 offset_int maxsize
= dstref
->basesize
< 0 ? maxobjsize
: dstref
->basesize
;
1077 gcc_assert (maxsize
<= maxobjsize
);
1079 /* For references to the same base object, determine if there's a pair
1080 of valid offsets into the two references such that access between
1081 them doesn't overlap. Adjust both upper bounds to be valid for
1082 the smaller size (i.e., at most MAXSIZE - SIZE). */
1084 if (maxsize
< acs
.dstoff
[1] + acs
.dstsiz
[0])
1085 acs
.dstoff
[1] = maxsize
- acs
.dstsiz
[0];
1087 if (maxsize
< acs
.srcoff
[1] + acs
.srcsiz
[0])
1088 acs
.srcoff
[1] = maxsize
- acs
.srcsiz
[0];
1090 /* Check to see if there's enough space for both accesses without
1091 overlap. Determine the optimistic (maximum) amount of available
1094 if (acs
.dstoff
[0] <= acs
.srcoff
[0])
1096 if (acs
.dstoff
[1] < acs
.srcoff
[1])
1097 space
= acs
.srcoff
[1] + acs
.srcsiz
[0] - acs
.dstoff
[0];
1099 space
= acs
.dstoff
[1] + acs
.dstsiz
[0] - acs
.srcoff
[0];
1102 space
= acs
.dstoff
[1] + acs
.dstsiz
[0] - acs
.srcoff
[0];
1104 /* Overlap is certain if the distance between the farthest offsets
1105 of the opposite accesses is less than the sum of the lower bounds
1106 of the sizes of the two accesses. */
1107 bool overlap_certain
= space
< acs
.dstsiz
[0] + acs
.srcsiz
[0];
1109 /* For a constant-offset, constant size access, consider the largest
1110 distance between the offset bounds and the lower bound of the access
1111 size. If the overlap isn't certain return success. */
1112 if (!overlap_certain
1113 && acs
.dstoff
[0] == acs
.dstoff
[1]
1114 && acs
.srcoff
[0] == acs
.srcoff
[1]
1115 && acs
.dstsiz
[0] == acs
.dstsiz
[1]
1116 && acs
.srcsiz
[0] == acs
.srcsiz
[1])
1119 /* Overlap is not certain but may be possible. */
1121 offset_int access_min
= acs
.dstsiz
[0] + acs
.srcsiz
[0];
1123 /* Determine the conservative (minimum) amount of space. */
1124 space
= wi::abs (acs
.dstoff
[0] - acs
.srcoff
[0]);
1125 offset_int d
= wi::abs (acs
.dstoff
[0] - acs
.srcoff
[1]);
1128 d
= wi::abs (acs
.dstoff
[1] - acs
.srcoff
[0]);
1132 /* For a strict test (used for strcpy and similar with unknown or
1133 variable bounds or sizes), consider the smallest distance between
1134 the offset bounds and either the upper bound of the access size
1135 if known, or the lower bound otherwise. */
1136 if (access_min
<= space
&& (access_min
!= 0 || !strfunc_unknown_args
))
1139 /* When strcat overlap is certain it is always a single byte:
1140 the terminating NUL, regardless of offsets and sizes. When
1141 overlap is only possible its range is [0, 1]. */
1142 acs
.ovlsiz
[0] = dstref
->sizrange
[0] == dstref
->sizrange
[1] ? 1 : 0;
1145 offset_int endoff
= dstref
->offrange
[0] + dstref
->sizrange
[0];
1146 if (endoff
<= srcref
->offrange
[0])
1147 acs
.ovloff
[0] = wi::smin (maxobjsize
, srcref
->offrange
[0]).to_shwi ();
1149 acs
.ovloff
[0] = wi::smin (maxobjsize
, endoff
).to_shwi ();
1151 acs
.sizrange
[0] = wi::smax (wi::abs (endoff
- srcref
->offrange
[0]) + 1,
1152 srcref
->sizrange
[0]).to_shwi ();
1153 if (dstref
->offrange
[0] == dstref
->offrange
[1])
1155 if (srcref
->offrange
[0] == srcref
->offrange
[1])
1156 acs
.ovloff
[1] = acs
.ovloff
[0];
1159 = wi::smin (maxobjsize
,
1160 srcref
->offrange
[1] + srcref
->sizrange
[1]).to_shwi ();
1164 = wi::smin (maxobjsize
,
1165 dstref
->offrange
[1] + dstref
->sizrange
[1]).to_shwi ();
1167 if (acs
.sizrange
[0] == 0)
1168 acs
.sizrange
[0] = 1;
1169 acs
.sizrange
[1] = wi::smax (acs
.dstsiz
[1], srcref
->sizrange
[1]).to_shwi ();
1173 /* Return true if the strcpy-like access overlaps. */
1176 builtin_access::strcpy_overlap ()
1178 return generic_overlap ();
1182 /* Return true if DSTREF and SRCREF describe accesses that either overlap
1183 one another or that, in order not to overlap, would imply that the size
1184 of the referenced object(s) exceeds the maximum size of an object. Set
1185 Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
1186 they may overlap in a way that's not apparent from the available data),
1190 builtin_access::overlap ()
1192 builtin_access
&acs
= *this;
1194 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1196 acs
.sizrange
[0] = wi::smax (dstref
->sizrange
[0],
1197 srcref
->sizrange
[0]).to_shwi ();
1198 acs
.sizrange
[1] = wi::smax (dstref
->sizrange
[1],
1199 srcref
->sizrange
[1]).to_shwi ();
1201 /* Check to see if the two references refer to regions that are
1202 too large not to overlap in the address space (whose maximum
1203 size is PTRDIFF_MAX). */
1204 offset_int size
= dstref
->sizrange
[0] + srcref
->sizrange
[0];
1205 if (maxobjsize
< size
)
1207 acs
.ovloff
[0] = (maxobjsize
- dstref
->sizrange
[0]).to_shwi ();
1208 acs
.ovlsiz
[0] = (size
- maxobjsize
).to_shwi ();
1212 /* If both base objects aren't known return the maximum possible
1213 offset that would make them not overlap. */
1214 if (!dstref
->base
|| !srcref
->base
)
1217 /* Set the access offsets. */
1218 acs
.dstoff
[0] = dstref
->offrange
[0];
1219 acs
.dstoff
[1] = dstref
->offrange
[1];
1221 /* If the base object is an array adjust the bounds of the offset
1222 to be non-negative and within the bounds of the array if possible. */
1224 && TREE_CODE (TREE_TYPE (dstref
->base
)) == ARRAY_TYPE
)
1226 if (acs
.dstoff
[0] < 0 && acs
.dstoff
[1] >= 0)
1229 if (acs
.dstoff
[1] < acs
.dstoff
[0])
1231 if (tree size
= TYPE_SIZE_UNIT (TREE_TYPE (dstref
->base
)))
1232 acs
.dstoff
[1] = wi::umin (acs
.dstoff
[1], wi::to_offset (size
));
1234 acs
.dstoff
[1] = wi::umin (acs
.dstoff
[1], maxobjsize
);
1238 acs
.srcoff
[0] = srcref
->offrange
[0];
1239 acs
.srcoff
[1] = srcref
->offrange
[1];
1242 && TREE_CODE (TREE_TYPE (srcref
->base
)) == ARRAY_TYPE
)
1244 if (acs
.srcoff
[0] < 0 && acs
.srcoff
[1] >= 0)
1247 if (tree size
= TYPE_SIZE_UNIT (TREE_TYPE (srcref
->base
)))
1248 acs
.srcoff
[1] = wi::umin (acs
.srcoff
[1], wi::to_offset (size
));
1249 else if (acs
.srcoff
[1] < acs
.srcoff
[0])
1250 acs
.srcoff
[1] = wi::umin (acs
.srcoff
[1], maxobjsize
);
1253 /* When the upper bound of the offset is less than the lower bound
1254 the former is the result of a negative offset being represented
1255 as a large positive value or vice versa. The resulting range is
1256 a union of two subranges: [MIN, UB] and [LB, MAX]. Since such
1257 a union is not representable using the current data structure
1258 replace it with the full range of offsets. */
1259 if (acs
.dstoff
[1] < acs
.dstoff
[0])
1261 acs
.dstoff
[0] = -maxobjsize
- 1;
1262 acs
.dstoff
[1] = maxobjsize
;
1265 /* Validate the offset and size of each reference on its own first.
1266 This is independent of whether or not the base objects are the
1267 same. Normally, this would have already been detected and
1268 diagnosed by -Warray-bounds, unless it has been disabled. */
1269 offset_int maxoff
= acs
.dstoff
[0] + dstref
->sizrange
[0];
1270 if (maxobjsize
< maxoff
)
1272 acs
.ovlsiz
[0] = (maxoff
- maxobjsize
).to_shwi ();
1273 acs
.ovloff
[0] = acs
.dstoff
[0].to_shwi () - acs
.ovlsiz
[0];
1277 /* Repeat the same as above but for the source offsets. */
1278 if (acs
.srcoff
[1] < acs
.srcoff
[0])
1280 acs
.srcoff
[0] = -maxobjsize
- 1;
1281 acs
.srcoff
[1] = maxobjsize
;
1284 maxoff
= acs
.srcoff
[0] + srcref
->sizrange
[0];
1285 if (maxobjsize
< maxoff
)
1287 acs
.ovlsiz
[0] = (maxoff
- maxobjsize
).to_shwi ();
1288 acs
.ovlsiz
[1] = (acs
.srcoff
[0] + srcref
->sizrange
[1]
1289 - maxobjsize
).to_shwi ();
1290 acs
.ovloff
[0] = acs
.srcoff
[0].to_shwi () - acs
.ovlsiz
[0];
1294 if (dstref
->base
!= srcref
->base
)
1297 acs
.dstsiz
[0] = dstref
->sizrange
[0];
1298 acs
.dstsiz
[1] = dstref
->sizrange
[1];
1300 acs
.srcsiz
[0] = srcref
->sizrange
[0];
1301 acs
.srcsiz
[1] = srcref
->sizrange
[1];
1303 /* Call the appropriate function to determine the overlap. */
1304 if ((this->*detect_overlap
) ())
1308 /* Unless the access size range has already been set, do so here. */
1309 sizrange
[0] = wi::smax (acs
.dstsiz
[0], srcref
->sizrange
[0]).to_shwi ();
1310 sizrange
[1] = wi::smax (acs
.dstsiz
[1], srcref
->sizrange
[1]).to_shwi ();
1318 /* Attempt to detect and diagnose an overlapping copy in a call expression
1319 EXPR involving an an access ACS to a built-in memory or string function.
1320 Return true when one has been detected, false otherwise. */
1323 maybe_diag_overlap (location_t loc
, gcall
*call
, builtin_access
&acs
)
1325 if (!acs
.overlap ())
1328 /* For convenience. */
1329 const builtin_memref
&dstref
= *acs
.dstref
;
1330 const builtin_memref
&srcref
= *acs
.srcref
;
1332 /* Determine the range of offsets and sizes of the overlap if it
1333 exists and issue diagnostics. */
1334 HOST_WIDE_INT
*ovloff
= acs
.ovloff
;
1335 HOST_WIDE_INT
*ovlsiz
= acs
.ovlsiz
;
1336 HOST_WIDE_INT
*sizrange
= acs
.sizrange
;
1338 tree func
= gimple_call_fndecl (call
);
1340 /* To avoid a combinatorial explosion of diagnostics format the offsets
1341 or their ranges as strings and use them in the warning calls below. */
1344 if (dstref
.offrange
[0] == dstref
.offrange
[1]
1345 || dstref
.offrange
[1] > HOST_WIDE_INT_MAX
)
1346 sprintf (offstr
[0], HOST_WIDE_INT_PRINT_DEC
,
1347 dstref
.offrange
[0].to_shwi ());
1350 "[" HOST_WIDE_INT_PRINT_DEC
", " HOST_WIDE_INT_PRINT_DEC
"]",
1351 dstref
.offrange
[0].to_shwi (),
1352 dstref
.offrange
[1].to_shwi ());
1354 if (srcref
.offrange
[0] == srcref
.offrange
[1]
1355 || srcref
.offrange
[1] > HOST_WIDE_INT_MAX
)
1357 HOST_WIDE_INT_PRINT_DEC
,
1358 srcref
.offrange
[0].to_shwi ());
1361 "[" HOST_WIDE_INT_PRINT_DEC
", " HOST_WIDE_INT_PRINT_DEC
"]",
1362 srcref
.offrange
[0].to_shwi (),
1363 srcref
.offrange
[1].to_shwi ());
1365 if (ovloff
[0] == ovloff
[1] || !ovloff
[1])
1366 sprintf (offstr
[2], HOST_WIDE_INT_PRINT_DEC
, ovloff
[0]);
1369 "[" HOST_WIDE_INT_PRINT_DEC
", " HOST_WIDE_INT_PRINT_DEC
"]",
1370 ovloff
[0], ovloff
[1]);
1372 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1373 bool must_overlap
= ovlsiz
[0] > 0;
1376 ovlsiz
[1] = ovlsiz
[0];
1380 /* Issue definitive "overlaps" diagnostic in this block. */
1382 if (sizrange
[0] == sizrange
[1])
1384 if (ovlsiz
[0] == ovlsiz
[1])
1385 warning_at (loc
, OPT_Wrestrict
,
1388 ? G_("%G%qD accessing %wu byte at offsets %s "
1389 "and %s overlaps %wu byte at offset %s")
1390 : G_("%G%qD accessing %wu byte at offsets %s "
1391 "and %s overlaps %wu bytes at offset "
1394 ? G_("%G%qD accessing %wu bytes at offsets %s "
1395 "and %s overlaps %wu byte at offset %s")
1396 : G_("%G%qD accessing %wu bytes at offsets %s "
1397 "and %s overlaps %wu bytes at offset "
1399 call
, func
, sizrange
[0],
1400 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1401 else if (ovlsiz
[1] >= 0 && ovlsiz
[1] < maxobjsize
.to_shwi ())
1402 warning_n (loc
, OPT_Wrestrict
, sizrange
[0],
1403 "%G%qD accessing %wu byte at offsets %s "
1404 "and %s overlaps between %wu and %wu bytes "
1406 "%G%qD accessing %wu bytes at offsets %s "
1407 "and %s overlaps between %wu and %wu bytes "
1409 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1410 ovlsiz
[0], ovlsiz
[1], offstr
[2]);
1412 warning_n (loc
, OPT_Wrestrict
, sizrange
[0],
1413 "%G%qD accessing %wu byte at offsets %s and "
1414 "%s overlaps %wu or more bytes at offset %s",
1415 "%G%qD accessing %wu bytes at offsets %s and "
1416 "%s overlaps %wu or more bytes at offset %s",
1417 call
, func
, sizrange
[0],
1418 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1422 if (sizrange
[1] >= 0 && sizrange
[1] < maxobjsize
.to_shwi ())
1424 if (ovlsiz
[0] == ovlsiz
[1])
1425 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[0],
1426 "%G%qD accessing between %wu and %wu bytes "
1427 "at offsets %s and %s overlaps %wu byte at "
1429 "%G%qD accessing between %wu and %wu bytes "
1430 "at offsets %s and %s overlaps %wu bytes "
1432 call
, func
, sizrange
[0], sizrange
[1],
1433 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1434 else if (ovlsiz
[1] >= 0 && ovlsiz
[1] < maxobjsize
.to_shwi ())
1435 warning_at (loc
, OPT_Wrestrict
,
1436 "%G%qD accessing between %wu and %wu bytes at "
1437 "offsets %s and %s overlaps between %wu and %wu "
1438 "bytes at offset %s",
1439 call
, func
, sizrange
[0], sizrange
[1],
1440 offstr
[0], offstr
[1], ovlsiz
[0], ovlsiz
[1],
1443 warning_at (loc
, OPT_Wrestrict
,
1444 "%G%qD accessing between %wu and %wu bytes at "
1445 "offsets %s and %s overlaps %wu or more bytes "
1447 call
, func
, sizrange
[0], sizrange
[1],
1448 offstr
[0], offstr
[1], ovlsiz
[0], offstr
[2]);
1452 if (ovlsiz
[0] != ovlsiz
[1])
1453 ovlsiz
[1] = maxobjsize
.to_shwi ();
1455 if (ovlsiz
[0] == ovlsiz
[1])
1456 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[0],
1457 "%G%qD accessing %wu or more bytes at offsets "
1458 "%s and %s overlaps %wu byte at offset %s",
1459 "%G%qD accessing %wu or more bytes at offsets "
1460 "%s and %s overlaps %wu bytes at offset %s",
1461 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1462 ovlsiz
[0], offstr
[2]);
1463 else if (ovlsiz
[1] >= 0 && ovlsiz
[1] < maxobjsize
.to_shwi ())
1464 warning_at (loc
, OPT_Wrestrict
,
1465 "%G%qD accessing %wu or more bytes at offsets %s "
1466 "and %s overlaps between %wu and %wu bytes "
1468 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1469 ovlsiz
[0], ovlsiz
[1], offstr
[2]);
1471 warning_at (loc
, OPT_Wrestrict
,
1472 "%G%qD accessing %wu or more bytes at offsets %s "
1473 "and %s overlaps %wu or more bytes at offset %s",
1474 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1475 ovlsiz
[0], offstr
[2]);
1479 /* Use more concise wording when one of the offsets is unbounded
1480 to avoid confusing the user with large and mostly meaningless
1483 if (DECL_P (dstref
.base
) && TREE_CODE (TREE_TYPE (dstref
.base
)) == ARRAY_TYPE
)
1484 open_range
= ((dstref
.offrange
[0] == 0
1485 && dstref
.offrange
[1] == maxobjsize
)
1486 || (srcref
.offrange
[0] == 0
1487 && srcref
.offrange
[1] == maxobjsize
));
1489 open_range
= ((dstref
.offrange
[0] == -maxobjsize
- 1
1490 && dstref
.offrange
[1] == maxobjsize
)
1491 || (srcref
.offrange
[0] == -maxobjsize
- 1
1492 && srcref
.offrange
[1] == maxobjsize
));
1494 if (sizrange
[0] == sizrange
[1] || sizrange
[1] == 1)
1499 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1500 "%G%qD accessing %wu byte may overlap "
1502 "%G%qD accessing %wu bytes may overlap "
1504 call
, func
, sizrange
[1], ovlsiz
[1]);
1506 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1507 "%G%qD accessing %wu byte at offsets %s "
1508 "and %s may overlap %wu byte at offset %s",
1509 "%G%qD accessing %wu bytes at offsets %s "
1510 "and %s may overlap %wu byte at offset %s",
1511 call
, func
, sizrange
[1], offstr
[0], offstr
[1],
1512 ovlsiz
[1], offstr
[2]);
1517 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1518 "%G%qD accessing %wu byte may overlap "
1520 "%G%qD accessing %wu bytes may overlap "
1522 call
, func
, sizrange
[1], ovlsiz
[1]);
1524 warning_n (loc
, OPT_Wrestrict
, sizrange
[1],
1525 "%G%qD accessing %wu byte at offsets %s and "
1526 "%s may overlap up to %wu bytes at offset %s",
1527 "%G%qD accessing %wu bytes at offsets %s and "
1528 "%s may overlap up to %wu bytes at offset %s",
1529 call
, func
, sizrange
[1], offstr
[0], offstr
[1],
1530 ovlsiz
[1], offstr
[2]);
1534 if (sizrange
[1] >= 0 && sizrange
[1] < maxobjsize
.to_shwi ())
1537 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[1],
1538 "%G%qD accessing between %wu and %wu bytes "
1539 "may overlap %wu byte",
1540 "%G%qD accessing between %wu and %wu bytes "
1541 "may overlap up to %wu bytes",
1542 call
, func
, sizrange
[0], sizrange
[1], ovlsiz
[1]);
1544 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[1],
1545 "%G%qD accessing between %wu and %wu bytes "
1546 "at offsets %s and %s may overlap %wu byte "
1548 "%G%qD accessing between %wu and %wu bytes "
1549 "at offsets %s and %s may overlap up to %wu "
1550 "bytes at offset %s",
1551 call
, func
, sizrange
[0], sizrange
[1],
1552 offstr
[0], offstr
[1], ovlsiz
[1], offstr
[2]);
1556 warning_n (loc
, OPT_Wrestrict
, ovlsiz
[1],
1557 "%G%qD accessing %wu or more bytes at offsets %s "
1558 "and %s may overlap %wu byte at offset %s",
1559 "%G%qD accessing %wu or more bytes at offsets %s "
1560 "and %s may overlap up to %wu bytes at offset %s",
1561 call
, func
, sizrange
[0], offstr
[0], offstr
[1],
1562 ovlsiz
[1], offstr
[2]);
1567 /* Validate REF offsets in an EXPRession passed as an argument to a CALL
1568 to a built-in function FUNC to make sure they are within the bounds
1569 of the referenced object if its size is known, or PTRDIFF_MAX otherwise.
1570 Both initial values of the offsets and their final value computed by
1571 the function by incrementing the initial value by the size are
1572 validated. Return true if the offsets are not valid and a diagnostic
1576 maybe_diag_offset_bounds (location_t loc
, gcall
*call
, tree func
, int strict
,
1577 tree expr
, const builtin_memref
&ref
)
1579 if (!warn_array_bounds
)
1582 offset_int ooboff
[] = { ref
.offrange
[0], ref
.offrange
[1] };
1583 tree oobref
= ref
.offset_out_of_bounds (strict
, ooboff
);
1587 if (EXPR_HAS_LOCATION (expr
))
1588 loc
= EXPR_LOCATION (expr
);
1590 loc
= expansion_point_location_if_in_system_header (loc
);
1594 char rangestr
[2][64];
1595 if (ooboff
[0] == ooboff
[1]
1596 || (ooboff
[0] != ref
.offrange
[0]
1597 && ooboff
[0].to_shwi () >= ooboff
[1].to_shwi ()))
1598 sprintf (rangestr
[0], "%lli", (long long) ooboff
[0].to_shwi ());
1600 sprintf (rangestr
[0], "[%lli, %lli]",
1601 (long long) ooboff
[0].to_shwi (),
1602 (long long) ooboff
[1].to_shwi ());
1604 if (oobref
== error_mark_node
)
1606 if (ref
.sizrange
[0] == ref
.sizrange
[1])
1607 sprintf (rangestr
[1], "%lli", (long long) ref
.sizrange
[0].to_shwi ());
1609 sprintf (rangestr
[1], "[%lli, %lli]",
1610 (long long) ref
.sizrange
[0].to_shwi (),
1611 (long long) ref
.sizrange
[1].to_shwi ());
1613 if (DECL_P (ref
.base
)
1614 && TREE_CODE (type
= TREE_TYPE (ref
.base
)) == ARRAY_TYPE
)
1616 if (warning_at (loc
, OPT_Warray_bounds
,
1617 "%G%qD pointer overflow between offset %s "
1618 "and size %s accessing array %qD with type %qT",
1619 call
, func
, rangestr
[0], rangestr
[1], ref
.base
, type
))
1620 inform (DECL_SOURCE_LOCATION (ref
.base
),
1621 "array %qD declared here", ref
.base
);
1623 warning_at (loc
, OPT_Warray_bounds
,
1624 "%G%qD pointer overflow between offset %s "
1626 call
, func
, rangestr
[0], rangestr
[1]);
1629 warning_at (loc
, OPT_Warray_bounds
,
1630 "%G%qD pointer overflow between offset %s "
1632 call
, func
, rangestr
[0], rangestr
[1]);
1634 else if (oobref
== ref
.base
)
1636 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
1638 /* True when the offset formed by an access to the reference
1639 is out of bounds, rather than the initial offset wich is
1640 in bounds. This implies access past the end. */
1641 bool form
= ooboff
[0] != ref
.offrange
[0];
1643 if (DECL_P (ref
.base
))
1645 if ((ref
.basesize
< maxobjsize
1646 && warning_at (loc
, OPT_Warray_bounds
,
1648 ? G_("%G%qD forming offset %s is out of "
1649 "the bounds [0, %wu] of object %qD with "
1651 : G_("%G%qD offset %s is out of the bounds "
1652 "[0, %wu] of object %qD with type %qT"),
1653 call
, func
, rangestr
[0], ref
.basesize
.to_uhwi (),
1654 ref
.base
, TREE_TYPE (ref
.base
)))
1655 || warning_at (loc
, OPT_Warray_bounds
,
1657 ? G_("%G%qD forming offset %s is out of "
1658 "the bounds of object %qD with type %qT")
1659 : G_("%G%qD offset %s is out of the bounds "
1660 "of object %qD with type %qT"),
1661 call
, func
, rangestr
[0],
1662 ref
.base
, TREE_TYPE (ref
.base
)))
1663 inform (DECL_SOURCE_LOCATION (ref
.base
),
1664 "%qD declared here", ref
.base
);
1666 else if (ref
.basesize
< maxobjsize
)
1667 warning_at (loc
, OPT_Warray_bounds
,
1669 ? G_("%G%qD forming offset %s is out of the bounds "
1671 : G_("%G%qD offset %s is out of the bounds [0, %wu]"),
1672 call
, func
, rangestr
[0], ref
.basesize
.to_uhwi ());
1674 warning_at (loc
, OPT_Warray_bounds
,
1676 ? G_("%G%qD forming offset %s is out of bounds")
1677 : G_("%G%qD offset %s is out of bounds"),
1678 call
, func
, rangestr
[0]);
1680 else if (TREE_CODE (ref
.ref
) == MEM_REF
)
1682 tree type
= TREE_TYPE (TREE_OPERAND (ref
.ref
, 0));
1683 if (POINTER_TYPE_P (type
))
1684 type
= TREE_TYPE (type
);
1685 type
= TYPE_MAIN_VARIANT (type
);
1687 warning_at (loc
, OPT_Warray_bounds
,
1688 "%G%qD offset %s from the object at %qE is out "
1689 "of the bounds of %qT",
1690 call
, func
, rangestr
[0], ref
.base
, type
);
1694 type
= TYPE_MAIN_VARIANT (TREE_TYPE (ref
.ref
));
1696 warning_at (loc
, OPT_Warray_bounds
,
1697 "%G%qD offset %s from the object at %qE is out "
1698 "of the bounds of referenced subobject %qD with type %qT "
1700 call
, func
, rangestr
[0], ref
.base
, TREE_OPERAND (ref
.ref
, 1),
1701 type
, ref
.refoff
.to_uhwi ());
1707 /* Check a CALL statement for restrict-violations and issue warnings
1708 if/when appropriate. */
1711 wrestrict_dom_walker::check_call (gcall
*call
)
1713 /* Avoid checking the call if it has already been diagnosed for
1715 if (gimple_no_warning_p (call
))
1718 tree func
= gimple_call_fndecl (call
);
1719 if (!func
|| DECL_BUILT_IN_CLASS (func
) != BUILT_IN_NORMAL
)
1722 bool with_bounds
= gimple_call_with_bounds_p (call
);
1724 /* Argument number to extract from the call (depends on the built-in
1726 unsigned dst_idx
= -1;
1727 unsigned src_idx
= -1;
1728 unsigned bnd_idx
= -1;
1730 /* Is this CALL to a string function (as opposed to one to a raw
1731 memory function). */
1734 switch (DECL_FUNCTION_CODE (func
))
1736 case BUILT_IN_MEMCPY
:
1737 case BUILT_IN_MEMCPY_CHK
:
1738 case BUILT_IN_MEMCPY_CHKP
:
1739 case BUILT_IN_MEMCPY_CHK_CHKP
:
1740 case BUILT_IN_MEMPCPY
:
1741 case BUILT_IN_MEMPCPY_CHK
:
1742 case BUILT_IN_MEMPCPY_CHKP
:
1743 case BUILT_IN_MEMPCPY_CHK_CHKP
:
1744 case BUILT_IN_MEMMOVE
:
1745 case BUILT_IN_MEMMOVE_CHK
:
1746 case BUILT_IN_MEMMOVE_CHKP
:
1747 case BUILT_IN_MEMMOVE_CHK_CHKP
:
1751 case BUILT_IN_STPNCPY
:
1752 case BUILT_IN_STPNCPY_CHK
:
1753 case BUILT_IN_STRNCAT
:
1754 case BUILT_IN_STRNCAT_CHK
:
1755 case BUILT_IN_STRNCPY
:
1756 case BUILT_IN_STRNCPY_CHK
:
1758 src_idx
= 1 + with_bounds
;
1759 bnd_idx
= 2 + 2 * with_bounds
;
1762 case BUILT_IN_STPCPY
:
1763 case BUILT_IN_STPCPY_CHK
:
1764 case BUILT_IN_STPCPY_CHKP
:
1765 case BUILT_IN_STPCPY_CHK_CHKP
:
1766 case BUILT_IN_STRCPY
:
1767 case BUILT_IN_STRCPY_CHK
:
1768 case BUILT_IN_STRCPY_CHKP
:
1769 case BUILT_IN_STRCPY_CHK_CHKP
:
1770 case BUILT_IN_STRCAT
:
1771 case BUILT_IN_STRCAT_CHK
:
1772 case BUILT_IN_STRCAT_CHKP
:
1773 case BUILT_IN_STRCAT_CHK_CHKP
:
1775 src_idx
= 1 + with_bounds
;
1779 /* Handle other string functions here whose access may need
1780 to be validated for in-bounds offsets and non-overlapping
1781 copies. (Not all _chkp functions have BUILT_IN_XXX_CHKP
1782 macros so they need to be handled here.) */
1786 unsigned nargs
= gimple_call_num_args (call
);
1788 tree dst
= dst_idx
< nargs
? gimple_call_arg (call
, dst_idx
) : NULL_TREE
;
1789 tree src
= src_idx
< nargs
? gimple_call_arg (call
, src_idx
) : NULL_TREE
;
1790 tree dstwr
= bnd_idx
< nargs
? gimple_call_arg (call
, bnd_idx
) : NULL_TREE
;
1792 /* For string functions with an unspecified or unknown bound,
1793 assume the size of the access is one. */
1794 if (!dstwr
&& strfun
)
1795 dstwr
= size_one_node
;
1797 /* DST and SRC can be null for a call with an insufficient number
1798 of arguments to a built-in function declared without a protype. */
1802 /* DST, SRC, or DSTWR can also have the wrong type in a call to
1803 a function declared without a prototype. Avoid checking such
1805 if (TREE_CODE (TREE_TYPE (dst
)) != POINTER_TYPE
1806 || TREE_CODE (TREE_TYPE (src
)) != POINTER_TYPE
1807 || (dstwr
&& !INTEGRAL_TYPE_P (TREE_TYPE (dstwr
))))
1810 if (check_bounds_or_overlap (call
, dst
, src
, dstwr
, NULL_TREE
))
1813 /* Avoid diagnosing the call again. */
1814 gimple_set_no_warning (call
, true);
1817 } /* anonymous namespace */
1819 /* Attempt to detect and diagnose invalid offset bounds and (except for
1820 memmove) overlapping copy in a call expression EXPR from SRC to DST
1821 and DSTSIZE and SRCSIZE bytes, respectively. Both DSTSIZE and
1822 SRCSIZE may be NULL. Return false when one or the other has been
1823 detected and diagnosed, true otherwise. */
1826 check_bounds_or_overlap (gcall
*call
, tree dst
, tree src
, tree dstsize
,
1827 tree srcsize
, bool bounds_only
/* = false */)
1829 location_t loc
= gimple_location (call
);
1831 if (tree block
= gimple_block (call
))
1832 if (location_t
*pbloc
= block_nonartificial_location (block
))
1835 loc
= expansion_point_location_if_in_system_header (loc
);
1837 tree func
= gimple_call_fndecl (call
);
1839 builtin_memref
dstref (dst
, dstsize
);
1840 builtin_memref
srcref (src
, srcsize
);
1842 builtin_access
acs (call
, dstref
, srcref
);
1844 /* Set STRICT to the value of the -Warray-bounds=N argument for
1845 string functions or when N > 1. */
1846 int strict
= (acs
.strict () || warn_array_bounds
> 1 ? warn_array_bounds
: 0);
1848 /* Validate offsets first to make sure they are within the bounds
1849 of the destination object if its size is known, or PTRDIFF_MAX
1851 if (maybe_diag_offset_bounds (loc
, call
, func
, strict
, dst
, dstref
)
1852 || maybe_diag_offset_bounds (loc
, call
, func
, strict
, src
, srcref
))
1854 gimple_set_no_warning (call
, true);
1861 || (DECL_FUNCTION_CODE (func
) != BUILT_IN_MEMMOVE
1862 && DECL_FUNCTION_CODE (func
) != BUILT_IN_MEMMOVE_CHK
)));
1867 if (operand_equal_p (dst
, src
, 0))
1869 warning_at (loc
, OPT_Wrestrict
,
1870 "%G%qD source argument is the same as destination",
1872 gimple_set_no_warning (call
, true);
1876 /* Return false when overlap has been detected. */
1877 if (maybe_diag_overlap (loc
, call
, acs
))
1879 gimple_set_no_warning (call
, true);
1887 make_pass_warn_restrict (gcc::context
*ctxt
)
1889 return new pass_wrestrict (ctxt
);