diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2010-06-03 20:39:03 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2010-06-03 20:39:03 +0000 |
commit | 5ed9b93c596c3926b6680b47de28c8ff6a8ff4b7 (patch) | |
tree | 5824a0fe1a9f4dbcf0d811bf9d6e335effedcb3d /lib/Sema/SemaExprCXX.cpp | |
parent | 0b29227012aacb1ae42277b0a63d28acb1b35270 (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.cpp | 23 |
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; } |