PR c++/88572 - wrong handling of braces on scalar init.
authorWill Wray <wjwray@gmail.com>
Wed, 20 Feb 2019 18:50:32 +0000 (13:50 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 20 Feb 2019 18:50:32 +0000 (13:50 -0500)
* decl.c (reshape_init_r): Allow braces around scalar initializer
within aggregate init.  Reject double braced-init of scalar
variable.

From-SVN: r269045

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/g++.dg/cpp0x/initlist69.C
gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C
gcc/testsuite/g++.dg/init/brace1.C
gcc/testsuite/g++.dg/init/brace2.C
gcc/testsuite/g++.dg/init/union2.C
gcc/testsuite/g++.dg/warn/Wbraces2.C

index bdbbf84..83d3ac9 100644 (file)
@@ -1,3 +1,10 @@
+2019-02-20  will wray  <wjwray@gmail.com>
+
+       PR c++/88572 - wrong handling of braces on scalar init.
+       * decl.c (reshape_init_r): Allow braces around scalar initializer
+       within aggregate init.  Reject double braced-init of scalar
+       variable.
+
 2019-02-20  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/84536
index 8fe547c..c164975 100644 (file)
@@ -6062,15 +6062,23 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
        {
          if (SCALAR_TYPE_P (type))
            {
-             if (cxx_dialect < cxx11
-                 /* Isn't value-initialization.  */
-                 || CONSTRUCTOR_NELTS (stripped_init) > 0)
+             if (cxx_dialect < cxx11)
                {
                  if (complain & tf_error)
                    error ("braces around scalar initializer for type %qT",
                           type);
                  init = error_mark_node;
                }
+             else if (first_initializer_p
+                      || (CONSTRUCTOR_NELTS (stripped_init) > 0
+                          && (BRACE_ENCLOSED_INITIALIZER_P
+                              (CONSTRUCTOR_ELT (stripped_init,0)->value))))
+               {
+                 if (complain & tf_error)
+                   error ("too many braces around scalar initializer"
+                          "for type %qT", type);
+                 init = error_mark_node;
+               }
            }
          else
            maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
index 5d59dfe..7995f59 100644 (file)
@@ -5,12 +5,12 @@ template <typename T>
 struct ca {
   T elem[1];
 
-  ca(const T (&s)[1]): elem{{s}} { }      // { dg-error "braces" }
+  ca(const T (&s)[1]): elem{{s}} { }      // { dg-error "invalid" }
   ca(const T (&s)[1],int): elem({{s}}) { } // { dg-error "paren|invalid" }
   ca(const T (&s)[1],char): elem(s) { }           // { dg-error "array" }
   ca(const T (&s)[1],double): elem{s} { }  // { dg-error "invalid" }
 
-  ca(const T &v): elem{{v}} { }              // { dg-error "braces" }
+  ca(const T &v): elem{{v}} { }              // OK
   ca(const T &v,int): elem{{{v}}} { } // { dg-error "braces" }
   ca(const T &v,char): elem{v} { }    // OK
   ca(const T &v,double): elem({v}) { } // { dg-error "paren" }
index 1850253..f1d1aa5 100644 (file)
@@ -42,7 +42,7 @@ foo ()
                        // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char'" "" { target c++17 } .-1 }
   bar ({ 10 });                // { dg-error "cannot convert \[^\n\r]* to 'E'" }
   bar (E { 9 });       // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
-  V v1 = { { 11 } };   // { dg-error "braces around scalar initializer for type 'E'" }
+  V v1 = { { 11 } };   // { dg-error "cannot convert '<brace-enclosed initializer list>' to 'E' in initialization" }
   V v2 = { E { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
   V v3 = { E { 5.0 } };        // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
                        // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char'" "" { target c++17 } .-1 }
@@ -108,7 +108,7 @@ foo2 ()
                        // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char'" "" { target c++17 } .-1 }
   bar ({ 10 });                // { dg-error "cannot convert \[^\n\r]* to 'E'" }
   bar (E { 9 });       // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
-  V v1 = { { 11 } };   // { dg-error "braces around scalar initializer for type 'E'" }
+  V v1 = { { 11 } };   // { dg-error "cannot convert '<brace-enclosed initializer list>' to 'E' in initialization" }
   V v2 = { E { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
   V v3 = { E { 5.0 } };        // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
                        // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char'" "" { target c++17 } .-1 }
@@ -176,7 +176,7 @@ foo3 ()
                        // { dg-error "narrowing conversion of '-4' from 'int' to 'unsigned char'" "" { target c++17 } .-1 }
   bar3 ({ 10 });       // { dg-error "cannot convert \[^\n\r]* to 'E'" }
   bar3 (E { 9 });      // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
-  M v1 = { { 11 } };   // { dg-error "braces around scalar initializer for type 'E'" }
+  M v1 = { { 11 } };   // { dg-error "cannot convert '<brace-enclosed initializer list>' to 'E' in initialization" }
   M v2 = { L { 12 } }; // { dg-error "cannot convert 'int' to 'E' in initialization" "" { target c++14_down } }
   M v3 = { L { 5.0 } };        // { dg-error "cannot convert 'double' to 'E' in initialization" "" { target c++14_down } }
                        // { dg-error "narrowing conversion of '5.0e.0' from 'double' to 'unsigned char'" "" { target c++17 } .-1 }
index a819fa2..a70c22a 100644 (file)
@@ -1,4 +1,5 @@
 // { dg-do compile }
 
-int i[4] = { { 3 } }; // { dg-error "brace" }
+int i[4] = { { 3 } }; // { dg-error "braces" "" { target c++98_only } }
+int j[4] = { { { 3 } } }; // { dg-error "braces" }
 
index e630752..db7085d 100644 (file)
@@ -6,3 +6,4 @@ int a = 2;
 int b = { 2,3 }; // { dg-error "5:scalar object 'b' requires one element in initializer" }
 int c = { { 2 } } ; // { dg-error "braces around scalar initializer" }
 int d = {}; // { dg-error "initializer" "" { target { ! c++11 } } }
+int e = {{}}; // { dg-error "braces around scalar initializer" }
index ac39f60..3a2d93b 100644 (file)
@@ -10,4 +10,5 @@ typedef union
 
 A a = { 0 };
 A b = {{ 0 }};
-A c = {{{ 0 }}};  // { dg-error "braces" }
+A c = {{{ 0 }}};    // { dg-error "braces" "" { target c++98_only } }
+A d = {{{{ 0 }}}};  // { dg-error "braces" }
index 6d54ede..a0da16a 100644 (file)
@@ -2,14 +2,14 @@
 // { dg-options "-Wmissing-braces" }
 int a[2][2] = { 0, 1, 2, 3 };                   // { dg-warning "missing braces" }
 int b[2][2] = { { 0, 1 }, { 2, 3 } };
-int c[2][2] = { { { 0 }, 1 }, { 2, 3 } };       // { dg-error "braces around scalar" }
+int c[2][2] = { { { 0 }, 1 }, { 2, 3 } };       // { dg-error "braces around scalar" "" { target c++98_only } }
 struct S { char s[6]; int i; };
 S d = { "hello", 1 };
 S e = { { "hello" }, 1 };
-S f = { { { "hello" } }, 1 };                   // { dg-error "braces around scalar" }
+S f = { { { "hello" } }, 1 };                   // { dg-error "braces around scalar|invalid conversion"  }
 S g = { 'h', 'e', 'l', 'l', 'o', '\0', 1 };     // { dg-warning "missing braces" }
 struct T { wchar_t s[6]; int i; };
 T i = { L"hello", 1 };
 T j = { { L"hello" }, 1 };
-T k = { { { L"hello" } }, 1 };                  // { dg-error "braces around scalar" }
+T k = { { { L"hello" } }, 1 };                  // { dg-error "braces around scalar|invalid conversion" }
 T l = { L'h', L'e', L'l', L'l', L'o', L'\0', 1 };// { dg-warning "missing braces" }