Fixes for override/final.
authorVille Voutilainen <ville.voutilainen@gmail.com>
Tue, 10 May 2011 17:58:30 +0000 (20:58 +0300)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 10 May 2011 17:58:30 +0000 (13:58 -0400)
* class.c (check_for_override): Diagnose final on a nonvirtual
member function, diagnose override for a virtual with no matching
override. Don't fiddle around with DECL_VINDEX.

From-SVN: r173626

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/virtual9.C

index f7a5683cd0b2418cb8c8b48acfd30b6ba414d3ba..aa2d2f51c3629c0ca6bb983dd82e22ecae8064dd 100644 (file)
@@ -1,3 +1,10 @@
+2011-05-10  Ville Voutilainen  <ville.voutilainen@gmail.com>
+
+       Fixes for override/final.
+       * class.c (check_for_override): Diagnose final on a nonvirtual
+       member function, diagnose override for a virtual with no matching
+       override. Don't fiddle around with DECL_VINDEX.
+
 2011-05-10  Nathan Froyd  <froydnj@codesourcery.com>
 
         * cp-tree.def (EXPR_PACK_EXPANSION): Add an operand.
index 12db2bcb0931c17aa8d9e976c90380cb9cce6cd2..198eca654315246f2cc3be624b63a044a02e049e 100644 (file)
@@ -2453,6 +2453,7 @@ get_basefndecls (tree name, tree t)
 void
 check_for_override (tree decl, tree ctype)
 {
+  bool overrides_found = false;
   if (TREE_CODE (decl) == TEMPLATE_DECL)
     /* In [temp.mem] we have:
 
@@ -2467,7 +2468,10 @@ check_for_override (tree decl, tree ctype)
     /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
        the error_mark_node so that we know it is an overriding
        function.  */
-    DECL_VINDEX (decl) = decl;
+    {
+      DECL_VINDEX (decl) = decl;
+      overrides_found = true;
+    }
 
   if (DECL_VIRTUAL_P (decl))
     {
@@ -2477,11 +2481,10 @@ check_for_override (tree decl, tree ctype)
       if (DECL_DESTRUCTOR_P (decl))
        TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
     }
-  else if (DECL_OVERRIDE_P (decl))
-    {
-      DECL_VINDEX (decl) = error_mark_node;
-      error ("%q+#D marked override, but does not override", decl);
-    }
+  else if (DECL_FINAL_P (decl))
+    error ("%q+#D marked final, but is not virtual", decl);
+  if (DECL_OVERRIDE_P (decl) && !overrides_found)
+    error ("%q+#D marked override, but does not override", decl);
 }
 
 /* Warn about hidden virtual functions that are not overridden in t.
index 0d85506a18524b3f27d1aaac53e7b98249318492..e133d9d7da001247365963c8f59926729a873766 100644 (file)
@@ -1,3 +1,7 @@
+2011-05-10  Ville Voutilainen  <ville.voutilainen@gmail.com>
+
+       * g++.dg/inherit/virtual9.C: Extend.
+
 2011-05-10  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR target/48857
index d3175e14798ceb72aed14008b866f6a3a3dee4f2..83e04790873f770bb0946af5db1f11681d195d77 100644 (file)
@@ -3,6 +3,7 @@ struct B
 {
   virtual void f() final {}
   virtual void g() {}
+  virtual void x() const {}
 };
 
 struct B2
@@ -20,7 +21,12 @@ template <class T> struct D2 : T
   void h() override {} // { dg-error "marked override, but does not override" }
 };
 
-struct D3 : D
+template <class T> struct D3 : T
+{
+  void h() override {}
+};
+
+struct D4 : D
 {
   void g() {} // { dg-error "virtual function" }
 };
@@ -30,10 +36,25 @@ struct B3
   virtual void f() final final {} // { dg-error "duplicate virt-specifier" }
 };
 
-void g() override {} // { dg-error "virt-specifiers" }
+struct B4
+{
+  void f() final {} // { dg-error "marked final, but is not virtual" }
+};
+
+struct D5 : B
+{
+  void ff() override {} // { dg-error "marked override, but does not override" }
+  virtual void fff() override {} // { dg-error "marked override, but does not override" }
+  virtual void x() override {} // { dg-error "marked override, but does not override" }
+  void g() override;
+};
+
+void D5::g() override {} // { dg-error "not allowed outside a class definition" }
+void g() override {} // { dg-error "not allowed outside a class definition" }
 
 int main()
 {
-  D2<B> d2;
-  D2<B2> d3;
+  D2<B> d;
+  D2<B2> d2;
+  D3<B2> d3;
 }