public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jason Merrill <jason@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r13-221] c++: fix arm-eabi crash building libstdc++ [PR105529]
Date: Tue, 10 May 2022 05:06:03 +0000 (GMT)	[thread overview]
Message-ID: <20220510050603.0E0983870C27@sourceware.org> (raw)

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

commit r13-221-gbb2921ab84dba014f24be06663636c7fb1361474
Author: Jason Merrill <jason@redhat.com>
Date:   Mon May 9 16:03:35 2022 -0400

    c++: fix arm-eabi crash building libstdc++ [PR105529]
    
    My recent change to cxx_eval_store_expression asserts that the target and
    value can only end up having different types in the case of an empty base;
    this was crashing arm-eabi compilers because in that ABI [cd]tors
    return *this, and weren't converting it to void* first.
    
    This also shares the 'return this' code between the three places it occurs.
    
    Thanks to Marek for the tests.
    
            PR c++/105529
    
    gcc/cp/ChangeLog:
    
            * decl.cc (maybe_return_this): Replace...
            (finish_constructor_body, finish_destructor_body): ...these.
            (finish_function_body): Call it.
            * optimize.cc (build_delete_destructor_body): Call it.
            * cp-tree.h (maybe_return_this): Declare.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/constexpr-dtor13.C: New test.
            * g++.dg/cpp2a/constexpr-dtor14.C: New test.

Diff:
---
 gcc/cp/cp-tree.h                              |  1 +
 gcc/cp/decl.cc                                | 47 ++++++---------------------
 gcc/cp/optimize.cc                            |  9 +----
 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C | 11 +++++++
 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C | 13 ++++++++
 5 files changed, 36 insertions(+), 45 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7e50db0e35a..9fb07d8ea39 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6841,6 +6841,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 void maybe_return_this			(void);
 extern tree begin_function_body			(void);
 extern void finish_function_body		(tree);
 extern tree outer_curly_brace_block		(tree);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 872b02d55bd..9c9cf9f7f6b 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -86,9 +86,7 @@ static tree check_initializer (tree, tree, int, vec<tree, va_gc> **);
 static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
 static void copy_type_enum (tree , tree);
 static void check_function_type (tree, tree);
-static void finish_constructor_body (void);
 static void begin_destructor_body (void);
-static void finish_destructor_body (void);
 static void record_key_method_defined (tree);
 static tree create_array_type_for_decl (tree, tree, tree, location_t);
 static tree get_atexit_node (void);
@@ -17502,22 +17500,20 @@ store_parm_decls (tree current_function_parms)
 }
 
 \f
-/* Set the return value of the constructor (if present).  */
+/* Set the return value of the [cd]tor if the ABI wants that.  */
 
-static void
-finish_constructor_body (void)
+void
+maybe_return_this (void)
 {
-  tree val;
-  tree exprstmt;
-
   if (targetm.cxx.cdtor_returns_this ())
     {
-      val = DECL_ARGUMENTS (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);
-      /* Return the address of the object.  */
-      exprstmt = build_stmt (input_location, RETURN_EXPR, val);
+      tree exprstmt = build_stmt (input_location, RETURN_EXPR, val);
       add_stmt (exprstmt);
     }
 }
@@ -17590,28 +17586,6 @@ begin_destructor_body (void)
     }
 }
 
-/* At the end of every destructor we generate code to delete the object if
-   necessary.  Do that now.  */
-
-static void
-finish_destructor_body (void)
-{
-  tree exprstmt;
-
-  if (targetm.cxx.cdtor_returns_this ())
-    {
-      tree val;
-
-      val = DECL_ARGUMENTS (current_function_decl);
-      suppress_warning (val, OPT_Wuse_after_free);
-      val = build2 (MODIFY_EXPR, TREE_TYPE (val),
-		    DECL_RESULT (current_function_decl), val);
-      /* Return the address of the object.  */
-      exprstmt = build_stmt (input_location, RETURN_EXPR, val);
-      add_stmt (exprstmt);
-    }
-}
-
 /* Do the necessary processing for the beginning of a function body, which
    in this case includes member-initializers, but not the catch clauses of
    a function-try-block.  Currently, this means opening a binding level
@@ -17662,10 +17636,9 @@ finish_function_body (tree compstmt)
 
   if (processing_template_decl)
     /* Do nothing now.  */;
-  else if (DECL_CONSTRUCTOR_P (current_function_decl))
-    finish_constructor_body ();
-  else if (DECL_DESTRUCTOR_P (current_function_decl))
-    finish_destructor_body ();
+  else if (DECL_CONSTRUCTOR_P (current_function_decl)
+	   || DECL_DESTRUCTOR_P (current_function_decl))
+    maybe_return_this ();
 }
 
 /* Given a function, returns the BLOCK corresponding to the outermost level
diff --git a/gcc/cp/optimize.cc b/gcc/cp/optimize.cc
index 13ab8b7361e..5c134fd2fed 100644
--- a/gcc/cp/optimize.cc
+++ b/gcc/cp/optimize.cc
@@ -163,14 +163,7 @@ build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
 
   /* Return the address of the object.
      ??? How is it useful to return an invalid address?  */
-  if (targetm.cxx.cdtor_returns_this ())
-    {
-      tree val = DECL_ARGUMENTS (delete_dtor);
-      suppress_warning (val, OPT_Wuse_after_free);
-      val = build2 (MODIFY_EXPR, TREE_TYPE (val),
-                    DECL_RESULT (delete_dtor), val);
-      add_stmt (build_stmt (0, RETURN_EXPR, val));
-    }
+  maybe_return_this ();
 }
 
 /* Return name of comdat group for complete and base ctor (or dtor)
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C
new file mode 100644
index 00000000000..7b289614fc1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C
@@ -0,0 +1,11 @@
+// PR c++/105529
+// { dg-do compile { target c++20 } }
+// { dg-options "-O" }
+
+struct allocator {
+  constexpr ~allocator() {}
+};
+struct S {
+  S(int, int, allocator = allocator());
+};
+void to_string() { S(0, '\0'); }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C
new file mode 100644
index 00000000000..9c55121eb8a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C
@@ -0,0 +1,13 @@
+// PR c++/105529
+// { dg-do compile { target c++20 } }
+// { dg-options "-O" }
+// Like constexpr-dtor13.C, except that allocator is not an empty class.
+
+struct allocator {
+  constexpr ~allocator() {}
+  int a;
+};
+struct S {
+  S(int, int, allocator = allocator());
+};
+void to_string() { S(0, '\0'); }


                 reply	other threads:[~2022-05-10  5:06 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220510050603.0E0983870C27@sourceware.org \
    --to=jason@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).