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