aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-02-16 22:45:48 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-02-16 22:45:48 +0000
commit22cfaf512e4f66105fb1f8dd39e0a77787fbdf9b (patch)
tree836dc88bd53e8fb7e71a5aa36b414520341a51c2
parent3336353578a02eb7dc35926c2440577993196e36 (diff)
Elide copy construction in new expressions. PR11757.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150738 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGExprCXX.cpp14
-rw-r--r--test/CodeGenCXX/debug-info-limit.cpp4
-rw-r--r--test/CodeGenCXX/exceptions.cpp15
-rw-r--r--test/CodeGenCXX/new.cpp11
-rw-r--r--test/CodeGenObjCXX/copy.mm2
5 files changed, 16 insertions, 30 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 12bdc7e43f..47e57032e0 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -890,20 +890,6 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
return;
}
- if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)) {
- CXXConstructorDecl *Ctor = CCE->getConstructor();
- // Per C++ [expr.new]p15, if we have an initializer, then we're performing
- // direct initialization. C++ [dcl.init]p5 requires that we
- // zero-initialize storage if there are no user-declared constructors.
- if (!Ctor->getParent()->hasUserDeclaredConstructor() &&
- !Ctor->getParent()->isEmpty())
- CGF.EmitNullInitialization(NewPtr, ElementType);
-
- CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false,
- NewPtr, CCE->arg_begin(), CCE->arg_end());
- return;
- }
- // We have a POD type.
if (!Init)
return;
diff --git a/test/CodeGenCXX/debug-info-limit.cpp b/test/CodeGenCXX/debug-info-limit.cpp
index 75f9271b00..bca887b4db 100644
--- a/test/CodeGenCXX/debug-info-limit.cpp
+++ b/test/CodeGenCXX/debug-info-limit.cpp
@@ -7,8 +7,8 @@ public:
int z;
};
-A *foo () {
- A *a = new A();
+A *foo (A* x) {
+ A *a = new A(*x);
return a;
}
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp
index 2a5cbb4900..079c1e5e72 100644
--- a/test/CodeGenCXX/exceptions.cpp
+++ b/test/CodeGenCXX/exceptions.cpp
@@ -194,12 +194,9 @@ namespace test3 {
// CHECK: [[SAVED0:%.*]] = alloca i8*
// CHECK-NEXT: [[SAVED1:%.*]] = alloca i8*
// CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
- // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 8
- // CHECK: [[TMPACTIVE:%.*]] = alloca i1
// CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
// CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
- // CHECK-NEXT: store i1 false, i1* [[TMPACTIVE]]
// CHECK-NEXT: br i1 [[COND]]
return (cond ?
@@ -209,24 +206,18 @@ namespace test3 {
// CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]]
// CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]]
// CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
- // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[TMP]])
- // CHECK: store i1 true, i1* [[TMPACTIVE]]
- // CHECK-NEXT: invoke void @_ZN5test31AC1ERKS0_([[A]]* [[CAST]], [[A]]* [[TMP]])
- // CHECK: store i1 false, i1* [[CLEANUPACTIVE]]
- // CHECK-NEXT: br label
+ // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[CAST]])
+ // CHECK: br label
// -> cond.end
new(foo(),10.0) A(makeA()) :
- // CHECK: [[MAKE:%.*]] = invoke [[A]]* @_ZN5test38makeAPtrEv()
+ // CHECK: [[MAKE:%.*]] = call [[A]]* @_ZN5test38makeAPtrEv()
// CHECK: br label
// -> cond.end
makeAPtr());
// cond.end:
// CHECK: [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]]
- // CHECK-NEXT: [[ISACTIVE:%.*]] = load i1* [[TMPACTIVE]]
- // CHECK-NEXT: br i1 [[ISACTIVE]]
- // CHECK: invoke void @_ZN5test31AD1Ev
// CHECK: ret [[A]]* [[RESULT]]
// in the EH path:
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index 810a585bca..8d9f641ba1 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -239,3 +239,14 @@ namespace PR11523 {
// CHECK: store i64 -1
NewTy* f() { return new NewTy[2](); }
}
+
+namespace PR11757 {
+ // Make sure we elide the copy construction.
+ struct X { X(); X(const X&); };
+ X* a(X* x) { return new X(X()); }
+ // CHECK: define {{.*}} @_ZN7PR117571aEPNS_1XE
+ // CHECK: [[CALL:%.*]] = call noalias i8* @_Znwm
+ // CHECK-NEXT: [[CASTED:%.*]] = bitcast i8* [[CALL]] to
+ // CHECK-NEXT: call void @_ZN7PR117571XC1Ev({{.*}}* [[CASTED]])
+ // CHECK-NEXT: ret {{.*}} [[CASTED]]
+}
diff --git a/test/CodeGenObjCXX/copy.mm b/test/CodeGenObjCXX/copy.mm
index a61ccd4e5d..9382ee870a 100644
--- a/test/CodeGenObjCXX/copy.mm
+++ b/test/CodeGenObjCXX/copy.mm
@@ -14,8 +14,6 @@ namespace test0 {
// CHECK-NEXT: call noalias i8* @_Znwm(
// CHECK-NEXT: bitcast
// CHECK-NEXT: bitcast
- // CHECK-NEXT: call void @llvm.memset.p0i8.i64(
- // CHECK-NEXT: bitcast
// CHECK-NEXT: bitcast
// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(
// CHECK-NEXT: ret