re PR c++/40308 (Brace initialization fails for member initializers in constructor...
authorJason Merrill <jason@redhat.com>
Tue, 2 Jun 2009 17:02:38 +0000 (13:02 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 2 Jun 2009 17:02:38 +0000 (13:02 -0400)
PR c++/40308
PR c++/40311
* typeck.c (cp_build_modify_expr): Always pass init-lists to the
conversion code.
* call.c (implicit_conversion): Allow init-list conversion to scalar
during direct-initialization, too.  Mark the conversion bad if it
has too many levels of braces.
(convert_like_real): And give a helpful error.

From-SVN: r148089

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/initlist13.C
gcc/testsuite/g++.dg/cpp0x/initlist18.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/initlist19.C [new file with mode: 0644]

index 448b558..e3eb576 100644 (file)
@@ -1,4 +1,13 @@
-2009-06-01  Jason Merrill  <jason@redhat.com>
+2009-06-02  Jason Merrill  <jason@redhat.com>
+
+       PR c++/40308
+       PR c++/40311
+       * typeck.c (cp_build_modify_expr): Always pass init-lists to the
+       conversion code.
+       * call.c (implicit_conversion): Allow init-list conversion to scalar
+       during direct-initialization, too.  Mark the conversion bad if it
+       has too many levels of braces.
+       (convert_like_real): And give a helpful error.
 
        PR c++/40306
        PR c++/40307
index 138abe0..1ab27c7 100644 (file)
@@ -1406,21 +1406,27 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
        return build_list_conv (to, expr, flags);
 
       /* Allow conversion from an initializer-list with one element to a
-        scalar type if this is copy-initialization.  Direct-initialization
-        would be something like int i({1}), which is invalid.  */
-      if (SCALAR_TYPE_P (to) && CONSTRUCTOR_NELTS (expr) <= 1
-         && (flags & LOOKUP_ONLYCONVERTING))
+        scalar type.  */
+      if (SCALAR_TYPE_P (to))
        {
+         int nelts = CONSTRUCTOR_NELTS (expr);
          tree elt;
-         if (CONSTRUCTOR_NELTS (expr) == 1)
+
+         if (nelts == 0)
+           elt = integer_zero_node;
+         else if (nelts == 1)
            elt = CONSTRUCTOR_ELT (expr, 0)->value;
          else
-           elt = integer_zero_node;
+           elt = error_mark_node;
+
          conv = implicit_conversion (to, TREE_TYPE (elt), elt,
                                      c_cast_p, flags);
          if (conv)
            {
              conv->check_narrowing = true;
+             if (BRACE_ENCLOSED_INITIALIZER_P (elt))
+               /* Too many levels of braces, i.e. '{{1}}'.  */
+               conv->bad_p = true;
              return conv;
            }
        }
@@ -4698,6 +4704,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       && convs->kind != ck_base)
     {
       conversion *t = convs;
+
+      /* Give a helpful error if this is bad because of excess braces.  */
+      if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+         && SCALAR_TYPE_P (totype)
+         && CONSTRUCTOR_NELTS (expr) > 0
+         && BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value))
+       permerror (input_location, "too many braces around initializer for %qT", totype);
+
       for (; t; t = convs->u.next)
        {
          if (t->kind == ck_user || !t->bad_p)
index 6f6bd39..b384fea 100644 (file)
@@ -6081,8 +6081,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 
   if (modifycode == INIT_EXPR)
     {
-      if (TREE_CODE (rhs) == CONSTRUCTOR)
+      if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
+       /* Do the default thing.  */;
+      else if (TREE_CODE (rhs) == CONSTRUCTOR)
        {
+         /* Compound literal.  */
          if (! same_type_p (TREE_TYPE (rhs), lhstype))
            /* Call convert to generate an error; see PR 11063.  */
            rhs = convert (lhstype, rhs);
index 9743b5d..fda5ce3 100644 (file)
@@ -1,5 +1,9 @@
 2009-06-02  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/initlist13.C: Remove expected error.
+       * g++.dg/cpp0x/initlist18.C: New.
+       * g++.dg/cpp0x/initlist19.C: New.
+
        * g++.dg/cpp0x/auto14.C: New.
 
 2009-06-02  Eric Botcazou  <ebotcazou@adacore.com>
index 98af92b..9ed6c74 100644 (file)
@@ -2,4 +2,7 @@
 // { dg-do compile }
 // { dg-options "-std=gnu++0x" }
 
-__complex__ int i ({0});       // { dg-error "cannot convert" }
+#include <complex>
+
+__complex__ int i ({0});
+std::complex<int> i2 ({0});
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist18.C b/gcc/testsuite/g++.dg/cpp0x/initlist18.C
new file mode 100644 (file)
index 0000000..c9a9bcd
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/40308, 40311
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+template< typename T >
+struct test {
+   test() : data{} {}
+
+   T data;
+};
+
+int main()
+{
+   test<int> x;
+   test<int*> y;
+   int * a = new int{};
+   int * b = new int{5};
+   return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist19.C b/gcc/testsuite/g++.dg/cpp0x/initlist19.C
new file mode 100644 (file)
index 0000000..418cddc
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-options "-std=c++0x" }
+
+void f(double);
+int main()
+{
+  f({{1}});                    // { dg-error "too many braces" }
+  // { dg-error "" "" { target *-*-* } 6 } allow other errors, too
+}