https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125304
--- Comment #4 from David Malcolm <dmalcolm at gcc dot gnu.org> --- Claude Code also generated this useful report, which I hand-checked against the graphviz output: ● Here's the path to the false positive using correct terminology: Exploded Path to False Positive enode 0: Origin enode 2 (at snode 16, line 127): Entry to test_ctor_empty() enode 23 (at snode 17, line 128): std::string s; - variable declaration enodes 24-43: Constructor execution and three __analyzer_eval() calls enode 44 (at snode 41, line 116): Destructor ~basic_string() calls _M_dispose() - Call string becomes: [std::basic_string::_M_dispose (&s);] enode 45 (at snode 0, line 93): Entry to _M_dispose() enode 46 (at snode 1, line 70): _M_data() call - Returns &s._M_local_buf (plain pointer, no CAST_REG) - Stored in temp _4 enode 47 (at snode 2, line 75): _M_local_data() call - Calls std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf) - Returns &CAST_REG(...) s._M_local_buf - Stored in temp _5 enode 48 (at snode 3, line 84): Comparison if (_M_data() == _M_local_data()) - Comparing _4 (plain) vs _5 (CAST_REG-wrapped) - Analyzer cannot prove equality - Takes false branch only enode 49 (at snode 8, line 98): _M_destroy() - calls deallocate() enode 50 (at snode 9, line 35): __builtin_operator_delete(__p) - False positive warning emitted here
