diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2014-04-03 13:41:55 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2014-04-03 13:41:55 +0000 |
commit | 880a467be7f2b84126e19ea3f4d6872d5a3f1252 (patch) | |
tree | 8b8e9e063ebd4925080cfaaf28f2c840cedb712f /gcc | |
parent | 0886676007c494d1a74efb0512d31f36171f3b0c (diff) | |
download | gcc-880a467be7f2b84126e19ea3f4d6872d5a3f1252.zip gcc-880a467be7f2b84126e19ea3f4d6872d5a3f1252.tar.gz gcc-880a467be7f2b84126e19ea3f4d6872d5a3f1252.tar.bz2 |
invoke.texi (Wnon-virtual-dtor): Adjust documentation.
* doc/invoke.texi (Wnon-virtual-dtor): Adjust documentation.
(Weffc++): Remove Scott's numbering, merge lists and reference
Wnon-virtual-dtor.
c-family/
* c.opt (Wnon-virtual-dtor): Auto set when Weffc++.
cp/
* class.c (accessible_nvdtor_p): New.
(check_bases): Don't check base destructor here ...
(check_bases_and_members): ... check them here. Trigger on
Wnon-virtual-dtor flag.
(finish_struct_1): Use accessible_nvdtor_p.
testsuite/
* g++.dg/warn/Wnvdtor.C: Add non-polymorphic case.
* g++.dg/warn/Wnvdtor-2.C: New.
* g++.dg/warn/Wnvdtor-3.C: New.
* g++.dg/warn/Wnvdtor-4.C: New.
* g++.dg/warn/Weff1.C: Delete.
* g++.old-deja/g++.benjamin/15309-1.C: Delete.
* g++.old-deja/g++.benjamin/15309-2.C: Delete.
From-SVN: r209056
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/c-family/c.opt | 2 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/class.c | 80 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 33 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Weff1.C | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wnvdtor-2.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wnvdtor-3.C | 56 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wnvdtor-4.C | 56 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wnvdtor.C | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.benjamin/15309-1.C | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.benjamin/15309-2.C | 10 |
14 files changed, 235 insertions, 86 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d7eef5..f01c406 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2014-04-03 Nathan Sidwell <nathan@codesourcery.com> + + * doc/invoke.texi (Wnon-virtual-dtor): Adjust documentation. + (Weffc++): Remove Scott's numbering, merge lists and reference + Wnon-virtual-dtor. + + c-family/ + + cp/ + * class.c (accessible_nvdtor_p): New. + (check_bases): Don't check base destructor here ... + (check_bases_and_members): ... check them here. Trigger on + Wnon-virtual-dtor flag. + (finish_struct_1): Use accessible_nvdtor_p. + + testsuite/ + * g++.dg/warn/Wnvdtor.C: Add non-polymorphic case. + * g++.dg/warn/Wnvdtor-2.C: New. + * g++.dg/warn/Wnvdtor-3.C: New. + * g++.dg/warn/Wnvdtor-4.C: New. + * g++.dg/warn/Weff1.C: Delete. + * g++.old-deja/g++.benjamin/15309-1.C: Delete. + * g++.old-deja/g++.benjamin/15309-2.C: Delete. + 2014-04-03 Nick Clifton <nickc@redhat.com> * config/rl78/rl78-expand.md (movqi): Handle (SUBREG (SYMBOL_REF)) diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index c83bf54..e2b0474 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2014-04-03 Nathan Sidwell <nathan@codesourcery.com> + + * c.opt (Wnon-virtual-dtor): Auto set when Weffc++. + 2014-04-02 Marek Polacek <polacek@redhat.com> * c-common.h (c_expand_expr): Remove declaration. diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 7d0a2cd..2abf66c 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -569,7 +569,7 @@ C++ ObjC++ Var(warn_nontemplate_friend) Init(1) Warning Warn when non-templatized friend functions are declared within a template Wnon-virtual-dtor -C++ ObjC++ Var(warn_nonvdtor) Warning +C++ ObjC++ Var(warn_nonvdtor) Warning LangEnabledBy(C++ ObjC++,Weffc++) Warn about non-virtual destructors Wnonnull diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 43094b3..d174767 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2014-04-03 Nathan Sidwell <nathan@codesourcery.com> + + * class.c (accessible_nvdtor_p): New. + (check_bases): Don't check base destructor here ... + (check_bases_and_members): ... check them here. Trigger on + Wnon-virtual-dtor flag. + (finish_struct_1): Use accessible_nvdtor_p. + 2014-04-01 Jason Merrill <jason@redhat.com> * pt.c (process_partial_specialization): Say "not deducible" diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d277e07..1dfcd91 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -149,6 +149,7 @@ static tree *build_base_field (record_layout_info, tree, splay_tree, tree *); static void build_base_fields (record_layout_info, splay_tree, tree *); static void check_methods (tree); static void remove_zero_width_bit_fields (tree); +static bool accessible_nvdtor_p (tree); static void check_bases (tree, int *, int *); static void check_bases_and_members (tree); static tree create_vtable_ptr (tree, tree *); @@ -1476,6 +1477,33 @@ inherit_targ_abi_tags (tree t) mark_type_abi_tags (t, false); } +/* Return true, iff class T has a non-virtual destructor that is + accessible from outside the class heirarchy (i.e. is public, or + there's a suitable friend. */ + +static bool +accessible_nvdtor_p (tree t) +{ + tree dtor = CLASSTYPE_DESTRUCTORS (t); + + /* An implicitly declared destructor is always public. And, + if it were virtual, we would have created it by now. */ + if (!dtor) + return true; + + if (DECL_VINDEX (dtor)) + return false; /* Virtual */ + + if (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor)) + return true; /* Public */ + + if (CLASSTYPE_FRIEND_CLASSES (t) + || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))) + return true; /* Has friends */ + + return false; +} + /* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P, and NO_CONST_ASN_REF_P. Also set flag bits in T based on properties of the bases. */ @@ -1512,13 +1540,6 @@ check_bases (tree t, if (!CLASSTYPE_LITERAL_P (basetype)) CLASSTYPE_LITERAL_P (t) = false; - /* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P - here because the case of virtual functions but non-virtual - dtor is handled in finish_struct_1. */ - if (!TYPE_POLYMORPHIC_P (basetype)) - warning (OPT_Weffc__, - "base class %q#T has a non-virtual destructor", basetype); - /* If the base class doesn't have copy constructors or assignment operators that take const references, then the derived class cannot have such a member automatically @@ -5547,6 +5568,27 @@ check_bases_and_members (tree t) TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t); TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t); + /* Warn if a base of a polymorphic type has an accessible + non-virtual destructor. It is only now that we know the class is + polymorphic. Although a polymorphic base will have a already + been diagnosed during its definition, we warn on use too. */ + if (TYPE_POLYMORPHIC_P (t) && warn_nonvdtor) + { + tree binfo, base_binfo; + unsigned i; + + for (binfo = TYPE_BINFO (t), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + { + tree basetype = TREE_TYPE (base_binfo); + + if (accessible_nvdtor_p (basetype)) + warning (OPT_Wnon_virtual_dtor, + "base class %q#T has accessible non-virtual destructor", + basetype); + } + } + /* If the class has no user-declared constructor, but does have non-static const or reference data members that can never be initialized, issue a warning. */ @@ -6597,25 +6639,11 @@ finish_struct_1 (tree t) /* This warning does not make sense for Java classes, since they cannot have destructors. */ - if (!TYPE_FOR_JAVA (t) && warn_nonvdtor && TYPE_POLYMORPHIC_P (t)) - { - tree dtor; - - dtor = CLASSTYPE_DESTRUCTORS (t); - if (/* An implicitly declared destructor is always public. And, - if it were virtual, we would have created it by now. */ - !dtor - || (!DECL_VINDEX (dtor) - && (/* 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); - } + if (!TYPE_FOR_JAVA (t) && warn_nonvdtor + && TYPE_POLYMORPHIC_P (t) && accessible_nvdtor_p (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 eca4e8f..4bf6866 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -2670,9 +2670,10 @@ the compiler to never throw an exception. @opindex Wnon-virtual-dtor @opindex Wno-non-virtual-dtor Warn when a class has virtual functions and an accessible non-virtual -destructor, in which case it is possible but unsafe to delete -an instance of a derived class through a pointer to the base class. -This warning is also enabled if @option{-Weffc++} is specified. +destructor itself or in a base class, or has in which case it is +possible but unsafe to delete an instance of a derived class through a +pointer to the base class. This warning is automatically enabled if +@option{-Weffc++} is specified. @item -Wreorder @r{(C++ and Objective-C++ only)} @opindex Wreorder @@ -2716,40 +2717,34 @@ The following @option{-W@dots{}} options are not affected by @option{-Wall}. @opindex Weffc++ @opindex Wno-effc++ Warn about violations of the following style guidelines from Scott Meyers' -@cite{Effective C++, Second Edition} book: +@cite{Effective C++} series of books: @itemize @bullet @item -Item 11: Define a copy constructor and an assignment operator for classes +Define a copy constructor and an assignment operator for classes with dynamically-allocated memory. @item -Item 12: Prefer initialization to assignment in constructors. +Prefer initialization to assignment in constructors. @item -Item 14: Make destructors virtual in base classes. +Have @code{operator=} return a reference to @code{*this}. @item -Item 15: Have @code{operator=} return a reference to @code{*this}. +Don't try to return a reference when you must return an object. @item -Item 23: Don't try to return a reference when you must return an object. - -@end itemize - -Also warn about violations of the following style guidelines from -Scott Meyers' @cite{More Effective C++} book: - -@itemize @bullet -@item -Item 6: Distinguish between prefix and postfix forms of increment and +Distinguish between prefix and postfix forms of increment and decrement operators. @item -Item 7: Never overload @code{&&}, @code{||}, or @code{,}. +Never overload @code{&&}, @code{||}, or @code{,}. @end itemize +This option also enables @option{-Wnon-virtual-dtor}, which is also +one of the effective C++ recommendations. + When selecting this option, be aware that the standard library headers do not obey all of these guidelines; use @samp{grep -v} to filter out those warnings. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1ffa4b9..b51d81e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2014-04-03 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/warn/Wnvdtor.C: Add non-polymorphic case. + * g++.dg/warn/Wnvdtor-2.C: New. + * g++.dg/warn/Wnvdtor-3.C: New. + * g++.dg/warn/Wnvdtor-4.C: New. + * g++.dg/warn/Weff1.C: Delete. + * g++.old-deja/g++.benjamin/15309-1.C: Delete. + * g++.old-deja/g++.benjamin/15309-2.C: Delete. + 2014-04-02 Jan Hubicka <hubicka@ucw.cz> PR ipa/60659 diff --git a/gcc/testsuite/g++.dg/warn/Weff1.C b/gcc/testsuite/g++.dg/warn/Weff1.C deleted file mode 100644 index a00dc29..0000000 --- a/gcc/testsuite/g++.dg/warn/Weff1.C +++ /dev/null @@ -1,5 +0,0 @@ -// { dg-options "-Weffc++" } - -struct S {}; -/* Base classes should have virtual destructors. */ -struct T : public S {}; // { dg-warning "" } diff --git a/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C b/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C index d40de3d..de7c74bd 100644 --- a/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C +++ b/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C @@ -6,18 +6,18 @@ // 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" } +struct A { protected: - ~A(); + ~A(); // inaccessible - no warning public: virtual void f() = 0; }; -struct B // { dg-bogus "non-virtual destructor" } +struct B { private: - ~B(); + ~B(); // inaccessible - no warning public: virtual void f() = 0; }; @@ -52,3 +52,6 @@ private: public: virtual void f() = 0; }; + +struct H {}; +struct I : H {}; diff --git a/gcc/testsuite/g++.dg/warn/Wnvdtor-3.C b/gcc/testsuite/g++.dg/warn/Wnvdtor-3.C new file mode 100644 index 0000000..8ec8154 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wnvdtor-3.C @@ -0,0 +1,56 @@ +// { dg-do compile } +// { dg-options "-Weffc++" } + +// 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 +{ +protected: + ~A(); // inaccessible - no warning +public: + virtual void f() = 0; +}; + +struct B +{ +private: + ~B(); // inaccessible - no warning +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; +}; + +struct H {}; +struct I : H {}; diff --git a/gcc/testsuite/g++.dg/warn/Wnvdtor-4.C b/gcc/testsuite/g++.dg/warn/Wnvdtor-4.C new file mode 100644 index 0000000..f63ffdc --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wnvdtor-4.C @@ -0,0 +1,56 @@ +// { dg-do compile } +// { dg-options "-Weffc++ -Wno-non-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 +{ +protected: + ~A(); +public: + virtual void f() = 0; +}; + +struct B +{ +private: + ~B(); +public: + virtual void f() = 0; +}; + +struct C +{ + virtual void f() = 0; +}; + +struct D +{ + ~D(); + virtual void f() = 0; +}; + +struct E; + +struct F +{ +protected: + friend class E; + ~F(); +public: + virtual void f() = 0; +}; + +struct G +{ +private: + friend class E; + ~G(); +public: + virtual void f() = 0; +}; + +struct H {}; +struct I : H {}; diff --git a/gcc/testsuite/g++.dg/warn/Wnvdtor.C b/gcc/testsuite/g++.dg/warn/Wnvdtor.C index b04fdcb..f03cff5 100644 --- a/gcc/testsuite/g++.dg/warn/Wnvdtor.C +++ b/gcc/testsuite/g++.dg/warn/Wnvdtor.C @@ -8,3 +8,4 @@ extern "Java" virtual void bar( void); }; } + diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/15309-1.C b/gcc/testsuite/g++.old-deja/g++.benjamin/15309-1.C deleted file mode 100644 index aa5530f..0000000 --- a/gcc/testsuite/g++.old-deja/g++.benjamin/15309-1.C +++ /dev/null @@ -1,21 +0,0 @@ -// { dg-do assemble } -// { dg-options "-Wnon-virtual-dtor -Weffc++" } -// 981203 bkoz -// g++/15309 - -class bahamian { -public: - bahamian (); - ~bahamian (); -}; - -class miami : public bahamian // { dg-warning "" } // WARNING - -{ -public: - miami (); - ~miami (); -}; - - - - diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/15309-2.C b/gcc/testsuite/g++.old-deja/g++.benjamin/15309-2.C deleted file mode 100644 index 2831797..0000000 --- a/gcc/testsuite/g++.old-deja/g++.benjamin/15309-2.C +++ /dev/null @@ -1,10 +0,0 @@ -// { dg-do assemble } -// { dg-options "-Wnon-virtual-dtor -Weffc++" } -// 981203 bkoz -// g++/15309 - -class bermuda { // { dg-warning "" } // WARNING - -public: - virtual int func1(int); - ~bermuda(); -}; |