aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-04-28 18:53:58 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-04-28 18:53:58 +0000
commit3b4d490b09347e0b68ec0511ddfae79dfaba77a6 (patch)
tree2422ff73708becc504c68743a16f55d37829925a
parentf8b1771677743d24c7391305cad8853c513ec0f8 (diff)
When value-initializing the elements of an array not not included in the initializer make sure
that a non-trivial C++ constructor gets called. Fixes rdar://9347552 & http://llvm.org/PR9801 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130421 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGExprAgg.cpp10
-rw-r--r--test/CodeGenCXX/value-init.cpp41
2 files changed, 50 insertions, 1 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 53bc58b69c..457e44d086 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -622,6 +622,13 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();
+ bool hasNonTrivialCXXConstructor = false;
+ if (CGF.getContext().getLangOptions().CPlusPlus)
+ if (const RecordType *RT = ElementType->getAs<RecordType>()) {
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ hasNonTrivialCXXConstructor = !RD->hasTrivialConstructor();
+ }
+
// FIXME: were we intentionally ignoring address spaces and GC attributes?
for (uint64_t i = 0; i != NumArrayElements; ++i) {
@@ -629,7 +636,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
// then we're done.
if (i == NumInitElements &&
Dest.isZeroed() &&
- CGF.getTypes().isZeroInitializable(ElementType))
+ CGF.getTypes().isZeroInitializable(ElementType) &&
+ !hasNonTrivialCXXConstructor)
break;
llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
index 188c8f5a14..890b144de3 100644
--- a/test/CodeGenCXX/value-init.cpp
+++ b/test/CodeGenCXX/value-init.cpp
@@ -83,6 +83,47 @@ namespace ptrmem {
}
}
+namespace PR9801 {
+
+struct Test {
+ Test() : i(10) {}
+ Test(int i) : i(i) {}
+ int i;
+private:
+ int j;
+};
+
+struct Test2 {
+ Test t;
+};
+
+struct Test3 : public Test { };
+
+// CHECK: define void @_ZN6PR98011fEv
+void f() {
+ // CHECK: call void @_ZN6PR98014TestC1Ei
+ // CHECK: call void @_ZN6PR98014TestC1Ev
+ // CHECK: call void @_ZN6PR98014TestC1Ev
+ Test partial[3] = { 1 };
+
+ // CHECK: call void @_ZN6PR98014TestC1Ev
+ // CHECK: call void @_ZN6PR98014TestC1Ev
+ // CHECK: call void @_ZN6PR98014TestC1Ev
+ Test empty[3] = {};
+
+ // CHECK: call void @_ZN6PR98015Test2C1Ev
+ // CHECK: call void @_ZN6PR98015Test2C1Ev
+ // CHECK: call void @_ZN6PR98015Test2C1Ev
+ Test2 empty2[3] = {};
+
+ // CHECK: call void @_ZN6PR98015Test3C1Ev
+ // CHECK: call void @_ZN6PR98015Test3C1Ev
+ // CHECK: call void @_ZN6PR98015Test3C1Ev
+ Test3 empty3[3] = {};
+}
+
+}
+
namespace zeroinit {
struct S { int i; };