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