https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101550
Bug ID: 101550 Summary: -Wanalyzer-file-leak false positive with an array of pointers, open and fdopen. Product: gcc Version: 11.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: analyzer Assignee: dmalcolm at gcc dot gnu.org Reporter: amatej at redhat dot com Target Milestone: --- Hello, I have the following program: ---------------------------------------------------------- #include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> typedef struct { FILE *foo_file; } Foo; FILE* open_target_file() { int fd = open("some.txt", O_CREAT|O_TRUNC|O_RDWR, 0666); if (fd == -1) { return NULL; } FILE *f = fdopen(fd, "w+b"); if (f == NULL) { close(fd); return NULL; } return f; } void prepare_next_transfer(Foo **targets) { Foo *a1 = targets[0]; a1->foo_file = open_target_file(); if (a1->foo_file != NULL) { fclose(a1->foo_file); } } int main() { Foo a1 = {NULL}; Foo *data[] = {&a1, NULL}; prepare_next_transfer(data); } ---------------------------------------------------------- When I run: $ gcc program.c -fanalyzer I get: In function ‘prepare_next_transfer’: program.c:34:11: warning: leak of ‘f’ [CWE-401] [-Wanalyzer-malloc-leak] 34 | if (a1->foo_file != NULL) { | ~~^~~~~~~~~~ ‘prepare_next_transfer’: events 1-2 | | 28 | prepare_next_transfer(Foo **data) | | ^~~~~~~~~~~~~~~~~~~~~ | | | | | (1) entry to ‘prepare_next_transfer’ |...... | 32 | a1->foo_file = open_target_file(); | | ~~~~~~~~~~~~~~~~~~ | | | | | (2) calling ‘open_target_file’ from ‘prepare_next_transfer’ | +--> ‘open_target_file’: events 3-9 | | 11 | open_target_file() | | ^~~~~~~~~~~~~~~~ | | | | | (3) entry to ‘open_target_file’ |...... | 14 | if (fd == -1) { | | ~ | | | | | (4) following ‘false’ branch (when ‘fd != -1’)... |...... | 18 | FILE *f = fdopen(fd, "w+b"); | | ~~~~~~~~~~~~~~~~~ | | | | | (5) ...to here | | (6) allocated here | 19 | if (f == NULL) { | | ~ | | | | | (7) assuming ‘f’ is non-NULL | | (8) following ‘false’ branch (when ‘f’ is non-NULL)... |...... | 24 | return f; | | ~ | | | | | (9) ...to here | <------+ | ‘prepare_next_transfer’: events 10-11 | | 32 | a1->foo_file = open_target_file(); | | ^~~~~~~~~~~~~~~~~~ | | | | | (10) returning to ‘prepare_next_transfer’ from ‘open_target_file’ | 33 | | 34 | if (a1->foo_file != NULL) { | | ~~~~~~~~~~~~ | | | | | (11) ‘f’ leaks here; was allocated at (6) | I think this is a false positive since ‘f’ is returned from ‘open_target_file’ assigned to ‘a1->foo_file‘ and fclosed, there should be no leak. It goes away if fopen is used instead of open and fdopen or if the array of pointers is not used. I am using gcc-11.1.1-6.fc35.x86_64. Thank you for your work.