[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class

2020-01-23 Thread Pierre Habouzit via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG7596d3c50c4b: [objc_direct] Allow for direct messages be 
sent to `self` when it is a Class (authored by MadCoder).

Repository:
  rG LLVM Github Monorepo

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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct 
method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 
'directMethod'}}
+}
+@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)


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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self 

[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class

2020-01-22 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman accepted this revision.
arphaman added a comment.
This revision is now accepted and ready to land.

LGTM


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

https://reviews.llvm.org/D72747



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class

2020-01-22 Thread Pierre Habouzit via Phabricator via cfe-commits
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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct 
method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 
'directMethod'}}
+}
+@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)


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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 'directMethod'}}
+}
+@end
Index: clang/lib/Sema/SemaExprObjC.cpp

[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class

2020-01-22 Thread Pierre Habouzit via Phabricator via cfe-commits
MadCoder updated this revision to Diff 239610.
MadCoder added a comment.

adding the non ARC test I forgot to add


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


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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct 
method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 
'directMethod'}}
+}
+@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)


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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 'directMethod'}}
+}
+@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)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class

2020-01-21 Thread Pierre Habouzit via Phabricator via cfe-commits
MadCoder updated this revision to Diff 239477.
MadCoder added a comment.

fixed @ahatanak feedback


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


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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct 
method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 
'directMethod'}}
+}
+@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)


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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 'directMethod'}}
+}
+@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)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class

2020-01-21 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman added a comment.

Please add a test that exercises path without ARC enabled.




Comment at: clang/lib/Sema/SemaExprObjC.cpp:3019
+if (ReceiverType->isObjCClassType() && !isImplicit &&
+(!Receiver->isObjCSelfExpr() || !getLangOpts().ObjCAutoRefCount)) {
   Diag(Receiver->getExprLoc(),

NIT: It feels easier to read if the condition is `&& 
!(Receiver->isObjCSelfExpr() && getLangOpts().ObjCAutoRefCount)`.


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

https://reviews.llvm.org/D72747



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class

2020-01-16 Thread Pierre Habouzit via Phabricator via cfe-commits
MadCoder updated this revision to Diff 238698.
MadCoder added a comment.

Added some more tests to make sure it works along inheritance chains as expected


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


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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct 
method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 
'directMethod'}}
+}
+@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)


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))
+@interface Root
+- (Class)class;
++ (void)directMethod __attribute__((objc_direct)); // expected-note {{direct method 'directMethod' declared here}}
++ (void)anotherDirectMethod __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@end
+
+@interface Sub : Root
+@end
+
+@implementation Sub
++ (void)foo {
+  [self directMethod]; // this should not warn
+}
+@end
+
+__attribute__((objc_root_class))
+@interface Other
+@end
+
+@implementation Other
++ (void)bar {
+  [self directMethod]; // expected-error {{no known class method for selector 'directMethod'}}
+}
+@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)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class

2020-01-14 Thread Pierre Habouzit via Phabricator via cfe-commits
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))
+@interface Root
+- (Class)class;
++ (void)directMethod1 __attribute__((objc_direct)); // expected-note {{direct 
method 'directMethod1' declared here}}
++ (void)directMethod2 __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@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)


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))
+@interface Root
+- (Class)class;
++ (void)directMethod1 __attribute__((objc_direct)); // expected-note {{direct method 'directMethod1' declared here}}
++ (void)directMethod2 __attribute__((objc_direct));
+@end
+
+@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}}
+}
+@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)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits