From: Fariborz Jahanian Date: Wed, 26 Oct 2011 20:53:59 +0000 (+0000) Subject: Objective-c: fix an ir-gen crash where objc messag returns a _Complex X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6c29edaa6fa0bd71c9b1770647a02ae686db87bd;p=clang 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 63f6f2c9f0..4730416dd1 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1325,13 +1325,13 @@ public: /// 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 @@ struct NullReturnState { // 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 0000000000..08246d5824 --- /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]]