diff options
author | David Malcolm <dmalcolm@redhat.com> | 2024-02-15 16:01:36 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2024-02-15 16:01:36 -0500 |
commit | 617bd59c659dcf6e5391409a2e9f64f75e905a96 (patch) | |
tree | 48f6d8d643e67c17e6d753f27151ecb4be8a5bc5 | |
parent | 0d5d1c75f5c68b6064640c3154ae5f4c0b464905 (diff) | |
download | gcc-617bd59c659dcf6e5391409a2e9f64f75e905a96.zip gcc-617bd59c659dcf6e5391409a2e9f64f75e905a96.tar.gz gcc-617bd59c659dcf6e5391409a2e9f64f75e905a96.tar.bz2 |
analyzer: remove offset_region size overloads [PR111266]
PR analyzer/111266 reports a missing -Wanalyzer-out-of-bounds when
accessing relative to a concrete byte offset.
Root cause is that offset_region::get_{byte,bit}_size_sval were
attempting to compute the size that's valid to access, rather than the
size of the access attempt.
Fixed by removing these vfunc overrides from offset_region as the
base class implementation does the right thing.
gcc/analyzer/ChangeLog:
PR analyzer/111266
* region.cc (offset_region::get_byte_size_sval): Delete.
(offset_region::get_bit_size_sval): Delete.
* region.h (region::get_byte_size): Add comment clarifying that
this relates to the size of the access, rather than the size
that's valid to access.
(region::get_bit_size): Likewise.
(region::get_byte_size_sval): Likewise.
(region::get_bit_size_sval): Likewise.
(offset_region::get_byte_size_sval): Delete.
(offset_region::get_bit_size_sval): Delete.
gcc/testsuite/ChangeLog:
PR analyzer/111266
* c-c++-common/analyzer/out-of-bounds-pr111266.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
-rw-r--r-- | gcc/analyzer/region.cc | 48 | ||||
-rw-r--r-- | gcc/analyzer/region.h | 20 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr111266.c | 11 |
3 files changed, 23 insertions, 56 deletions
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index 249852a..50821a5 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -1990,54 +1990,6 @@ offset_region::get_relative_symbolic_offset (region_model_manager *mgr return get_byte_offset (); } -/* Implementation of region::get_byte_size_sval vfunc for offset_region. */ - -const svalue * -offset_region::get_byte_size_sval (region_model_manager *mgr) const -{ - tree offset_cst = get_byte_offset ()->maybe_get_constant (); - byte_size_t byte_size; - /* If the offset points in the middle of the region, - return the remaining bytes. */ - if (get_byte_size (&byte_size) && offset_cst) - { - byte_size_t offset = wi::to_offset (offset_cst); - byte_range r (0, byte_size); - if (r.contains_p (offset)) - { - tree remaining_byte_size = wide_int_to_tree (size_type_node, - byte_size - offset); - return mgr->get_or_create_constant_svalue (remaining_byte_size); - } - } - - return region::get_byte_size_sval (mgr); -} - -/* Implementation of region::get_bit_size_sval vfunc for offset_region. */ - -const svalue * -offset_region::get_bit_size_sval (region_model_manager *mgr) const -{ - tree offset_cst = get_bit_offset (mgr)->maybe_get_constant (); - bit_size_t bit_size; - /* If the offset points in the middle of the region, - return the remaining bits. */ - if (get_bit_size (&bit_size) && offset_cst) - { - bit_size_t offset = wi::to_offset (offset_cst); - bit_range r (0, bit_size); - if (r.contains_p (offset)) - { - tree remaining_bit_size = wide_int_to_tree (size_type_node, - bit_size - offset); - return mgr->get_or_create_constant_svalue (remaining_bit_size); - } - } - - return region::get_bit_size_sval (mgr); -} - /* class sized_region : public region. */ /* Implementation of region::accept vfunc for sized_region. */ diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h index 3d3ff8e..70557ba 100644 --- a/gcc/analyzer/region.h +++ b/gcc/analyzer/region.h @@ -187,20 +187,28 @@ public: /* Attempt to get the size of this region as a concrete number of bytes. If successful, return true and write the size to *OUT. - Otherwise return false. */ + Otherwise return false. + This is the accessed size, not necessarily the size that's valid to + access. */ virtual bool get_byte_size (byte_size_t *out) const; /* Attempt to get the size of this region as a concrete number of bits. If successful, return true and write the size to *OUT. - Otherwise return false. */ + Otherwise return false. + This is the accessed size, not necessarily the size that's valid to + access. */ virtual bool get_bit_size (bit_size_t *out) const; /* Get a symbolic value describing the size of this region in bytes - (which could be "unknown"). */ + (which could be "unknown"). + This is the accessed size, not necessarily the size that's valid to + access. */ virtual const svalue *get_byte_size_sval (region_model_manager *mgr) const; /* Get a symbolic value describing the size of this region in bits - (which could be "unknown"). */ + (which could be "unknown"). + This is the accessed size, not necessarily the size that's valid to + access. */ virtual const svalue *get_bit_size_sval (region_model_manager *mgr) const; /* Attempt to get the offset in bits of this region relative to its parent. @@ -978,10 +986,6 @@ public: bool get_relative_concrete_offset (bit_offset_t *out) const final override; const svalue *get_relative_symbolic_offset (region_model_manager *mgr) const final override; - const svalue * get_byte_size_sval (region_model_manager *mgr) - const final override; - const svalue * get_bit_size_sval (region_model_manager *mgr) - const final override; private: const svalue *m_byte_offset; diff --git a/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr111266.c b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr111266.c new file mode 100644 index 0000000..cee3663 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr111266.c @@ -0,0 +1,11 @@ +#include <stdint.h> +void *malloc (__SIZE_TYPE__); +void free (void *); + +void test_binop2 () +{ + char *p = (char *) malloc (4); + int32_t *i = (int32_t *) (p + 3); + *i = 20042; /* { dg-warning "heap-based buffer overflow" } */ + free (p); +} |