xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/infinite-loop.mm (revision 7df0f0b410674437f0b56262043e22b177709161)
189a1d03eSRichard// RUN: %check_clang_tidy %s bugprone-infinite-loop %t -- -- -fblocks
289a1d03eSRichard// RUN: %check_clang_tidy %s bugprone-infinite-loop %t -- -- -fblocks -fobjc-arc
389a1d03eSRichard
489a1d03eSRichardtypedef __typeof(sizeof(int)) NSUInteger;
589a1d03eSRichard
689a1d03eSRichard@interface NSArray
789a1d03eSRichard+(instancetype)alloc;
889a1d03eSRichard-(instancetype)init;
989a1d03eSRichard@property(readonly) NSUInteger count;
1089a1d03eSRichard-(void)addObject: (id)anObject;
1189a1d03eSRichard@end
1289a1d03eSRichard
1389a1d03eSRichard@interface I
1489a1d03eSRichard-(void) instanceMethod;
1589a1d03eSRichard+(void) classMethod;
1689a1d03eSRichard+(instancetype)alloc;
1789a1d03eSRichard-(instancetype)init;
1889a1d03eSRichard@end
1989a1d03eSRichard
2089a1d03eSRichardvoid plainCFunction() {
2189a1d03eSRichard  int i = 0;
2289a1d03eSRichard  int j = 0;
2389a1d03eSRichard  while (i < 10) {
2489a1d03eSRichard    // 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]
2589a1d03eSRichard    j++;
2689a1d03eSRichard  }
2789a1d03eSRichard}
2889a1d03eSRichard
2989a1d03eSRichard@implementation I
3089a1d03eSRichard- (void)instanceMethod {
3189a1d03eSRichard  int i = 0;
3289a1d03eSRichard  int j = 0;
3389a1d03eSRichard  while (i < 10) {
3489a1d03eSRichard    // 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]
3589a1d03eSRichard    j++;
3689a1d03eSRichard  }
3789a1d03eSRichard}
3889a1d03eSRichard
3989a1d03eSRichard+ (void)classMethod {
4089a1d03eSRichard  int i = 0;
4189a1d03eSRichard  int j = 0;
4289a1d03eSRichard  while (i < 10) {
4389a1d03eSRichard    // 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]
4489a1d03eSRichard    j++;
4589a1d03eSRichard  }
4689a1d03eSRichard}
47*7df0f0b4Sziqingluo-90
48*7df0f0b4Sziqingluo-90+ (void)recursiveMethod {
49*7df0f0b4Sziqingluo-90  static int i = 0;
50*7df0f0b4Sziqingluo-90
51*7df0f0b4Sziqingluo-90  i++;
52*7df0f0b4Sziqingluo-90  while (i < 10) {
53*7df0f0b4Sziqingluo-90    // 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*7df0f0b4Sziqingluo-90    [I classMethod];
55*7df0f0b4Sziqingluo-90  }
56*7df0f0b4Sziqingluo-90
57*7df0f0b4Sziqingluo-90  id x = [[I alloc] init];
58*7df0f0b4Sziqingluo-90
59*7df0f0b4Sziqingluo-90  while (i < 10) {
60*7df0f0b4Sziqingluo-90    // 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*7df0f0b4Sziqingluo-90    [x instanceMethod];
62*7df0f0b4Sziqingluo-90  }
63*7df0f0b4Sziqingluo-90  while (i < 10) {
64*7df0f0b4Sziqingluo-90    // no warning, there is a recursive call that can mutate the static local variable
65*7df0f0b4Sziqingluo-90    [I recursiveMethod];
66*7df0f0b4Sziqingluo-90  }
67*7df0f0b4Sziqingluo-90}
6889a1d03eSRichard@end
6989a1d03eSRichard
7089a1d03eSRichardvoid testArrayCount() {
7189a1d03eSRichard  NSArray *arr = [[NSArray alloc] init];
7289a1d03eSRichard  NSUInteger max_count = 10;
7389a1d03eSRichard  while ([arr count] < max_count) {
7489a1d03eSRichard    // No warning. Array count is updated on every iteration.
7589a1d03eSRichard    [arr addObject: [[I alloc] init]];
7689a1d03eSRichard  }
7789a1d03eSRichard}
7889a1d03eSRichard
7989a1d03eSRichardvoid testArrayCountWithConstant() {
8089a1d03eSRichard  NSArray *arr = [[NSArray alloc] init];
8189a1d03eSRichard  while ([arr count] < 10) {
8289a1d03eSRichard    // No warning. Array count is updated on every iteration.
8389a1d03eSRichard    [arr addObject: [[I alloc] init]];
8489a1d03eSRichard  }
8589a1d03eSRichard}
8689a1d03eSRichard
8789a1d03eSRichardvoid testArrayCountProperty() {
8889a1d03eSRichard  NSArray *arr = [[NSArray alloc] init];
8989a1d03eSRichard  NSUInteger max_count = 10;
9089a1d03eSRichard  while (arr.count < max_count) {
9189a1d03eSRichard    // No warning. Array count is updated on every iteration.
9289a1d03eSRichard    [arr addObject: [[I alloc] init]];
9389a1d03eSRichard  }
9489a1d03eSRichard}
9589a1d03eSRichard
9689a1d03eSRichardvoid testArrayCountPropertyWithConstant() {
9789a1d03eSRichard  NSArray *arr = [[NSArray alloc] init];
9889a1d03eSRichard  while (arr.count < 10) {
9989a1d03eSRichard    // No warning. Array count is updated on every iteration.
10089a1d03eSRichard    [arr addObject: [[I alloc] init]];
10189a1d03eSRichard  }
10289a1d03eSRichard}
10389a1d03eSRichard
10489a1d03eSRichard@interface MyArray {
10589a1d03eSRichard  @public NSUInteger _count;
10689a1d03eSRichard}
10789a1d03eSRichard+(instancetype)alloc;
10889a1d03eSRichard-(instancetype)init;
10989a1d03eSRichard-(void)addObject: (id)anObject;
11089a1d03eSRichard
11189a1d03eSRichard-(void)populate;
11289a1d03eSRichard@end
11389a1d03eSRichard
11489a1d03eSRichard@implementation MyArray
11589a1d03eSRichard-(void)populate {
11689a1d03eSRichard  NSUInteger max_count = 10;
11789a1d03eSRichard  while (_count < max_count) {
11889a1d03eSRichard    // No warning. Array count is updated on every iteration.
11989a1d03eSRichard    [self addObject: [[I alloc] init]];
12089a1d03eSRichard  }
12189a1d03eSRichard}
12289a1d03eSRichard
12389a1d03eSRichard-(void)populateWithConstant {
12489a1d03eSRichard  while (_count < 10) {
12589a1d03eSRichard    // No warning. Array count is updated on every iteration.
12689a1d03eSRichard    [self addObject: [[I alloc] init]];
12789a1d03eSRichard  }
12889a1d03eSRichard}
12989a1d03eSRichard@end
13089a1d03eSRichard
13189a1d03eSRichardvoid testArrayCountIvar() {
13289a1d03eSRichard  MyArray *arr = [[MyArray alloc] init];
13389a1d03eSRichard  NSUInteger max_count = 10;
13489a1d03eSRichard  while (arr->_count < max_count) {
13589a1d03eSRichard    // No warning. Array count is updated on every iteration.
13689a1d03eSRichard    [arr addObject: [[I alloc] init]];
13789a1d03eSRichard  }
13889a1d03eSRichard}
13989a1d03eSRichard
14089a1d03eSRichardvoid testArrayCountIvarWithConstant() {
14189a1d03eSRichard  MyArray *arr = [[MyArray alloc] init];
14289a1d03eSRichard  while (arr->_count < 10) {
14389a1d03eSRichard    // No warning. Array count is updated on every iteration.
14489a1d03eSRichard    [arr addObject: [[I alloc] init]];
14589a1d03eSRichard  }
14689a1d03eSRichard}
147