1 | // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -Wno-objc-root-class %s |
2 | |
3 | typedef signed char BOOL; |
4 | typedef unsigned int NSUInteger; |
5 | |
6 | @interface NSObject |
7 | +(id)alloc; |
8 | -(id)init; |
9 | -(id)autorelease; |
10 | -(id)copy; |
11 | -(id)retain; |
12 | @end |
13 | |
14 | @interface Subscriptable : NSObject |
15 | - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)index; |
16 | - (id)objectAtIndexedSubscript:(NSUInteger)index; |
17 | |
18 | - (void)setObject:(id)obj forKeyedSubscript:(id)key; |
19 | - (id)objectForKeyedSubscript:(id)key; |
20 | @end |
21 | |
22 | @interface Test : Subscriptable |
23 | @end |
24 | |
25 | @implementation Test |
26 | |
27 | // <rdar://problem/6946338> for subscripting |
28 | - (id)storeDoesNotRetain { |
29 | Test *cell = [[[Test alloc] init] autorelease]; |
30 | |
31 | NSObject *string1 = [[NSObject alloc] init]; // expected-warning {{Potential leak}} |
32 | cell[0] = string1; |
33 | cell[self] = string1; |
34 | cell[string1] = self; |
35 | |
36 | return cell; |
37 | } |
38 | |
39 | // <rdar://problem/8824416> for subscripting |
40 | - (id)getDoesNotRetain:(BOOL)keyed { |
41 | if (keyed) |
42 | return [self[self] autorelease]; // expected-warning{{Object autoreleased too many times}} |
43 | else |
44 | return [self[0] autorelease]; // expected-warning{{Object autoreleased too many times}} |
45 | } |
46 | |
47 | // <rdar://problem/9241180> for subscripting |
48 | - (id)testUninitializedObject:(BOOL)keyed { |
49 | Test *o; |
50 | if (keyed) { |
51 | if (o[self]) // expected-warning {{Subscript access on an uninitialized object pointer}} |
52 | return o; // no-warning (sink) |
53 | } else { |
54 | if (o[0]) // expected-warning {{Subscript access on an uninitialized object pointer}} |
55 | return o; // no-warning (sink) |
56 | } |
57 | return self; |
58 | } |
59 | |
60 | - (void)testUninitializedArgument:(id)input testCase:(unsigned)testCase { |
61 | NSUInteger i; |
62 | id o; |
63 | |
64 | switch (testCase) { |
65 | case 0: |
66 | self[0] = o; // expected-warning {{Argument for subscript setter is an uninitialized value}} |
67 | break; |
68 | case 1: |
69 | self[i] = input; // expected-warning {{Subscript index is an uninitialized value}} |
70 | break; |
71 | case 2: |
72 | (void)self[i]; // expected-warning {{Subscript index is an uninitialized value}} |
73 | break; |
74 | case 3: |
75 | self[input] = o; // expected-warning {{Argument for subscript setter is an uninitialized value}} |
76 | break; |
77 | case 4: |
78 | self[o] = input; // expected-warning {{Subscript index is an uninitialized value}} |
79 | break; |
80 | case 5: |
81 | (void)self[o]; // expected-warning {{Subscript index is an uninitialized value}} |
82 | break; |
83 | default: |
84 | break; |
85 | } |
86 | |
87 | } |
88 | |
89 | @end |
90 | |