analyzer: use __attribute__((nonnull)) at top level of analysis [PR106325]
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 6 Dec 2022 18:26:57 +0000 (13:26 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Tue, 6 Dec 2022 18:26:57 +0000 (13:26 -0500)
commitdcfc7ac94dbcf6c86c0c58ce6dc1d8bd853e4093
tree7b7ec97a683ffb661dae376e7436e21744c5fa30
parentfa19bfbb0a19950fcbce8c3ccb0a116faab477d0
analyzer: use __attribute__((nonnull)) at top level of analysis [PR106325]

PR analyzer/106325 reports false postives from
-Wanalyzer-null-dereference on code like this:

__attribute__((nonnull))
void foo_a (Foo *p)
{
  foo_b (p);

  switch (p->type)
    {
      /* ... */
    }
}

where foo_b (p) has a:

  g_return_if_fail (p);

that expands to:

  if (!p)
    {
      return;
    }

The analyzer "sees" the comparison against NULL in foo_b, and splits the
analysis into the NULL and not-NULL cases; later, back in foo_a,  at
  switch (p->type)
it complains that p is NULL.

Previously we were only using __attribute__((nonnull)) as something to
complain about when it was violated; we weren't using it as a source of
knowledge.

This patch fixes things by making the analyzer respect
__attribute__((nonnull)) at the top-level of the analysis: any such
params are now assumed to be non-NULL, so that the analyzer assumes the
g_return_if_fail inside foo_b doesn't fail when called from foo_a

Doing so fixes the false positives.

gcc/analyzer/ChangeLog:
PR analyzer/106325
* region-model-manager.cc
(region_model_manager::get_or_create_null_ptr): New.
* region-model-manager.h
(region_model_manager::get_or_create_null_ptr): New decl.
* region-model.cc (region_model::on_top_level_param): Add
"nonnull" param and make use of it.
(region_model::push_frame): When handling a top-level entrypoint
to the analysis, determine which params __attribute__((nonnull))
applies to, and pass to on_top_level_param.
* region-model.h (region_model::on_top_level_param): Add "nonnull"
param.

gcc/testsuite/ChangeLog:
PR analyzer/106325
* gcc.dg/analyzer/attr-nonnull-pr106325.c: New test.
* gcc.dg/analyzer/attribute-nonnull.c (test_6): New.
(test_7): New.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
gcc/analyzer/region-model-manager.cc
gcc/analyzer/region-model-manager.h
gcc/analyzer/region-model.cc
gcc/analyzer/region-model.h
gcc/testsuite/gcc.dg/analyzer/attr-nonnull-pr106325.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c