[cfe-commits] r136172 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExprCXX.cpp test/SemaCXX/new-delete.cpp
Eli Friedman
eli.friedman at gmail.com
Tue Jul 26 15:50:18 PDT 2011
Author: efriedma
Date: Tue Jul 26 17:50:18 2011
New Revision: 136172
URL: http://llvm.org/viewvc/llvm-project?rev=136172&view=rev
Log:
Diagnose trying to delete a pointer to an abstract class with a non-virtual destructor. PR10504.
I'm not completely sure the standard allows us to reject this, but if it doesn't, it should. :)
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/new-delete.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=136172&r1=136171&r2=136172&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jul 26 17:50:18 2011
@@ -3406,6 +3406,8 @@
def warn_delete_non_virtual_dtor : Warning<
"delete called on %0 that has virtual functions but non-virtual destructor">,
InGroup<DeleteNonVirtualDtor>, DefaultIgnore;
+def err_delete_abstract_non_virtual_dtor : Error<
+ "cannot delete %0, which is abstract and does not have a virtual destructor">;
def warn_overloaded_virtual : Warning<
"%q0 hides overloaded virtual %select{function|functions}1">,
InGroup<OverloadedVirtual>, DefaultIgnore;
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=136172&r1=136171&r2=136172&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Jul 26 17:50:18 2011
@@ -1913,6 +1913,18 @@
DiagnoseUseOfDecl(Dtor, StartLoc);
}
+ // Deleting an abstract class with a non-virtual destructor is always
+ // undefined per [expr.delete]p3, and leads to strange-looking
+ // linker errors.
+ if (PointeeRD->isAbstract()) {
+ CXXDestructorDecl *dtor = PointeeRD->getDestructor();
+ if (dtor && !dtor->isVirtual()) {
+ Diag(StartLoc, diag::err_delete_abstract_non_virtual_dtor)
+ << PointeeElem;
+ return ExprError();
+ }
+ }
+
// C++ [expr.delete]p3:
// In the first alternative (delete object), if the static type of the
// object to be deleted is different from its dynamic type, the static
@@ -1924,7 +1936,7 @@
if (!ArrayForm && PointeeRD->isPolymorphic() &&
!PointeeRD->hasAttr<FinalAttr>()) {
CXXDestructorDecl *dtor = PointeeRD->getDestructor();
- if (!dtor || !dtor->isVirtual())
+ if (dtor && !dtor->isVirtual())
Diag(StartLoc, diag::warn_delete_non_virtual_dtor) << PointeeElem;
}
Modified: cfe/trunk/test/SemaCXX/new-delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/new-delete.cpp?rev=136172&r1=136171&r2=136172&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/new-delete.cpp (original)
+++ cfe/trunk/test/SemaCXX/new-delete.cpp Tue Jul 26 17:50:18 2011
@@ -409,3 +409,10 @@
void f(A *x) { 1+delete x; } // expected-warning {{deleting pointer to incomplete type}} \
// expected-error {{invalid operands to binary expression}}
}
+
+namespace PR10504 {
+ struct A {
+ virtual void foo() = 0;
+ };
+ void f(A *x) { delete x; } // expected-error {{cannot delete 'PR10504::A', which is abstract and does not have a virtual destructor}}
+}
More information about the cfe-commits
mailing list