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