[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
Wed Jan 22 08:50:29 PST 2020


MadCoder updated this revision to Diff 239615.
MadCoder added a comment.

with the test for real


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72747/new/

https://reviews.llvm.org/D72747

Files:
  clang/lib/Sema/SemaExprObjC.cpp
  clang/test/SemaObjC/method-direct-arc.m
  clang/test/SemaObjC/method-direct.m


Index: clang/test/SemaObjC/method-direct.m
===================================================================
--- clang/test/SemaObjC/method-direct.m
+++ clang/test/SemaObjC/method-direct.m
@@ -89,7 +89,10 @@
 }
 - (void)otherRootDirect {
 }
++ (void)someRootDirectMethod { // expected-note {{direct method 'someRootDirectMethod' declared here}}
+}
 + (void)otherClassRootDirect {
+  [self someRootDirectMethod]; // expected-error {{messaging a Class with a method that is possibly direct}}
 }
 - (void)rootExtensionDirect {
 }
Index: clang/test/SemaObjC/method-direct-arc.m
===================================================================
--- /dev/null
+++ clang/test/SemaObjC/method-direct-arc.m
@@ -0,0 +1,48 @@
+// 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)directMethod __attribute__((objc_direct)); // expected-note {{direct method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+ at end
+
+ at implementation Root
+- (Class)class
+{
+  return object_getClass(self);
+}
++ (void)directMethod {
+}
++ (void)anotherDirectMethod {
+  [self directMethod]; // this should not warn
+}
++ (void)regularMethod {
+  [self directMethod];        // this should not warn
+  [self anotherDirectMethod]; // this should not warn
+}
+- (void)regularInstanceMethod {
+  [[self class] directMethod]; // expected-error {{messaging a Class with a method that is possibly direct}}
+}
+ at end
+
+ at interface Sub : Root
+ at end
+
+ at implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+ at end
+
+__attribute__((objc_root_class))
+ at interface Other
+ at end
+
+ at implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 'directMethod'}}
+}
+ 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.239615.patch
Type: text/x-patch
Size: 2714 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200122/a2c48b37/attachment.bin>


More information about the cfe-commits mailing list