https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108455
Bug ID: 108455
Summary: -Wanalyzer-deref-before-check false positive seen in
git pack-revindex.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 54299
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54299&action=edit
Reduced reproducer
I'm attaching a reduced reproducer
https://godbolt.org/z/7oMrno8rd
Complains about:
../../src/pack-revindex.c: In function ‘load_revindex_from_disk’:
../../src/pack-revindex.c:123:8: warning: check of ‘data’ for NULL after
already dereferencing it [-Wanalyzer-deref-before-check]
123 | if (data)
| ^
‘load_revindex_from_disk’: events 1-11
|
| 63 | int load_revindex_from_disk(char *revindex_name, uint32_t
num_objects,
| | ^~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (1) entry to ‘load_revindex_from_disk’
|......
| 73 | if (fd < 0) {
| | ~
| | |
| | (2) following ‘false’ branch (when ‘fd >= 0’)...
|......
| 77 | if (fstat(fd, &st)) {
| | ~~~~~~~~~~~~~~~
| | ||
| | |(3) ...to here
| | (4) following ‘false’ branch...
|......
| 82 | revindex_size = xsize_t(st.st_size);
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (5) ...to here
| 83 |
| 84 | if (revindex_size < ((12) + (2 *
the_repository->hash_algo->rawsz))) {
| | ~
| | |
| | (6) following ‘false’ branch...
|......
| 90 | if (revindex_size - ((12) + (2 *
the_repository->hash_algo->rawsz)) !=
| | ~ ~~
| | | |
| | (8) following ‘false’ branch... (7) ...to here
|......
| 97 | data = xmmap(((void *)0), revindex_size, 0x1, 0x02, fd, 0);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (9) ...to here
|......
| 100 | if (git_bswap32(hdr->signature) != 0x52494458) {
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (10) pointer ‘data’ is dereferenced here
| 101 | ret =
| 102 | (error(_("reverse-index file %s has unknown signature"),
revindex_name),
| |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (11) calling ‘_’ from ‘load_revindex_from_disk’
|
+--> ‘_’: events 12-14
|
| 37 | static inline __attribute__((format_arg(1))) const char
*_(const char *msgid) {
| | ^
| | |
| |
(12) entry to ‘_’
| 38 | if (!*msgid)
| | ~
| | |
| | (13) following ‘false’ branch...
| 39 | return "";
| 40 | return gettext(msgid);
| | ~~~~~~~~~~~~~~
| | |
| | (14) ...to here
|
<------+
|
‘load_revindex_from_disk’: events 15-18
|
| 102 | (error(_("reverse-index file %s has unknown signature"),
revindex_name),
| |
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (15) returning to ‘load_revindex_from_disk’ from ‘_’
|......
| 122 | if (ret) {
| | ~
| | |
| | (16) following ‘true’ branch (when ‘ret != 0’)...
| 123 | if (data)
| | ~
| | |
| | (17) ...to here
| | (18) pointer ‘data’ is checked for NULL here but it was
already dereferenced at (10)
|
Yes it does check the pointer for NULL after dereferencing it, but this is in
shared cleanup code. There are other paths to the check for NULL in which the
pointer hasn't yet been dereferenced.