re PR c++/40308 (Brace initialization fails for member initializers in constructor for class templates)

PR c++/40308
	PR c++/40311
	* typeck.c (cp_build_modify_expr): Always pass init-lists to the
	conversion code.
	* call.c (implicit_conversion): Allow init-list conversion to scalar
	during direct-initialization, too.  Mark the conversion bad if it
	has too many levels of braces.
	(convert_like_real): And give a helpful error.

From-SVN: r148089
This commit is contained in:
Jason Merrill 2009-06-02 13:02:38 -04:00 committed by Jason Merrill
parent ccafc19b5b
commit 4ea08463a7
7 changed files with 69 additions and 9 deletions

View File

@ -1,4 +1,13 @@
2009-06-01 Jason Merrill <jason@redhat.com>
2009-06-02 Jason Merrill <jason@redhat.com>
PR c++/40308
PR c++/40311
* typeck.c (cp_build_modify_expr): Always pass init-lists to the
conversion code.
* call.c (implicit_conversion): Allow init-list conversion to scalar
during direct-initialization, too. Mark the conversion bad if it
has too many levels of braces.
(convert_like_real): And give a helpful error.
PR c++/40306
PR c++/40307

View File

@ -1406,21 +1406,27 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
return build_list_conv (to, expr, flags);
/* Allow conversion from an initializer-list with one element to a
scalar type if this is copy-initialization. Direct-initialization
would be something like int i({1}), which is invalid. */
if (SCALAR_TYPE_P (to) && CONSTRUCTOR_NELTS (expr) <= 1
&& (flags & LOOKUP_ONLYCONVERTING))
scalar type. */
if (SCALAR_TYPE_P (to))
{
int nelts = CONSTRUCTOR_NELTS (expr);
tree elt;
if (CONSTRUCTOR_NELTS (expr) == 1)
if (nelts == 0)
elt = integer_zero_node;
else if (nelts == 1)
elt = CONSTRUCTOR_ELT (expr, 0)->value;
else
elt = integer_zero_node;
elt = error_mark_node;
conv = implicit_conversion (to, TREE_TYPE (elt), elt,
c_cast_p, flags);
if (conv)
{
conv->check_narrowing = true;
if (BRACE_ENCLOSED_INITIALIZER_P (elt))
/* Too many levels of braces, i.e. '{{1}}'. */
conv->bad_p = true;
return conv;
}
}
@ -4698,6 +4704,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
&& convs->kind != ck_base)
{
conversion *t = convs;
/* Give a helpful error if this is bad because of excess braces. */
if (BRACE_ENCLOSED_INITIALIZER_P (expr)
&& SCALAR_TYPE_P (totype)
&& CONSTRUCTOR_NELTS (expr) > 0
&& BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value))
permerror (input_location, "too many braces around initializer for %qT", totype);
for (; t; t = convs->u.next)
{
if (t->kind == ck_user || !t->bad_p)

View File

@ -6081,8 +6081,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
if (modifycode == INIT_EXPR)
{
if (TREE_CODE (rhs) == CONSTRUCTOR)
if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
/* Do the default thing. */;
else if (TREE_CODE (rhs) == CONSTRUCTOR)
{
/* Compound literal. */
if (! same_type_p (TREE_TYPE (rhs), lhstype))
/* Call convert to generate an error; see PR 11063. */
rhs = convert (lhstype, rhs);

View File

@ -1,5 +1,9 @@
2009-06-02 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/initlist13.C: Remove expected error.
* g++.dg/cpp0x/initlist18.C: New.
* g++.dg/cpp0x/initlist19.C: New.
* g++.dg/cpp0x/auto14.C: New.
2009-06-02 Eric Botcazou <ebotcazou@adacore.com>

View File

@ -2,4 +2,7 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
__complex__ int i ({0}); // { dg-error "cannot convert" }
#include <complex>
__complex__ int i ({0});
std::complex<int> i2 ({0});

View File

@ -0,0 +1,19 @@
// PR c++/40308, 40311
// { dg-do run }
// { dg-options "-std=c++0x" }
template< typename T >
struct test {
test() : data{} {}
T data;
};
int main()
{
test<int> x;
test<int*> y;
int * a = new int{};
int * b = new int{5};
return 0;
}

View File

@ -0,0 +1,8 @@
// { dg-options "-std=c++0x" }
void f(double);
int main()
{
f({{1}}); // { dg-error "too many braces" }
// { dg-error "" "" { target *-*-* } 6 } allow other errors, too
}