summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Expr.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-09-10 23:27:10 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-09-10 23:27:10 +0000
commita8bac37bb1141f046286e2f246a4ecc470509a46 (patch)
treeabda1fd7af4c73835cfd6bc38b320f6efc15dd1e /clang/lib/AST/Expr.cpp
parentdb76892e72e458030804b9d6d9e2eea16d52f229 (diff)
downloadbcm5719-llvm-a8bac37bb1141f046286e2f246a4ecc470509a46.tar.gz
bcm5719-llvm-a8bac37bb1141f046286e2f246a4ecc470509a46.zip
Test destructors in delete expressions and of temporaries for throwing.
llvm-svn: 113664
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r--clang/lib/AST/Expr.cpp26
1 files changed, 23 insertions, 3 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 65dafae35e4..c9dae17f808 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1457,11 +1457,32 @@ Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const {
}
case CXXDeleteExprClass: {
- // FIXME: check if destructor might throw
CanThrowResult CT = CanCalleeThrow(
cast<CXXDeleteExpr>(this)->getOperatorDelete());
if (CT == CT_Can)
return CT;
+ const Expr *Arg = cast<CXXDeleteExpr>(this)->getArgument();
+ // Unwrap exactly one implicit cast, which converts all pointers to void*.
+ if (const ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg))
+ Arg = Cast->getSubExpr();
+ if (const PointerType *PT = Arg->getType()->getAs<PointerType>()) {
+ if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>()) {
+ CanThrowResult CT2 = CanCalleeThrow(
+ cast<CXXRecordDecl>(RT->getDecl())->getDestructor());
+ if (CT2 == CT_Can)
+ return CT2;
+ CT = MergeCanThrow(CT, CT2);
+ }
+ }
+ return MergeCanThrow(CT, CanSubExprsThrow(C, this));
+ }
+
+ case CXXBindTemporaryExprClass: {
+ // The bound temporary has to be destroyed again, which might throw.
+ CanThrowResult CT = CanCalleeThrow(
+ cast<CXXBindTemporaryExpr>(this)->getTemporary()->getDestructor());
+ if (CT == CT_Can)
+ return CT;
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
}
@@ -1486,8 +1507,7 @@ Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const {
case ParenListExprClass:
case VAArgExprClass:
case CXXDefaultArgExprClass:
- case CXXBindTemporaryExprClass:
- case CXXExprWithTemporariesClass: // FIXME: this thing calls destructors
+ case CXXExprWithTemporariesClass:
case ObjCIvarRefExprClass:
case ObjCIsaExprClass:
case ShuffleVectorExprClass:
OpenPOWER on IntegriCloud