https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125304
--- Comment #3 from David Malcolm <dmalcolm at gcc dot gnu.org> --- FWIW I've been using Claude Code to help debug this. Here's the summary it came up with of our conversation: Root cause analysis: At the comparison `_M_data() == _M_local_data()` in the _M_is_local() method (line 84 of the test case): - _M_data() returns a plain pointer: &s._M_local_buf - _M_local_data() calls std::pointer_traits<pointer>::pointer_to(*_M_local_buf), which creates a CAST_REG wrapper: &CAST_REG(..., s._M_local_buf) Both point to the same location, but the analyzer's region/svalue comparison logic incorrectly concludes the pointers are "definitely non-equal" when one is wrapped in CAST_REG and the other is not. This causes the analyzer to only explore the false branch of the comparison, skipping the `return true;` early exit. The false branch leads to _M_destroy() being called on stack memory, producing the false positive. The correct behavior would be to either: 1. Recognize that both pointers refer to the same location (best) 2. Return "unknown" and explore both branches conservatively (acceptable) The current behavior of concluding "definitely non-equal" is incorrect and leads to false positives. Exploded graph analysis (using -fdump-analyzer-exploded-graph and -fdiagnostics-add-output=sarif:analyzer-graphs=yes) confirms that at the comparison point, the analyzer creates only one outgoing edge (false branch) instead of exploring both branches or just the true branch.
