From 8161c4adea7f1842f9d28633d82e912ebb7a4cf9 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 15 Oct 2024 13:23:17 -0400 Subject: [PATCH] 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) : Compare rvalueness. gcc/testsuite/ChangeLog: * g++.dg/template/unify12.C: New test. Reviewed-by: Jason Merrill --- 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 c9219d5b3a5a..0141c53b617c 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 000000000000..bed52d0fa36c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify12.C @@ -0,0 +1,24 @@ +// PR c++/116710 +// { dg-do compile { target c++11 } } + +template struct A : T {}; + +template +void f(void (*)(T &), typename A::type * = 0); + +void f(...); + +void g(int &&); + +void q() { f(g); } // OK + +template +struct B { operator B(); }; + +template +void h(B); + +int main() { + B b; + h(b); // { dg-error "no match" } +} -- 2.47.2