[clang-tools-extra] a85eb11 - [clang-tidy] Extend LoopConvert on array with `!=` comparison
Nathan James via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 4 10:59:10 PST 2021
Author: Nathan James
Date: 2021-03-04T18:58:59Z
New Revision: a85eb11129ce941e91b5bc3b188e469aaca4425f
URL: https://github.com/llvm/llvm-project/commit/a85eb11129ce941e91b5bc3b188e469aaca4425f
DIFF: https://github.com/llvm/llvm-project/commit/a85eb11129ce941e91b5bc3b188e469aaca4425f.diff
LOG: [clang-tidy] Extend LoopConvert on array with `!=` comparison
Enables transforming loops of the form:
```
for (int i = 0; I != container.size(); ++I) { container[I]...; }
for (int i = 0; I != N; ++I) { FixedArrSizeN[I]...; }
```
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D97940
Added:
Modified:
clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/modernize-loop-convert-basic.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
index 9df343f81d1c..9f6ef08ef839 100644
--- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -83,6 +83,17 @@ static const StatementMatcher incrementVarMatcher() {
return declRefExpr(to(varDecl(equalsBoundNode(InitVarName))));
}
+static StatementMatcher
+arrayConditionMatcher(internal::Matcher<Expr> LimitExpr) {
+ return binaryOperator(
+ anyOf(allOf(hasOperatorName("<"), hasLHS(integerComparisonMatcher()),
+ hasRHS(LimitExpr)),
+ allOf(hasOperatorName(">"), hasLHS(LimitExpr),
+ hasRHS(integerComparisonMatcher())),
+ allOf(hasOperatorName("!="),
+ hasOperands(integerComparisonMatcher(), LimitExpr))));
+}
+
/// The matcher for loops over arrays.
/// \code
/// for (int i = 0; i < 3 + 2; ++i) { ... }
@@ -99,18 +110,12 @@ StatementMatcher makeArrayLoopMatcher() {
StatementMatcher ArrayBoundMatcher =
expr(hasType(isInteger())).bind(ConditionBoundName);
- return forStmt(
- unless(isInTemplateInstantiation()),
- hasLoopInit(declStmt(hasSingleDecl(initToZeroMatcher()))),
- hasCondition(anyOf(
- binaryOperator(hasOperatorName("<"),
- hasLHS(integerComparisonMatcher()),
- hasRHS(ArrayBoundMatcher)),
- binaryOperator(hasOperatorName(">"), hasLHS(ArrayBoundMatcher),
- hasRHS(integerComparisonMatcher())))),
- hasIncrement(
- unaryOperator(hasOperatorName("++"),
- hasUnaryOperand(incrementVarMatcher()))))
+ return forStmt(unless(isInTemplateInstantiation()),
+ hasLoopInit(declStmt(hasSingleDecl(initToZeroMatcher()))),
+ hasCondition(arrayConditionMatcher(ArrayBoundMatcher)),
+ hasIncrement(
+ unaryOperator(hasOperatorName("++"),
+ hasUnaryOperand(incrementVarMatcher()))))
.bind(LoopNameArray);
}
@@ -278,22 +283,16 @@ StatementMatcher makePseudoArrayLoopMatcher() {
declRefExpr(to(varDecl(equalsBoundNode(EndVarName))))),
EndInitMatcher));
- return forStmt(
- unless(isInTemplateInstantiation()),
- hasLoopInit(
- anyOf(declStmt(declCountIs(2),
- containsDeclaration(0, initToZeroMatcher()),
- containsDeclaration(1, EndDeclMatcher)),
- declStmt(hasSingleDecl(initToZeroMatcher())))),
- hasCondition(anyOf(
- binaryOperator(hasOperatorName("<"),
- hasLHS(integerComparisonMatcher()),
- hasRHS(IndexBoundMatcher)),
- binaryOperator(hasOperatorName(">"), hasLHS(IndexBoundMatcher),
- hasRHS(integerComparisonMatcher())))),
- hasIncrement(
- unaryOperator(hasOperatorName("++"),
- hasUnaryOperand(incrementVarMatcher()))))
+ return forStmt(unless(isInTemplateInstantiation()),
+ hasLoopInit(
+ anyOf(declStmt(declCountIs(2),
+ containsDeclaration(0, initToZeroMatcher()),
+ containsDeclaration(1, EndDeclMatcher)),
+ declStmt(hasSingleDecl(initToZeroMatcher())))),
+ hasCondition(arrayConditionMatcher(IndexBoundMatcher)),
+ hasIncrement(
+ unaryOperator(hasOperatorName("++"),
+ hasUnaryOperand(incrementVarMatcher()))))
.bind(LoopNamePseudoArray);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-loop-convert-basic.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-loop-convert-basic.cpp
index 06b1b739632f..b2cd0e2ab513 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize-loop-convert-basic.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-loop-convert-basic.cpp
@@ -95,6 +95,33 @@ void f() {
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
// CHECK-FIXES: for (auto & Tea : Teas)
// CHECK-FIXES-NEXT: Tea.g();
+
+ for (int I = 0; N > I; ++I) {
+ printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]);
+ Sum += Arr[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ for (int I = 0; N != I; ++I) {
+ printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]);
+ Sum += Arr[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ for (int I = 0; I != N; ++I) {
+ printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]);
+ Sum += Arr[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int & I : Arr)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
}
const int *constArray() {
@@ -589,6 +616,33 @@ void f() {
// CHECK-FIXES: for (int I : *Cv)
// CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
// CHECK-FIXES-NEXT: Sum += I + 2;
+
+ for (int I = 0, E = V.size(); E > I; ++I) {
+ printf("Fibonacci number is %d\n", V[I]);
+ Sum += V[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ for (int I = 0, E = V.size(); I != E; ++I) {
+ printf("Fibonacci number is %d\n", V[I]);
+ Sum += V[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
+
+ for (int I = 0, E = V.size(); E != I; ++I) {
+ printf("Fibonacci number is %d\n", V[I]);
+ Sum += V[I] + 2;
+ }
+ // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+ // CHECK-FIXES: for (int I : V)
+ // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+ // CHECK-FIXES-NEXT: Sum += I + 2;
}
// Ensure that 'const auto &' is used with containers of non-trivial types.
More information about the cfe-commits
mailing list