diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-07-26 23:27:24 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-07-26 23:27:24 +0000 |
commit | ef8c79c52200e4f7c32f8ef2744c1557b7f3f3ea (patch) | |
tree | 7c9ea4f14179e0fd2254ab8d0366be8f79db4c13 /lib/Sema/SemaExprCXX.cpp | |
parent | 0cdb55b4347458c898e77d2255df71ebca194c3f (diff) |
Re-fix r136172 so it isn't an error; apparently, some people are fond of their undefined behavior.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136183 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 86a4ecc1fc..94a5bafa7c 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1913,18 +1913,6 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, 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 @@ -1933,11 +1921,20 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, // behavior is undefined. // // Note: a final class cannot be derived from, no issue there - if (!ArrayForm && PointeeRD->isPolymorphic() && - !PointeeRD->hasAttr<FinalAttr>()) { + if (PointeeRD->isPolymorphic() && !PointeeRD->hasAttr<FinalAttr>()) { CXXDestructorDecl *dtor = PointeeRD->getDestructor(); - if (dtor && !dtor->isVirtual()) - Diag(StartLoc, diag::warn_delete_non_virtual_dtor) << PointeeElem; + if (dtor && !dtor->isVirtual()) { + if (PointeeRD->isAbstract()) { + // If the class is abstract, we warn by default, because we're + // sure the code has undefined behavior. + Diag(StartLoc, diag::warn_delete_abstract_non_virtual_dtor) + << PointeeElem; + } else if (!ArrayForm) { + // Otherwise, if this is not an array delete, it's a bit suspect, + // but not necessarily wrong. + Diag(StartLoc, diag::warn_delete_non_virtual_dtor) << PointeeElem; + } + } } } else if (getLangOptions().ObjCAutoRefCount && |