diff options
author | Martin Sebor <msebor@redhat.com> | 2021-03-18 13:36:09 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2021-03-18 13:38:00 -0600 |
commit | 30b10dacd0a8c926c22eab7d4aeb52ff86534acf (patch) | |
tree | b39b32d49992bc87c3a9f7b7b349bbce699e5aef /gcc/gimple-array-bounds.cc | |
parent | c5e55673b486533c4d6d19ac903460f70b48f11a (diff) | |
download | gcc-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.cc | 19 |
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. */ |