DR 1214 established that an initializer of the form ({something}) is
only valid for an object of class type. This patch implements that,
though I've only made it a pedwarn as there is some uncertainty about
whether this is actually what we want. I've also split the patch into
two to make it easier to revert if that turns out not to be the case;
the first part is a cleanup which is correct either way.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 93e7eecc08c50085336928d8093baff55103d176
Author: Jason Merrill <ja...@redhat.com>
Date: Thu Aug 4 17:32:17 2011 -0400
* init.c (perform_member_init): Always build_aggr_init
for a class member with an explicit mem-initializer.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 31171cf..d9e475e 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -547,7 +547,8 @@ perform_member_init (tree member, tree init)
finish_expr_stmt (init);
}
}
- else if (type_build_ctor_call (type))
+ else if (type_build_ctor_call (type)
+ || (init && CLASS_TYPE_P (strip_array_types (type))))
{
if (TREE_CODE (type) == ARRAY_TYPE)
{
commit ffa8f76324849e367023a06b0ae663a798db64ad
Author: Jason Merrill <ja...@redhat.com>
Date: Thu Aug 4 17:32:32 2011 -0400
PR c++/47453
* typeck.c (build_x_compound_expr_from_list): Also complain
about ({...}).
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index f53deb9..a1f6761 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5470,6 +5470,16 @@ build_x_compound_expr_from_list (tree list, expr_list_kind exp,
{
tree expr = TREE_VALUE (list);
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && !CONSTRUCTOR_IS_DIRECT_INIT (expr))
+ {
+ if (complain & tf_error)
+ pedwarn (EXPR_LOC_OR_HERE (expr), 0, "list-initializer for "
+ "non-class type must not be parenthesized");
+ else
+ return error_mark_node;
+ }
+
if (TREE_CHAIN (list))
{
if (complain & tf_error)
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist13.C b/gcc/testsuite/g++.dg/cpp0x/initlist13.C
index 9ed6c74..bc5ee2c 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist13.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist13.C
@@ -4,5 +4,5 @@
#include <complex>
-__complex__ int i ({0});
-std::complex<int> i2 ({0});
+__complex__ int i {0};
+std::complex<int> i2 {0};
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist50.C b/gcc/testsuite/g++.dg/cpp0x/initlist50.C
index ef4e72c..5cb23e2 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist50.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist50.C
@@ -8,7 +8,7 @@ struct A2 {
template <class T> struct B {
T ar[1];
- B(T t):ar({t}) {}
+ B(T t):ar{t} {}
};
int main(){
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist56.C b/gcc/testsuite/g++.dg/cpp0x/initlist56.C
new file mode 100644
index 0000000..862b41b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist56.C
@@ -0,0 +1,37 @@
+// PR c++/47453
+// { dg-options "-std=c++0x -pedantic-errors" }
+
+// invalid
+int a({0}); // { dg-error "" }
+
+// invalid
+int const &b({0}); // { dg-error "" }
+
+// invalid
+struct A1 { int a[2]; A1(); };
+A1::A1():a({1, 2}) { } // { dg-error "" }
+
+struct A { explicit A(int, int); A(int, long); };
+
+// invalid
+A c({1, 2}); // { dg-error "" }
+
+// valid (by copy constructor).
+A d({1, 2L});
+
+// valid
+A e{1, 2};
+
+#include <initializer_list>
+
+struct B {
+ template<typename ...T>
+ B(std::initializer_list<int>, T ...);
+};
+
+// invalid (the first phase only considers init-list ctors)
+// (for the second phase, no constructor is viable)
+B f{1, 2, 3}; // { dg-error "" }
+
+// valid (T deduced to <>).
+B g({1, 2, 3});