]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: covariant reference return types [PR99664]
authorPatrick Palka <ppalka@redhat.com>
Fri, 16 Jul 2021 20:21:10 +0000 (16:21 -0400)
committerPatrick Palka <ppalka@redhat.com>
Fri, 16 Jul 2021 20:21:10 +0000 (16:21 -0400)
This implements the wording changes of CWG 960 which clarifies that two
reference types are covariant only if they're both lvalue references
or both rvalue references.

DR 960
PR c++/99664

gcc/cp/ChangeLog:

* search.c (check_final_overrider): Compare TYPE_REF_IS_RVALUE
when the return types are references.

gcc/testsuite/ChangeLog:

* g++.dg/inherit/covariant23.C: New test.

gcc/cp/search.c
gcc/testsuite/g++.dg/inherit/covariant23.C [new file with mode: 0644]

index af41bfe58352295c411609a309a41dee29e81558..943671acff85045aead153a508c8e7361590b098 100644 (file)
@@ -1948,7 +1948,13 @@ check_final_overrider (tree overrider, tree basefn)
       fail = !INDIRECT_TYPE_P (base_return);
       if (!fail)
        {
-         fail = cp_type_quals (base_return) != cp_type_quals (over_return);
+         if (cp_type_quals (base_return) != cp_type_quals (over_return))
+           fail = 1;
+
+         if (TYPE_REF_P (base_return)
+             && (TYPE_REF_IS_RVALUE (base_return)
+                 != TYPE_REF_IS_RVALUE (over_return)))
+           fail = 1;
 
          base_return = TREE_TYPE (base_return);
          over_return = TREE_TYPE (over_return);
diff --git a/gcc/testsuite/g++.dg/inherit/covariant23.C b/gcc/testsuite/g++.dg/inherit/covariant23.C
new file mode 100644 (file)
index 0000000..b27be15
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/99664
+// { dg-do compile { target c++11 } }
+
+struct Res { };
+
+struct A {
+  virtual Res &&f();
+  virtual Res &g();
+};
+
+struct B : A {
+  Res &f() override; // { dg-error "return type" }
+  Res &&g() override; // { dg-error "return type" }
+};