From: Jonathan Wakely Date: Sat, 4 Jun 2011 16:18:36 +0000 (+0000) Subject: invoke.texi: Document -Wdelete-non-virtual-dtor. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=014ab419efc12a59efebd2720d79e1c055675c85;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 926e1b8f1fd..ddfb4f95a1a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2011-06-04 Jonathan Wakely + + * doc/invoke.texi: Document -Wdelete-non-virtual-dtor. + 2011-06-04 Jakub Jelinek PR target/49281 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 4ddc60d9cc5..38a6d5560ba 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2011-06-02 Jonathan Wakely + + * c.opt: Add -Wdelete-non-virtual-dtor. + * c-opts.c (c_common_handle_option): Include it in -Wall. + 2011-05-30 Nathan Froyd PR bootstrap/49190 diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 3cd3e56ff3a..5cf58acd62d 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 6fc72789689..c4cf4d083d2 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 2e70bc6d141..48f39f4da21 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2011-06-04 Jonathan Wakely + + * init.c (build_delete): Warn when deleting type with non-virtual + destructor. + 2011-06-03 Jakub Jelinek PR c++/49276 diff --git a/gcc/cp/init.c b/gcc/cp/init.c index d92dacce888..3b926657c5e 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 585901e29da..a0690426fd1 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 fb95911a932..30639929fb6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-06-04 Jonathan Wakely + + * testsuite/g++.dg/warn/delete-non-virtual-dtor.C: New. + 2011-06-04 Jonathan Wakely PR c++/33840 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 00000000000..9849b1edfa8 --- /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; +} +