aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Wray <wjwray@gmail.com>2019-02-20 13:50:32 -0500
committerJason Merrill <jason@gcc.gnu.org>2019-02-20 13:50:32 -0500
commitcb13308543771f56bbc932933b9ec7bbb95d37ac (patch)
tree99ccbbc756b3caee0a6e8b12607a4867d33e25f0
parent990525f659db023bbcaf8d313916e4533843c664 (diff)
downloadgcc-cb13308543771f56bbc932933b9ec7bbb95d37ac.zip
gcc-cb13308543771f56bbc932933b9ec7bbb95d37ac.tar.gz
gcc-cb13308543771f56bbc932933b9ec7bbb95d37ac.tar.bz2
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. From-SVN: r269045
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist69.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C6
-rw-r--r--gcc/testsuite/g++.dg/init/brace1.C3
-rw-r--r--gcc/testsuite/g++.dg/init/brace2.C1
-rw-r--r--gcc/testsuite/g++.dg/init/union2.C3
-rw-r--r--gcc/testsuite/g++.dg/warn/Wbraces2.C6
8 files changed, 31 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bdbbf84..83d3ac9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 8fe547c..c164975 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist69.C b/gcc/testsuite/g++.dg/cpp0x/initlist69.C
index 5d59dfe..7995f59 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist69.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist69.C
@@ -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" }
diff --git a/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C
index 1850253..f1d1aa5 100644
--- a/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C
+++ b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C
@@ -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 }
diff --git a/gcc/testsuite/g++.dg/init/brace1.C b/gcc/testsuite/g++.dg/init/brace1.C
index a819fa2..a70c22a 100644
--- a/gcc/testsuite/g++.dg/init/brace1.C
+++ b/gcc/testsuite/g++.dg/init/brace1.C
@@ -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" }
diff --git a/gcc/testsuite/g++.dg/init/brace2.C b/gcc/testsuite/g++.dg/init/brace2.C
index e6307525f..db7085d 100644
--- a/gcc/testsuite/g++.dg/init/brace2.C
+++ b/gcc/testsuite/g++.dg/init/brace2.C
@@ -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" }
diff --git a/gcc/testsuite/g++.dg/init/union2.C b/gcc/testsuite/g++.dg/init/union2.C
index ac39f60..3a2d93b 100644
--- a/gcc/testsuite/g++.dg/init/union2.C
+++ b/gcc/testsuite/g++.dg/init/union2.C
@@ -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" }
diff --git a/gcc/testsuite/g++.dg/warn/Wbraces2.C b/gcc/testsuite/g++.dg/warn/Wbraces2.C
index 6d54ede..a0da16a 100644
--- a/gcc/testsuite/g++.dg/warn/Wbraces2.C
+++ b/gcc/testsuite/g++.dg/warn/Wbraces2.C
@@ -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" }