aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-18 04:13:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-18 04:13:32 +0000
commit213d70b58b4f48050c3e545ce1bd4b0ec3af74be (patch)
tree9661e582f190ec53f160cc5d852bd6467a49f92c /lib/Sema/SemaExprCXX.cpp
parent7d5088aa52d6e32b309ad0af32ea520ddbc5f953 (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.cpp23
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));
}