1// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -Wno-objc-root-class %s
2
3typedef signed char BOOL;
4typedef 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