A parenthesized initializer containing a pack expansion that expands to
0 elements is treated as value-initialization. We were handling that
properly for variable initializers, but not for mem-initializers in
constructors.
Tested x86_64-pc-linux-gnu, applying to trunk, 4.7 and 4.6.
commit 58c6706693964e81e846905cdd747a4aec015d09
Author: Jason Merrill <ja...@redhat.com>
Date: Tue Apr 3 15:31:39 2012 -0400
PR c++/52796
* pt.c (tsubst_initializer_list): A pack expansion with no elements
means value-initialization.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index aabe477..03acd5b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -19470,6 +19470,7 @@ tsubst_initializer_list (tree t, tree argvec)
}
else
{
+ tree tmp;
decl = tsubst_copy (TREE_PURPOSE (t), argvec,
tf_warning_or_error, NULL_TREE);
@@ -19478,10 +19479,17 @@ tsubst_initializer_list (tree t, tree argvec)
in_base_initializer = 1;
init = TREE_VALUE (t);
+ tmp = init;
if (init != void_type_node)
init = tsubst_expr (init, argvec,
tf_warning_or_error, NULL_TREE,
/*integral_constant_expression_p=*/false);
+ if (init == NULL_TREE && tmp != NULL_TREE)
+ /* If we had an initializer but it instantiated to nothing,
+ value-initialize the object. This will only occur when
+ the initializer was a pack expansion where the parameter
+ packs used in that expansion were of length zero. */
+ init = void_type_node;
in_base_initializer = 0;
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-value1.C b/gcc/testsuite/g++.dg/cpp0x/variadic-value1.C
new file mode 100644
index 0000000..179919a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-value1.C
@@ -0,0 +1,24 @@
+// PR c++/52796
+// { dg-do run { target c++11 } }
+
+inline void *operator new(__SIZE_TYPE__ s, void *p) { return p; }
+
+struct A
+{
+ int i;
+ template<class... Ts>
+ A(Ts&&... ts): i(ts...) { }
+};
+
+static union {
+ unsigned char c[sizeof(A)];
+ int i;
+};
+
+int main()
+{
+ i = 0xdeadbeef;
+ new(c) A;
+ if (i != 0)
+ __builtin_abort();
+}