diff options
author | Jason Merrill <jason@redhat.com> | 2008-02-12 23:06:03 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2008-02-12 23:06:03 -0500 |
commit | 156d614f906a2a88588408b945668e6190945199 (patch) | |
tree | 9467d9f7fb0d91dccb3d88c71a3a1f1047e02651 /gcc | |
parent | 7f7682fe3dd7d4515f83d2ba93cfb604c57b8446 (diff) | |
download | gcc-156d614f906a2a88588408b945668e6190945199.zip gcc-156d614f906a2a88588408b945668e6190945199.tar.gz gcc-156d614f906a2a88588408b945668e6190945199.tar.bz2 |
re PR c++/34824 (ICE with explicit copy constructor)
PR c++/34824
* call.c (convert_like_real): Pass LOOKUP_ONLYCONVERTING to build_temp
if we're doing conversions to call a user-defined conversion function.
From-SVN: r132282
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/call.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/overload/copy1.C | 20 |
3 files changed, 39 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0fc1c1e..9a832de 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2008-02-12 Jason Merrill <jason@redhat.com> + + PR c++/34824 + * call.c (convert_like_real): Pass LOOKUP_ONLYCONVERTING to build_temp + if we're doing conversions to call a user-defined conversion function. + 2008-02-12 Steven Bosscher <steven@gcc.gnu.org> PR c++/29048 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 745c8e8..71ac859 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4319,6 +4319,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, { tree totype = convs->type; diagnostic_fn_t diagnostic_fn; + int flags; if (convs->bad_p && convs->kind != ck_user @@ -4357,6 +4358,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, { struct z_candidate *cand = convs->cand; tree convfn = cand->fn; + unsigned i; + + /* Set user_conv_p on the argument conversions, so rvalue/base + handling knows not to allow any more UDCs. */ + for (i = 0; i < cand->num_convs; ++i) + cand->convs[i]->user_conv_p = true; expr = build_over_call (cand, LOOKUP_NORMAL); @@ -4454,8 +4461,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* Copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination [is treated as direct-initialization]. [dcl.init] */ - expr = build_temp (expr, totype, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, - &diagnostic_fn); + flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING; + if (convs->user_conv_p) + /* This conversion is being done in the context of a user-defined + conversion, so don't allow any more. */ + flags |= LOOKUP_NO_CONVERSION; + expr = build_temp (expr, totype, flags, &diagnostic_fn); if (diagnostic_fn && fn) diagnostic_fn (" initializing argument %P of %qD", argnum, fn); return build_cplus_new (totype, expr); diff --git a/gcc/testsuite/g++.dg/overload/copy1.C b/gcc/testsuite/g++.dg/overload/copy1.C new file mode 100644 index 0000000..87f8317 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/copy1.C @@ -0,0 +1,20 @@ +// PR c++/34824 + +struct A; + +struct B +{ + B (A const &); // { dg-warning "note" } + B (B &); // { dg-warning "note" } +}; + +struct A +{ + A (B); +}; + +B +f (B const& b) +{ + return b; // { dg-error "" } +} |