xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/infinite-loop.mm (revision 7df0f0b410674437f0b56262043e22b177709161)
1// RUN: %check_clang_tidy %s bugprone-infinite-loop %t -- -- -fblocks
2// RUN: %check_clang_tidy %s bugprone-infinite-loop %t -- -- -fblocks -fobjc-arc
3
4typedef __typeof(sizeof(int)) NSUInteger;
5
6@interface NSArray
7+(instancetype)alloc;
8-(instancetype)init;
9@property(readonly) NSUInteger count;
10-(void)addObject: (id)anObject;
11@end
12
13@interface I
14-(void) instanceMethod;
15+(void) classMethod;
16+(instancetype)alloc;
17-(instancetype)init;
18@end
19
20void plainCFunction() {
21  int i = 0;
22  int j = 0;
23  while (i < 10) {
24    // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (i) are updated in the loop body [bugprone-infinite-loop]
25    j++;
26  }
27}
28
29@implementation I
30- (void)instanceMethod {
31  int i = 0;
32  int j = 0;
33  while (i < 10) {
34    // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (i) are updated in the loop body [bugprone-infinite-loop]
35    j++;
36  }
37}
38
39+ (void)classMethod {
40  int i = 0;
41  int j = 0;
42  while (i < 10) {
43    // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (i) are updated in the loop body [bugprone-infinite-loop]
44    j++;
45  }
46}
47
48+ (void)recursiveMethod {
49  static int i = 0;
50
51  i++;
52  while (i < 10) {
53    // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (i) are updated in the loop body [bugprone-infinite-loop]
54    [I classMethod];
55  }
56
57  id x = [[I alloc] init];
58
59  while (i < 10) {
60    // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of its condition variables (i) are updated in the loop body [bugprone-infinite-loop]
61    [x instanceMethod];
62  }
63  while (i < 10) {
64    // no warning, there is a recursive call that can mutate the static local variable
65    [I recursiveMethod];
66  }
67}
68@end
69
70void testArrayCount() {
71  NSArray *arr = [[NSArray alloc] init];
72  NSUInteger max_count = 10;
73  while ([arr count] < max_count) {
74    // No warning. Array count is updated on every iteration.
75    [arr addObject: [[I alloc] init]];
76  }
77}
78
79void testArrayCountWithConstant() {
80  NSArray *arr = [[NSArray alloc] init];
81  while ([arr count] < 10) {
82    // No warning. Array count is updated on every iteration.
83    [arr addObject: [[I alloc] init]];
84  }
85}
86
87void testArrayCountProperty() {
88  NSArray *arr = [[NSArray alloc] init];
89  NSUInteger max_count = 10;
90  while (arr.count < max_count) {
91    // No warning. Array count is updated on every iteration.
92    [arr addObject: [[I alloc] init]];
93  }
94}
95
96void testArrayCountPropertyWithConstant() {
97  NSArray *arr = [[NSArray alloc] init];
98  while (arr.count < 10) {
99    // No warning. Array count is updated on every iteration.
100    [arr addObject: [[I alloc] init]];
101  }
102}
103
104@interface MyArray {
105  @public NSUInteger _count;
106}
107+(instancetype)alloc;
108-(instancetype)init;
109-(void)addObject: (id)anObject;
110
111-(void)populate;
112@end
113
114@implementation MyArray
115-(void)populate {
116  NSUInteger max_count = 10;
117  while (_count < max_count) {
118    // No warning. Array count is updated on every iteration.
119    [self addObject: [[I alloc] init]];
120  }
121}
122
123-(void)populateWithConstant {
124  while (_count < 10) {
125    // No warning. Array count is updated on every iteration.
126    [self addObject: [[I alloc] init]];
127  }
128}
129@end
130
131void testArrayCountIvar() {
132  MyArray *arr = [[MyArray alloc] init];
133  NSUInteger max_count = 10;
134  while (arr->_count < max_count) {
135    // No warning. Array count is updated on every iteration.
136    [arr addObject: [[I alloc] init]];
137  }
138}
139
140void testArrayCountIvarWithConstant() {
141  MyArray *arr = [[MyArray alloc] init];
142  while (arr->_count < 10) {
143    // No warning. Array count is updated on every iteration.
144    [arr addObject: [[I alloc] init]];
145  }
146}
147