From 30b10dacd0a8c926c22eab7d4aeb52ff86534acf Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 18 Mar 2021 13:36:09 -0600 Subject: 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. --- gcc/gimple-array-bounds.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'gcc/gimple-array-bounds.cc') 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. */ -- cgit v1.1