[PATCH] D72747: [objc_direct] Allow for direct messages be sent to `self` when it is a Class
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
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
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
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
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
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
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
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