aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2024-10-15 13:23:17 -0400
committerPatrick Palka <ppalka@redhat.com>2024-10-15 13:23:17 -0400
commit8161c4adea7f1842f9d28633d82e912ebb7a4cf9 (patch)
treef5d161da39c4a640138b1c1df01cd46dcad7365c /gcc
parentbb2bfdb2048aed18ef7dc01b51816a800e83ce54 (diff)
downloadgcc-8161c4adea7f1842f9d28633d82e912ebb7a4cf9.zip
gcc-8161c4adea7f1842f9d28633d82e912ebb7a4cf9.tar.gz
gcc-8161c4adea7f1842f9d28633d82e912ebb7a4cf9.tar.bz2
c++: unifying lvalue vs rvalue (non-forwarding) ref [PR116710]
When unifying two (non-forwarding) reference types, unify immediately recurses into the referenced type without first comparing rvalueness. (Note that at this point forwarding references and other reference parameters have already been stripped to their referenced type by maybe_adjust_types_for_deduction, so this code path applies only to nested reference types.) PR c++/116710 gcc/cp/ChangeLog: * pt.cc (unify) <case REFERENCE_TYPE>: Compare rvalueness. gcc/testsuite/ChangeLog: * g++.dg/template/unify12.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.cc3
-rw-r--r--gcc/testsuite/g++.dg/template/unify12.C24
2 files changed, 26 insertions, 1 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index c9219d5..0141c53 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -25161,7 +25161,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 0000000..bed52d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/unify12.C
@@ -0,0 +1,24 @@
+// PR c++/116710
+// { dg-do compile { target c++11 } }
+
+template<class T> struct A : T {};
+
+template<class 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" }
+}