From: Eli Friedman Date: Thu, 16 Feb 2012 22:45:48 +0000 (+0000) Subject: Elide copy construction in new expressions. PR11757. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=22cfaf512e4f66105fb1f8dd39e0a77787fbdf9b;p=clang Elide copy construction in new expressions. PR11757. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150738 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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(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