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

            Bug ID: 108475
           Summary: -Wanalyzer-deref-before-check false positives seen in
                    haproxy's tcpcheck.c
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: dmalcolm at gcc dot gnu.org
  Target Milestone: ---

Created attachment 54314
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54314&action=edit
Reproducer

I'm attaching a reduced reproducer for a false +ve from
-Wanalyzer-deref-before-check

https://godbolt.org/z/s9fvbT3fP

Trunk emits this, all of which appear to be a false positives:

<source>: In function 'proxy_parse_httpchk_req':
<source>:138:6: warning: check of 'meth' for NULL after already dereferencing
it [-Wanalyzer-deref-before-check]
  138 |   if (meth) {
      |      ^
  'proxy_parse_httpchk_req': events 1-14
    |
    |  110 |   if (hdrs || body) {
    |      |      ^
    |      |      |
    |      |      (1) following 'false' branch...
    |......
    |  115 |   chk = calloc(1, sizeof(*chk));
    |      |         ~~~~~~~~~~~~~~~~~~~~~~~
    |      |         |
    |      |         (2) ...to here
    |  116 |   if (!chk) {
    |      |      ~
    |      |      |
    |      |      (3) following 'false' branch (when 'chk' is non-NULL)...
    |......
    |  120 |   chk->action = TCPCHK_ACT_SEND;
    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |               |
    |      |               (4) ...to here
    |......
    |  127 |   if (*args[cur_arg]) {
    |      |      ~~~~~~~~~~~~~~~
    |      |      ||
    |      |      |(5) pointer 'meth' is dereferenced here
    |      |      (6) following 'true' branch...
    |  128 |     if (!*args[cur_arg + 1])
    |      |        ~      ~
    |      |        |      |
    |      |        |      (7) ...to here
    |      |        (8) following 'false' branch...
    |......
    |  131 |       meth = args[cur_arg];
    |      |                  ~
    |      |                  |
    |      |                  (9) ...to here
    |  132 |   }
    |  133 |   if (*args[cur_arg + 1])
    |      |      ~
    |      |      |
    |      |      (10) following 'true' branch...
    |  134 |     uri = args[cur_arg + 1];
    |      |               ~
    |      |               |
    |      |               (11) ...to here
    |  135 |   if (*args[cur_arg + 2])
    |      |      ~
    |      |      |
    |      |      (12) following 'false' branch...
    |......
    |  138 |   if (meth) {
    |      |      ~
    |      |      |
    |      |      (13) ...to here
    |      |      (14) pointer 'meth' is checked for NULL here but it was
already dereferenced at (5)
    |
<source>:147:6: warning: check of 'uri' for NULL after already dereferencing it
[-Wanalyzer-deref-before-check]
  147 |   if (uri) {
      |      ^
  'proxy_parse_httpchk_req': events 1-18
    |
    |  110 |   if (hdrs || body) {
    |      |      ^
    |      |      |
    |      |      (1) following 'false' branch...
    |......
    |  115 |   chk = calloc(1, sizeof(*chk));
    |      |         ~~~~~~~~~~~~~~~~~~~~~~~
    |      |         |
    |      |         (2) ...to here
    |  116 |   if (!chk) {
    |      |      ~
    |      |      |
    |      |      (3) following 'false' branch (when 'chk' is non-NULL)...
    |......
    |  120 |   chk->action = TCPCHK_ACT_SEND;
    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |               |
    |      |               (4) ...to here
    |......
    |  127 |   if (*args[cur_arg]) {
    |      |      ~
    |      |      |
    |      |      (5) following 'true' branch...
    |  128 |     if (!*args[cur_arg + 1])
    |      |        ~ ~~~~~~~~~~~~~~~~~~
    |      |        | |    |
    |      |        | |    (6) ...to here
    |      |        | (7) pointer 'uri' is dereferenced here
    |      |        (8) following 'false' branch...
    |......
    |  131 |       meth = args[cur_arg];
    |      |                  ~
    |      |                  |
    |      |                  (9) ...to here
    |  132 |   }
    |  133 |   if (*args[cur_arg + 1])
    |      |      ~
    |      |      |
    |      |      (10) following 'true' branch...
    |  134 |     uri = args[cur_arg + 1];
    |      |               ~
    |      |               |
    |      |               (11) ...to here
    |  135 |   if (*args[cur_arg + 2])
    |      |      ~
    |      |      |
    |      |      (12) following 'false' branch...
    |......
    |  138 |   if (meth) {
    |      |      ~
    |      |      |
    |      |      (13) ...to here
    |      |      (14) following 'true' branch (when 'meth' is non-NULL)...
    |  139 |     chk->send.http.meth.meth = find_http_meth(meth, strlen(meth));
    |      |                                                     ~~~~~~~~~~~~
    |      |                                                     |
    |      |                                                     (15) ...to
here
    |......
    |  142 |     if (!chk->send.http.meth.str.area) {
    |      |        ~
    |      |        |
    |      |        (16) following 'false' branch...
    |......
    |  147 |   if (uri) {
    |      |      ~
    |      |      |
    |      |      (17) ...to here
    |      |      (18) pointer 'uri' is checked for NULL here but it was
already dereferenced at (7)
    |
<source>:154:6: warning: check of 'vsn' for NULL after already dereferencing it
[-Wanalyzer-deref-before-check]
  154 |   if (vsn) {
      |      ^
  'proxy_parse_httpchk_req': events 1-12
    |
    |  108 |   hdrs = (*args[cur_arg + 2] ? strstr(args[cur_arg + 2], "\r\n") :
NULL);
    |      |           ^~~~~~~~~~~~~~~~~~
    |      |           |
    |      |           (1) pointer 'vsn' is dereferenced here
    |  109 |   body = (*args[cur_arg + 2] ? strstr(args[cur_arg + 2],
"\r\n\r\n") : NULL);
    |  110 |   if (hdrs || body) {
    |      |      ~     
    |      |      |
    |      |      (2) following 'false' branch...
    |......
    |  115 |   chk = calloc(1, sizeof(*chk));
    |      |         ~~~~~~~~~~~~~~~~~~~~~~~
    |      |         |
    |      |         (3) ...to here
    |  116 |   if (!chk) {
    |      |      ~     
    |      |      |
    |      |      (4) following 'false' branch (when 'chk' is non-NULL)...
    |......
    |  120 |   chk->action = TCPCHK_ACT_SEND;
    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |               |
    |      |               (5) ...to here
    |......
    |  135 |   if (*args[cur_arg + 2])
    |      |      ~     
    |      |      |
    |      |      (6) following 'true' branch...
    |  136 |     vsn = args[cur_arg + 2];
    |      |               ~
    |      |               |
    |      |               (7) ...to here
    |  137 | 
    |  138 |   if (meth) {
    |      |      ~     
    |      |      |
    |      |      (8) following 'false' branch (when 'meth' is NULL)...
    |......
    |  147 |   if (uri) {
    |      |      ~     
    |      |      |
    |      |      (9) ...to here
    |      |      (10) following 'false' branch (when 'uri' is NULL)...
    |......
    |  154 |   if (vsn) {
    |      |      ~     
    |      |      |
    |      |      (11) ...to here
    |      |      (12) pointer 'vsn' is checked for NULL here but it was
already dereferenced at (1)
    |

Reply via email to