From: Will Wray Date: Wed, 20 Feb 2019 18:50:32 +0000 (-0500) Subject: PR c++/88572 - wrong handling of braces on scalar init. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cb13308543771f56bbc932933b9ec7bbb95d37ac;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bdbbf841275..83d3ac94039 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-02-20 will wray + + 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 PR c++/84536 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8fe547c3ac5..c164975318b 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 5d59dfeaa11..7995f595a47 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist69.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist69.C @@ -5,12 +5,12 @@ template 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 185025308ba..f1d1aa5dfdc 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 '' 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 '' 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 '' 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 a819fa2587c..a70c22a1de3 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 e6307525fbf..db7085d93ab 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 ac39f6092ef..3a2d93b2556 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 6d54ede9b4c..a0da16a285c 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" }