https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109335
--- Comment #4 from Alejandro Colomar <alx at kernel dot org> ---
Here's a smaller reproducer:
$ cat pass.c
#include <stdlib.h>
void my_free(char *p);
[[gnu::malloc(my_free)]] char *my_malloc(void);
int main(void)
{
char *p;
p = my_malloc();
my_free(p); // 2 false positives.
}
char *my_malloc(void)
{
return malloc(42);
}
void my_free(char *p)
{
free(p);
}
$ gcc-14 -Wall -Wextra pass.c -fanalyzer -O3
pass.c: In function ‘main’:
pass.c:10:9: warning: ‘p’ should have been deallocated with ‘free’ but was
deallocated with ‘my_free’ [CWE-762] [-Wanalyzer-mismatching-deallocation]
10 | my_free(p); // 2 false positives.
| ^~~~~~~~~~
‘main’: events 1-2
|
| 6 | int main(void)
| | ^~~~
| | |
| | (1) entry to ‘main’
|......
| 9 | p = my_malloc();
| | ~~~~~~~~~~~
| | |
| | (2) calling ‘my_malloc’ from ‘main’
|
+--> ‘my_malloc’: events 3-4
|
| 13 | char *my_malloc(void)
| | ^~~~~~~~~
| | |
| | (3) entry to ‘my_malloc’
| 14 | {
| 15 | return malloc(42);
| | ~~~~~~~~~~
| | |
| | (4) allocated here (expects deallocation
with ‘free’)
|
<------+
|
‘main’: events 5-6
|
| 9 | p = my_malloc();
| | ^~~~~~~~~~~
| | |
| | (5) returning to ‘main’ from ‘my_malloc’
| 10 | my_free(p); // 2 false positives.
| | ~~~~~~~~~~
| | |
| | (6) deallocated with ‘my_free’ here; allocation at (4)
expects deallocation with ‘free’
|
pass.c: In function ‘my_malloc’:
pass.c:15:16: warning: leak of ‘p’ [CWE-401] [-Wanalyzer-malloc-leak]
15 | return malloc(42);
| ^~~~~~~~~~
‘main’: events 1-3
|
| 6 | int main(void)
| | ^~~~
| | |
| | (1) entry to ‘main’
|......
| 9 | p = my_malloc();
| | ~~~~~~~~~~~
| | |
| | (2) allocated here
| | (3) calling ‘my_malloc’ from ‘main’
|
+--> ‘my_malloc’: events 4-5
|
| 13 | char *my_malloc(void)
| | ^~~~~~~~~
| | |
| | (4) entry to ‘my_malloc’
| 14 | {
| 15 | return malloc(42);
| | ~~~~~~~~~~
| | |
| | (5) ‘p’ leaks here; was allocated at (2)
|