Tested x86_64-pc-linux-gnu, ok for trunk? -- 8< --
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. --- gcc/gimple-ssa-warn-access.cc | 50 ++++++++----------- .../g++.dg/warn/Wdangling-pointer-6.C | 30 +++++++++++ 2 files changed, 50 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wdangling-pointer-6.C diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index b3de4b77924..d0d2148c872 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -4528,39 +4528,34 @@ pass_waccess::check_dangling_stores (basic_block bb, if (!m_ptr_qry.get_ref (lhs, stmt, &lhs_ref, 0)) continue; - if (auto_var_p (lhs_ref.ref)) - continue; - - if (DECL_P (lhs_ref.ref)) + if (TREE_CODE (lhs_ref.ref) == MEM_REF) { - if (!POINTER_TYPE_P (TREE_TYPE (lhs_ref.ref)) - || lhs_ref.deref > 0) - continue; + lhs_ref.ref = TREE_OPERAND (lhs_ref.ref, 0); + ++lhs_ref.deref; } - else if (TREE_CODE (lhs_ref.ref) == SSA_NAME) + if (TREE_CODE (lhs_ref.ref) == ADDR_EXPR) + { + lhs_ref.ref = TREE_OPERAND (lhs_ref.ref, 0); + --lhs_ref.deref; + } + if (TREE_CODE (lhs_ref.ref) == SSA_NAME) { gimple *def_stmt = SSA_NAME_DEF_STMT (lhs_ref.ref); if (!gimple_nop_p (def_stmt)) /* Avoid looking at or before stores into unknown objects. */ return; - tree var = SSA_NAME_VAR (lhs_ref.ref); - if (TREE_CODE (var) == PARM_DECL && DECL_BY_REFERENCE (var)) - /* Avoid by-value arguments transformed into by-reference. */ - continue; + lhs_ref.ref = SSA_NAME_VAR (lhs_ref.ref); + } - } - else if (TREE_CODE (lhs_ref.ref) == MEM_REF) - { - tree arg = TREE_OPERAND (lhs_ref.ref, 0); - if (TREE_CODE (arg) == SSA_NAME) - { - gimple *def_stmt = SSA_NAME_DEF_STMT (arg); - if (!gimple_nop_p (def_stmt)) - return; - } - } + if (TREE_CODE (lhs_ref.ref) == PARM_DECL + && (lhs_ref.deref - DECL_BY_REFERENCE (lhs_ref.ref)) > 0) + /* Assignment through a (real) pointer/reference parameter. */; + else if (TREE_CODE (lhs_ref.ref) == VAR_DECL + && !auto_var_p (lhs_ref.ref)) + /* Assignment to/through a non-local variable. */; else + /* Something else, don't warn. */ continue; if (stores.add (lhs_ref.ref)) @@ -4587,13 +4582,8 @@ pass_waccess::check_dangling_stores (basic_block bb, location_t loc = DECL_SOURCE_LOCATION (rhs_ref.ref); inform (loc, "%qD declared here", rhs_ref.ref); - if (DECL_P (lhs_ref.ref)) - loc = DECL_SOURCE_LOCATION (lhs_ref.ref); - else if (EXPR_HAS_LOCATION (lhs_ref.ref)) - loc = EXPR_LOCATION (lhs_ref.ref); - - if (loc != UNKNOWN_LOCATION) - inform (loc, "%qE declared here", lhs_ref.ref); + loc = DECL_SOURCE_LOCATION (lhs_ref.ref); + inform (loc, "%qD declared here", lhs_ref.ref); } } diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-pointer-6.C b/gcc/testsuite/g++.dg/warn/Wdangling-pointer-6.C new file mode 100644 index 00000000000..20d47edecc5 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wdangling-pointer-6.C @@ -0,0 +1,30 @@ +// PR c++/109514 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-O2 -Werror=dangling-pointer" } + +struct _Rb_tree_node_base { + _Rb_tree_node_base *_M_parent; +}; +struct _Rb_tree_header { + _Rb_tree_node_base _M_header; + void _M_move_data() { _M_header._M_parent->_M_parent = &_M_header; } +}; +struct _Rb_tree { + _Rb_tree_header _M_impl; + _Rb_tree_node_base *&_M_root() { return _M_impl._M_header._M_parent; } + _Rb_tree(); + _Rb_tree &operator=(_Rb_tree &&); +}; +_Rb_tree &_Rb_tree::operator=(_Rb_tree &&) { + if (_M_root()) + _M_impl._M_move_data(); + return *this; +} +struct set { + _Rb_tree _M_t; +}; +set FilterRs(); +void f() { + set rs; + rs = FilterRs(); +}; base-commit: f32f7881fb0db085479525b5a23db5dabd990c3b -- 2.31.1