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 | 91a3d27ec0a586e5068df28b026d7e6cba626488 (patch) | |
| tree | 58016680ebcc82440c269bf7a71f06f82b7a2419 /clang/lib | |
| parent | d83e3e7750f29c1e2dde2d1e48c2d74861cd3cd6 (diff) | |
| download | bcm5719-llvm-91a3d27ec0a586e5068df28b026d7e6cba626488.tar.gz bcm5719-llvm-91a3d27ec0a586e5068df28b026d7e6cba626488.zip | |
Make sure to check the accessibility of and mark the destructor for the
operand of a throw expression. Fixes PR7281.
llvm-svn: 105408
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 203bc358a71..da64c4824b5 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/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; } |

