aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-08-20 16:57:37 +0000
committerDouglas Gregor <dgregor@apple.com>2010-08-20 16:57:37 +0000
commit452b7f22d75d1838df72653dcaacbf92b6c34e71 (patch)
treec5288593203233dc98c770fb8adcfe15bc39dd1e
parent0930b6e6c819aa5c871c4cfb7f8f4bb5a15af5af (diff)
Fix a major regression with value-initialization of class types with
trivial default constructors. We're weren't zero-initializing them, which manifested as <rdar://problem/8320532> (a regression in the GCC test suite) and is likely to have caused significant other breakage. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111650 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGExprCXX.cpp8
-rw-r--r--test/CodeGenCXX/value-init.cpp27
2 files changed, 34 insertions, 1 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index eb984d3cbb..8c67b8bba6 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -320,8 +320,14 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
InitType = getContext().getBaseElementType(Array);
const CXXRecordDecl *RD =
cast<CXXRecordDecl>(InitType->getAs<RecordType>()->getDecl());
- if (RD->hasTrivialConstructor())
+ if (RD->hasTrivialConstructor()) {
+ // The constructor is trivial, but we may still need to zero-initialize
+ // the class.
+ if (E->requiresZeroInitialization())
+ EmitNullInitialization(Dest, E->getType());
+
return;
+ }
}
// Code gen optimization to eliminate copy constructor and return
// its first argument instead, if in fact that argument is a temporary
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
index ec1f8263e4..327362836b 100644
--- a/test/CodeGenCXX/value-init.cpp
+++ b/test/CodeGenCXX/value-init.cpp
@@ -67,3 +67,30 @@ namespace test1 {
B();
}
}
+
+namespace ptrmem {
+ struct S {
+ int mem1;
+ int S::*mem2;
+ };
+
+ // CHECK: define i32 @_ZN6ptrmem4testEPNS_1SE
+ int test(S *s) {
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ // CHECK: getelementptr
+ // CHECK: ret
+ return s->*S().mem2;
+ }
+}
+
+namespace zeroinit {
+ struct S { int i; };
+
+ // CHECK: define i32 @_ZN8zeroinit4testEv()
+ int test() {
+ // CHECK: call void @llvm.memset.p0i8.i64
+ // CHECK: getelementptr
+ // CHECK: ret i32
+ return S().i;
+ }
+}