https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118585

--- Comment #1 from Alejandro Colomar <alx at kernel dot org> ---
If I change foo() --which takes void*-- by bar() --which takes const void*--,
then the warnings are triggered.

I guess the analyzer thinks foo() might correctly free(p) inside, but that
assumption would be incompatible with p++ right after the call.

alx@devuan:~/tmp/gcc$ cat bar.c 
#include <stdlib.h>

[[gnu::malloc(free)]] void *my_malloc(size_t);

int bar(const void *p);

void
f(void)
{
        int *p;

        p = my_malloc(100);
        if (bar(p))
                p++;

        free(p);
}

void
g(void)
{
        int *p;

        p = malloc(200);
        if (bar(p))
                p++;

        free(p);
}
alx@devuan:~/tmp/gcc$ gcc-15 -Wall -Wextra -O3 -fanalyzer -S bar.c
bar.c: In function ‘f’:
bar.c:14:18: warning: leak of ‘p’ [CWE-401] [-Wanalyzer-malloc-leak]
   14 |                 p++;
      |                 ~^~
  ‘f’: events 1-4
   12 |         p = my_malloc(100);
      |             ^~~~~~~~~~~~~~
      |             |
      |             (1) allocated here
   13 |         if (bar(p))
      |            ~ 
      |            |
      |            (2) following ‘true’ branch... ─>─┐
      |                                              │
      |                                              │
      |┌─────────────────────────────────────────────┘
   14 |│                p++;
      |│                ~~~
      |│                 |
      |└────────────────>(3) ...to here
      |                  (4) ⚠️  ‘p’ leaks here; was allocated at (1)
bar.c: In function ‘g’:
bar.c:26:18: warning: leak of ‘p’ [CWE-401] [-Wanalyzer-malloc-leak]
   26 |                 p++;
      |                 ~^~
  ‘g’: events 1-4
   24 |         p = malloc(200);
      |             ^~~~~~~~~~~
      |             |
      |             (1) allocated here
   25 |         if (bar(p))
      |            ~ 
      |            |
      |            (2) following ‘true’ branch... ─>─┐
      |                                              │
      |                                              │
      |┌─────────────────────────────────────────────┘
   26 |│                p++;
      |│                ~~~
      |│                 |
      |└────────────────>(3) ...to here
      |                  (4) ⚠️  ‘p’ leaks here; was allocated at (1)
bar.c:25:13: warning: ‘p’ may be used uninitialized [-Wmaybe-uninitialized]
   25 |         if (bar(p))
      |             ^~~~~~
bar.c:5:5: note: by argument 1 of type ‘const void *’ to ‘bar’ declared here
    5 | int bar(const void *p);
      |     ^~~

Reply via email to