From 7506ab1de576b07067bf3c0acb74f9d80ece7a86 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Tue, 10 May 2011 20:58:30 +0300 Subject: [PATCH] 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. From-SVN: r173626 --- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/class.c | 15 ++++++++----- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/inherit/virtual9.C | 29 +++++++++++++++++++++---- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f7a5683cd0b..aa2d2f51c36 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2011-05-10 Ville Voutilainen + + 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 * cp-tree.def (EXPR_PACK_EXPANSION): Add an operand. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 12db2bcb093..198eca65431 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0d85506a185..e133d9d7da0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-05-10 Ville Voutilainen + + * g++.dg/inherit/virtual9.C: Extend. + 2011-05-10 Michael Meissner PR target/48857 diff --git a/gcc/testsuite/g++.dg/inherit/virtual9.C b/gcc/testsuite/g++.dg/inherit/virtual9.C index d3175e14798..83e04790873 100644 --- a/gcc/testsuite/g++.dg/inherit/virtual9.C +++ b/gcc/testsuite/g++.dg/inherit/virtual9.C @@ -3,6 +3,7 @@ struct B { virtual void f() final {} virtual void g() {} + virtual void x() const {} }; struct B2 @@ -20,7 +21,12 @@ template struct D2 : T void h() override {} // { dg-error "marked override, but does not override" } }; -struct D3 : D +template 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 d2; - D2 d3; + D2 d; + D2 d2; + D3 d3; } -- 2.30.2