1 /* Array bounds checking.
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
27 #include "gimple-array-bounds.h"
28 #include "gimple-iterator.h"
29 #include "gimple-walk.h"
31 #include "fold-const.h"
32 #include "diagnostic-core.h"
35 #include "alloc-pool.h"
36 #include "vr-values.h"
40 // This purposely returns a value_range, not a value_range_equiv, to
41 // break the dependency on equivalences for this pass.
44 array_bounds_checker::get_value_range (const_tree op
)
46 return ranges
->get_value_range (op
);
49 /* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible
50 arrays and "struct" hacks. If VRP can determine that the array
51 subscript is a constant, check if it is outside valid range. If
52 the array subscript is a RANGE, warn if it is non-overlapping with
53 valid range. IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside
54 a ADDR_EXPR. Returns true if a warning has been issued. */
57 array_bounds_checker::check_array_ref (location_t location
, tree ref
,
58 bool ignore_off_by_one
)
60 if (TREE_NO_WARNING (ref
))
63 tree low_sub
= TREE_OPERAND (ref
, 1);
64 tree up_sub
= low_sub
;
65 tree up_bound
= array_ref_up_bound (ref
);
67 /* Referenced decl if one can be determined. */
68 tree decl
= NULL_TREE
;
70 /* Set for accesses to interior zero-length arrays. */
71 bool interior_zero_len
= false;
76 || TREE_CODE (up_bound
) != INTEGER_CST
77 || (warn_array_bounds
< 2
78 && array_at_struct_end_p (ref
)))
80 /* Accesses to trailing arrays via pointers may access storage
81 beyond the types array bounds. For such arrays, or for flexible
82 array members, as well as for other arrays of an unknown size,
83 replace the upper bound with a more permissive one that assumes
84 the size of the largest object is PTRDIFF_MAX. */
85 tree eltsize
= array_ref_element_size (ref
);
87 if (TREE_CODE (eltsize
) != INTEGER_CST
88 || integer_zerop (eltsize
))
91 up_bound_p1
= NULL_TREE
;
95 tree ptrdiff_max
= TYPE_MAX_VALUE (ptrdiff_type_node
);
96 tree maxbound
= ptrdiff_max
;
97 tree arg
= TREE_OPERAND (ref
, 0);
99 const bool compref
= TREE_CODE (arg
) == COMPONENT_REF
;
102 /* Try to determine the size of the trailing array from
103 its initializer (if it has one). */
104 if (tree refsize
= component_ref_size (arg
, &interior_zero_len
))
105 if (TREE_CODE (refsize
) == INTEGER_CST
)
109 if (maxbound
== ptrdiff_max
)
111 /* Try to determine the size of the base object. Avoid
112 COMPONENT_REF already tried above. Using its DECL_SIZE
113 size wouldn't necessarily be correct if the reference is
114 to its flexible array member initialized in a different
117 if (tree base
= get_addr_base_and_unit_offset (arg
, &off
))
119 if (!compref
&& DECL_P (base
))
120 if (tree basesize
= DECL_SIZE_UNIT (base
))
121 if (TREE_CODE (basesize
) == INTEGER_CST
)
127 if (known_gt (off
, 0))
128 maxbound
= wide_int_to_tree (sizetype
,
129 wi::sub (wi::to_wide (maxbound
),
134 maxbound
= fold_convert (sizetype
, maxbound
);
136 up_bound_p1
= int_const_binop (TRUNC_DIV_EXPR
, maxbound
, eltsize
);
138 if (up_bound_p1
!= NULL_TREE
)
139 up_bound
= int_const_binop (MINUS_EXPR
, up_bound_p1
,
140 build_int_cst (ptrdiff_type_node
, 1));
142 up_bound
= NULL_TREE
;
146 up_bound_p1
= int_const_binop (PLUS_EXPR
, up_bound
,
147 build_int_cst (TREE_TYPE (up_bound
), 1));
149 tree low_bound
= array_ref_low_bound (ref
);
151 tree artype
= TREE_TYPE (TREE_OPERAND (ref
, 0));
156 if (up_bound
&& tree_int_cst_equal (low_bound
, up_bound_p1
))
157 warned
= warning_at (location
, OPT_Warray_bounds
,
158 "array subscript %E is outside array bounds of %qT",
161 const value_range
*vr
= NULL
;
162 if (TREE_CODE (low_sub
) == SSA_NAME
)
164 vr
= get_value_range (low_sub
);
165 if (!vr
->undefined_p () && !vr
->varying_p ())
167 low_sub
= vr
->kind () == VR_RANGE
? vr
->max () : vr
->min ();
168 up_sub
= vr
->kind () == VR_RANGE
? vr
->min () : vr
->max ();
174 else if (vr
&& vr
->kind () == VR_ANTI_RANGE
)
177 && TREE_CODE (up_sub
) == INTEGER_CST
178 && (ignore_off_by_one
179 ? tree_int_cst_lt (up_bound
, up_sub
)
180 : tree_int_cst_le (up_bound
, up_sub
))
181 && TREE_CODE (low_sub
) == INTEGER_CST
182 && tree_int_cst_le (low_sub
, low_bound
))
183 warned
= warning_at (location
, OPT_Warray_bounds
,
184 "array subscript [%E, %E] is outside "
185 "array bounds of %qT",
186 low_sub
, up_sub
, artype
);
189 && TREE_CODE (up_sub
) == INTEGER_CST
190 && (ignore_off_by_one
191 ? !tree_int_cst_le (up_sub
, up_bound_p1
)
192 : !tree_int_cst_le (up_sub
, up_bound
)))
193 warned
= warning_at (location
, OPT_Warray_bounds
,
194 "array subscript %E is above array bounds of %qT",
196 else if (TREE_CODE (low_sub
) == INTEGER_CST
197 && tree_int_cst_lt (low_sub
, low_bound
))
198 warned
= warning_at (location
, OPT_Warray_bounds
,
199 "array subscript %E is below array bounds of %qT",
202 if (!warned
&& interior_zero_len
)
203 warned
= warning_at (location
, OPT_Wzero_length_bounds
,
204 (TREE_CODE (low_sub
) == INTEGER_CST
205 ? G_("array subscript %E is outside the bounds "
206 "of an interior zero-length array %qT")
207 : G_("array subscript %qE is outside the bounds "
208 "of an interior zero-length array %qT")),
213 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
215 fprintf (dump_file
, "Array bound warning for ");
216 dump_generic_expr (MSG_NOTE
, TDF_SLIM
, ref
);
217 fprintf (dump_file
, "\n");
220 ref
= decl
? decl
: TREE_OPERAND (ref
, 0);
222 tree rec
= NULL_TREE
;
223 if (TREE_CODE (ref
) == COMPONENT_REF
)
225 /* For a reference to a member of a struct object also mention
226 the object if it's known. It may be defined in a different
227 function than the out-of-bounds access. */
228 rec
= TREE_OPERAND (ref
, 0);
231 ref
= TREE_OPERAND (ref
, 1);
235 inform (DECL_SOURCE_LOCATION (ref
), "while referencing %qD", ref
);
236 if (rec
&& DECL_P (rec
))
237 inform (DECL_SOURCE_LOCATION (rec
), "defined here %qD", rec
);
239 TREE_NO_WARNING (ref
) = 1;
245 /* Checks one MEM_REF in REF, located at LOCATION, for out-of-bounds
246 references to string constants. If VRP can determine that the array
247 subscript is a constant, check if it is outside valid range.
248 If the array subscript is a RANGE, warn if it is non-overlapping
250 IGNORE_OFF_BY_ONE is true if the MEM_REF is inside an ADDR_EXPR
251 (used to allow one-past-the-end indices for code that takes
252 the address of the just-past-the-end element of an array).
253 Returns true if a warning has been issued. */
256 array_bounds_checker::check_mem_ref (location_t location
, tree ref
,
257 bool ignore_off_by_one
)
259 if (TREE_NO_WARNING (ref
))
262 tree arg
= TREE_OPERAND (ref
, 0);
263 /* The constant and variable offset of the reference. */
264 tree cstoff
= TREE_OPERAND (ref
, 1);
265 tree varoff
= NULL_TREE
;
267 const offset_int maxobjsize
= tree_to_shwi (max_object_size ());
269 /* The array or string constant bounds in bytes. Initially set
270 to [-MAXOBJSIZE - 1, MAXOBJSIZE] until a tighter bound is
272 offset_int arrbounds
[2] = { -maxobjsize
- 1, maxobjsize
};
274 /* The minimum and maximum intermediate offset. For a reference
275 to be valid, not only does the final offset/subscript must be
276 in bounds but all intermediate offsets should be as well.
277 GCC may be able to deal gracefully with such out-of-bounds
278 offsets so the checking is only enbaled at -Warray-bounds=2
279 where it may help detect bugs in uses of the intermediate
280 offsets that could otherwise not be detectable. */
281 offset_int ioff
= wi::to_offset (fold_convert (ptrdiff_type_node
, cstoff
));
282 offset_int extrema
[2] = { 0, wi::abs (ioff
) };
284 /* The range of the byte offset into the reference. */
285 offset_int offrange
[2] = { 0, 0 };
287 const value_range
*vr
= NULL
;
289 /* Determine the offsets and increment OFFRANGE for the bounds of each.
290 The loop computes the range of the final offset for expressions such
291 as (A + i0 + ... + iN)[CSTOFF] where i0 through iN are SSA_NAMEs in
293 const unsigned limit
= param_ssa_name_def_chain_limit
;
294 for (unsigned n
= 0; TREE_CODE (arg
) == SSA_NAME
&& n
< limit
; ++n
)
296 gimple
*def
= SSA_NAME_DEF_STMT (arg
);
297 if (!is_gimple_assign (def
))
300 tree_code code
= gimple_assign_rhs_code (def
);
301 if (code
== POINTER_PLUS_EXPR
)
303 arg
= gimple_assign_rhs1 (def
);
304 varoff
= gimple_assign_rhs2 (def
);
306 else if (code
== ASSERT_EXPR
)
308 arg
= TREE_OPERAND (gimple_assign_rhs1 (def
), 0);
314 /* VAROFF should always be a SSA_NAME here (and not even
315 INTEGER_CST) but there's no point in taking chances. */
316 if (TREE_CODE (varoff
) != SSA_NAME
)
319 vr
= get_value_range (varoff
);
320 if (!vr
|| vr
->undefined_p () || vr
->varying_p ())
323 if (!vr
->constant_p ())
326 if (vr
->kind () == VR_RANGE
)
329 = wi::to_offset (fold_convert (ptrdiff_type_node
, vr
->min ()));
331 = wi::to_offset (fold_convert (ptrdiff_type_node
, vr
->max ()));
339 /* When MIN >= MAX, the offset is effectively in a union
340 of two ranges: [-MAXOBJSIZE -1, MAX] and [MIN, MAXOBJSIZE].
341 Since there is no way to represent such a range across
342 additions, conservatively add [-MAXOBJSIZE -1, MAXOBJSIZE]
344 offrange
[0] += arrbounds
[0];
345 offrange
[1] += arrbounds
[1];
350 /* For an anti-range, analogously to the above, conservatively
351 add [-MAXOBJSIZE -1, MAXOBJSIZE] to OFFRANGE. */
352 offrange
[0] += arrbounds
[0];
353 offrange
[1] += arrbounds
[1];
356 /* Keep track of the minimum and maximum offset. */
357 if (offrange
[1] < 0 && offrange
[1] < extrema
[0])
358 extrema
[0] = offrange
[1];
359 if (offrange
[0] > 0 && offrange
[0] > extrema
[1])
360 extrema
[1] = offrange
[0];
362 if (offrange
[0] < arrbounds
[0])
363 offrange
[0] = arrbounds
[0];
365 if (offrange
[1] > arrbounds
[1])
366 offrange
[1] = arrbounds
[1];
369 if (TREE_CODE (arg
) == ADDR_EXPR
)
371 arg
= TREE_OPERAND (arg
, 0);
372 if (TREE_CODE (arg
) != STRING_CST
373 && TREE_CODE (arg
) != PARM_DECL
374 && TREE_CODE (arg
) != VAR_DECL
)
380 /* The type of the object being referred to. It can be an array,
381 string literal, or a non-array type when the MEM_REF represents
382 a reference/subscript via a pointer to an object that is not
383 an element of an array. Incomplete types are excluded as well
384 because their size is not known. */
385 tree reftype
= TREE_TYPE (arg
);
386 if (POINTER_TYPE_P (reftype
)
387 || !COMPLETE_TYPE_P (reftype
)
388 || TREE_CODE (TYPE_SIZE_UNIT (reftype
)) != INTEGER_CST
)
391 /* Except in declared objects, references to trailing array members
392 of structs and union objects are excluded because MEM_REF doesn't
393 make it possible to identify the member where the reference
395 if (RECORD_OR_UNION_TYPE_P (reftype
)
397 || (DECL_EXTERNAL (arg
) && array_at_struct_end_p (ref
))))
403 if (TREE_CODE (reftype
) == ARRAY_TYPE
)
405 eltsize
= wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (reftype
)));
406 if (tree dom
= TYPE_DOMAIN (reftype
))
408 tree bnds
[] = { TYPE_MIN_VALUE (dom
), TYPE_MAX_VALUE (dom
) };
409 if (TREE_CODE (arg
) == COMPONENT_REF
)
411 offset_int size
= maxobjsize
;
412 if (tree fldsize
= component_ref_size (arg
))
413 size
= wi::to_offset (fldsize
);
414 arrbounds
[1] = wi::lrshift (size
, wi::floor_log2 (eltsize
));
416 else if (array_at_struct_end_p (arg
) || !bnds
[0] || !bnds
[1])
417 arrbounds
[1] = wi::lrshift (maxobjsize
, wi::floor_log2 (eltsize
));
419 arrbounds
[1] = (wi::to_offset (bnds
[1]) - wi::to_offset (bnds
[0])
423 arrbounds
[1] = wi::lrshift (maxobjsize
, wi::floor_log2 (eltsize
));
425 /* Determine a tighter bound of the non-array element type. */
426 tree eltype
= TREE_TYPE (reftype
);
427 while (TREE_CODE (eltype
) == ARRAY_TYPE
)
428 eltype
= TREE_TYPE (eltype
);
429 eltsize
= wi::to_offset (TYPE_SIZE_UNIT (eltype
));
434 tree size
= TYPE_SIZE_UNIT (reftype
);
436 if (tree initsize
= DECL_SIZE_UNIT (arg
))
437 if (tree_int_cst_lt (size
, initsize
))
440 arrbounds
[1] = wi::to_offset (size
);
446 /* Compute the more permissive upper bound when IGNORE_OFF_BY_ONE
447 is set (when taking the address of the one-past-last element
448 of an array) but always use the stricter bound in diagnostics. */
449 offset_int ubound
= arrbounds
[1];
450 if (ignore_off_by_one
)
453 if (arrbounds
[0] == arrbounds
[1]
454 || offrange
[0] >= ubound
455 || offrange
[1] < arrbounds
[0])
457 /* Treat a reference to a non-array object as one to an array
458 of a single element. */
459 if (TREE_CODE (reftype
) != ARRAY_TYPE
)
460 reftype
= build_array_type_nelts (reftype
, 1);
462 /* Extract the element type out of MEM_REF and use its size
463 to compute the index to print in the diagnostic; arrays
464 in MEM_REF don't mean anything. A type with no size like
465 void is as good as having a size of 1. */
466 tree type
= TREE_TYPE (ref
);
467 while (TREE_CODE (type
) == ARRAY_TYPE
)
468 type
= TREE_TYPE (type
);
469 if (tree size
= TYPE_SIZE_UNIT (type
))
471 offrange
[0] = offrange
[0] / wi::to_offset (size
);
472 offrange
[1] = offrange
[1] / wi::to_offset (size
);
476 if (offrange
[0] == offrange
[1])
477 warned
= warning_at (location
, OPT_Warray_bounds
,
478 "array subscript %wi is outside array bounds "
480 offrange
[0].to_shwi (), reftype
);
482 warned
= warning_at (location
, OPT_Warray_bounds
,
483 "array subscript [%wi, %wi] is outside "
484 "array bounds of %qT",
485 offrange
[0].to_shwi (),
486 offrange
[1].to_shwi (), reftype
);
487 if (warned
&& DECL_P (arg
))
488 inform (DECL_SOURCE_LOCATION (arg
), "while referencing %qD", arg
);
491 TREE_NO_WARNING (ref
) = 1;
495 if (warn_array_bounds
< 2)
498 /* At level 2 check also intermediate offsets. */
500 if (extrema
[i
] < -arrbounds
[1] || extrema
[i
= 1] > ubound
)
502 HOST_WIDE_INT tmpidx
= extrema
[i
].to_shwi () / eltsize
.to_shwi ();
504 if (warning_at (location
, OPT_Warray_bounds
,
505 "intermediate array offset %wi is outside array bounds "
506 "of %qT", tmpidx
, reftype
))
508 TREE_NO_WARNING (ref
) = 1;
516 /* Searches if the expr T, located at LOCATION computes
517 address of an ARRAY_REF, and call check_array_ref on it. */
520 array_bounds_checker::check_addr_expr (location_t location
, tree t
)
522 /* Check each ARRAY_REF and MEM_REF in the reference chain. */
526 if (TREE_CODE (t
) == ARRAY_REF
)
527 warned
= check_array_ref (location
, t
, true /*ignore_off_by_one*/);
528 else if (TREE_CODE (t
) == MEM_REF
)
529 warned
= check_mem_ref (location
, t
, true /*ignore_off_by_one*/);
532 TREE_NO_WARNING (t
) = true;
534 t
= TREE_OPERAND (t
, 0);
536 while (handled_component_p (t
) || TREE_CODE (t
) == MEM_REF
);
538 if (TREE_CODE (t
) != MEM_REF
539 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
540 || TREE_NO_WARNING (t
))
543 tree tem
= TREE_OPERAND (TREE_OPERAND (t
, 0), 0);
544 tree low_bound
, up_bound
, el_sz
;
545 if (TREE_CODE (TREE_TYPE (tem
)) != ARRAY_TYPE
546 || TREE_CODE (TREE_TYPE (TREE_TYPE (tem
))) == ARRAY_TYPE
547 || !TYPE_DOMAIN (TREE_TYPE (tem
)))
550 low_bound
= TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (tem
)));
551 up_bound
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tem
)));
552 el_sz
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (tem
)));
554 || TREE_CODE (low_bound
) != INTEGER_CST
556 || TREE_CODE (up_bound
) != INTEGER_CST
558 || TREE_CODE (el_sz
) != INTEGER_CST
)
562 if (!mem_ref_offset (t
).is_constant (&idx
))
566 idx
= wi::sdiv_trunc (idx
, wi::to_offset (el_sz
));
569 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
571 fprintf (dump_file
, "Array bound warning for ");
572 dump_generic_expr (MSG_NOTE
, TDF_SLIM
, t
);
573 fprintf (dump_file
, "\n");
575 warned
= warning_at (location
, OPT_Warray_bounds
,
576 "array subscript %wi is below "
577 "array bounds of %qT",
578 idx
.to_shwi (), TREE_TYPE (tem
));
580 else if (idx
> (wi::to_offset (up_bound
)
581 - wi::to_offset (low_bound
) + 1))
583 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
585 fprintf (dump_file
, "Array bound warning for ");
586 dump_generic_expr (MSG_NOTE
, TDF_SLIM
, t
);
587 fprintf (dump_file
, "\n");
589 warned
= warning_at (location
, OPT_Warray_bounds
,
590 "array subscript %wu is above "
591 "array bounds of %qT",
592 idx
.to_uhwi (), TREE_TYPE (tem
));
598 inform (DECL_SOURCE_LOCATION (t
), "while referencing %qD", t
);
600 TREE_NO_WARNING (t
) = 1;
604 /* Callback for walk_tree to check a tree for out of bounds array
605 accesses. The array_bounds_checker class is passed in DATA. */
608 array_bounds_checker::check_array_bounds (tree
*tp
, int *walk_subtree
,
612 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
615 if (EXPR_HAS_LOCATION (t
))
616 location
= EXPR_LOCATION (t
);
618 location
= gimple_location (wi
->stmt
);
620 *walk_subtree
= TRUE
;
623 array_bounds_checker
*checker
= (array_bounds_checker
*) wi
->info
;
624 if (TREE_CODE (t
) == ARRAY_REF
)
625 warned
= checker
->check_array_ref (location
, t
,
626 false/*ignore_off_by_one*/);
627 else if (TREE_CODE (t
) == MEM_REF
)
628 warned
= checker
->check_mem_ref (location
, t
,
629 false /*ignore_off_by_one*/);
630 else if (TREE_CODE (t
) == ADDR_EXPR
)
632 checker
->check_addr_expr (location
, t
);
633 *walk_subtree
= FALSE
;
635 /* Propagate the no-warning bit to the outer expression. */
637 TREE_NO_WARNING (t
) = true;
642 /* A dom_walker subclass for use by check_all_array_refs, to walk over
643 all statements of all reachable BBs and call check_array_bounds on
646 class check_array_bounds_dom_walker
: public dom_walker
649 check_array_bounds_dom_walker (array_bounds_checker
*checker
)
650 : dom_walker (CDI_DOMINATORS
,
651 /* Discover non-executable edges, preserving EDGE_EXECUTABLE
652 flags, so that we can merge in information on
653 non-executable edges from vrp_folder . */
654 REACHABLE_BLOCKS_PRESERVING_FLAGS
),
655 checker (checker
) { }
656 ~check_array_bounds_dom_walker () {}
658 edge
before_dom_children (basic_block
) FINAL OVERRIDE
;
661 array_bounds_checker
*checker
;
664 /* Implementation of dom_walker::before_dom_children.
666 Walk over all statements of BB and call check_array_bounds on them,
667 and determine if there's a unique successor edge. */
670 check_array_bounds_dom_walker::before_dom_children (basic_block bb
)
672 gimple_stmt_iterator si
;
673 for (si
= gsi_start_bb (bb
); !gsi_end_p (si
); gsi_next (&si
))
675 gimple
*stmt
= gsi_stmt (si
);
676 struct walk_stmt_info wi
;
677 if (!gimple_has_location (stmt
)
678 || is_gimple_debug (stmt
))
681 memset (&wi
, 0, sizeof (wi
));
685 walk_gimple_op (stmt
, array_bounds_checker::check_array_bounds
, &wi
);
688 /* Determine if there's a unique successor edge, and if so, return
689 that back to dom_walker, ensuring that we don't visit blocks that
690 became unreachable during the VRP propagation
691 (PR tree-optimization/83312). */
692 return find_taken_edge (bb
, NULL_TREE
);
696 array_bounds_checker::check ()
698 check_array_bounds_dom_walker
w (this);
699 w
.walk (ENTRY_BLOCK_PTR_FOR_FN (fun
));