aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely.gcc@gmail.com>2011-06-04 16:18:36 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2011-06-04 17:18:36 +0100
commit014ab419efc12a59efebd2720d79e1c055675c85 (patch)
tree4ce2195c12b8ddb26d94b2802f6dbe2017ee0eee
parentf90d37ec0c1fbac6a987b546167ba9a26d399c5f (diff)
downloadgcc-014ab419efc12a59efebd2720d79e1c055675c85.zip
gcc-014ab419efc12a59efebd2720d79e1c055675c85.tar.gz
gcc-014ab419efc12a59efebd2720d79e1c055675c85.tar.bz2
invoke.texi: Document -Wdelete-non-virtual-dtor.
* doc/invoke.texi: Document -Wdelete-non-virtual-dtor. c-family: * c.opt: Add -Wdelete-non-virtual-dtor. * c-opts.c (c_common_handle_option): Include it in -Wall. cp: * init.c (build_delete): Warn when deleting type with non-virtual destructor. testsuite: * testsuite/g++.dg/warn/delete-non-virtual-dtor.C: New. From-SVN: r174643
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-opts.c1
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/init.c19
-rw-r--r--gcc/doc/invoke.texi9
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/warn/delete-non-virtual-dtor.C44
9 files changed, 95 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 926e1b8..ddfb4f9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2011-06-04 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * doc/invoke.texi: Document -Wdelete-non-virtual-dtor.
+
2011-06-04 Jakub Jelinek <jakub@redhat.com>
PR target/49281
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 4ddc60d..38a6d55 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+2011-06-02 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * c.opt: Add -Wdelete-non-virtual-dtor.
+ * c-opts.c (c_common_handle_option): Include it in -Wall.
+
2011-05-30 Nathan Froyd <froydnj@gcc.gnu.org>
PR bootstrap/49190
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 3cd3e56..5cf58ac 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -405,6 +405,7 @@ c_common_handle_option (size_t scode, const char *arg, int value,
warn_sign_compare = value;
warn_reorder = value;
warn_cxx0x_compat = value;
+ warn_delnonvdtor = value;
}
cpp_opts->warn_trigraphs = value;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 6fc7278..c4cf4d0 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -331,6 +331,10 @@ Wdeclaration-after-statement
C ObjC Var(warn_declaration_after_statement) Warning
Warn when a declaration is found after a statement
+Wdelete-non-virtual-dtor
+C++ ObjC++ Var(warn_delnonvdtor) Warning
+Warn about deleting polymorphic objects with non-virtual destructors
+
Wdeprecated
C C++ ObjC ObjC++ Var(warn_deprecated) Init(1) Warning
Warn if a deprecated compiler feature, class, method, or field is used
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2e70bc6..48f39f4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2011-06-04 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * init.c (build_delete): Warn when deleting type with non-virtual
+ destructor.
+
2011-06-03 Jakub Jelinek <jakub@redhat.com>
PR c++/49276
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index d92dacc..3b92665 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3421,6 +3421,25 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
}
complete_p = false;
}
+ else if (warn_delnonvdtor && MAYBE_CLASS_TYPE_P (type)
+ && !CLASSTYPE_FINAL (type) && TYPE_POLYMORPHIC_P (type))
+ {
+ tree dtor;
+ dtor = CLASSTYPE_DESTRUCTORS (type);
+ if (!dtor || !DECL_VINDEX (dtor))
+ {
+ if (CLASSTYPE_PURE_VIRTUALS (type))
+ warning (OPT_Wdelete_non_virtual_dtor,
+ "deleting object of abstract class type %qT"
+ " which has non-virtual destructor"
+ " will cause undefined behaviour", type);
+ else
+ warning (OPT_Wdelete_non_virtual_dtor,
+ "deleting object of polymorphic class type %qT"
+ " which has non-virtual destructor"
+ " might cause undefined behaviour", type);
+ }
+ }
}
if (VOID_TYPE_P (type) || !complete_p || !MAYBE_CLASS_TYPE_P (type))
/* Call the builtin operator delete. */
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 585901e..a069042 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -2331,6 +2331,15 @@ Warn when a class seems unusable because all the constructors or
destructors in that class are private, and it has neither friends nor
public static member functions.
+@item -Wdelete-non-virtual-dtor @r{(C++ and Objective-C++ only)}
+@opindex Wdelete-non-virtual-dtor
+@opindex Wno-delete-non-virtual-dtor
+Warn when @samp{delete} is used to destroy an instance of a class which
+has virtual functions and non-virtual destructor. It is unsafe to delete
+an instance of a derived class through a pointer to a base class if the
+base class does not have a virtual destructor. This warning is enabled
+by @option{-Wall}.
+
@item -Wnoexcept @r{(C++ and Objective-C++ only)}
@opindex Wnoexcept
@opindex Wno-noexcept
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fb95911..3063992 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2011-06-04 Jonathan Wakely <jwakely.gcc@gmail.com>
+ * testsuite/g++.dg/warn/delete-non-virtual-dtor.C: New.
+
+2011-06-04 Jonathan Wakely <jwakely.gcc@gmail.com>
+
PR c++/33840
* g++.dg/diagnostic/bitfld2.C: New.
diff --git a/gcc/testsuite/g++.dg/warn/delete-non-virtual-dtor.C b/gcc/testsuite/g++.dg/warn/delete-non-virtual-dtor.C
new file mode 100644
index 0000000..9849b1e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/delete-non-virtual-dtor.C
@@ -0,0 +1,44 @@
+// { dg-options "-std=gnu++0x -Wdelete-non-virtual-dtor" }
+// { dg-do compile }
+
+struct polyBase { virtual void f(); };
+
+void f(polyBase* p, polyBase* arr)
+{
+ delete p; // { dg-warning "non-virtual destructor might" }
+ delete [] arr;
+}
+
+struct polyDerived : polyBase { };
+
+void f(polyDerived* p, polyDerived* arr)
+{
+ delete p; // { dg-warning "non-virtual destructor might" }
+ delete [] arr;
+}
+
+struct absDerived : polyBase { virtual void g() = 0; };
+
+void f(absDerived* p, absDerived* arr)
+{
+ delete p; // { dg-warning "non-virtual destructor will" }
+ delete [] arr;
+}
+
+struct finalDerived final : polyBase { };
+
+void f(finalDerived* p, finalDerived* arr)
+{
+ delete p; // no error for final classes
+ delete [] arr;
+}
+
+struct safeBase { virtual ~safeBase(); };
+struct safeDerived : safeBase { virtual void f(); };
+
+void f(safeDerived* p, safeDerived* arr)
+{
+ delete p; // no error because base has virtual dtor
+ delete [] arr;
+}
+