summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaObjC
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2015-03-19 19:18:22 +0000
committerNico Weber <nicolasweber@gmx.de>2015-03-19 19:18:22 +0000
commit0055a19926b7b23cfc49b5b645769698ba5aa129 (patch)
tree80013c2d762e266554b7c5e8c0e0b25640bf6598 /clang/test/SemaObjC
parentf3d3db65de4e2937cd2efa3de984b2d35c9ec5c0 (diff)
downloadbcm5719-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.m103
-rw-r--r--clang/test/SemaObjC/property-deprecated-warning.m66
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
OpenPOWER on IntegriCloud