Objective-c: fix an ir-gen crash where objc messag returns a _Complex
value and ABI requires return slot to be passed as first
argument to message sent. // rdar://10331109


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143053 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 63f6f2c..4730416 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1325,13 +1325,13 @@
 /// value.
 struct NullReturnState {
   llvm::BasicBlock *NullBB;
-
-  NullReturnState() : NullBB(0) {}
+  llvm::BasicBlock *callBB;
+  NullReturnState() : NullBB(0), callBB(0) {}
 
   void init(CodeGenFunction &CGF, llvm::Value *receiver) {
     // Make blocks for the null-init and call edges.
     NullBB = CGF.createBasicBlock("msgSend.nullinit");
-    llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
+    callBB = CGF.createBasicBlock("msgSend.call");
 
     // Check for a null receiver and, if there is one, jump to the
     // null-init test.
@@ -1351,13 +1351,29 @@
 
     // Emit the null-init block and perform the null-initialization there.
     CGF.EmitBlock(NullBB);
-    assert(result.isAggregate() && "null init of non-aggregate result?");
-    CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
+    if (!resultType->isAnyComplexType()) {
+      assert(result.isAggregate() && "null init of non-aggregate result?");
+      CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
+      // Jump to the continuation block.
+      CGF.EmitBlock(contBB);
+      return result;
+    }
 
-    // Jump to the continuation block.
+    // _Complex type
+    // FIXME. Now easy to handle any other scalar type whose result is returned
+    // in memory due to ABI limitations.
     CGF.EmitBlock(contBB);
-
-    return result;
+    CodeGenFunction::ComplexPairTy CallCV = result.getComplexVal();
+    llvm::Type *MemberType = CallCV.first->getType();
+    llvm::Constant *ZeroCV = llvm::Constant::getNullValue(MemberType);
+    // Create phi instruction for scalar complex value.
+    llvm::PHINode *PHIReal = CGF.Builder.CreatePHI(MemberType, 2);
+    PHIReal->addIncoming(ZeroCV, NullBB);
+    PHIReal->addIncoming(CallCV.first, callBB);
+    llvm::PHINode *PHIImag = CGF.Builder.CreatePHI(MemberType, 2);
+    PHIImag->addIncoming(ZeroCV, NullBB);
+    PHIImag->addIncoming(CallCV.second, callBB);
+    return RValue::getComplex(PHIReal, PHIImag);
   }
 };
 
diff --git a/test/CodeGenObjC/complex-double-abi.m b/test/CodeGenObjC/complex-double-abi.m
new file mode 100644
index 0000000..08246d5
--- /dev/null
+++ b/test/CodeGenObjC/complex-double-abi.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-apple-macosx10.7.2 %s -o - | FileCheck %s 
+// rdar://10331109
+
+@interface CNumber
+- (double _Complex)sum;
+@end
+
+double _Complex foo(CNumber *x) {
+  return [x sum];
+}
+
+// CHECK: [[T4:%.*]] = phi double [ 0.000000e+00, [[NULLINIT:%.*]] ], [ [[R1:%.*]], [[MSGCALL:%.*]] ]
+// CHECK: [[T5:%.*]] = phi double [ 0.000000e+00, [[NULLINIT:%.*]] ], [ [[I1:%.*]], [[MSGCALL:%.*]] ]
+
+// CHECK: store double [[T4]]
+// CHECK: store double [[T5]]