summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-01-18 09:52:52 +0000
committerHans Wennborg <hans@hanshq.net>2019-01-18 09:52:52 +0000
commitbce836466f34a8483f97aaf99129e01de5d7d3b5 (patch)
tree30a7287083b6eb64f97d3e9f54d464ce847248f4
parent466291e83811ac6aa2e2c59b198dae1acc486f9b (diff)
Merging r351459:
------------------------------------------------------------------------ r351459 | arphaman | 2019-01-17 19:12:45 +0100 (Thu, 17 Jan 2019) | 13 lines [ObjC] Follow-up r350768 and allow the use of unavailable methods that are declared in a parent class from within the @implementation context This commit extends r350768 and allows the use of methods marked as unavailable that are declared in a parent class/category from within the @implementation of the class where the method is marked as unavailable. This allows users to call init that's marked as unavailable even if they don't define it. rdar://47134898 Differential Revision: https://reviews.llvm.org/D56816 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_80@351535 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclAttr.cpp8
-rw-r--r--test/SemaObjC/call-unavailable-init-in-self.m22
-rw-r--r--test/SemaObjC/infer-availability-from-init.m4
3 files changed, 25 insertions, 9 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index eb95cc748b..139ac8aab4 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -7365,13 +7365,11 @@ ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K,
return true;
} else if (K == AR_Unavailable) {
// It is perfectly fine to refer to an 'unavailable' Objective-C method
- // when it's actually defined and is referenced from within the
- // @implementation itself. In this context, we interpret unavailable as a
- // form of access control.
+ // when it is referenced from within the @implementation itself. In this
+ // context, we interpret unavailable as a form of access control.
if (const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) {
if (const auto *Impl = dyn_cast<ObjCImplDecl>(C)) {
- if (MD->getClassInterface() == Impl->getClassInterface() &&
- MD->isDefined())
+ if (MD->getClassInterface() == Impl->getClassInterface())
return true;
}
}
diff --git a/test/SemaObjC/call-unavailable-init-in-self.m b/test/SemaObjC/call-unavailable-init-in-self.m
index fa6f670cc9..48fc2326af 100644
--- a/test/SemaObjC/call-unavailable-init-in-self.m
+++ b/test/SemaObjC/call-unavailable-init-in-self.m
@@ -5,13 +5,24 @@
+ (instancetype)new;
+ (instancetype)alloc;
+- (void)declaredInSuper;
+
+@end
+
+@interface NSObject (Category)
+
+- (void)declaredInSuperCategory;
+
@end
@interface Sub: NSObject
- (instancetype)init __attribute__((unavailable)); // expected-note 4 {{'init' has been explicitly marked unavailable here}}
-- (void)notImplemented __attribute__((unavailable)); // expected-note {{'notImplemented' has been explicitly marked unavailable here}}
+- (void)notImplemented __attribute__((unavailable));
+
+- (void)declaredInSuper __attribute__((unavailable));
+- (void)declaredInSuperCategory __attribute__((unavailable));
@end
@@ -34,7 +45,14 @@
}
- (void)reportUseOfUnimplemented {
- [self notImplemented]; // expected-error {{'notImplemented' is unavailable}}
+ [self notImplemented];
+}
+
+- (void)allowSuperCallUsingSelf {
+ [self declaredInSuper];
+ [[Sub alloc] declaredInSuper];
+ [self declaredInSuperCategory];
+ [[Sub alloc] declaredInSuperCategory];
}
@end
diff --git a/test/SemaObjC/infer-availability-from-init.m b/test/SemaObjC/infer-availability-from-init.m
index f9996ec708..7aa1e53c09 100644
--- a/test/SemaObjC/infer-availability-from-init.m
+++ b/test/SemaObjC/infer-availability-from-init.m
@@ -47,12 +47,12 @@ void usenotmyobject() {
}
@interface FromSelf : NSObject
--(instancetype)init __attribute__((unavailable)); // expected-note {{'init' has been explicitly marked unavailable here}}
+-(instancetype)init __attribute__((unavailable));
+(FromSelf*)another_one;
@end
@implementation FromSelf
+(FromSelf*)another_one {
- [self new]; // expected-error{{'new' is unavailable}}
+ [self new];
}
@end