aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2023-07-20 20:24:01 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2023-07-20 20:24:01 -0400
commit5a0aff76a9980488a760ece72323e7ed1f2c0e5e (patch)
tree382a01e1241ddbbaff0be556823ddcefcb5304e2
parente2bf82d510378a4cc195622f6bbf281a5d9a4124 (diff)
downloadgcc-5a0aff76a9980488a760ece72323e7ed1f2c0e5e.zip
gcc-5a0aff76a9980488a760ece72323e7ed1f2c0e5e.tar.gz
gcc-5a0aff76a9980488a760ece72323e7ed1f2c0e5e.tar.bz2
analyzer: fix ICE on certain pointer subtractions [PR110387]
gcc/analyzer/ChangeLog: PR analyzer/110387 * region.h (struct cast_region::key_t): Support "m_type" being null by using "m_original_region" for empty/deleted slots. gcc/testsuite/ChangeLog: PR analyzer/110387 * gcc.dg/analyzer/out-of-bounds-pr110387.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
-rw-r--r--gcc/analyzer/region.h16
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-pr110387.c19
2 files changed, 30 insertions, 5 deletions
diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h
index 0c79490..2cbb923 100644
--- a/gcc/analyzer/region.h
+++ b/gcc/analyzer/region.h
@@ -1107,7 +1107,7 @@ public:
key_t (const region *original_region, tree type)
: m_original_region (original_region), m_type (type)
{
- gcc_assert (type);
+ gcc_assert (original_region);
}
hashval_t hash () const
@@ -1124,10 +1124,16 @@ public:
&& m_type == other.m_type);
}
- void mark_deleted () { m_type = reinterpret_cast<tree> (1); }
- void mark_empty () { m_type = NULL_TREE; }
- bool is_deleted () const { return m_type == reinterpret_cast<tree> (1); }
- bool is_empty () const { return m_type == NULL_TREE; }
+ void mark_deleted ()
+ {
+ m_original_region = reinterpret_cast<const region *> (1);
+ }
+ void mark_empty () { m_original_region = nullptr; }
+ bool is_deleted () const
+ {
+ return m_original_region == reinterpret_cast<const region *> (1);
+ }
+ bool is_empty () const { return m_original_region == nullptr; }
const region *m_original_region;
tree m_type;
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-pr110387.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-pr110387.c
new file mode 100644
index 0000000..a046659
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-pr110387.c
@@ -0,0 +1,19 @@
+char a, b, c, d;
+long x;
+
+void
+_S_copy (long __n)
+{
+ __builtin_memcpy (&a, &d, __n); /* { dg-prune-output "-Wanalyzer-out-of-bounds" } */
+ /* This only warns on some targets; the purpose of the test is to verify that
+ we don't ICE. */
+}
+
+void
+_M_construct ()
+{
+ x = &c - &b;
+ unsigned long __dnew = x;
+ if (__dnew > 1)
+ _S_copy (&c - &b);
+}