Fix nested lifetime extension when a std::initializer_list member is
initialized during aggregate initialization of the surrounding structure. llvm-svn: 185117
This commit is contained in:
parent
5c5e6179a0
commit
8d7f11da50
|
@ -5348,13 +5348,15 @@ static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD) {
|
|||
I != E; ++I) {
|
||||
if (I->isUnnamedBitfield())
|
||||
continue;
|
||||
Expr *SubInit = ILE->getInit(Index);
|
||||
if (I->getType()->isReferenceType())
|
||||
performReferenceExtension(ILE->getInit(Index), ExtendingD);
|
||||
else if (isa<InitListExpr>(ILE->getInit(Index)))
|
||||
performReferenceExtension(SubInit, ExtendingD);
|
||||
else if (isa<InitListExpr>(SubInit) ||
|
||||
isa<CXXStdInitializerListExpr>(SubInit))
|
||||
// This may be either aggregate-initialization of a member or
|
||||
// initialization of a std::initializer_list object. Either way,
|
||||
// we should recursively lifetime-extend that initializer.
|
||||
performLifetimeExtension(ILE->getInit(Index), ExtendingD);
|
||||
performLifetimeExtension(SubInit, ExtendingD);
|
||||
++Index;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -395,3 +395,39 @@ namespace partly_constant {
|
|||
// 'il' reference.
|
||||
// CHECK: store {{.*}}* @[[PARTLY_CONSTANT_OUTER]], {{.*}}** @_ZN15partly_constant2ilE, align 8
|
||||
}
|
||||
|
||||
namespace nested {
|
||||
struct A { A(); ~A(); };
|
||||
struct B { const A &a; ~B(); };
|
||||
struct C { std::initializer_list<B> b; ~C(); };
|
||||
void f();
|
||||
// CHECK: define void @_ZN6nested1gEv(
|
||||
void g() {
|
||||
// CHECK: call void @_ZN6nested1AC1Ev(
|
||||
// CHECK-NOT: call
|
||||
// CHECK: call void @_ZN6nested1AC1Ev(
|
||||
// CHECK-NOT: call
|
||||
const C &c { { { A() }, { A() } } };
|
||||
|
||||
// CHECK: call void @_ZN6nested1fEv(
|
||||
// CHECK-NOT: call
|
||||
f();
|
||||
|
||||
// CHECK: call void @_ZN6nested1CD1Ev(
|
||||
// CHECK-NOT: call
|
||||
|
||||
// Destroy B[2] array.
|
||||
// FIXME: This isn't technically correct: reverse construction order would
|
||||
// destroy the second B then the second A then the first B then the first A.
|
||||
// CHECK: call void @_ZN6nested1BD1Ev(
|
||||
// CHECK-NOT: call
|
||||
// CHECK: br
|
||||
|
||||
// CHECK-NOT: call
|
||||
// CHECK: call void @_ZN6nested1AD1Ev(
|
||||
// CHECK-NOT: call
|
||||
// CHECK: call void @_ZN6nested1AD1Ev(
|
||||
// CHECK-NOT: call
|
||||
// CHECK: }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue