From: Eli Friedman Date: Tue, 25 Jun 2013 01:24:22 +0000 (+0000) Subject: Fix noexcept for delete expressions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=72aa4c431b650800140457636c8481fd965f1534;p=clang 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 dfdf5ec25f..836385d031 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -790,11 +790,8 @@ static CanThrowResult canSubExprsThrow(Sema &S, const Expr *CE) { 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(D); @@ -945,7 +942,9 @@ CanThrowResult Sema::canThrow(const Expr *E) { cast(E)->getOperatorDelete()); if (const RecordType *RT = DTy->getAs()) { const CXXRecordDecl *RD = cast(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 1f5969d493..33388cf310 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 @@ struct S2 { void *operator new(__typeof__(sizeof(int)) sz, int) throw(); +struct IncompleteStruct; + struct Bad1 { ~Bad1() throw(int); }; @@ -104,6 +106,7 @@ void implicits() { 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());