PR c++/7302
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Aug 2007 15:08:24 +0000 (15:08 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Aug 2007 15:08:24 +0000 (15:08 +0000)
        * 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

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wnvdtor-2.C [new file with mode: 0644]

index 50ba76f..8b582c6 100644 (file)
@@ -1,3 +1,7 @@
+2007-08-20  Pawel Sikora  <pluto@pld-linux.org>
+
+        * doc/invoke.texi (-Wnon-virtual-dtor): Update documentation.
+
 2007-08-20  David Edelsohn  <edelsohn@gnu.org>
 
        * dwarf2out.c (text_section_used): Move declaration outside ifdef
index 566b80b..f6ddb5e 100644 (file)
@@ -1,3 +1,9 @@
+2007-08-20  Pawel Sikora  <pluto@pld-linux.org>
+
+       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  <rguenther@suse.de>
 
        PR c++/22369
index f41033c..07dc954 100644 (file)
@@ -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);
index 3815e59..73d4966 100644 (file)
@@ -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
index 08a9c43..c94e48b 100644 (file)
@@ -1,3 +1,7 @@
+2007-03-20  Pawel Sikora  <pluto@pld-linux.org>
+
+        * g++.dg/warn/Wnvdtor-2.C: New testcase.
+
 2007-08-20  Dorit Nuzman  <dorit@il.ibm.com>
 
        * 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 (file)
index 0000000..cd078ac
--- /dev/null
@@ -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;
+};