Author: pete Date: Wed Jan 2 09:25:30 2019 New Revision: 350224 URL: http://llvm.org/viewvc/llvm-project?rev=350224&view=rev Log: Only convert objc messages to alloc to objc_alloc if the receiver is a class.
r348687 converted [Foo alloc] to objc_alloc(Foo). However the objc runtime method only takes a Class, not an arbitrary pointer. This makes sure we are messaging a class before we convert these messages. rdar://problem/46943703 Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp cfe/trunk/test/CodeGenObjC/convert-messages-to-runtime-calls.m Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=350224&r1=350223&r2=350224&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGObjC.cpp (original) +++ cfe/trunk/lib/CodeGen/CGObjC.cpp Wed Jan 2 09:25:30 2019 @@ -370,7 +370,8 @@ static Optional<llvm::Value *> tryGenerateSpecializedMessageSend(CodeGenFunction &CGF, QualType ResultType, llvm::Value *Receiver, const CallArgList& Args, Selector Sel, - const ObjCMethodDecl *method) { + const ObjCMethodDecl *method, + bool isClassMessage) { auto &CGM = CGF.CGM; if (!CGM.getCodeGenOpts().ObjCConvertMessagesToRuntimeCalls) return None; @@ -378,7 +379,8 @@ tryGenerateSpecializedMessageSend(CodeGe auto &Runtime = CGM.getLangOpts().ObjCRuntime; switch (Sel.getMethodFamily()) { case OMF_alloc: - if (Runtime.shouldUseRuntimeFunctionsForAlloc() && + if (isClassMessage && + Runtime.shouldUseRuntimeFunctionsForAlloc() && ResultType->isObjCObjectPointerType()) { // [Foo alloc] -> objc_alloc(Foo) if (Sel.isUnarySelector() && Sel.getNameForSlot(0) == "alloc") @@ -550,7 +552,8 @@ RValue CodeGenFunction::EmitObjCMessageE // Call runtime methods directly if we can. if (Optional<llvm::Value *> SpecializedResult = tryGenerateSpecializedMessageSend(*this, ResultType, Receiver, Args, - E->getSelector(), method)) { + E->getSelector(), method, + isClassMessage)) { result = RValue::get(SpecializedResult.getValue()); } else { result = Runtime.GenerateMessageSend(*this, Return, ResultType, Modified: cfe/trunk/test/CodeGenObjC/convert-messages-to-runtime-calls.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/convert-messages-to-runtime-calls.m?rev=350224&r1=350223&r2=350224&view=diff ============================================================================== --- cfe/trunk/test/CodeGenObjC/convert-messages-to-runtime-calls.m (original) +++ cfe/trunk/test/CodeGenObjC/convert-messages-to-runtime-calls.m Wed Jan 2 09:25:30 2019 @@ -54,7 +54,9 @@ void test2(void* x) { @class A; @interface B + (A*) alloc; -+ (A*)allocWithZone:(void*)zone; ++ (A*) allocWithZone:(void*)zone; +- (A*) alloc; +- (A*) allocWithZone:(void*)zone; - (A*) retain; - (A*) autorelease; @end @@ -79,6 +81,19 @@ A* test_allocWithZone_class_ptr() { return [B allocWithZone:nil]; } +// Only call objc_alloc on a Class, not an instance +// CHECK-LABEL: define {{.*}}void @test_alloc_instance +void test_alloc_instance(A *a) { + // CALLS: {{call.*@objc_alloc}} + // CALLS: {{call.*@objc_allocWithZone}} + // CALLS: {{call.*@objc_msgSend}} + // CALLS: {{call.*@objc_msgSend}} + [A alloc]; + [A allocWithZone:nil]; + [a alloc]; + [a allocWithZone:nil]; +} + // Make sure we get a bitcast on the return type as the // call will return i8* which we have to cast to A* // CHECK-LABEL: define {{.*}}void @test_retain_class_ptr _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits