https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104434
Bug ID: 104434 Summary: Analyzer doesn't know about "pure" and "const" functions Product: gcc Version: 12.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: --- Consider: extern int pure_p (int) __attribute__ ((pure)); extern void do_stuff (void); void test (int a) { void *p; if (pure_p (a)) { p = __builtin_malloc (1024); if (!p) return; } do_stuff (); if (pure_p (a)) __builtin_free (p); } Currently trunk -fanalyzer emits these warnings: /tmp/foo.c: In function ‘test’: /tmp/foo.c:14:6: warning: leak of ‘p’ [CWE-401] [-Wanalyzer-malloc-leak] 14 | if (pure_p (a)) | ^ ‘test’: events 1-7 | | 7 | if (pure_p (a)) | | ^ | | | | | (1) following ‘true’ branch... | 8 | { | 9 | p = __builtin_malloc (1024); | | ~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (2) ...to here | | (3) allocated here | 10 | if (!p) | | ~ | | | | | (4) assuming ‘p’ is non-NULL | | (5) following ‘false’ branch (when ‘p’ is non-NULL)... |...... | 13 | do_stuff (); | | ~~~~~~~~~~~ | | | | | (6) ...to here | 14 | if (pure_p (a)) | | ~ | | | | | (7) following ‘false’ branch... | ‘test’: event 8 | |cc1: | (8): ...to here | ‘test’: event 9 | | 14 | if (pure_p (a)) | | ^ | | | | | (9) ‘p’ leaks here; was allocated at (3) | /tmp/foo.c:15:5: warning: use of uninitialized value ‘p’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value] 15 | __builtin_free (p); | ^~~~~~~~~~~~~~~~~~ ‘test’: events 1-6 | | 6 | void *p; | | ^ | | | | | (1) region created on stack here | 7 | if (pure_p (a)) | | ~ | | | | | (2) following ‘false’ branch... |...... | 13 | do_stuff (); | | ~~~~~~~~~~~ | | | | | (3) ...to here | 14 | if (pure_p (a)) | | ~ | | | | | (4) following ‘true’ branch... | 15 | __builtin_free (p); | | ~~~~~~~~~~~~~~~~~~ | | | | | (5) ...to here | | (6) use of uninitialized value ‘p’ here | by considering the execution paths where pure_p (a) is true then false (the false leak diagnostic), and false then true (the false uninit diagnostic) Presumably the analyzer should consider that the result of a pure/const function doesn't change, and thus only considers the true/true and false/false paths.