New rule:
- Method decls in @implementation are considered "redeclarations"
and inherit deprecated/availability from the @interface.
- All other cases are consider overrides, which do not inherit
deprecated/availability. For example:
(a) @interface redeclares a method in an adopted protocol.
(b) A subclass redeclares a method in a superclass.
(c) A protocol redeclares a method from another protocol it adopts.
The idea is that API authors should have the ability to easily
move availability/deprecated up and down a class/protocol hierarchy.
A redeclaration means that the availability/deprecation is a blank
slate.
Fixes <rdar://problem/
13574571>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178937
91177308-0d34-0410-b5e6-
96231b3b80d8
ObjCMethodDecl *oldMethod) {
// Merge the attributes, including deprecated/unavailable
- mergeDeclAttributes(newMethod, oldMethod, AMK_Override);
+ AvailabilityMergeKind MergeKind =
+ isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration
+ : AMK_Override;
+ mergeDeclAttributes(newMethod, oldMethod, MergeKind);
// Merge attributes from the parameters.
ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(),
MergedObsoleted == Obsoleted)
return NULL;
+ // Only create a new attribute if !Override, but we want to do
+ // the checking.
if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
- MergedDeprecated, MergedObsoleted)) {
+ MergedDeprecated, MergedObsoleted) &&
+ !Override) {
return ::new (Context) AvailabilityAttr(Range, Context, Platform,
Introduced, Deprecated,
Obsoleted, IsUnavailable, Message,
// rdar://11475360
@interface B : A
-- (void)method; // expected-note {{method 'method' declared here}}
+- (void)method; // NOTE: we expect 'method' to *not* inherit availability.
- (void)overridden __attribute__((availability(macosx,introduced=10.4))); // expected-warning{{overriding method introduced after overridden method on OS X (10.4 vs. 10.3)}}
- (void)overridden2 __attribute__((availability(macosx,introduced=10.2)));
- (void)overridden3 __attribute__((availability(macosx,deprecated=10.4)));
void f(A *a, B *b) {
[a method]; // expected-warning{{'method' is deprecated: first deprecated in OS X 10.2}}
- [b method]; // expected-warning {{'method' is deprecated: first deprecated in OS X 10.2}}
+ [b method]; // no-warning
[a proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}}
[b proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in OS X 10.2}}
}
typedef signed char BOOL;
@protocol P
-@property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{property 'ptarget' is declared deprecated here}}
+@property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'ptarget' is declared deprecated here}} expected-note {{method 'ptarget' declared here}}
@end
@protocol P1<P>
-- (void)setPtarget:(id)arg; // expected-note {{method 'setPtarget:' declared here}}
+- (void)setPtarget:(id)arg;
@end
@interface UITableViewCell<P1>
-@property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}}
+@property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}} expected-note {{method 'setTarget:' declared here}}
@end
@interface PSTableCell : UITableViewCell
- - (void)setTarget:(id)target; // expected-note {{method 'setTarget:' declared here}}
+ - (void)setTarget:(id)target;
@end
@interface UITableViewCell(UIDeprecated)
-@property(nonatomic,assign) id dep_target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{method 'dep_target' declared here}} \
- // expected-note 2 {{property 'dep_target' is declared deprecated here}} \
- // expected-note {{method 'setDep_target:' declared here}}
+@property(nonatomic,assign) id dep_target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{method 'dep_target' declared here}} \
+ // expected-note 4 {{property 'dep_target' is declared deprecated here}} \
+ // expected-note 2 {{method 'setDep_target:' declared here}}
@end
@implementation PSTableCell
- (void)setTarget:(id)target {};
- (void)setPtarget:(id)val {};
+- (void) Meth {
+ [self setTarget: (id)0]; // no-warning
+ [self setDep_target: [self dep_target]]; // expected-warning {{'dep_target' is deprecated: first deprecated in iOS 3.0}} \
+ // expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}}
+
+ [self setPtarget: (id)0]; // no-warning
+}
+@end
+
+@implementation UITableViewCell
+@synthesize target;
+@synthesize ptarget;
+- (void)setPtarget:(id)val {};
+- (void)setTarget:(id)target {};
- (void) Meth {
[self setTarget: (id)0]; // expected-warning {{'setTarget:' is deprecated: first deprecated in iOS 3.0}}
[self setDep_target: [self dep_target]]; // expected-warning {{'dep_target' is deprecated: first deprecated in iOS 3.0}} \
// expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}}
- [self setPtarget: (id)0]; // expected-warning {{setPtarget:' is deprecated: first deprecated in iOS 3.0}}
+ [self setPtarget: (id)0]; // no-warning
}
@end
@end
@interface ProtocolInCategory (TheCategory) <P1>
-- (id)ptarget; // expected-note {{method 'ptarget' declared here}}
+- (id)ptarget;
@end
-id useDeprecatedProperty(ProtocolInCategory *obj) {
- return [obj ptarget]; // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}}
+id useDeprecatedProperty(ProtocolInCategory *obj, id<P> obj2, int flag) {
+ if (flag)
+ return [obj ptarget]; // no-warning
+ return [obj2 ptarget]; // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}}
}
@interface NSObject @end
@protocol myProtocol
-@property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8)));
+@property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{method 'myProtocolProperty' declared here}} \
+ // expected-note {{property 'myProtocolProperty' is declared deprecated here}}
@end
@interface Foo : NSObject
@end
@interface Bar : Foo <myProtocol>
-@property int myProperty; // expected-note {{'myProperty' declared here}}
-@property int myProtocolProperty; // expected-note {{'myProtocolProperty' declared here}}
+@property int myProperty;
+@property int myProtocolProperty;
@end
-void test(Foo *y, Bar *x) {
+void test(Foo *y, Bar *x, id<myProtocol> z) {
y.myProperty = 0; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}}
[y myProperty]; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}}
x.myProperty = 1; // no-warning
- [x myProperty]; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}}
+ [x myProperty]; // no-warning
x.myProtocolProperty = 0; // no-warning
- [x myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}}
+ [x myProtocolProperty]; // no-warning
+ [z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}}
}