For a constexpr delegating constructor, we should be able to just use
the delegated initializer.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 4443d34fb34484de797d087066dfe87fb55afc1f
Author: Jason Merrill <ja...@redhat.com>
Date: Mon Dec 19 15:50:09 2011 -0500
PR c++/51526
* semantics.c (build_data_member_initialization): Handle
delegating constructor.
(build_constexpr_constructor_member_initializers): Likewise.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 2788daa..ec56ab5 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5801,6 +5801,12 @@ build_data_member_initialization (tree t, VEC(constructor_elt,gc) **vec)
the const_cast. */
member = op;
}
+ else if (op == current_class_ptr
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (TREE_TYPE (member)),
+ current_class_type)))
+ /* Delegating constructor. */
+ member = op;
else
{
/* We don't put out anything for an empty base. */
@@ -5907,7 +5913,20 @@ build_constexpr_constructor_member_initializers (tree type, tree body)
else
gcc_assert (errorcount > 0);
if (ok)
- return build_constructor (type, vec);
+ {
+ if (VEC_length (constructor_elt, vec) > 0)
+ {
+ /* In a delegating constructor, return the target. */
+ constructor_elt *ce = VEC_index (constructor_elt, vec, 0);
+ if (ce->index == current_class_ptr)
+ {
+ body = ce->value;
+ VEC_free (constructor_elt, gc, vec);
+ return body;
+ }
+ }
+ return build_constructor (type, vec);
+ }
else
return error_mark_node;
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-delegating.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-delegating.C
new file mode 100644
index 0000000..a020888
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-delegating.C
@@ -0,0 +1,15 @@
+// PR c++/51526
+// { dg-options -std=c++0x }
+
+const int j = 42;
+
+struct S {
+ int i;
+ constexpr S(int i) : i(i) {}
+ constexpr S() : S(j) {}
+};
+
+constexpr S s{};
+
+#define SA(X) static_assert((X),#X)
+SA(s.i == 42);