Commit c5adc427 by Jason Merrill Committed by Jason Merrill

call.c (implicit_conversion): Handle conversion from initializer-list to scalar.

	* call.c (implicit_conversion): Handle conversion from
	initializer-list to scalar.
	(convert_like_real): Likewise.  Avoid crashing on list
	initialization with bad conversions.
	(can_convert): Use LOOKUP_EXPLICIT.
	(can_convert_arg_bad): Add flags parm.
	* cp-tree.h: Adjust.
	* typeck.c (convert_for_assignment): Pass flags.

From-SVN: r147933
parent eaf4cf4f
2009-05-27 Jason Merrill <jason@redhat.com>
* call.c (implicit_conversion): Handle conversion from
initializer-list to scalar.
(convert_like_real): Likewise. Avoid crashing on list
initialization with bad conversions.
(can_convert): Use LOOKUP_EXPLICIT.
(can_convert_arg_bad): Add flags parm.
* cp-tree.h: Adjust.
* typeck.c (convert_for_assignment): Pass flags.
2009-05-27 Ian Lance Taylor <iant@google.com> 2009-05-27 Ian Lance Taylor <iant@google.com>
* Make-lang.in (g++$(exeext)): Change $(COMPILER) to $(LINKER). * Make-lang.in (g++$(exeext)): Change $(COMPILER) to $(LINKER).
......
...@@ -1400,9 +1400,31 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, ...@@ -1400,9 +1400,31 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
if (conv) if (conv)
return conv; return conv;
if (is_std_init_list (to) && expr if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
&& BRACE_ENCLOSED_INITIALIZER_P (expr)) {
return build_list_conv (to, expr, flags); if (is_std_init_list (to))
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))
{
tree elt;
if (CONSTRUCTOR_NELTS (expr) == 1)
elt = CONSTRUCTOR_ELT (expr, 0)->value;
else
elt = integer_zero_node;
conv = implicit_conversion (to, TREE_TYPE (elt), elt,
c_cast_p, flags);
if (conv)
{
conv->check_narrowing = true;
return conv;
}
}
}
if (expr != NULL_TREE if (expr != NULL_TREE
&& (MAYBE_CLASS_TYPE_P (from) && (MAYBE_CLASS_TYPE_P (from)
...@@ -4669,6 +4691,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, ...@@ -4669,6 +4691,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (convs->bad_p if (convs->bad_p
&& convs->kind != ck_user && convs->kind != ck_user
&& convs->kind != ck_list
&& convs->kind != ck_ambig && convs->kind != ck_ambig
&& convs->kind != ck_ref_bind && convs->kind != ck_ref_bind
&& convs->kind != ck_rvalue && convs->kind != ck_rvalue
...@@ -4748,6 +4771,17 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, ...@@ -4748,6 +4771,17 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
return expr; return expr;
} }
case ck_identity: case ck_identity:
if (BRACE_ENCLOSED_INITIALIZER_P (expr))
{
int nelts = CONSTRUCTOR_NELTS (expr);
if (nelts == 0)
expr = integer_zero_node;
else if (nelts == 1)
expr = CONSTRUCTOR_ELT (expr, 0)->value;
else
gcc_unreachable ();
}
if (type_unknown_p (expr)) if (type_unknown_p (expr))
expr = instantiate_type (totype, expr, complain); expr = instantiate_type (totype, expr, complain);
/* Convert a constant to its underlying value, unless we are /* Convert a constant to its underlying value, unless we are
...@@ -7185,7 +7219,7 @@ tourney (struct z_candidate *candidates) ...@@ -7185,7 +7219,7 @@ tourney (struct z_candidate *candidates)
bool bool
can_convert (tree to, tree from) can_convert (tree to, tree from)
{ {
return can_convert_arg (to, from, NULL_TREE, LOOKUP_NORMAL); return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT);
} }
/* Returns nonzero if ARG (of type FROM) can be converted to TO. */ /* Returns nonzero if ARG (of type FROM) can be converted to TO. */
...@@ -7213,7 +7247,7 @@ can_convert_arg (tree to, tree from, tree arg, int flags) ...@@ -7213,7 +7247,7 @@ can_convert_arg (tree to, tree from, tree arg, int flags)
/* Like can_convert_arg, but allows dubious conversions as well. */ /* Like can_convert_arg, but allows dubious conversions as well. */
bool bool
can_convert_arg_bad (tree to, tree from, tree arg) can_convert_arg_bad (tree to, tree from, tree arg, int flags)
{ {
conversion *t; conversion *t;
void *p; void *p;
...@@ -7222,7 +7256,7 @@ can_convert_arg_bad (tree to, tree from, tree arg) ...@@ -7222,7 +7256,7 @@ can_convert_arg_bad (tree to, tree from, tree arg)
p = conversion_obstack_alloc (0); p = conversion_obstack_alloc (0);
/* Try to perform the conversion. */ /* Try to perform the conversion. */
t = implicit_conversion (to, from, arg, /*c_cast_p=*/false, t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
LOOKUP_NORMAL); flags);
/* Free all the conversions we allocated. */ /* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p); obstack_free (&conversion_obstack, p);
......
...@@ -4191,7 +4191,7 @@ extern tree build_op_call (tree, VEC(tree,gc) **, ...@@ -4191,7 +4191,7 @@ extern tree build_op_call (tree, VEC(tree,gc) **,
extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree); extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree);
extern bool can_convert (tree, tree); extern bool can_convert (tree, tree);
extern bool can_convert_arg (tree, tree, tree, int); extern bool can_convert_arg (tree, tree, tree, int);
extern bool can_convert_arg_bad (tree, tree, tree); extern bool can_convert_arg_bad (tree, tree, tree, int);
extern bool enforce_access (tree, tree, tree); extern bool enforce_access (tree, tree, tree);
extern tree convert_default_arg (tree, tree, tree, int); extern tree convert_default_arg (tree, tree, tree, int);
extern tree convert_arg_to_ellipsis (tree); extern tree convert_arg_to_ellipsis (tree);
......
...@@ -6702,7 +6702,7 @@ convert_for_assignment (tree type, tree rhs, ...@@ -6702,7 +6702,7 @@ convert_for_assignment (tree type, tree rhs,
We allow bad conversions here because by the time we get to this point We allow bad conversions here because by the time we get to this point
we are committed to doing the conversion. If we end up doing a bad we are committed to doing the conversion. If we end up doing a bad
conversion, convert_like will complain. */ conversion, convert_like will complain. */
if (!can_convert_arg_bad (type, rhstype, rhs)) if (!can_convert_arg_bad (type, rhstype, rhs, flags))
{ {
/* When -Wno-pmf-conversions is use, we just silently allow /* When -Wno-pmf-conversions is use, we just silently allow
conversions from pointers-to-members to plain pointers. If conversions from pointers-to-members to plain pointers. If
......
2009-05-27 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/initlist15.C: New.
* g++.dg/cpp0x/initlist16.C: New.
* g++.dg/cpp0x/initlist17.C: New.
2009-05-27 Janne Blomqvist <jb@gcc.gnu.org> 2009-05-27 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/39178 PR fortran/39178
......
// { dg-options "-std=c++0x" }
#include <vector>
#include <typeinfo>
using namespace std;
template< typename ... ArgTypes >
void test( ArgTypes ... args ) {
vector<type_info*> x = { &typeid(ArgTypes)... }; // { dg-error "" }
}
int main()
{
test( 1, 3.14f, 2.78 );
return 0;
}
// { dg-options "-std=c++0x" }
// { dg-do run }
extern "C" void abort();
void f(int i) { if (i != 42) abort(); }
int main()
{
f({42});
return {0};
}
// { dg-options "-std=c++0x" }
void f(int i);
int main()
{
f({42.0}); // { dg-error "narrowing" }
return {1.0}; // { dg-error "narrowing" }
}
...@@ -30,4 +30,4 @@ int main() ...@@ -30,4 +30,4 @@ int main()
return i; return i;
} }
// { dg-error "could not convert" "" { target *-*-* } 28 } // { dg-error "cannot convert" "" { target *-*-* } 28 }
...@@ -29,4 +29,4 @@ int test01() ...@@ -29,4 +29,4 @@ int test01()
return i; return i;
} }
// { dg-error "could not convert" "" { target *-*-* } 27 } // { dg-error "cannot convert" "" { target *-*-* } 27 }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment