From: David Malcolm Date: Thu, 27 Aug 2020 11:42:27 +0000 (-0400) Subject: analyzer: fix false NULL deref warning after previous deref [PR96792] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=49bfbf18c0bb9d83934f0ce765dc031ebfbda38e;p=gcc.git 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 --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; +}