Fix noexcept for delete expressions.
Using "delete" on a pointer to an incomplete type can't throw.
While I'm here, clean up the signature of the canCalleeThrow() helper.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184810 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index dfdf5ec..836385d 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -790,11 +790,8 @@
return R;
}
-static CanThrowResult canCalleeThrow(Sema &S, const Expr *E,
- const Decl *D,
- bool NullThrows = true) {
- if (!D)
- return NullThrows ? CT_Can : CT_Cannot;
+static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D) {
+ assert(D && "Expected decl");
// See if we can get a function type from the decl somehow.
const ValueDecl *VD = dyn_cast<ValueDecl>(D);
@@ -945,7 +942,9 @@
cast<CXXDeleteExpr>(E)->getOperatorDelete());
if (const RecordType *RT = DTy->getAs<RecordType>()) {
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- CT = mergeCanThrow(CT, canCalleeThrow(*this, E, RD->getDestructor()));
+ const CXXDestructorDecl *DD = RD->getDestructor();
+ if (DD)
+ CT = mergeCanThrow(CT, canCalleeThrow(*this, E, DD));
}
if (CT == CT_Can)
return CT;
diff --git a/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp b/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
index 1f5969d..33388cf 100644
--- a/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
+++ b/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -fms-extensions %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -fms-extensions -Wno-delete-incomplete %s
// expected-no-diagnostics
#define P(e) static_assert(noexcept(e), "expected nothrow")
@@ -91,6 +91,8 @@
void *operator new(__typeof__(sizeof(int)) sz, int) throw();
+struct IncompleteStruct;
+
struct Bad1 {
~Bad1() throw(int);
};
@@ -104,6 +106,7 @@
N(new int);
P(new (0) int);
P(delete (int*)0);
+ P(delete (IncompleteStruct*)0);
N(delete (Bad1*)0);
N(delete (Bad2*)0);
N(S2());