[PATCH] D73208: [objc_direct] fix codegen for mismatched Decl/Impl return types

Pierre Habouzit via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 22 08:59:53 PST 2020


MadCoder created this revision.
MadCoder added reviewers: dexonsmith, ahatanak, erik.pilkington, arphaman.
MadCoder added a project: clang.
Herald added a subscriber: cfe-commits.

For non direct methods, the codegen uses the type of the Implementation.
Because Objective-C rules allow some differences between the Declaration
and Implementation return types, when the Implementation is in this
translation unit, the type of the Implementation should be preferred to
emit the Function over the Declaration.

Radar-Id: rdar://problem/58797748


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73208

Files:
  clang/lib/CodeGen/CGObjCMac.cpp
  clang/test/CodeGenObjC/direct-method-ret-mismatch.m


Index: clang/test/CodeGenObjC/direct-method-ret-mismatch.m
===================================================================
--- /dev/null
+++ clang/test/CodeGenObjC/direct-method-ret-mismatch.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm -fobjc-arc -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+
+__attribute__((objc_root_class))
+ at interface Root
+- (Root *)method __attribute__((objc_direct));
+ at end
+
+ at implementation Root
+// CHECK-LABEL: define internal i8* @"\01-[Root something]"(
+- (id)something {
+  // CHECK: %{{[^ ]*}} = call {{.*}} @"\01-[Root method]"
+  return [self method];
+}
+
+// CHECK-LABEL: define hidden i8* @"\01-[Root method]"(
+- (id)method {
+  return self;
+}
+ at end
Index: clang/lib/CodeGen/CGObjCMac.cpp
===================================================================
--- clang/lib/CodeGen/CGObjCMac.cpp
+++ clang/lib/CodeGen/CGObjCMac.cpp
@@ -4029,10 +4029,28 @@
 llvm::Function *
 CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD,
                                       const ObjCContainerDecl *CD) {
-  auto I = DirectMethodDefinitions.find(OMD->getCanonicalDecl());
+  auto *COMD = OMD->getCanonicalDecl();
+  auto I = DirectMethodDefinitions.find(COMD);
   if (I != DirectMethodDefinitions.end())
     return I->second;
 
+  // If this translation unit sees the implementation, we need to use
+  // it to generate the llvm::Function below. It is important to do so
+  // because Objective-C allows for return types to be somewhat mismatched
+  // and the Body of the function will expect to be generated with
+  // the type of its implementation.
+  if (!OMD->getBody()) {
+    if (auto *OI = dyn_cast<ObjCInterfaceDecl>(CD)) {
+      if (auto *Impl = OI->getImplementation())
+        if (auto *M = Impl->getMethod(OMD->getSelector(), OMD->isInstanceMethod()))
+          OMD = M;
+    } else if (auto *CI = dyn_cast<ObjCCategoryDecl>(CD)) {
+      if (auto *Impl = OI->getImplementation())
+        if (auto *M = Impl->getMethod(OMD->getSelector(), OMD->isInstanceMethod()))
+          OMD = M;
+    }
+  }
+
   SmallString<256> Name;
   GetNameForMethod(OMD, CD, Name, /*ignoreCategoryNamespace*/true);
 
@@ -4042,7 +4060,7 @@
   llvm::Function *Method =
       llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
                              Name.str(), &CGM.getModule());
-  DirectMethodDefinitions.insert(std::make_pair(OMD->getCanonicalDecl(), Method));
+  DirectMethodDefinitions.insert(std::make_pair(COMD, Method));
 
   return Method;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D73208.239617.patch
Type: text/x-patch
Size: 2534 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200122/7f7950c7/attachment-0001.bin>


More information about the cfe-commits mailing list