diff options
-rw-r--r-- | gcc/cp/class.cc | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.cc | 23 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wuse-after-free3.C | 4 |
4 files changed, 25 insertions, 5 deletions
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index 4766b7c..6fdb56a 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -5053,6 +5053,8 @@ build_clone (tree fn, tree name, bool need_vtt_parm_p, clone = copy_fndecl_with_name (fn, name, ERROR_MARK, need_vtt_parm_p, omit_inherited_parms_p); DECL_CLONED_FUNCTION (clone) = fn; + + maybe_prepare_return_this (clone); } /* Remember where this function came from. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7b0b7c6..5614b71 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6979,6 +6979,7 @@ extern tree lookup_enumerator (tree, tree); extern bool start_preparsed_function (tree, tree, int); extern bool start_function (cp_decl_specifier_seq *, const cp_declarator *, tree); +extern tree maybe_prepare_return_this (tree); extern void maybe_return_this (void); extern tree begin_function_body (void); extern void finish_function_body (tree); diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index e269f68..bce8068 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -17926,16 +17926,31 @@ store_parm_decls (tree current_function_parms) } +/* Mark CDTOR's implicit THIS argument for returning, if required by + the ABI.. Return the decl for THIS, if it is to be returned, and + NULL otherwise. */ + +tree +maybe_prepare_return_this (tree cdtor) +{ + if (targetm.cxx.cdtor_returns_this ()) + if (tree val = DECL_ARGUMENTS (cdtor)) + { + suppress_warning (val, OPT_Wuse_after_free); + return val; + } + + return NULL_TREE; +} + /* Set the return value of the [cd]tor if the ABI wants that. */ void -maybe_return_this (void) +maybe_return_this () { - if (targetm.cxx.cdtor_returns_this ()) + if (tree val = maybe_prepare_return_this (current_function_decl)) { /* Return the address of the object. */ - tree val = DECL_ARGUMENTS (current_function_decl); - suppress_warning (val, OPT_Wuse_after_free); val = fold_convert (TREE_TYPE (DECL_RESULT (current_function_decl)), val); val = build2 (MODIFY_EXPR, TREE_TYPE (val), DECL_RESULT (current_function_decl), val); diff --git a/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C index e5b1578..8ef8202 100644 --- a/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C +++ b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C @@ -11,5 +11,7 @@ struct A A::~A () { operator delete (this); - f (); // { dg-warning "used after" } + f (); // { dg-warning "used after" "" { xfail arm_eabi } } + // arm_eabi's cdtors return this, which disables -Wuse-after-free + // warnings for cdtors' "this". } |