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

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/infinite-loop.mm