aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2010-06-03 20:39:03 +0000
committerEli Friedman <eli.friedman@gmail.com>2010-06-03 20:39:03 +0000
commit5ed9b93c596c3926b6680b47de28c8ff6a8ff4b7 (patch)
tree5824a0fe1a9f4dbcf0d811bf9d6e335effedcb3d /lib/Sema/SemaExprCXX.cpp
parent0b29227012aacb1ae42277b0a63d28acb1b35270 (diff)
Make sure to check the accessibility of and mark the destructor for the
operand of a throw expression. Fixes PR7281. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105408 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r--lib/Sema/SemaExprCXX.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 203bc358a7..da64c4824b 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -458,11 +458,28 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
return true;
E = Res.takeAs<Expr>();
+ // If the exception has class type, we need additional handling.
+ const RecordType *RecordTy = Ty->getAs<RecordType>();
+ if (!RecordTy)
+ return false;
+ CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+
// If we are throwing a polymorphic class type or pointer thereof,
// exception handling will make use of the vtable.
- if (const RecordType *RecordTy = Ty->getAs<RecordType>())
- MarkVTableUsed(ThrowLoc, cast<CXXRecordDecl>(RecordTy->getDecl()));
-
+ MarkVTableUsed(ThrowLoc, RD);
+
+ // If the class has a non-trivial destructor, we must be able to call it.
+ if (RD->hasTrivialDestructor())
+ return false;
+
+ CXXDestructorDecl *Destructor =
+ const_cast<CXXDestructorDecl*>(RD->getDestructor(Context));
+ if (!Destructor)
+ return false;
+
+ MarkDeclarationReferenced(E->getExprLoc(), Destructor);
+ CheckDestructorAccess(E->getExprLoc(), Destructor,
+ PDiag(diag::err_access_dtor_temp) << Ty);
return false;
}