[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class
Pierre Habouzit via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 14 20:37:09 PST 2020
MadCoder created this revision.
MadCoder added reviewers: ahatanak, arphaman, dexonsmith, erik.pilkington.
MadCoder added a project: clang.
Herald added a subscriber: cfe-commits.
Sending a message to `self` when it is const and within a class method is safe because we know that `self` is the Class itself.
We can only relax this error in ARC.
Radar-Id: rdar://problem/58581965
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D72747
Files:
clang/lib/Sema/SemaExprObjC.cpp
clang/test/SemaObjC/method-direct-arc.m
Index: clang/test/SemaObjC/method-direct-arc.m
===================================================================
--- /dev/null
+++ clang/test/SemaObjC/method-direct-arc.m
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fobjc-arc -fsyntax-only -verify -Wselector-type-mismatch %s
+
+extern Class object_getClass(id);
+
+__attribute__((objc_root_class))
+ at interface Root
+- (Class)class;
++ (void)directMethod1 __attribute__((objc_direct)); // expected-note {{direct method 'directMethod1' declared here}}
++ (void)directMethod2 __attribute__((objc_direct));
+ at end
+
+ at implementation Root
+- (Class)class
+{
+ return object_getClass(self);
+}
++ (void)directMethod1 {
+}
++ (void)directMethod2 {
+ [self directMethod1]; // this should not warn
+}
++ (void)regularMethod {
+ [self directMethod1]; // this should not warn
+ [self directMethod2]; // this should not warn
+}
+- (void)regularInstanceMethod {
+ [[self class] directMethod1]; // expected-error {{messaging a Class with a method that is possibly direct}}
+}
+ at end
Index: clang/lib/Sema/SemaExprObjC.cpp
===================================================================
--- clang/lib/Sema/SemaExprObjC.cpp
+++ clang/lib/Sema/SemaExprObjC.cpp
@@ -3012,7 +3012,11 @@
<< Method->getDeclName();
}
- if (ReceiverType->isObjCClassType() && !isImplicit) {
+ // Under ARC, self can't be assigned, and doing a direct call to `self`
+ // when it's a Class is hence safe. For other cases, we can't trust `self`
+ // is what we think it is, so we reject it.
+ if (ReceiverType->isObjCClassType() && !isImplicit &&
+ (!Receiver->isObjCSelfExpr() || !getLangOpts().ObjCAutoRefCount)) {
Diag(Receiver->getExprLoc(),
diag::err_messaging_class_with_direct_method);
Diag(Method->getLocation(), diag::note_direct_method_declared_at)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72747.238165.patch
Type: text/x-patch
Size: 1827 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200115/5a1edf83/attachment-0001.bin>
More information about the cfe-commits
mailing list