https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94851

David Malcolm <dmalcolm at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|-fanalyzer erroniously      |-fanalyzer erroneously
                   |reporting NULL dereference  |reporting NULL dereference
                   |- simple test case attached |- simple test case attached
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2020-05-08
     Ever confirmed|0                           |1

--- Comment #2 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
Thanks for filing this bug.

It does indeed look like a false positive.

With -fanalyzer-verbosity=3 I get this output:

----------------------------------------------------------------------
$ ./xgcc -B. -c -fanalyzer t.c -O2 -fanalyzer-verbosity=3
t.c: In function ‘pamark’:
t.c:48:19: warning: dereference of NULL ‘last’ [CWE-690]
[-Wanalyzer-null-dereference]
   48 |    last->m_next   = p;
      |    ~~~~~~~~~~~~~~~^~~
  ‘pamark’: events 1-5
    |
    |   28 |  while(p != (AMARK*)NULL && p->m_name != (char)c) {
    |      |       ^
    |      |       |
    |      |       (1) following ‘false’ branch (when ‘p’ is NULL)...
    |......
    |   33 |  if(p != (AMARK*) NULL) {
    |      |    ~   
    |      |    |
    |      |    (2) ...to here
    |      |    (3) following ‘false’ branch (when ‘p’ is NULL)...
    |......
    |   40 |   if((p = (AMARK*) malloc(sizeof(AMARK))) == (AMARK*) NULL)
    |      |     ~              ~~~~~~~~~~~~~~~~~~~~~
    |      |     |              |
    |      |     |              (4) ...to here
    |      |     (5) following ‘false’ branch (when ‘p’ is non-NULL)...
    |
  ‘pamark’: event 6
    |
    |   43 |   p->m_next = (AMARK*) NULL;
    |      |             ^
    |      |             |
    |      |             (6) ...to here
    |
  ‘pamark’: events 7-10
    |
    |
----------------------------------------------------------------------

It's considering the case where at:

        AMARK*  p    = curbp->b_amark;
        AMARK*  last = curbp->b_amark;

both pointers are NULL.

I'm not sure why it's filtered those events at the default verbosity level.

It's also not printing events 7-10 for some reason, but with
-fdiagnostics-path-format=separate-events they show up as:

t.c:43:13: note: (7) ‘last’ is NULL
t.c:45:5: note: (8) following ‘false’ branch...
   45 |   if(curbp->b_amark == (AMARK*) NULL)
      |     ^
t.c:48:19: note: (9) ...to here
   48 |    last->m_next   = p;
      |    ~~~~~~~~~~~~~~~^~~
t.c:48:19: note: (10) dereference of NULL ‘last’

However, it seems to have lost the fact that "curbp->b_amark == NULL" at event
(8); hence a false positive.

I've tried to simplify the reproducer but have had no success so far.

Reply via email to