diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c9219d5b3a5ae0fe0e5ba723a96d8c0526820973..0141c53b617c87e7ac3afac1fa7e7a5bfca1a474 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 0000000000000000000000000000000000000000..bed52d0fa36cd33dc88ce6bc43a31589fd7e1646 --- /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" } +}