aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGCXX.cpp3
-rw-r--r--lib/Sema/SemaDeclCXX.cpp4
-rw-r--r--test/CodeGenCXX/copy-constructor-elim-2.cpp7
3 files changed, 14 insertions, 0 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 7b9ee20aba..b0f23af820 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -590,6 +590,9 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,
Arg = ICE->getSubExpr();
}
+ if (const CXXFunctionalCastExpr *FCE = dyn_cast<CXXFunctionalCastExpr>(Arg))
+ Arg = FCE->getSubExpr();
+
if (const CXXBindTemporaryExpr *BindExpr =
dyn_cast<CXXBindTemporaryExpr>(Arg))
Arg = BindExpr->getSubExpr();
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index b70b0dccb7..f29300e4ac 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3793,6 +3793,8 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
if (ICE->getCastKind() == CastExpr::CK_NoOp)
E = ICE->getSubExpr();
+ if (CXXFunctionalCastExpr *FCE = dyn_cast<CXXFunctionalCastExpr>(E))
+ E = FCE->getSubExpr();
while (CXXBindTemporaryExpr *BE = dyn_cast<CXXBindTemporaryExpr>(E))
E = BE->getSubExpr();
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
@@ -3803,6 +3805,8 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
Elidable = !CE->getCallReturnType()->isReferenceType();
else if (isa<CXXTemporaryObjectExpr>(E))
Elidable = true;
+ else if (isa<CXXConstructExpr>(E))
+ Elidable = true;
}
return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp
new file mode 100644
index 0000000000..3a06c10ff1
--- /dev/null
+++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct A { int x; A(int); ~A(); };
+A f() { return A(0); }
+// CHECK: define void @_Z1fv
+// CHECK: call void @_ZN1AC1Ei
+// CHECK-NEXT: ret void