[gcc r11-2968] analyzer: fix false NULL deref warning after previous deref [PR96792]
David Malcolm
dmalcolm@gcc.gnu.org
Tue Sep 1 14:59:08 GMT 2020
https://gcc.gnu.org/g:49bfbf18c0bb9d83934f0ce765dc031ebfbda38e
commit r11-2968-g49bfbf18c0bb9d83934f0ce765dc031ebfbda38e
Author: David Malcolm <dmalcolm@redhat.com>
Date: Thu Aug 27 07:42:27 2020 -0400
analyzer: fix false NULL deref warning after previous deref [PR96792]
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.
Diff:
---
gcc/analyzer/region-model.cc | 9 ++++++++
gcc/testsuite/gcc.dg/analyzer/pr96792.c | 39 +++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
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;
+}
More information about the Gcc-cvs
mailing list