PR c++/34824
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Feb 2008 04:06:03 +0000 (04:06 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Feb 2008 04:06:03 +0000 (04:06 +0000)
        * 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
gcc/cp/call.c
gcc/testsuite/g++.dg/overload/copy1.C [new file with mode: 0644]

index 0fc1c1e..9a832de 100644 (file)
@@ -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
index 745c8e8..71ac859 100644 (file)
@@ -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 (file)
index 0000000..87f8317
--- /dev/null
@@ -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 "" }
+}