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]

Patch PR c++/40239


Hello,

During value-initialization of a struct member that is not explicitely
initialized we copy-initialize the struct member with the result of a
TARGET_EXPR, and that involves copying the result of that TARGET_EXPR
using its copy constructor. The patch below direct-initializes the
struct member with the TARGET_EXPR instead. I couldn't find a more
direct way of doing that value-initialization proper so that it doesn't
involve copying. I thought about using build_value_init instead of going
the TARGET_EXPR route, but convert_for_initialization (called by digest_init_r)
wouldn't be happy as the result of build_value_init is void. So this patch
was the a smallest surgery I could come up with.

In any case, this bug is not a regression (even if it's a rejects-valid)
so I won't commit this before the comming stage 1, should it be
accepted.

Tested against trunk on x86_64-unknown-linux-gnu and starred at the
output assembly to make sure the value-initialization really happened.

        Dodji

commit abb546dcd2fbc18695fdb37c2f52a0f203b50491
Author: Dodji Seketeli <dodji@redhat.com>
Date:   Mon Jan 11 16:57:19 2010 +0100

    Fix PR c++/40239
    
    gcc/cp/ChangeLog:
    	* typeck2.c (process_init_constructor_record):
    	value-initialize members that are are not explicitely
    	initialized.
    
    gcc/testsuite/ChangeLog:
    	* gcc/testsuite/g++.dg/init/aggr5.C: New test.
    	* gcc/testsuite/g++.dg/init/aggr5.C: New test.

diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 66ff3c1..a4b6f6c 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1143,12 +1143,17 @@ process_init_constructor_record (tree type, tree init)
       else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
 	{
 	  /* If this type needs constructors run for
-	     default-initialization, we can't rely on the back end to do it
+	     value-initialization, we can't rely on the back end to do it
 	     for us, so build up TARGET_EXPRs.  If the type in question is
 	     a class, just build one up; if it's an array, recurse.  */
 	  if (MAYBE_CLASS_TYPE_P (TREE_TYPE (field)))
-	    next = build_functional_cast (TREE_TYPE (field), NULL_TREE,
-                                          tf_warning_or_error);
+	    {
+	      next = build_functional_cast (TREE_TYPE (field), NULL_TREE,
+					    tf_warning_or_error);
+	      /* direct-initialize the target with the temporary.  */
+	      if (TREE_CODE (next) == TARGET_EXPR)
+		TARGET_EXPR_DIRECT_INIT_P (next) = true;
+	    }
 	  else
 	    next = build_constructor (init_list_type_node, NULL);
 
diff --git a/gcc/testsuite/g++.dg/init/aggr5.C b/gcc/testsuite/g++.dg/init/aggr5.C
new file mode 100644
index 0000000..3bad4b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/aggr5.C
@@ -0,0 +1,12 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/40239
+// { dg-do "compile" }
+
+struct B { B() { } private: B(B const&); };
+struct A { int a; B b; };
+
+int
+main()
+{
+  A a = {0};
+}
diff --git a/gcc/testsuite/g++.dg/init/aggr6.C b/gcc/testsuite/g++.dg/init/aggr6.C
new file mode 100644
index 0000000..56f91a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/aggr6.C
@@ -0,0 +1,12 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/40239
+// { dg-do compile }
+
+struct B { B() { } private: B(B const&); };
+struct A { int a; B b; };
+
+int
+main()
+{
+  A a = {};
+}


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