From c0c26c6996c1a08ec2d218fbdf94955177030223 Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 13 Feb 2008 04:06:03 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132282 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/call.c | 15 +++++++++++++-- gcc/testsuite/g++.dg/overload/copy1.C | 20 ++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/copy1.C 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 + + 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 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 "" } +} -- 2.7.4