On 10/15/24 12:47 AM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk?

OK.

-- >8 --

When unifying two (non-forwarding) reference types, unify immediately
recurses into the reference type without first comparing rvalueness.
(Note that at this point forwarding references have already been
collapsed into non-references by maybe_adjust_types_for_deduction.)

gcc/cp/ChangeLog:

        * pt.cc (unify) <case REFERENCE_TYPE>: Compare rvalueness.

gcc/testsuite/ChangeLog:

        * g++.dg/template/unify12.C: New test.
---
  gcc/cp/pt.cc                            |  3 ++-
  gcc/testsuite/g++.dg/template/unify12.C | 24 ++++++++++++++++++++++++
  2 files changed, 26 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/template/unify12.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index af784a41265..c7cbf6df26c 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -25154,7 +25154,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
        }
case REFERENCE_TYPE:
-      if (!TYPE_REF_P (arg))
+      if (!TYPE_REF_P (arg)
+         || TYPE_REF_IS_RVALUE (parm) != TYPE_REF_IS_RVALUE (arg))
        return unify_type_mismatch (explain_p, parm, arg);
        return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
                    strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
diff --git a/gcc/testsuite/g++.dg/template/unify12.C 
b/gcc/testsuite/g++.dg/template/unify12.C
new file mode 100644
index 00000000000..84e4efb4cd9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/unify12.C
@@ -0,0 +1,24 @@
+// PR c++/116710
+// { dg-do compile { target c++11 } }
+
+template <typename T> struct A : T {};
+
+template <typename T>
+void f(void (*)(T &), typename A<T>::type * = 0);
+
+void f(...);
+
+void g(int &&);
+
+void q() { f(g); } // OK
+
+template<class T>
+struct B { operator B<T&>(); };
+
+template<class T>
+void h(B<T&>);
+
+int main() {
+  B<int&&> b;
+  h(b); // { dg-error "no match" }
+}

Reply via email to