зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
4e6356426f
Коммит
0b34cf7399
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче