summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorPete Cooper <peter_cooper@apple.com>2019-01-02 17:25:30 +0000
committerPete Cooper <peter_cooper@apple.com>2019-01-02 17:25:30 +0000
commitde0a8d37a017d39a0a6cfa99ea71a47bf6bb0cc4 (patch)
treef84a4bce7f4eb2d9fbedfaabf0dfbdffa357b2cc /clang
parentecc89b76cb8f3a9732bebb1a094b840bdb4c2302 (diff)
downloadbcm5719-llvm-de0a8d37a017d39a0a6cfa99ea71a47bf6bb0cc4.tar.gz
bcm5719-llvm-de0a8d37a017d39a0a6cfa99ea71a47bf6bb0cc4.zip
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 llvm-svn: 350224
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp9
-rw-r--r--clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m17
2 files changed, 22 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 8d24b15f76a..9c66ff0e8fb 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -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(CodeGenFunction &CGF, QualType ResultType,
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::EmitObjCMessageExpr(const ObjCMessageExpr *E,
// 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,
diff --git a/clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m b/clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
index adbbd4b1738..8ce024fe809 100644
--- a/clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
+++ b/clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
@@ -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
OpenPOWER on IntegriCloud