aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-array-bounds.cc
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-03-18 13:36:09 -0600
committerMartin Sebor <msebor@redhat.com>2021-03-18 13:38:00 -0600
commit30b10dacd0a8c926c22eab7d4aeb52ff86534acf (patch)
treeb39b32d49992bc87c3a9f7b7b349bbce699e5aef /gcc/gimple-array-bounds.cc
parentc5e55673b486533c4d6d19ac903460f70b48f11a (diff)
downloadgcc-30b10dacd0a8c926c22eab7d4aeb52ff86534acf.zip
gcc-30b10dacd0a8c926c22eab7d4aeb52ff86534acf.tar.gz
gcc-30b10dacd0a8c926c22eab7d4aeb52ff86534acf.tar.bz2
PR middle-end/99502 - missing -Warray-bounds on partial out of bounds
gcc/ChangeLog: PR middle-end/99502 * gimple-array-bounds.cc (inbounds_vbase_memaccess_p): Rename... (inbounds_memaccess_p): ...to this. Check the ending offset of the accessed member. gcc/testsuite/ChangeLog: PR middle-end/99502 * g++.dg/warn/Warray-bounds-22.C: New test. * g++.dg/warn/Warray-bounds-23.C: New test. * g++.dg/warn/Warray-bounds-24.C: New test.
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. */