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" }
+}