Test destructors in delete expressions and of temporaries for throwing.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113664 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sebastian Redl 2010-09-10 23:27:10 +00:00
Родитель 4e6356426f
Коммит 0b34cf7399
2 изменённых файлов: 34 добавлений и 4 удалений

Просмотреть файл

@ -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:

Просмотреть файл

@ -86,9 +86,19 @@ struct S2 {
void *operator new(__typeof__(sizeof(int)) sz, int) throw();
struct Bad1 {
~Bad1() throw(int);
};
struct Bad2 {
void operator delete(void*) throw(int);
};
void implicits() {
N(new int);
P(new (0) int);
P(delete (int*)0);
N(delete (Bad1*)0);
N(delete (Bad2*)0);
N(S2());
P(S2(0, 0));
S2 s;
@ -98,7 +108,7 @@ void implicits() {
P(s - 0);
N(static_cast<int>(s));
P(static_cast<float>(s));
// FIXME: test destructors of temporaries
N(Bad1());
}
struct V {