diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-18 04:13:32 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-18 04:13:32 +0000 |
commit | 213d70b58b4f48050c3e545ce1bd4b0ec3af74be (patch) | |
tree | 9661e582f190ec53f160cc5d852bd6467a49f92c /lib/Sema/SemaExprCXX.cpp | |
parent | 7d5088aa52d6e32b309ad0af32ea520ddbc5f953 (diff) |
Diagnose uses of deleted destructors and inaccessible defaulted destructors.
We had two separate issues here: firstly, varions functions were assuming that
they did not need to perform semantic checks on trivial destructors (this is
not true in C++11, where a trivial destructor can nonetheless be private or
deleted), and a bunch of DiagnoseUseOfDecl calls were missing for uses of
destructors.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150866 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index ca8411918a..74bac67140 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -637,8 +637,8 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, if (isPointer) return Owned(E); - // If the class has a non-trivial destructor, we must be able to call it. - if (RD->hasTrivialDestructor()) + // If the class has a destructor, we must be able to call it. + if (RD->hasIrrelevantDestructor()) return Owned(E); CXXDestructorDecl *Destructor @@ -649,6 +649,7 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, MarkFunctionReferenced(E->getExprLoc(), Destructor); CheckDestructorAccess(E->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_exception) << Ty); + DiagnoseUseOfDecl(Destructor, E->getExprLoc()); return Owned(E); } @@ -1318,6 +1319,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, CheckDestructorAccess(StartLoc, dtor, PDiag(diag::err_access_dtor) << Context.getBaseElementType(AllocType)); + DiagnoseUseOfDecl(dtor, StartLoc); } } @@ -2064,7 +2066,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, UsualArrayDeleteWantsSize = (OperatorDelete->getNumParams() == 2); } - if (!PointeeRD->hasTrivialDestructor()) + if (!PointeeRD->hasIrrelevantDestructor()) if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { MarkFunctionReferenced(StartLoc, const_cast<CXXDestructorDecl*>(Dtor)); @@ -4309,23 +4311,28 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { } // That should be enough to guarantee that this type is complete. - // If it has a trivial destructor, we can avoid the extra copy. CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - if (RD->isInvalidDecl() || RD->hasTrivialDestructor()) + if (RD->isInvalidDecl() || RD->isDependentContext()) return Owned(E); - CXXDestructorDecl *Destructor = LookupDestructor(RD); - CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor); if (Destructor) { MarkFunctionReferenced(E->getExprLoc(), Destructor); CheckDestructorAccess(E->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_temp) << E->getType()); + DiagnoseUseOfDecl(Destructor, E->getExprLoc()); + } + + // If destructor is trivial, we can avoid the extra copy. + if (Destructor->isTrivial()) + return Owned(E); + if (Destructor) // We need a cleanup, but we don't need to remember the temporary. ExprNeedsCleanups = true; - } + + CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor); return Owned(CXXBindTemporaryExpr::Create(Context, Temp, E)); } |