re PR c++/49267 (Ambiguity with conversion functions "T&" and "T&&", initializing...
authorJason Merrill <jason@redhat.com>
Mon, 5 Sep 2011 04:33:48 +0000 (00:33 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 5 Sep 2011 04:33:48 +0000 (00:33 -0400)
PR c++/49267
PR c++/49458
DR 1328
* call.c (reference_binding): Set rvaluedness_matches_p properly
for reference to function conversion ops.
(compare_ics): Adjust.

From-SVN: r178520

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/rv-conv1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/rv-func3.C [new file with mode: 0644]

index d61f5f782b702e2370bdeac7fa07b169e2bb13df..718bcb3b9856cf0e411efd35fc12ad8e47eb4c12 100644 (file)
@@ -1,5 +1,12 @@
 2011-09-04  Jason Merrill  <jason@redhat.com>
 
+       PR c++/49267
+       PR c++/49458
+       DR 1328
+       * call.c (reference_binding): Set rvaluedness_matches_p properly
+       for reference to function conversion ops.
+       (compare_ics): Adjust.
+
        * class.c (trivial_default_constructor_is_constexpr): Rename from
        synthesized_default_constructor_is_constexpr.
        (type_has_constexpr_default_constructor): Adjust.
index 84212603b1ab5f5f1bb14858e42f8f6518dc43a4..1fa5fc81852e2e58acb12cc9c817472c20abbc73 100644 (file)
@@ -1652,6 +1652,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
        /* The top-level caller requested that we pretend that the lvalue
           be treated as an rvalue.  */
        conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
+      else if (TREE_CODE (rfrom) == REFERENCE_TYPE)
+       /* Handle rvalue reference to function properly.  */
+       conv->rvaluedness_matches_p
+         = (TYPE_REF_IS_RVALUE (rto) == TYPE_REF_IS_RVALUE (rfrom));
       else
        conv->rvaluedness_matches_p 
           = (TYPE_REF_IS_RVALUE (rto) == !is_lvalue);
@@ -7960,13 +7964,13 @@ compare_ics (conversion *ics1, conversion *ics2)
 
   if (ref_conv1 && ref_conv2)
     {
-      if (!ref_conv1->this_p && !ref_conv2->this_p
-         && (TYPE_REF_IS_RVALUE (ref_conv1->type)
-             != TYPE_REF_IS_RVALUE (ref_conv2->type)))
+      if (!ref_conv1->this_p && !ref_conv2->this_p)
        {
-         if (ref_conv1->rvaluedness_matches_p)
+         if (ref_conv1->rvaluedness_matches_p
+             > ref_conv2->rvaluedness_matches_p)
            return 1;
-         if (ref_conv2->rvaluedness_matches_p)
+         if (ref_conv2->rvaluedness_matches_p
+             > ref_conv1->rvaluedness_matches_p)
            return -1;
        }
 
index 2f149c4d42cb0dba2df2d258eab9059fa76e579c..1b465cecaff8aac975b0daef26ebcff12fb4f952 100644 (file)
@@ -1,5 +1,11 @@
 2011-09-04  Jason Merrill  <jason@redhat.com>
 
+       PR c++/49267
+       * g++.dg/cpp0x/rv-conv1.C: New.
+
+       DR 1328
+       * g++.dg/cpp0x/rv-func3.C: New.
+
        * g++.dg/cpp0x/constexpr-default-ctor.C: New.
 
        PR c++/50248
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-conv1.C b/gcc/testsuite/g++.dg/cpp0x/rv-conv1.C
new file mode 100644 (file)
index 0000000..3852991
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/49267
+// { dg-options -std=c++0x }
+
+struct X {
+  operator int&();
+  operator int&&();
+};
+
+int&&x = X();
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-func3.C b/gcc/testsuite/g++.dg/cpp0x/rv-func3.C
new file mode 100644 (file)
index 0000000..8504682
--- /dev/null
@@ -0,0 +1,10 @@
+// DR 1328
+// { dg-options -std=c++0x }
+
+template <class T> struct A {
+  operator T&();  // #1
+  operator T&&(); // #2
+};
+typedef int Fn();
+A<Fn> a;
+Fn&& f = a;