From 156d614f906a2a88588408b945668e6190945199 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 12 Feb 2008 23:06:03 -0500 Subject: [PATCH] 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 --- 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 0fc1c1e3c28..9a832de8006 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 745c8e8d50a..71ac85973d9 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 00000000000..87f8317acbe --- /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.30.2