From: jason Date: Mon, 20 Aug 2007 15:08:24 +0000 (+0000) Subject: PR c++/7302 X-Git-Tag: upstream/4.9.2~46791 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a37e11205961890d4a52cca73615df79976171b2;p=platform%2Fupstream%2Flinaro-gcc.git PR c++/7302 * cp/class.c (finish_struct_1): Warn when a class has virtual functions and accessible non-virtual destructor. * doc/invoke.texi (-Wnon-virtual-dtor): Update documentation. * g++.dg/warn/Wnvdtor-2.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127649 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 50ba76f..8b582c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2007-08-20 Pawel Sikora + + * doc/invoke.texi (-Wnon-virtual-dtor): Update documentation. + 2007-08-20 David Edelsohn * dwarf2out.c (text_section_used): Move declaration outside ifdef diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 566b80b..f6ddb5e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2007-08-20 Pawel Sikora + + PR c++/7302 + * class.c (finish_struct_1): Warn when a class has virtual + functions and accessible non-virtual destructor. + 2007-08-20 Richard Guenther PR c++/22369 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index f41033c..07dc954 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5120,17 +5120,19 @@ finish_struct_1 (tree t) tree dtor; dtor = CLASSTYPE_DESTRUCTORS (t); - /* Warn only if the dtor is non-private or the class has - friends. */ if (/* An implicitly declared destructor is always public. And, if it were virtual, we would have created it by now. */ !dtor || (!DECL_VINDEX (dtor) - && (!TREE_PRIVATE (dtor) - || CLASSTYPE_FRIEND_CLASSES (t) - || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))))) - warning (0, "%q#T has virtual functions but non-virtual destructor", - t); + && (/* public non-virtual */ + (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor)) + || (/* non-public non-virtual with friends */ + (TREE_PRIVATE (dtor) || TREE_PROTECTED (dtor)) + && (CLASSTYPE_FRIEND_CLASSES (t) + || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))))))) + warning (OPT_Wnon_virtual_dtor, + "%q#T has virtual functions and accessible" + " non-virtual destructor", t); } complete_vars (t); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 3815e59..73d4966 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -2011,9 +2011,10 @@ public static member functions. @item -Wnon-virtual-dtor @r{(C++ only)} @opindex Wnon-virtual-dtor -Warn when a class appears to be polymorphic, thereby requiring a virtual -destructor, yet it declares a non-virtual one. This warning is also -enabled if -Weffc++ is specified. +Warn when a class has virtual functions and accessible non-virtual +destructor, in which case it would be possible but unsafe to delete +an instance of a derived class through a pointer to the base class. +This warning is also enabled if -Weffc++ is specified. @item -Wreorder @r{(C++ only)} @opindex Wreorder diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 08a9c43..c94e48b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-03-20 Pawel Sikora + + * g++.dg/warn/Wnvdtor-2.C: New testcase. + 2007-08-20 Dorit Nuzman * gcc.dg/vect/costmodel/ppc/costmodel-vect-outer-fir.c: Add missing }. diff --git a/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C b/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C new file mode 100644 index 0000000..cd078ac --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C @@ -0,0 +1,54 @@ +// PR c++/7302 +// { dg-do compile } +// { dg-options "-Wnon-virtual-dtor" } + +// Warn when a class has virtual functions and accessible non-virtual +// destructor, in which case it would be possible but unsafe to delete +// an instance of a derived class through a pointer to the base class. + +struct A +{ // { dg-bogus "non-virtual destructor" } +protected: + ~A(); +public: + virtual void f() = 0; +}; + +struct B +{ // { dg-bogus "non-virtual destructor" } +private: + ~B(); +public: + virtual void f() = 0; +}; + +struct C +{ // { dg-warning "non-virtual destructor" } + virtual void f() = 0; +}; + +struct D +{ // { dg-warning "non-virtual destructor" } + ~D(); + virtual void f() = 0; +}; + +struct E; + +struct F +{ // { dg-warning "non-virtual destructor" } +protected: + friend class E; + ~F(); +public: + virtual void f() = 0; +}; + +struct G +{ // { dg-warning "non-virtual destructor" } +private: + friend class E; + ~G(); +public: + virtual void f() = 0; +};