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
This commit is contained in:
parent
eaf4cf4fdc
commit
c5adc4275c
10 changed files with 99 additions and 10 deletions
|
@ -1,3 +1,14 @@
|
|||
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>
|
||||
|
||||
* 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,
|
|||
if (conv)
|
||||
return conv;
|
||||
|
||||
if (is_std_init_list (to) && expr
|
||||
&& BRACE_ENCLOSED_INITIALIZER_P (expr))
|
||||
return build_list_conv (to, expr, flags);
|
||||
if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
|
||||
{
|
||||
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
|
||||
&& (MAYBE_CLASS_TYPE_P (from)
|
||||
|
@ -4669,6 +4691,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
|
||||
if (convs->bad_p
|
||||
&& convs->kind != ck_user
|
||||
&& convs->kind != ck_list
|
||||
&& convs->kind != ck_ambig
|
||||
&& convs->kind != ck_ref_bind
|
||||
&& convs->kind != ck_rvalue
|
||||
|
@ -4748,6 +4771,17 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
return expr;
|
||||
}
|
||||
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))
|
||||
expr = instantiate_type (totype, expr, complain);
|
||||
/* Convert a constant to its underlying value, unless we are
|
||||
|
@ -7185,7 +7219,7 @@ tourney (struct z_candidate *candidates)
|
|||
bool
|
||||
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. */
|
||||
|
@ -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. */
|
||||
|
||||
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;
|
||||
void *p;
|
||||
|
@ -7222,7 +7256,7 @@ can_convert_arg_bad (tree to, tree from, tree arg)
|
|||
p = conversion_obstack_alloc (0);
|
||||
/* Try to perform the conversion. */
|
||||
t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
|
||||
LOOKUP_NORMAL);
|
||||
flags);
|
||||
/* Free all the conversions we allocated. */
|
||||
obstack_free (&conversion_obstack, p);
|
||||
|
||||
|
|
|
@ -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 bool can_convert (tree, tree);
|
||||
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 tree convert_default_arg (tree, tree, tree, int);
|
||||
extern tree convert_arg_to_ellipsis (tree);
|
||||
|
|
|
@ -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 are committed to doing the conversion. If we end up doing a bad
|
||||
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
|
||||
conversions from pointers-to-members to plain pointers. If
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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>
|
||||
|
||||
PR fortran/39178
|
||||
|
|
17
gcc/testsuite/g++.dg/cpp0x/initlist15.C
Normal file
17
gcc/testsuite/g++.dg/cpp0x/initlist15.C
Normal file
|
@ -0,0 +1,17 @@
|
|||
// { 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;
|
||||
}
|
12
gcc/testsuite/g++.dg/cpp0x/initlist16.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/initlist16.C
Normal file
|
@ -0,0 +1,12 @@
|
|||
// { 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};
|
||||
}
|
9
gcc/testsuite/g++.dg/cpp0x/initlist17.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/initlist17.C
Normal file
|
@ -0,0 +1,9 @@
|
|||
// { 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()
|
|||
return i;
|
||||
}
|
||||
|
||||
// { dg-error "could not convert" "" { target *-*-* } 28 }
|
||||
// { dg-error "cannot convert" "" { target *-*-* } 28 }
|
||||
|
|
|
@ -29,4 +29,4 @@ int test01()
|
|||
return i;
|
||||
}
|
||||
|
||||
// { dg-error "could not convert" "" { target *-*-* } 27 }
|
||||
// { dg-error "cannot convert" "" { target *-*-* } 27 }
|
||||
|
|
Loading…
Add table
Reference in a new issue