From: Patrick Palka Date: Tue, 15 Oct 2024 17:23:17 +0000 (-0400) Subject: c++: unifying lvalue vs rvalue (non-forwarding) ref [PR116710] X-Git-Tag: basepoints/gcc-16~5187 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8161c4adea7f1842f9d28633d82e912ebb7a4cf9;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c9219d5b3a5..0141c53b617 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 00000000000..bed52d0fa36 --- /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" } +}