public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug analyzer/108325] New: -Wanalyzer-null-dereference false positive with *f = 42
@ 2023-01-07  5:27 mengli.ming at outlook dot com
  0 siblings, 0 replies; only message in thread
From: mengli.ming at outlook dot com @ 2023-01-07  5:27 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 108325
           Summary: -Wanalyzer-null-dereference false positive with *f =
                    42
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: mengli.ming at outlook dot com
  Target Milestone: ---

I got a false positive error when compiling the following program with
gcc(trunk) `-O0 -fanalyzer` in https://godbolt.org/z/db7v3PGYe. 

In this case, the eval statement in line 16 gives two results, FALSE and
UNKNOWN. The UNKNOWN here is a little odd, and then analyzer analyzes the codes
inside the if statement, however, these are unreachable codes.

Input:

```
#include "stdio.h"
#include "stdbool.h"
void __analyzer_eval(int);

struct a
{
    int b;
} c()
{
    struct a d = {1};
    int e = 0;
    int *f = (int *)e;

    for (d.b = 0; e == 0; e++)
    {
        __analyzer_eval(true == ((!d.b) && e));
        if ((!d.b) && e)
        {
            __analyzer_eval(true == ((!d.b) && e));
            *f = 42;
        }
    }
}

void main() { c(); }

```

Output:

```
<source>: In function 'c':
<source>:16:9: warning: FALSE
   16 |         __analyzer_eval(true == ((!d.b) && e));
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:16:9: warning: UNKNOWN
<source>:19:13: warning: TRUE
   19 |             __analyzer_eval(true == ((!d.b) && e));
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:16:9: warning: FALSE
   16 |         __analyzer_eval(true == ((!d.b) && e));
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:16:9: warning: FALSE
<source>:16:9: warning: UNKNOWN
<source>:19:13: warning: TRUE
   19 |             __analyzer_eval(true == ((!d.b) && e));
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:16:9: warning: FALSE
   16 |         __analyzer_eval(true == ((!d.b) && e));
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:20:16: warning: dereference of NULL 'f' [CWE-476]
[-Wanalyzer-null-dereference]
   20 |             *f = 42;
      |             ~~~^~~~
  'c': events 1-20
    |
    |   12 |     int *f = (int *)e;
    |      |          ^
    |      |          |
    |      |          (1) 'f' is NULL
    |   13 | 
    |   14 |     for (d.b = 0; e == 0; e++)
    |      |                   ~~~~~~  ~~~
    |      |                     |      |
    |      |                     |      (11) ...to here
    |      |                     (2) following 'true' branch (when 'e == 0')...
    |      |                     (12) following 'true' branch (when 'e ==
0')...
    |   15 |     {
    |   16 |         __analyzer_eval(true == ((!d.b) && e));
    |      |                                 ~~~~~~~~~~~~~
    |      |                                     |   |
    |      |                                     |   (4) following 'true'
branch...
    |      |                                     |   (5) ...to here
    |      |                                     |   (6) following 'false'
branch (when 'e == 0')...
    |      |                                     |   (7) ...to here
    |      |                                     |   (14) following 'true'
branch...
    |      |                                     |   (15) ...to here
    |      |                                     (3) ...to here
    |      |                                     (13) ...to here
    |   17 |         if ((!d.b) && e)
    |      |            ~~~~~~~~~~~~
    |      |            |       |
    |      |            |       (9) ...to here
    |      |            |       (10) following 'false' branch (when 'e ==
0')...
    |      |            |       (17) ...to here
    |      |            (8) following 'true' branch...
    |      |            (16) following 'true' branch...
    |   18 |         {
    |   19 |             __analyzer_eval(true == ((!d.b) && e));
    |      |                                     ~~~~~~~~~~~~~
    |      |                                             |
    |      |                                             (18) following 'true'
branch...
    |      |                                             (19) ...to here
    |   20 |             *f = 42;
    |      |             ~~~~~~~
    |      |                |
    |      |                (20) dereference of NULL 'f'
    |

```

I set it directly to 0 in the initialization of `d.b`, and then keep the
semantics of the for loop executing only one time, and after making the
following transformation (https://godbolt.org/z/nvePK1sdb), the NPD warning
disappeared, and the eval statement in line 19 is not output.

Thank you for taking the time to review these cases.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-01-07  5:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-07  5:27 [Bug analyzer/108325] New: -Wanalyzer-null-dereference false positive with *f = 42 mengli.ming at outlook dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).