invoke.texi (Wnon-virtual-dtor): Adjust documentation.
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 3 Apr 2014 13:41:55 +0000 (13:41 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 3 Apr 2014 13:41:55 +0000 (13:41 +0000)
* 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

14 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c.opt
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Weff1.C [deleted file]
gcc/testsuite/g++.dg/warn/Wnvdtor-2.C
gcc/testsuite/g++.dg/warn/Wnvdtor-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wnvdtor-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wnvdtor.C
gcc/testsuite/g++.old-deja/g++.benjamin/15309-1.C [deleted file]
gcc/testsuite/g++.old-deja/g++.benjamin/15309-2.C [deleted file]

index 5d7eef5e68e1656888bc7391ca4c0e942cec4677..f01c4066f883bf4c152c428b5cf74af645c45343 100644 (file)
@@ -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))
index c83bf5497dab261a7f0eeed7d14671379f24d0cc..e2b047482c55abc67132011fc3152c59911def68 100644 (file)
@@ -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.
index 7d0a2cd4ac6e6605cc3b2e2ade495c09fc1c8cd1..2abf66cb781635e3bfa7b405652e02209a84c12b 100644 (file)
@@ -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
index 43094b38c8cce04eb51c3ccf25b03034cf099e25..d174767edd779f54a510f9062d5869bf62f6ed8d 100644 (file)
@@ -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"
index d277e0758eea42f017b2dcaeba8328dc1d9ae381..1dfcd918b30da4400a6112b3adad94b62c8d8681 100644 (file)
@@ -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);
 
index eca4e8f1afa08fc9ef8b77f08ec0709d56aceb55..4bf686660deb98b8f3c8395b63519581b8b87e7f 100644 (file)
@@ -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.
index 1ffa4b96ba6544baa0834fef68d8509cb33c66d1..b51d81ed943dcd11c67155410f27a88238ae9380 100644 (file)
@@ -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 (file)
index a00dc29..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-// { dg-options "-Weffc++" }
-
-struct S {};
-/* Base classes should have virtual destructors.  */
-struct T : public S {}; // { dg-warning "" }
index d40de3d7c1a5578dc8f9467818963d11efefe07b..de7c74bdfafb82936e1a9b0893264cfec8fae2db 100644 (file)
@@ -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 (file)
index 0000000..8ec8154
--- /dev/null
@@ -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 (file)
index 0000000..f63ffdc
--- /dev/null
@@ -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 {};
index b04fdcbe6b1fdcbfbe3cb7e2ceef8be8545f2665..f03cff5b31ced686c5d1a03aa43907c613d584b9 100644 (file)
@@ -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 (file)
index aa5530f..0000000
+++ /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 (file)
index 2831797..0000000
+++ /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();
-};