[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
Thu Jan 30 15:16:44 PST 2020
MadCoder updated this revision to Diff 241601.
MadCoder added a comment.
damn you tabs!
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D73208/new/
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
@@ -4032,22 +4032,50 @@
llvm::Function *
CGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD,
const ObjCContainerDecl *CD) {
- auto I = DirectMethodDefinitions.find(OMD->getCanonicalDecl());
- if (I != DirectMethodDefinitions.end())
- return I->second;
+ auto *COMD = OMD->getCanonicalDecl();
+ auto I = DirectMethodDefinitions.find(COMD);
+ llvm::Function *OldFn = nullptr, *Fn = nullptr;
- SmallString<256> Name;
- GetNameForMethod(OMD, CD, Name, /*ignoreCategoryNamespace*/true);
+ if (I != DirectMethodDefinitions.end()) {
+ // Objective-C allows for the declaration and implementation types
+ // to differ slightly.
+ //
+ // If we're being asked for the Function associated for a method
+ // implementation, a previous value might have been cached
+ // based on the type of the canonical declaration.
+ //
+ // If these do not match, then we'll replace this function with
+ // a new one that has the proper type below.
+ if (!OMD->getBody() || COMD->getReturnType() == OMD->getReturnType()) {
+ return I->second;
+ }
+ OldFn = I->second;
+ }
CodeGenTypes &Types = CGM.getTypes();
llvm::FunctionType *MethodTy =
Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
- llvm::Function *Method =
- llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
- Name.str(), &CGM.getModule());
- DirectMethodDefinitions.insert(std::make_pair(OMD->getCanonicalDecl(), Method));
- return Method;
+ if (OldFn) {
+ Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
+ "", &CGM.getModule());
+ Fn->takeName(OldFn);
+ OldFn->replaceAllUsesWith(
+ llvm::ConstantExpr::getBitCast(Fn, OldFn->getType()));
+ OldFn->eraseFromParent();
+
+ // Replace the cached function in the map.
+ I->second = Fn;
+ } else {
+ SmallString<256> Name;
+ GetNameForMethod(OMD, CD, Name, /*ignoreCategoryNamespace*/ true);
+
+ Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
+ Name.str(), &CGM.getModule());
+ DirectMethodDefinitions.insert(std::make_pair(COMD, Fn));
+ }
+
+ return Fn;
}
void CGObjCCommonMac::GenerateDirectMethodPrologue(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D73208.241601.patch
Type: text/x-patch
Size: 3232 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200130/b5390f47/attachment-0001.bin>
More information about the cfe-commits
mailing list