]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: unifying lvalue vs rvalue (non-forwarding) ref [PR116710]
authorPatrick Palka <ppalka@redhat.com>
Tue, 15 Oct 2024 17:23:17 +0000 (13:23 -0400)
committerPatrick Palka <ppalka@redhat.com>
Tue, 15 Oct 2024 17:23:17 +0000 (13:23 -0400)
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>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/template/unify12.C [new file with mode: 0644]

index c9219d5b3a5ae0fe0e5ba723a96d8c0526820973..0141c53b617c87e7ac3afac1fa7e7a5bfca1a474 100644 (file)
@@ -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 (file)
index 0000000..bed52d0
--- /dev/null
@@ -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" }
+}