https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98223
--- Comment #2 from David Malcolm <dmalcolm at gcc dot gnu.org> --- I believe the existing false positive may relate to bug 97072, where the analyzer doesn't capture that the pointer to the malloc-ed buffer has been written to one of the fields (perhaps due to state-merging), and hence reports a leak when the frame is popped. Comparing the before/after EVRP patch gimple dumps, I see: --- pr94851-1.c.071i.analyzer.before 2021-01-05 11:08:02.809471975 -0500 +++ pr94851-1.c.071i.analyzer.after 2021-01-05 11:04:26.915680635 -0500 @@ -39,7 +39,7 @@ pamark () goto <bb 6>; [5.50%] <bb 6> [local count: 114863531]: - # p_2 = PHI <p_8(4), p_8(5)> + # p_2 = PHI <0B(4), p_8(5)> # last_16 = PHI <last_10(4), last_10(5)> if (p_2 != 0B) goto <bb 7>; [70.00%] i.e. the ranger EVRP patch adds the "knowledge" that p_2 is NULL when reached from BB 4. Comparing the .supergraph.eg.dot dumps I see that both before/after consider a malloc leak, but after the EVRP patch it considers the path in which the loop isn't entered due to p being NULL. It's considering the shortest path through the egraph as: 24 │ while (p != (AMARK *)NULL && p->m_name != (char)c) { <-- (1) p NULL here, skipping the loop 25 │ last = p; 26 │ p = p->m_next; 27 │ } 28 │ 29 │ if (p != (AMARK *)NULL) { <-- (2) p non-NULL here, skipping the malloc 30 │ printf("over writing mark %c\n", c); 31 │ } else { 32 │ if ((p = (AMARK *)malloc(sizeof(AMARK))) == (AMARK *)NULL) ... 43 │ p->m_name = (char)c; <-- (3) to here So the improved PHI from EVRP means that we hit bug 96374, which means that we reject the false positive, albeit for the wrong reasons. I plan to remove the xfail for now, but am recording this information here since the false leak may reappear if we fix bug 96374 without fixing bug 97072.