From cb13308543771f56bbc932933b9ec7bbb95d37ac Mon Sep 17 00:00:00 2001 From: Will Wray Date: Wed, 20 Feb 2019 13:50:32 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/decl.c | 14 +++++++++++--- gcc/testsuite/g++.dg/cpp0x/initlist69.C | 4 ++-- gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C | 6 +++--- gcc/testsuite/g++.dg/init/brace1.C | 3 ++- gcc/testsuite/g++.dg/init/brace2.C | 1 + gcc/testsuite/g++.dg/init/union2.C | 3 ++- gcc/testsuite/g++.dg/warn/Wbraces2.C | 6 +++--- 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 + + 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 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 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 '' 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 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" } -- 2.7.4