[clang] 7596d3c - [objc_direct] Allow for direct messages be sent to `self` when it is a Class
Pierre Habouzit via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 23 22:58:40 PST 2020
Author: Pierre Habouzit
Date: 2020-01-23T22:39:28-08:00
New Revision: 7596d3c50c4b265612d326369e2a015cf8c60801
URL: https://github.com/llvm/llvm-project/commit/7596d3c50c4b265612d326369e2a015cf8c60801
DIFF: https://github.com/llvm/llvm-project/commit/7596d3c50c4b265612d326369e2a015cf8c60801.diff
LOG: [objc_direct] Allow for direct messages be sent to `self` when it is a Class
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 warning in ARC.
Signed-off-by: Pierre Habouzit <phabouzit at apple.com>
Radar-Id: rdar://problem/58581965
Differential Revision: https://reviews.llvm.org/D72747
Added:
clang/test/SemaObjC/method-direct-arc.m
Modified:
clang/lib/Sema/SemaExprObjC.cpp
clang/test/SemaObjC/method-direct.m
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index c61b13cf5980..7914dc57f9e1 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -3012,7 +3012,11 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
<< 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)
diff --git a/clang/test/SemaObjC/method-direct-arc.m b/clang/test/SemaObjC/method-direct-arc.m
new file mode 100644
index 000000000000..6877cddb073b
--- /dev/null
+++ b/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
diff --git a/clang/test/SemaObjC/method-direct.m b/clang/test/SemaObjC/method-direct.m
index 4829a67cd8a9..c2cbdbebdaf4 100644
--- a/clang/test/SemaObjC/method-direct.m
+++ b/clang/test/SemaObjC/method-direct.m
@@ -89,7 +89,10 @@ + (void)classRootDirect {
}
- (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 {
}
More information about the cfe-commits
mailing list