public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/testme)] call maybe_return_this in build_clone
@ 2023-11-19  5:22 Alexandre Oliva
  0 siblings, 0 replies; 6+ messages in thread
From: Alexandre Oliva @ 2023-11-19  5:22 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:d9c00a766c3c2bd3d66c1c66f3545ee159e37ce5

commit d9c00a766c3c2bd3d66c1c66f3545ee159e37ce5
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Sat Nov 18 02:32:05 2023 -0300

    call maybe_return_this in build_clone
    
    __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.

Diff:
---
 gcc/cp/class.cc                              |  2 ++
 gcc/cp/cp-tree.h                             |  1 +
 gcc/cp/decl.cc                               | 23 +++++++++++++++++++----
 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 9d4d95f85bf..1abf5d90edc 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 1fa710d7154..e1abb2a79dd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6956,6 +6956,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 d2ed46b1453..038c5ab71f2 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17896,16 +17896,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);
diff --git a/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C
index e5b157865bf..8ef82021380 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".
 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] call maybe_return_this in build_clone
@ 2023-11-29  4:35 Alexandre Oliva
  0 siblings, 0 replies; 6+ messages in thread
From: Alexandre Oliva @ 2023-11-29  4:35 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:177f6f2b2283bb92b8cbb78ca69f67eab7d52ef1

commit 177f6f2b2283bb92b8cbb78ca69f67eab7d52ef1
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Wed Nov 29 00:54:47 2023 -0300

    call maybe_return_this in build_clone
    
    __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.

Diff:
---
 gcc/cp/class.cc                              |  2 ++
 gcc/cp/cp-tree.h                             |  1 +
 gcc/cp/decl.cc                               | 23 +++++++++++++++++++----
 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 4766b7cf832..6fdb56abfb9 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 7b0b7c6a17e..5614b71eed4 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 e269f689c1c..bce806819d5 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17926,16 +17926,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);
diff --git a/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C
index e5b157865bf..8ef82021380 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".
 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] call maybe_return_this in build_clone
@ 2023-11-23 11:46 Alexandre Oliva
  0 siblings, 0 replies; 6+ messages in thread
From: Alexandre Oliva @ 2023-11-23 11:46 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:05d962f732678129dba10f6597442b94c498064b

commit 05d962f732678129dba10f6597442b94c498064b
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Sat Nov 18 02:32:05 2023 -0300

    call maybe_return_this in build_clone
    
    __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.

Diff:
---
 gcc/cp/class.cc                              |  2 ++
 gcc/cp/cp-tree.h                             |  1 +
 gcc/cp/decl.cc                               | 23 +++++++++++++++++++----
 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 4766b7cf832..6fdb56abfb9 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 7b0b7c6a17e..5614b71eed4 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 e6f75d771e0..4b3791c4606 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17908,16 +17908,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);
diff --git a/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C
index e5b157865bf..8ef82021380 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".
 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] call maybe_return_this in build_clone
@ 2023-11-19  5:25 Alexandre Oliva
  0 siblings, 0 replies; 6+ messages in thread
From: Alexandre Oliva @ 2023-11-19  5:25 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:0b4f16ab66a981f8d8a9a739a8f6508012401658

commit 0b4f16ab66a981f8d8a9a739a8f6508012401658
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Sat Nov 18 02:32:05 2023 -0300

    call maybe_return_this in build_clone
    
    __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.

Diff:
---
 gcc/cp/class.cc                              |  2 ++
 gcc/cp/cp-tree.h                             |  1 +
 gcc/cp/decl.cc                               | 23 +++++++++++++++++++----
 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 9d4d95f85bf..1abf5d90edc 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 1fa710d7154..e1abb2a79dd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6956,6 +6956,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 d2ed46b1453..038c5ab71f2 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17896,16 +17896,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);
diff --git a/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C
index e5b157865bf..8ef82021380 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".
 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] call maybe_return_this in build_clone
@ 2023-11-19  4:44 Alexandre Oliva
  0 siblings, 0 replies; 6+ messages in thread
From: Alexandre Oliva @ 2023-11-19  4:44 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b2a69234e4e88a36ba00f597ba3681ba2a7c270a

commit b2a69234e4e88a36ba00f597ba3681ba2a7c270a
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Sat Nov 18 02:32:05 2023 -0300

    call maybe_return_this in build_clone
    
    __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.

Diff:
---
 gcc/cp/class.cc                              |  2 ++
 gcc/cp/cp-tree.h                             |  1 +
 gcc/cp/decl.cc                               | 23 +++++++++++++++++++----
 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 9d4d95f85bf..1abf5d90edc 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 1fa710d7154..e1abb2a79dd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6956,6 +6956,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 d2ed46b1453..038c5ab71f2 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17896,16 +17896,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);
diff --git a/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C
index e5b157865bf..8ef82021380 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".
 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [gcc(refs/users/aoliva/heads/testme)] call maybe_return_this in build_clone
@ 2023-11-18  5:36 Alexandre Oliva
  0 siblings, 0 replies; 6+ messages in thread
From: Alexandre Oliva @ 2023-11-18  5:36 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:2c4dcfc2f8fbadde4331e69e68cba71c249b5855

commit 2c4dcfc2f8fbadde4331e69e68cba71c249b5855
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Sat Nov 18 02:32:05 2023 -0300

    call maybe_return_this in build_clone
    
    __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.

Diff:
---
 gcc/cp/class.cc                              |  2 ++
 gcc/cp/cp-tree.h                             |  1 +
 gcc/cp/decl.cc                               | 23 +++++++++++++++++++----
 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 9d4d95f85bf..1abf5d90edc 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 1fa710d7154..e1abb2a79dd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6956,6 +6956,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 d2ed46b1453..038c5ab71f2 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17896,16 +17896,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);
diff --git a/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C b/gcc/testsuite/g++.dg/warn/Wuse-after-free3.C
index e5b157865bf..8ef82021380 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".
 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-11-29  4:35 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-19  5:22 [gcc(refs/users/aoliva/heads/testme)] call maybe_return_this in build_clone Alexandre Oliva
  -- strict thread matches above, loose matches on Subject: below --
2023-11-29  4:35 Alexandre Oliva
2023-11-23 11:46 Alexandre Oliva
2023-11-19  5:25 Alexandre Oliva
2023-11-19  4:44 Alexandre Oliva
2023-11-18  5:36 Alexandre Oliva

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).