Patchwork C++ PATCHes for c++/47453 (rejecting ({...}) for non-class types)

login
register
mail settings
Submitter Jason Merrill
Date Aug. 5, 2011, 7:18 p.m.
Message ID <4E3C4204.805@redhat.com>
Download mbox | patch
Permalink /patch/108715/
State New
Headers show

Comments

Jason Merrill - Aug. 5, 2011, 7:18 p.m.
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.

Patch

commit ffa8f76324849e367023a06b0ae663a798db64ad
Author: Jason Merrill <jason@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});