summaryrefslogtreecommitdiffstats
path: root/test/SemaObjC/arc-peformselector.m
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-07-05 22:38:59 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-07-05 22:38:59 +0000
commit9670e179a67d868e171feac44fb8f9e2f108c5e8 (patch)
treefdbc7fbb4072a90c7a2ffce680c19f82b927e20a /test/SemaObjC/arc-peformselector.m
parentb18b8ad63061c23daf4d95b022764027739691d8 (diff)
objc-arc: enforce performSelector rules in rejecting retaining selectors
passed to it, and unknown selectors causing potential leak. // rdar://9659270 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134449 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaObjC/arc-peformselector.m')
-rw-r--r--test/SemaObjC/arc-peformselector.m38
1 files changed, 38 insertions, 0 deletions
diff --git a/test/SemaObjC/arc-peformselector.m b/test/SemaObjC/arc-peformselector.m
new file mode 100644
index 0000000000..e637f3d76f
--- /dev/null
+++ b/test/SemaObjC/arc-peformselector.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -verify %s
+// rdar://9659270
+
+@interface NSObject
+- (id)copy; // expected-note {{method declared here}}
+- (id) test __attribute__((ns_returns_retained)); // expected-note {{method declared here}}
++ (id) new ; // expected-note {{method declared here}}
+- (id) init __attribute__((ns_returns_not_retained));
+- (id)PlusZero;
+- (id)PlusOne __attribute__((ns_returns_retained)); // expected-note {{method declared here}}
+@end
+
+@interface I : NSObject
+{
+ SEL sel1;
+}
+- (id)performSelector:(SEL)aSelector;
+- (id)performSelector:(SEL)aSelector withObject:(id)object;
+- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
+@end
+
+@implementation I
+- (id) Meth {
+ return [self performSelector : @selector(copy)]; // expected-error {{performSelector names a selector which retains the object}}
+ return [self performSelector : @selector(test)]; // expected-error {{performSelector names a selector which retains the object}}
+ return [self performSelector : @selector(new)]; // expected-error {{performSelector names a selector which retains the object}}
+ return [self performSelector : @selector(init)];
+ return [self performSelector : sel1]; // expected-warning {{performSelector may cause a leak because its selector is unknown}} \
+ // expected-note {{used here}}
+
+ return [self performSelector : @selector(PlusZero)];
+ return [self performSelector : @selector(PlusOne)]; // expected-error {{performSelector names a selector which retains the object}}
+}
+
+- (id)performSelector:(SEL)aSelector { return 0; }
+- (id)performSelector:(SEL)aSelector withObject:(id)object { return 0; }
+- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2 { return 0; }
+@end