This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch PR c++/40239
- From: Dodji Seketeli <dodji at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: jason at redhat dot com
- Date: Tue, 12 Jan 2010 11:58:21 +0100
- Subject: 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 = {};
+}