diff options
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 3 | ||||
-rw-r--r-- | test/CodeGenCXX/call-arg-zero-temp.cpp | 23 |
4 files changed, 39 insertions, 5 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 44e5207e53..cfa669dc4b 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -566,10 +566,6 @@ CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, assert(!ClassDecl->hasUserDeclaredCopyConstructor() && "EmitCXXConstructorCall - user declared copy constructor"); const Expr *E = (*ArgBeg); - // FIXME. This may not be correct. But till now, we were skipping - // code gen of trivial copy constructors regardless of their arguments. - if (isa<CXXZeroInitValueExpr>(E)) - return; QualType Ty = E->getType(); llvm::Value *Src = EmitLValue(E).getAddress(); EmitAggregateCopy(This, Src, Ty); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 29ca900ed3..d3d1c61fe9 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -303,6 +303,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::CXXReinterpretCastExprClass: case Expr::CXXConstCastExprClass: return EmitCastLValue(cast<CastExpr>(E)); + case Expr::CXXZeroInitValueExprClass: + return EmitNullInitializationLValue(cast<CXXZeroInitValueExpr>(E)); } } @@ -1313,6 +1315,18 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { } } +LValue CodeGenFunction::EmitNullInitializationLValue( + const CXXZeroInitValueExpr *E) { + QualType Ty = E->getType(); + const llvm::Type *LTy = ConvertTypeForMem(Ty); + llvm::AllocaInst *Alloc = CreateTempAlloca(LTy); + unsigned Align = getContext().getTypeAlign(Ty)/8; + Alloc->setAlignment(Align); + LValue lvalue = LValue::MakeAddr(Alloc, Qualifiers()); + EmitMemSetToZero(lvalue.getAddress(), Ty); + return lvalue; +} + //===--------------------------------------------------------------------===// // Expression Emission //===--------------------------------------------------------------------===// diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 3048257d2c..a32a7eabad 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -817,7 +817,8 @@ public: LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E); LValue EmitConditionalOperatorLValue(const ConditionalOperator *E); LValue EmitCastLValue(const CastExpr *E); - + LValue EmitNullInitializationLValue(const CXXZeroInitValueExpr *E); + llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field, diff --git a/test/CodeGenCXX/call-arg-zero-temp.cpp b/test/CodeGenCXX/call-arg-zero-temp.cpp new file mode 100644 index 0000000000..2c44f69d97 --- /dev/null +++ b/test/CodeGenCXX/call-arg-zero-temp.cpp @@ -0,0 +1,23 @@ +// RUN: clang-cc -triple x86_64-apple-darwin -S %s -o %t-64.s && +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s && +// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s && +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s && +// RUN: true + + +extern "C" int printf(...); + +struct obj{ int a; float b; double d; }; + +void foo(obj o) { + printf("%d %f %f\n", o.a, o.b, o.d); +} + +int main() { + obj o = obj(); + foo(obj()); +} + +// CHECK-LP64: call __Z3foo3obj + +// CHECK-LP32: call __Z3foo3obj |