Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to master as r11-2968-g49bfbf18c0bb9d83934f0ce765dc031ebfbda38e.

gcc/analyzer/ChangeLog:
        PR analyzer/96792
        * region-model.cc (region_model::deref_rvalue): Add the constraint
        that PTR_SVAL is non-NULL.

gcc/testsuite/ChangeLog:
        PR analyzer/96792
        * gcc.dg/analyzer/pr96792.c: New test.
---
 gcc/analyzer/region-model.cc            |  9 ++++++
 gcc/testsuite/gcc.dg/analyzer/pr96792.c | 39 +++++++++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96792.c

diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index d47e8960296..a7bc48115ee 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1398,6 +1398,15 @@ region_model::deref_rvalue (const svalue *ptr_sval, tree 
ptr_tree,
 {
   gcc_assert (ptr_sval);
 
+  /* If we're dereferencing PTR_SVAL, assume that it is non-NULL; add this
+     as a constraint.  This suppresses false positives from
+     -Wanalyzer-null-dereference for the case where we later have an
+     if (PTR_SVAL) that would occur if we considered the false branch
+     and transitioned the malloc state machine from start->null.  */
+  tree null_ptr_cst = build_int_cst (ptr_sval->get_type (), 0);
+  const svalue *null_ptr = m_mgr->get_or_create_constant_svalue (null_ptr_cst);
+  m_constraints->add_constraint (ptr_sval, NE_EXPR, null_ptr);
+
   switch (ptr_sval->get_kind ())
     {
     default:
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96792.c 
b/gcc/testsuite/gcc.dg/analyzer/pr96792.c
new file mode 100644
index 00000000000..7757645a133
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96792.c
@@ -0,0 +1,39 @@
+#define NULL (void *)0
+
+struct block
+{
+  void *function;
+  const struct block *superblock;
+};
+
+struct global_block
+{
+  struct block block;
+  void *compunit_symtab;
+};
+
+extern const struct block *block_global_block (const struct block *block);
+
+void *
+block_objfile (const struct block *block)
+{
+  const struct global_block *global_block;
+
+  if (block->function != NULL)
+    return block->function;
+
+  global_block = (struct global_block *) block_global_block (block);
+  return global_block->compunit_symtab;
+}
+
+const struct block *
+block_global_block (const struct block *block)
+{
+  if (block == NULL)
+    return NULL;
+
+  while (block->superblock != NULL)
+    block = block->superblock;
+
+  return block;
+}
-- 
2.26.2

Reply via email to