]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
call maybe_return_this in build_clone
authorAlexandre Oliva <oliva@adacore.com>
Wed, 29 Nov 2023 07:00:35 +0000 (04:00 -0300)
committerTorbjörn SVENSSON <torbjorn.svensson@foss.st.com>
Fri, 9 Feb 2024 21:13:31 +0000 (22:13 +0100)
__dt_base doesn't get its body from a maybe_return_this caller, it's
rather cloned with the full body within build_clone, and then it's
left alone, without going through finish_function_body or
build_delete_destructor_body, that call maybe_return_this.

Now, this is correct as far as the generated code is concerned, since
the cloned body of a cdtor that returns this is also a cdtor body that
returns this.  The problem is that the decl for THIS is also cloned,
and it doesn't get the warning suppression introduced by
maybe_return_this, so Wuse-after-free3.C fails with an excess warning
at the closing brace of the dtor body.

I've split out the warning suppression from maybe_return_this, and
arranged to call that bit from the relevant build_clone case.
Unfortunately, because the warning is silenced for all uses of the
THIS decl, rather than only for the ABI-mandated return stmt, this
also silences the very warning that the testcase checks for.

I'm not revamping the warning suppression approach to overcome this,
so I'm xfailing the expected warning on ARM EABI, hoping that's the
only target with cdtor_return_this, and leaving it at that.

for  gcc/cp/ChangeLog

* decl.cc (maybe_prepare_return_this): Split out of...
(maybe_return_this): ... this.
* cp-tree.h (maybe_prepare_return_this): Declare.
* class.cc (build_clone): Call it.

for  gcc/testsuite/ChangeLog

* g++.dg/warn/Wuse-after-free3.C: xfail on arm_eabi.

(cherry picked from commit 0d24289d129639efdc79338a64188d6d404375e8)

gcc/cp/class.cc
gcc/cp/cp-tree.h
gcc/cp/decl.cc
gcc/testsuite/g++.dg/warn/Wuse-after-free3.C

index 68b62086340bcd1ab357907308b52b64c680b994..ab8dca5eeca05aba33b9c82d03dc413fea316cf2 100644 (file)
@@ -5016,6 +5016,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.  */
index 9e03488f0df461397be2acfd79d4a3af4907d3dd..53e8f6fc0ea89f409d9edc784ff05dcf9234ad64 100644 (file)
@@ -6889,6 +6889,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);
index bb4f2fb82080f6ac9b13283cb859df52af732932..0126684c7896773e190ab6126b577ea70eb56d40 100644 (file)
@@ -17828,16 +17828,31 @@ store_parm_decls (tree current_function_parms)
 }
 
 \f
+/* 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);
index e5b157865bf6e35ab72b98cef0164f6c4031375a..8ef82021380a36940fca198ab88d3b4e86679371 100644 (file)
@@ -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".
 }