Code-gen for CXXZeroInitValueExpr AST passed
as argument to a function call. Removes a FIXME.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84694 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 44e5207..cfa669d 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -566,10 +566,6 @@
       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 29ca900..d3d1c61 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -303,6 +303,8 @@
   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::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 3048257..a32a7ea 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -817,7 +817,8 @@
   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 0000000..2c44f69
--- /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