commit f6d43f1f8f3c233f916025837d246aba9e78fa65 Author: Jason Merrill Date: Mon Jan 27 11:16:14 2014 -0500 PR c++/58812 * call.c (convert_like_real): Give helpful error about excess braces for ck_rvalue of scalar type. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7d6e621..b72f2d4 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5879,9 +5879,11 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, && convs->kind != ck_ambig && (convs->kind != ck_ref_bind || convs->user_conv_p) - && convs->kind != ck_rvalue + && (convs->kind != ck_rvalue + || SCALAR_TYPE_P (totype)) && convs->kind != ck_base) { + bool complained = false; conversion *t = convs; /* Give a helpful error if this is bad because of excess braces. */ @@ -5889,7 +5891,13 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, && SCALAR_TYPE_P (totype) && CONSTRUCTOR_NELTS (expr) > 0 && BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value)) - permerror (loc, "too many braces around initializer for %qT", totype); + { + complained = permerror (loc, "too many braces around initializer " + "for %qT", totype); + while (BRACE_ENCLOSED_INITIALIZER_P (expr) + && CONSTRUCTOR_NELTS (expr) == 1) + expr = CONSTRUCTOR_ELT (expr, 0)->value; + } for (; t ; t = next_conversion (t)) { @@ -5925,9 +5933,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, else if (t->kind == ck_identity) break; } - if (permerror (loc, "invalid conversion from %qT to %qT", - TREE_TYPE (expr), totype) - && fn) + if (!complained) + complained = permerror (loc, "invalid conversion from %qT to %qT", + TREE_TYPE (expr), totype); + if (complained && fn) inform (DECL_SOURCE_LOCATION (fn), "initializing argument %P of %qD", argnum, fn); diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist76.C b/gcc/testsuite/g++.dg/cpp0x/initlist76.C new file mode 100644 index 0000000..ac419dd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist76.C @@ -0,0 +1,5 @@ +// PR c++/58812 +// { dg-require-effective-target c++11 } + +int i; +int&& j{{ i }}; // { dg-error "too many braces" } diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist77.C b/gcc/testsuite/g++.dg/cpp0x/initlist77.C new file mode 100644 index 0000000..49b9079 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist77.C @@ -0,0 +1,10 @@ +// PR c++/58651 +// { dg-require-effective-target c++11 } + +struct A +{ + int i; + A(int j) : i{{j}} {} // { dg-error "too many braces" } +}; + +A a(0);