// 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++;
  }
}
@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]];
  }
}
