From: Fariborz Jahanian Date: Mon, 30 Jan 2012 23:39:30 +0000 (+0000) Subject: test for a v-table dispatch that consumes an X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3c52d3633707453fbc08898935c45bed16953cfb;p=clang test for a v-table dispatch that consumes an argument. twik to support the test case. // rdar://10444476 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149298 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 0133ad2dbd..8f5fbe656e 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -5816,6 +5816,20 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, messageRef->setAlignment(16); messageRef->setSection("__DATA, __objc_msgrefs, coalesced"); } + + bool requiresnullCheck = false; + if (CGM.getLangOptions().ObjCAutoRefCount && method) + for (ObjCMethodDecl::param_const_iterator i = method->param_begin(), + e = method->param_end(); i != e; ++i) { + const ParmVarDecl *ParamDecl = (*i); + if (ParamDecl->hasAttr()) { + if (!nullReturn.NullBB) + nullReturn.init(CGF, arg0); + requiresnullCheck = true; + break; + } + } + llvm::Value *mref = CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy); @@ -5833,8 +5847,8 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, llvm::PointerType::getUnqual(fnType)); RValue result = CGF.EmitCall(fnInfo, callee, returnSlot, args); - CallArgList CallArgs; - return nullReturn.complete(CGF, result, resultType, CallArgs, 0); + return nullReturn.complete(CGF, result, resultType, formalArgs, + requiresnullCheck ? method : 0); } /// Generate code for a message send expression in the nonfragile abi. diff --git a/test/CodeGenObjC/ns_consume_null_check.m b/test/CodeGenObjC/ns_consume_null_check.m new file mode 100644 index 0000000000..ae9408c333 --- /dev/null +++ b/test/CodeGenObjC/ns_consume_null_check.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fobjc-dispatch-method=mixed -o - %s | FileCheck %s +// rdar://10444476 + +@interface NSObject +- (id) new; +@end + +@interface MyObject : NSObject +- (char)isEqual:(id) __attribute__((ns_consumed)) object; +@end + +MyObject *x; + +void foo() +{ + id obj = [NSObject new]; + [x isEqual : obj]; +} + +// CHECK: [[TMP:%.*]] = alloca i8 +// CHECK: [[FIVE:%.*]] = call i8* @objc_retain +// CHECK-NEXT: [[SIX:%.*]] = bitcast +// CHECK-NEXT: [[SEVEN:%.*]] = icmp eq i8* [[SIX]], null +// CHECK-NEXT: br i1 [[SEVEN]], label [[NULLINIT:%.*]], label [[CALL_LABEL:%.*]] +// CHECK: %msgSend_fn = load i8** getelementptr inbounds +// CHECK-NEXT: [[EIGHT:%.*]] = bitcast i8* %msgSend_fn +// CHECK-NEXT: [[CALL:%.*]] = call signext i8 [[EIGHT]] +// CHECK-NEXT store i8 [[CALL]], i8* [[TMP]] +// CHECK-NEXT br label [[CONT:%.*]] +// CHECK: call void @objc_release(i8* [[FIVE]]) nounwind +// CHECK-NEXT: call void @llvm.memset +// CHECK-NEXT br label [[CONT]]