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) |