r185117 - Fix nested lifetime extension when a std::initializer_list member is
Richard Smith
richard-llvm at metafoo.co.uk
Thu Jun 27 15:54:33 PDT 2013
Author: rsmith
Date: Thu Jun 27 17:54:33 2013
New Revision: 185117
URL: http://llvm.org/viewvc/llvm-project?rev=185117&view=rev
Log:
Fix nested lifetime extension when a std::initializer_list member is
initialized during aggregate initialization of the surrounding structure.
Modified:
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=185117&r1=185116&r2=185117&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Jun 27 17:54:33 2013
@@ -5348,13 +5348,15 @@ static void performLifetimeExtension(Exp
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;
}
}
Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=185117&r1=185116&r2=185117&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp Thu Jun 27 17:54:33 2013
@@ -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: }
+ }
+}
More information about the cfe-commits
mailing list