xref: /llvm-project/clang/test/Analysis/objc-subscript.m (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -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- (id)storeDoesNotRetain {
28  Test *cell = [[[Test alloc] init] autorelease];
29
30  NSObject *string1 = [[NSObject alloc] init]; // expected-warning {{Potential leak}}
31  cell[0] = string1;
32  cell[self] = string1;
33  cell[string1] = self;
34
35  return cell;
36}
37
38- (id)getDoesNotRetain:(BOOL)keyed {
39  if (keyed)
40    return [self[self] autorelease]; // expected-warning{{Object autoreleased too many times}}
41  else
42    return [self[0] autorelease]; // expected-warning{{Object autoreleased too many times}}
43}
44
45- (id)testUninitializedObject:(BOOL)keyed {
46  Test *o;
47  if (keyed) {
48    if (o[self]) // expected-warning {{Subscript access on an uninitialized object pointer}}
49      return o; // no-warning (sink)
50  } else {
51    if (o[0]) // expected-warning {{Subscript access on an uninitialized object pointer}}
52      return o; // no-warning (sink)
53  }
54  return self;
55}
56
57- (void)testUninitializedArgument:(id)input testCase:(unsigned)testCase {
58  NSUInteger i;
59  id o;
60
61  switch (testCase) {
62  case 0:
63    self[0] = o; // expected-warning {{Argument for subscript setter is an uninitialized value}}
64    break;
65  case 1:
66    self[i] = input; // expected-warning {{Subscript index is an uninitialized value}}
67    break;
68  case 2:
69    (void)self[i]; // expected-warning {{Subscript index is an uninitialized value}}
70    break;
71  case 3:
72    self[input] = o; // expected-warning {{Argument for subscript setter is an uninitialized value}}
73    break;
74  case 4:
75    self[o] = input; // expected-warning {{Subscript index is an uninitialized value}}
76    break;
77  case 5:
78    (void)self[o]; // expected-warning {{Subscript index is an uninitialized value}}
79    break;
80  default:
81    break;
82  }
83
84}
85
86@end
87