diff options
author | David Malcolm <dmalcolm@redhat.com> | 2020-08-17 21:12:35 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2020-08-18 21:20:18 -0400 |
commit | 400abebf48a90d0797718ab7c3864de331e85b70 (patch) | |
tree | 3eb261b4c6667c41868f290af8477b8d30097419 | |
parent | 5c265693bfa8e5f205e81c0452d54800334c32a9 (diff) | |
download | gcc-400abebf48a90d0797718ab7c3864de331e85b70.zip gcc-400abebf48a90d0797718ab7c3864de331e85b70.tar.gz gcc-400abebf48a90d0797718ab7c3864de331e85b70.tar.bz2 |
analyzer: fix ICE with negative bit offsets [PR96648]
PR analyzer/96648 reports an ICE within get_field_at_bit_offset due
to a negative bit offset, arising due to pointer arithmetic.
This patch replaces an assertion with handling for this case, fixing the
ICE.
gcc/analyzer/ChangeLog:
PR analyzer/96648
* region.cc (get_field_at_bit_offset): Gracefully handle negative
values for bit_offset.
gcc/testsuite/ChangeLog:
PR analyzer/96648
* gcc.dg/analyzer/pr96648.c: New test.
-rw-r--r-- | gcc/analyzer/region.cc | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/pr96648.c | 36 |
2 files changed, 38 insertions, 1 deletions
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index eab1f27..770e2cb 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -226,7 +226,8 @@ static tree get_field_at_bit_offset (tree record_type, bit_offset_t bit_offset) { gcc_assert (TREE_CODE (record_type) == RECORD_TYPE); - gcc_assert (bit_offset >= 0); + if (bit_offset < 0) + return NULL; /* Find the first field that has an offset > BIT_OFFSET, then return the one preceding it. diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96648.c b/gcc/testsuite/gcc.dg/analyzer/pr96648.c new file mode 100644 index 0000000..a6b0c72 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr96648.c @@ -0,0 +1,36 @@ +/* { dg-additional-options "-O1" } */ + +struct vd { + struct vd *rs; +}; + +struct fh { + struct vd cl; +}; + +struct i3 { + struct fh *h4; +}; + +struct fh * +gm (void); + +void +j7 (struct vd *); + +inline void +mb (struct vd *e7) +{ + j7 (e7->rs); +} + +void +po (struct i3 *d2) +{ + struct i3 *s2; + + d2->h4 = gm (); + mb (&d2->h4->cl); + s2 = ({ d2 - 1; }); + po (s2); +} |