Author: Artem Dergachev Date: 2021-05-13T11:25:02-07:00 New Revision: 5ad2eeeadaf15856332f66ed7c244d52a86b0be7
URL: https://github.com/llvm/llvm-project/commit/5ad2eeeadaf15856332f66ed7c244d52a86b0be7 DIFF: https://github.com/llvm/llvm-project/commit/5ad2eeeadaf15856332f66ed7c244d52a86b0be7.diff LOG: [clang-tidy] bugprone-infinite-loop: React to ObjC ivars and messages. If the loop condition is a value of an instance variable, a property value, or a message result value, it's a good indication that the loop is not infinite and we have a really hard time proving the opposite so suppress the warning. Differential Revision: https://reviews.llvm.org/D102294 Added: Modified: clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.mm Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp index ab62b128d700f..8ac7f8eb28aee 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp @@ -61,7 +61,8 @@ static bool isVarThatIsPossiblyChanged(const Decl *Func, const Stmt *LoopStmt, isChanged(LoopStmt, Var, Context); // FIXME: Track references. } - } else if (isa<MemberExpr>(Cond) || isa<CallExpr>(Cond)) { + } else if (isa<MemberExpr, CallExpr, + ObjCIvarRefExpr, ObjCPropertyRefExpr, ObjCMessageExpr>(Cond)) { // FIXME: Handle MemberExpr. return true; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.mm b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.mm index 77d85acf248e7..8f157b3d721a4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.mm +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.mm @@ -1,8 +1,20 @@ // 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() { @@ -33,3 +45,81 @@ + (void)classMethod { } } @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]]; + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits