diff options
author | Nico Weber <nicolasweber@gmx.de> | 2015-03-19 19:18:22 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2015-03-19 19:18:22 +0000 |
commit | 0055a19926b7b23cfc49b5b645769698ba5aa129 (patch) | |
tree | 80013c2d762e266554b7c5e8c0e0b25640bf6598 /clang/test/SemaObjC | |
parent | f3d3db65de4e2937cd2efa3de984b2d35c9ec5c0 (diff) | |
download | bcm5719-llvm-0055a19926b7b23cfc49b5b645769698ba5aa129.tar.gz bcm5719-llvm-0055a19926b7b23cfc49b5b645769698ba5aa129.zip |
Add -Wpartial-availability.
This warns when using decls that are not available on all deployment targets.
For example, a call to
- (void)ppartialMethod __attribute__((availability(macosx,introduced=10.8)));
will warn if -mmacosx-version-min is set to less than 10.8.
To silence the warning, one has to explicitly redeclare the method like so:
@interface Whatever(MountainLionAPI)
- (void)ppartialMethod;
@end
This way, one cannot accidentally call a function that isn't available
everywhere. Having to add the redeclaration will hopefully remind the user
to add an explicit respondsToSelector: call as well.
Some projects build against old SDKs to get this effect, but building against
old SDKs suppresses some bug fixes -- see http://crbug.com/463171 for examples.
The hope is that SDK headers are annotated well enough with availability
attributes that new SDK + this warning offers the same amount of protection
as using an old SDK.
llvm-svn: 232750
Diffstat (limited to 'clang/test/SemaObjC')
-rw-r--r-- | clang/test/SemaObjC/attr-availability.m | 103 | ||||
-rw-r--r-- | clang/test/SemaObjC/property-deprecated-warning.m | 66 |
2 files changed, 168 insertions, 1 deletions
diff --git a/clang/test/SemaObjC/attr-availability.m b/clang/test/SemaObjC/attr-availability.m index c455bc7acce..bac4be2d1df 100644 --- a/clang/test/SemaObjC/attr-availability.m +++ b/clang/test/SemaObjC/attr-availability.m @@ -1,11 +1,21 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s +// RUN: %clang_cc1 -D WARN_PARTIAL -Wpartial-availability -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s @protocol P - (void)proto_method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 2 {{'proto_method' has been explicitly marked deprecated here}} + +#if defined(WARN_PARTIAL) + // expected-note@+2 2 {{'partial_proto_method' has been explicitly marked partial here}} +#endif +- (void)partial_proto_method __attribute__((availability(macosx,introduced=10.8))); @end @interface A <P> - (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}} +#if defined(WARN_PARTIAL) + // expected-note@+2 {{'partialMethod' has been explicitly marked partial here}} +#endif +- (void)partialMethod __attribute__((availability(macosx,introduced=10.8))); - (void)overridden __attribute__((availability(macosx,introduced=10.3))); // expected-note{{overridden method is here}} - (void)overridden2 __attribute__((availability(macosx,introduced=10.3))); @@ -18,6 +28,7 @@ // rdar://11475360 @interface B : A - (void)method; // NOTE: we expect 'method' to *not* inherit availability. +- (void)partialMethod; // Likewise. - (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))); @@ -31,6 +42,32 @@ void f(A *a, B *b) { [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}} + +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partialMethod' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'partialMethod' to silence this warning}} +#endif + [a partialMethod]; + [b partialMethod]; // no warning +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partial_proto_method' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'partial_proto_method' to silence this warning}} +#endif + [a partial_proto_method]; +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partial_proto_method' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'partial_proto_method' to silence this warning}} +#endif + [b partial_proto_method]; +} + +@interface A (NewAPI) +- (void)partialMethod; +- (void)partial_proto_method; +@end + +void f_after_redecl(A *a, B *b) { + [a partialMethod]; // no warning + [b partialMethod]; // no warning + [a partial_proto_method]; // no warning + [b partial_proto_method]; // no warning } // Test case for <rdar://problem/11627873>. Warn about @@ -87,3 +124,69 @@ id NSNibOwner, topNibObjects; } @end + +@protocol PartialProt +- (void)ppartialMethod __attribute__((availability(macosx,introduced=10.8))); ++ (void)ppartialMethod __attribute__((availability(macosx,introduced=10.8))); +@end + +@interface PartialI <PartialProt> +- (void)partialMethod __attribute__((availability(macosx,introduced=10.8))); ++ (void)partialMethod __attribute__((availability(macosx,introduced=10.8))); +@end + +@interface PartialI () +- (void)ipartialMethod1 __attribute__((availability(macosx,introduced=10.8))); +#if defined(WARN_PARTIAL) + // expected-note@+2 {{'ipartialMethod2' has been explicitly marked partial here}} +#endif +- (void)ipartialMethod2 __attribute__((availability(macosx,introduced=10.8))); ++ (void)ipartialMethod1 __attribute__((availability(macosx,introduced=10.8))); +#if defined(WARN_PARTIAL) + // expected-note@+2 {{'ipartialMethod2' has been explicitly marked partial here}} +#endif ++ (void)ipartialMethod2 __attribute__((availability(macosx,introduced=10.8))); +@end + +@interface PartialI (Redecls) +- (void)partialMethod; +- (void)ipartialMethod1; +- (void)ppartialMethod; ++ (void)partialMethod; ++ (void)ipartialMethod1; ++ (void)ppartialMethod; +@end + +void partialfun(PartialI* a) { + [a partialMethod]; // no warning + [a ipartialMethod1]; // no warning +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'ipartialMethod2' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'ipartialMethod2' to silence this warning}} +#endif + [a ipartialMethod2]; + [a ppartialMethod]; // no warning + [PartialI partialMethod]; // no warning + [PartialI ipartialMethod1]; // no warning +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'ipartialMethod2' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'ipartialMethod2' to silence this warning}} +#endif + [PartialI ipartialMethod2]; + [PartialI ppartialMethod]; // no warning +} + +#if defined(WARN_PARTIAL) + // expected-note@+2 {{'PartialI2' has been explicitly marked partial here}} +#endif +__attribute__((availability(macosx, introduced = 10.8))) @interface PartialI2 +@end + +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'PartialI2' is partial: introduced in OS X 10.8}} expected-note@+2 {{explicitly redeclare 'PartialI2' to silence this warning}} +#endif +void partialinter1(PartialI2* p) { +} + +@class PartialI2; + +void partialinter2(PartialI2* p) { // no warning +} diff --git a/clang/test/SemaObjC/property-deprecated-warning.m b/clang/test/SemaObjC/property-deprecated-warning.m index 4beb23ada33..cec376838de 100644 --- a/clang/test/SemaObjC/property-deprecated-warning.m +++ b/clang/test/SemaObjC/property-deprecated-warning.m @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -triple thumbv6-apple-ios3.0 -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -D WARN_PARTIAL -Wpartial-availability -fsyntax-only -triple thumbv6-apple-ios3.0 -verify -Wno-objc-root-class %s // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -triple thumbv6-apple-ios3.0 -verify -Wno-objc-root-class %s // rdar://12324295 @@ -6,29 +7,47 @@ typedef signed char BOOL; @protocol P @property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'ptarget' is declared deprecated here}} expected-note {{'ptarget' has been explicitly marked deprecated here}} + +#if defined(WARN_PARTIAL) +// expected-note@+2 {{property 'partialPtarget' is declared partial here}} expected-note@+2 {{'partialPtarget' has been explicitly marked partial here}} +#endif +@property(nonatomic,assign) id partialPtarget __attribute__((availability(ios,introduced=5.0))); @end @protocol P1<P> - (void)setPtarget:(id)arg; +- (void)setPartialPtarget:(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}} expected-note {{'setTarget:' has been explicitly marked deprecated here}} + +#if defined(WARN_PARTIAL) +// expected-note@+2 {{property 'partialTarget' is declared partial here}} expected-note@+2 {{'setPartialTarget:' has been explicitly marked partial here}} +#endif +@property(nonatomic,assign) id partialTarget __attribute__((availability(ios,introduced=5.0))); @end @interface PSTableCell : UITableViewCell - (void)setTarget:(id)target; + - (void)setPartialTarget:(id)target; @end @interface UITableViewCell(UIDeprecated) @property(nonatomic,assign) id dep_target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{'dep_target' has been explicitly marked deprecated here}} \ // expected-note 4 {{property 'dep_target' is declared deprecated here}} \ // expected-note 2 {{'setDep_target:' has been explicitly marked deprecated here}} + +#if defined(WARN_PARTIAL) +// expected-note@+2 4 {{property 'partial_dep_target' is declared partial here}} expected-note@+2 2 {{'partial_dep_target' has been explicitly marked partial here}} expected-note@+2 2 {{'setPartial_dep_target:' has been explicitly marked partial here}} +#endif +@property(nonatomic,assign) id partial_dep_target __attribute__((availability(ios,introduced=5.0))); @end @implementation PSTableCell - (void)setTarget:(id)target {}; +- (void)setPartialTarget:(id)target {}; - (void)setPtarget:(id)val {}; - (void) Meth { [self setTarget: (id)0]; // no-warning @@ -36,20 +55,41 @@ typedef signed char BOOL; // expected-warning {{'setDep_target:' is deprecated: first deprecated in iOS 3.0}} [self setPtarget: (id)0]; // no-warning + [self setPartialTarget: (id)0]; // no-warning +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partial_dep_target' is partial: introduced in iOS 5.0}} expected-warning@+2 {{'setPartial_dep_target:' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'partial_dep_target' to silence this warning}} expected-note@+2 {{explicitly redeclare 'setPartial_dep_target:' to silence this warning}} +#endif + [self setPartial_dep_target: [self partial_dep_target]]; + + [self setPartialPtarget: (id)0]; // no-warning } @end @implementation UITableViewCell @synthesize target; +@synthesize partialTarget; @synthesize ptarget; +@synthesize partialPtarget; - (void)setPtarget:(id)val {}; +- (void)setPartialPtarget:(id)val {}; - (void)setTarget:(id)target {}; +- (void)setPartialTarget:(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]; // no-warning + +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'setPartialTarget:' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'setPartialTarget:' to silence this warning}} +#endif + [self setPartialTarget: (id)0]; +#if defined(WARN_PARTIAL) + // expected-warning@+2 {{'partial_dep_target' is partial: introduced in iOS 5.0}} expected-warning@+2 {{'setPartial_dep_target:' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'partial_dep_target' to silence this warning}} expected-note@+2 {{explicitly redeclare 'setPartial_dep_target:' to silence this warning}} +#endif + [self setPartial_dep_target: [self partial_dep_target]]; + [self setPartialPtarget: (id)0]; // no-warning } @end @@ -58,11 +98,27 @@ typedef signed char BOOL; @property(getter=isEnabled,assign) BOOL enabled __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'isEnabled' has been explicitly marked deprecated here}} expected-note {{property 'enabled' is declared deprecated here}} @property(setter=setNewDelegate:,assign) id delegate __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'setNewDelegate:' has been explicitly marked deprecated here}} expected-note {{property 'delegate' is declared deprecated here}} + +#if defined(WARN_PARTIAL) +// expected-note@+2 {{property 'partialEnabled' is declared partial here}} expected-note@+2 {{'partialIsEnabled' has been explicitly marked partial here}} +#endif +@property(getter=partialIsEnabled,assign) BOOL partialEnabled __attribute__((availability(ios,introduced=5.0))); + +#if defined(WARN_PARTIAL) +// expected-note@+2 {{property 'partialDelegate' is declared partial here}} expected-note@+2 {{'partialSetNewDelegate:' has been explicitly marked partial here}} +#endif +@property(setter=partialSetNewDelegate:,assign) id partialDelegate __attribute__((availability(ios,introduced=5.0))); @end void testCustomAccessorNames(CustomAccessorNames *obj) { if ([obj isEnabled]) // expected-warning {{'isEnabled' is deprecated: first deprecated in iOS 3.0}} [obj setNewDelegate:0]; // expected-warning {{'setNewDelegate:' is deprecated: first deprecated in iOS 3.0}} + +#if defined(WARN_PARTIAL) +// expected-warning@+2 {{'partialIsEnabled' is partial: introduced in iOS 5.0}} expected-warning@+3 {{'partialSetNewDelegate:' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'partialIsEnabled' to silence this warning}} expected-note@+3 {{explicitly redeclare 'partialSetNewDelegate:' to silence this warning}} +#endif + if ([obj partialIsEnabled]) + [obj partialSetNewDelegate:0]; } @@ -71,12 +127,20 @@ void testCustomAccessorNames(CustomAccessorNames *obj) { @interface ProtocolInCategory (TheCategory) <P1> - (id)ptarget; +- (id)partialPtarget; @end 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}} + + if (flag) + return [obj partialPtarget]; // no-warning +#if defined(WARN_PARTIAL) +// expected-warning@+2 {{'partialPtarget' is partial: introduced in iOS 5.0}} expected-note@+2 {{explicitly redeclare 'partialPtarget' to silence this warning}} +#endif + return [obj2 partialPtarget]; } // rdar://15951801 |