diff options
| author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-09-10 23:27:10 +0000 | 
|---|---|---|
| committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-09-10 23:27:10 +0000 | 
| commit | a8bac37bb1141f046286e2f246a4ecc470509a46 (patch) | |
| tree | abda1fd7af4c73835cfd6bc38b320f6efc15dd1e /clang/lib/AST | |
| parent | db76892e72e458030804b9d6d9e2eea16d52f229 (diff) | |
| download | bcm5719-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')
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 26 | 
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:  | 

