Elidable CXXConstructExpr should inhibit calling destructor for temporary 
that is copied, not the one created. This is because eliding copy constructor 
means that the object that was to be copied will be constructed directly in 
memory the copy would be constructed in.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119044 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zhongxing Xu 2010-11-14 15:23:50 +00:00
Родитель ff624c195e
Коммит 249c9458e2
2 изменённых файлов: 13 добавлений и 11 удалений

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

@ -2579,18 +2579,11 @@ CFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors(BinaryOperator *E) {
return RHSBlock ? RHSBlock : LHSBlock;
}
static bool hasElidableCXXConstructExpr(CXXBindTemporaryExpr *E) {
if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E->getSubExpr()))
if (CE->isElidable())
return true;
return false;
}
CFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors(
CXXBindTemporaryExpr *E, bool BindToTemporary) {
// First add destructors for temporaries in subexpression.
CFGBlock *B = VisitForTemporaryDtors(E->getSubExpr());
if (!BindToTemporary && !hasElidableCXXConstructExpr(E)) {
if (!BindToTemporary) {
// If lifetime of temporary is not prolonged (by assigning to constant
// reference) add destructor for it.
autoCreateBlock();

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

@ -264,11 +264,14 @@ TestCtorInits::TestCtorInits()
// CHECK: Successors (2): B3 B2
// CHECK: [ B5 ]
// CHECK: 1: ~A() (Temporary object destructor)
// CHECK: 2: ~A() (Temporary object destructor)
// CHECK: Predecessors (1): B7
// CHECK: Successors (1): B4
// CHECK: [ B6 ]
// CHECK: 1: ~A() (Temporary object destructor)
// CHECK: 2: ~B() (Temporary object destructor)
// CHECK: 2: ~A() (Temporary object destructor)
// CHECK: 3: ~A() (Temporary object destructor)
// CHECK: 4: ~B() (Temporary object destructor)
// CHECK: Predecessors (1): B7
// CHECK: Successors (1): B4
// CHECK: [ B7 ]
@ -308,11 +311,14 @@ TestCtorInits::TestCtorInits()
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
// CHECK: 1: ~A() (Temporary object destructor)
// CHECK: 2: ~A() (Temporary object destructor)
// CHECK: Predecessors (1): B4
// CHECK: Successors (1): B1
// CHECK: [ B3 ]
// CHECK: 1: ~A() (Temporary object destructor)
// CHECK: 2: ~B() (Temporary object destructor)
// CHECK: 2: ~A() (Temporary object destructor)
// CHECK: 3: ~A() (Temporary object destructor)
// CHECK: 4: ~B() (Temporary object destructor)
// CHECK: Predecessors (1): B4
// CHECK: Successors (1): B1
// CHECK: [ B4 ]
@ -345,7 +351,8 @@ TestCtorInits::TestCtorInits()
// CHECK: Successors (1): B7
// CHECK: [ B9 ]
// CHECK: 1: ~A() (Temporary object destructor)
// CHECK: 2: ~B() (Temporary object destructor)
// CHECK: 2: ~A() (Temporary object destructor)
// CHECK: 3: ~B() (Temporary object destructor)
// CHECK: Predecessors (1): B10
// CHECK: Successors (1): B7
// CHECK: [ B10 ]
@ -385,6 +392,7 @@ TestCtorInits::TestCtorInits()
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
// CHECK: 1: ~A() (Temporary object destructor)
// CHECK: 2: ~A() (Temporary object destructor)
// CHECK: Predecessors (1): B3
// CHECK: Successors (1): B1
// CHECK: [ B3 ]
@ -418,6 +426,7 @@ TestCtorInits::TestCtorInits()
// CHECK: Successors (1): B0
// CHECK: [ B2 ]
// CHECK: 1: ~A() (Temporary object destructor)
// CHECK: 2: ~A() (Temporary object destructor)
// CHECK: Predecessors (1): B3
// CHECK: Successors (1): B1
// CHECK: [ B3 ]