This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/48873 (unnecessary dtor calls in new-expressions)


Here the issue was that build_new_1 wants to stabilize any constructor arguments so that the EH region for deleting the allocated memory can be as small as possible. But stabilize_expr was being over-eager, making a copy of a class with trivial constructors, but a non-trivial (and indeed non-callable) destructor. And even if it didn't have a problematic destructor, there's no reason to introduce extra copies of trivially copyable classes. So this patch changes stabilize_expr to only make copies of scalar types and class prvalues.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 21a411247eb5e59895aa54ff9a85e3cf8795a81a
Author: Jason Merrill <jason@redhat.com>
Date:   Wed May 4 11:15:30 2011 -0400

    	PR c++/48873
    	* tree.c (stabilize_expr): Don't make gratuitous copies of classes.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 0f2f86c..9a6e26d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3119,7 +3119,10 @@ stabilize_expr (tree exp, tree* initp)
 
   if (!TREE_SIDE_EFFECTS (exp))
     init_expr = NULL_TREE;
-  else if (!TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp))
+  /* There are no expressions with REFERENCE_TYPE, but there can be call
+     arguments with such a type; just treat it as a pointer.  */
+  else if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE
+	   || SCALAR_TYPE_P (exp)
 	   || !lvalue_or_rvalue_with_address_p (exp))
     {
       init_expr = get_target_expr (exp);
diff --git a/gcc/testsuite/g++.dg/init/new32.C b/gcc/testsuite/g++.dg/init/new32.C
new file mode 100644
index 0000000..f827857
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new32.C
@@ -0,0 +1,16 @@
+// PR c++/48873
+
+#include <new>
+
+struct D {
+private:
+  ~D();
+};
+
+template<class T>
+T& create();
+
+void f()
+{
+  D* dp = new (((void*) 0)) D(create<D>()); // #
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]