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