Initially noticed the false positive on fheroes2-1.0.3 project which uses -Werror by default. Here is the extracted example: // $ cat screen.cpp #include <set> #include <vector> struct R { int w; }; typedef std::vector<R> vr_t; typedef std::set<R> sr_t; static sr_t FilterRs (const sr_t & rs) { return rs; } vr_t getRs () { const vr_t filteredRs = []() { sr_t rs; rs = FilterRs (rs); return vr_t{rs.begin(), rs.end()}; }(); return filteredRs; } $ g++ -c -O2 screen.cpp -Werror=dangling-pointer In file included from /<<NIX>>/gcc-13.0.0/include/c++/13.0.1/set:62, from screen.cpp:1: In member function 'void std::_Rb_tree_header::_M_move_data(std::_Rb_tree_header&)', inlined from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_move_data(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, std::true_type) [with _Key = R; _Val = R; _KeyOfValue = std::_Identity<R>; _Compare = std::less<R>; _Alloc = std::allocator<R>]' at /<<NIX>>/gcc-13.0.0/include/c++/13.0.1/bits/stl_tree.h:1421:29, inlined from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_move_assign(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, std::true_type) [with _Key = R; _Val = R; _KeyOfValue = std::_Identity<R>; _Compare = std::less<R>; _Alloc = std::allocator<R>]' at /<<NIX>>/gcc-13.0.0/include/c++/13.0.1/bits/stl_tree.h:1710:14, inlined from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::operator=(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&&) [with _Key = R; _Val = R; _KeyOfValue = std::_Identity<R>; _Compare = std::less<R>; _Alloc = std::allocator<R>]' at /<<NIX>>/gcc-13.0.0/include/c++/13.0.1/bits/stl_tree.h:1744:21, inlined from 'std::set<_Key, _Compare, _Alloc>& std::set<_Key, _Compare, _Alloc>::operator=(std::set<_Key, _Compare, _Alloc>&&) [with _Key = R; _Compare = std::less<R>; _Alloc = std::allocator<R>]' at /<<NIX>>/gcc-13.0.0/include/c++/13.0.1/bits/stl_set.h:302:7, inlined from 'getRs()::<lambda()>' at screen.cpp:21:26, inlined from 'vr_t getRs()' at screen.cpp:24:7: /<<NIX>>/gcc-13.0.0/include/c++/13.0.1/bits/stl_tree.h:199:38: error: storing the address of local variable 'rs' in '*MEM[(struct _Rb_tree_node_base * &)&D.35566 + 16].std::_Rb_tree_node_base::_M_parent' [-Werror=dangling-pointer=] 199 | _M_header._M_parent->_M_parent = &_M_header; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~ screen.cpp: In function 'vr_t getRs()': screen.cpp:19:14: note: 'rs' declared here 19 | sr_t rs; | ^~ screen.cpp:19:14: note: '<unnamed>.std::set<R, std::less<R>, std::allocator<R> >::_M_t.std::_Rb_tree<R, R, std::_Identity<R>, std::less<R>, std::allocator<R> >::_M_impl.std::_Rb_tree<R, R, std::_Identity<R>, std::less<R>, std::allocator<R> >::_Rb_tree_impl<std::less<R>, true>::<unnamed>.std::_Rb_tree_header::_M_header.std::_Rb_tree_node_base::_M_parent' declared here cc1plus: some warnings being treated as errors I think it's a false positive (or maybe it exposes some NRVO bug?). $ g++ -v Using built-in specs. COLLECT_GCC=/<<NIX>>/gcc-13.0.0/bin/g++ COLLECT_LTO_WRAPPER=/<<NIX>>/gcc-13.0.0/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: Thread model: posix Supported LTO compression algorithms: zlib gcc version 13.0.1 20230409 (experimental) (GCC)
Confirmed. -Wdangling-pointer shouldn't warn about a store to an unknown object. And it should be able to figure out that this store is to sr itself, and not warn for that reason as well.
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:9964df74a9e99e850bf9b0b6ff5c47133f846db8 commit r13-7190-g9964df74a9e99e850bf9b0b6ff5c47133f846db8 Author: Jason Merrill <jason@redhat.com> Date: Fri Apr 14 13:37:16 2023 -0400 -Wdangling-pointer: fix MEM_REF handling [PR109514] Here we hit the MEM_REF case, with its arg an ADDR_EXPR, but had no handling for that and wrongly assumed it would be a reference to a local variable. This patch overhauls the logic for deciding whether the target is something to warn about so that we only warn if we specifically recognize the target as non-local. None of the existing tests regress as a result. PR c++/109514 gcc/ChangeLog: * gimple-ssa-warn-access.cc (pass_waccess::check_dangling_stores): Overhaul lhs_ref.ref analysis. gcc/testsuite/ChangeLog: * g++.dg/warn/Wdangling-pointer-6.C: New test.
Fixed.
Thank you, Jason! I tested the original code from fheroes2-1.0.3. It also compiles without warnings.