-Wdelete-non-virtual-dtor previously controlled two diagnostics: 1)
calling a non-virtual dtor from an abstract class, and 2) calling a
non-virtual dtor from a polymorphic class. 1) is a lot more severe
than 2), since 1) is a guaranteed crash, but 2) is just "code smell".
Previously, projects compiled with -Wall -Wno-delete-non-virtual-dtor,
which is somewhat reasonable, silently crashed on 1).
rdar://
40380564
Differential revision: https://reviews.llvm.org/D56405
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350585
91177308-0d34-0410-b5e6-
96231b3b80d8
def DeleteIncomplete : DiagGroup<"delete-incomplete">;
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
+def DeleteAbstractNonVirtualDtor : DiagGroup<"delete-abstract-non-virtual-dtor",
+ [DeleteNonVirtualDtor]>;
def AbstractFinalClass : DiagGroup<"abstract-final-class">;
def CXX11CompatDeprecatedWritableStr :
"qualify call to silence this warning">;
def warn_delete_abstract_non_virtual_dtor : Warning<
"%select{delete|destructor}0 called on %1 that is abstract but has "
- "non-virtual destructor">, InGroup<DeleteNonVirtualDtor>, ShowInSystemHeader;
+ "non-virtual destructor">, InGroup<DeleteAbstractNonVirtualDtor>, ShowInSystemHeader;
def warn_overloaded_virtual : Warning<
"%q0 hides overloaded virtual %select{function|functions}1">,
InGroup<OverloadedVirtual>, DefaultIgnore;
--- /dev/null
+// RUN: %clang_cc1 %s -verify -DDIAG1
+// RUN: %clang_cc1 %s -verify -DDIAG1 -DDIAG2 -Wdelete-non-virtual-dtor
+// RUN: %clang_cc1 %s -verify -DDIAG1 -Wmost -Wno-delete-non-virtual-dtor
+// RUN: %clang_cc1 %s -verify -Wmost -Wno-delete-abstract-non-virtual-dtor
+
+#ifndef DIAG1
+#ifndef DIAG2
+// expected-no-diagnostics
+#endif
+#endif
+
+struct S1 {
+ ~S1() {}
+ virtual void abs() = 0;
+};
+
+void f1(S1 *s1) { delete s1; }
+#ifdef DIAG1
+// expected-warning@-2 {{delete called on 'S1' that is abstract but has non-virtual destructor}}
+#endif
+
+struct Base {
+ virtual void abs() = 0;
+};
+struct S2 : Base {
+ ~S2() {}
+ void abs() {}
+};
+void f2(S2 *s2) { delete s2; }
+#ifdef DIAG2
+// expected-warning@-2 {{delete called on non-final 'S2' that has virtual functions but non-virtual destructor}}
+#endif