Re: [PATCH] C++0x, fixes for override/final
At Tue, 10 May 2011 00:46:54 -0400, Jason Merrill wrote: This is breaking an optimization: before this change we don't bother looking for overrides if we've never seen a virtual function with the same name. Just set overrides_found as well as DECL_VINDEX. Ok. Tests still pass. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 12db2bc..ba4378b 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) { + int overrides_found = 0; 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 = 1; +} if (DECL_VIRTUAL_P (decl)) { @@ -2477,11 +2481,11 @@ 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/g++.dg/inherit/virtual9.C b/gcc/testsuite/g++.dg/inherit/virtual9.C index d3175e1..83e0479 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 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() { - D2B d2; - D2B2 d3; + D2B d; + D2B2 d2; + D3B2 d3; }
Re: [PATCH] C++0x, fixes for override/final
Hi! Just small style nits: On Tue, May 10, 2011 at 09:35:42AM +0300, Ville Voutilainen wrote: --- 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) { + int overrides_found = 0; s/int/bool/;s/0/false/;s/1/true/ IMHO. 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 = 1; +} if (DECL_VIRTUAL_P (decl)) { + else if (DECL_FINAL_P (decl)) +error (%q+#D marked final, but is not virtual, decl); + if (DECL_OVERRIDE_P (decl) + !overrides_found) And the above condition is short enough that it could be on one line. +error (%q+#D marked override, but does not override, decl); } Jakub
Re: [PATCH] C++0x, fixes for override/final
At Tue, 10 May 2011 08:46:02 +0200, Jakub Jelinek wrote: Hi! Just small style nits: s/int/bool/;s/0/false/;s/1/true/ And the above condition is short enough that it could be on one line. Ok. Tests still pass. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 12db2bc..94a339d 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/g++.dg/inherit/virtual9.C b/gcc/testsuite/g++.dg/inherit/virtual9.C index d3175e1..83e0479 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 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() { - D2B d2; - D2B2 d3; + D2B d; + D2B2 d2; + D3B2 d3; }
Re: [PATCH] C++0x, fixes for override/final
Applied. Jason