aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-array-bounds.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimple-array-bounds.cc')
-rw-r--r--gcc/gimple-array-bounds.cc19
1 files changed, 14 insertions, 5 deletions
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index 54f3205..199d9f5 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -895,7 +895,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t)
problems discussed in pr98266 and pr97595. */
static bool
-inbounds_vbase_memaccess_p (tree t)
+inbounds_memaccess_p (tree t)
{
if (TREE_CODE (t) != COMPONENT_REF)
return false;
@@ -928,10 +928,19 @@ inbounds_vbase_memaccess_p (tree t)
object by adding its offset computed above to the MEM_REF offset. */
tree refoff = TREE_OPERAND (mref, 1);
tree fldoff = int_const_binop (PLUS_EXPR, fldpos, refoff);
+ /* Return false if the member offset is greater or equal to the size
+ of the complete object. */
+ if (!tree_int_cst_lt (fldoff, refsize))
+ return false;
+
+ tree fldsiz = DECL_SIZE_UNIT (fld);
+ if (!fldsiz || TREE_CODE (fldsiz) != INTEGER_CST)
+ return false;
- /* Return true if the member offset is less than the size of the complete
- object. */
- return tree_int_cst_lt (fldoff, refsize);
+ /* Return true if the offset just past the end of the member is less
+ than or equal to the size of the complete object. */
+ tree fldend = int_const_binop (PLUS_EXPR, fldoff, fldsiz);
+ return tree_int_cst_le (fldend, refsize);
}
/* Callback for walk_tree to check a tree for out of bounds array
@@ -965,7 +974,7 @@ array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree,
checker->check_addr_expr (location, t);
*walk_subtree = false;
}
- else if (inbounds_vbase_memaccess_p (t))
+ else if (inbounds_memaccess_p (t))
/* Hack: Skip MEM_REF checks in accesses to a member of a base class
at an offset that's within the bounds of the enclosing object.
See pr98266 and pr97595. */