[PATCH] D31757: [clang-tidy] Add a clang-tidy check for possible inefficient vector operations

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 13 07:20:10 PDT 2017


aaron.ballman added inline comments.


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.cpp:81
+          hasLoopInit(LoopVarInit),
+          hasCondition(binaryOperator(hasOperatorName("<"),
+                                      hasLHS(RefersToLoopVar),
----------------
Perhaps you could support other comparisons, but not attempt to generate a fix-it for them? It seems odd that this would trigger for `<` but not `<=`, but I can see why you'd not want to figure out the reserve call for `!(foo >= 10)`.


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.cpp:83
+                                      hasLHS(RefersToLoopVar),
+                                      hasRHS(expr().bind(LoopEndExprName)))),
+          hasIncrement(unaryOperator(hasOperatorName("++"),
----------------
Thinking out loud, but, what happens if the loop end expression has some hidden complexity to it? e.g.,
```
for (int i = 0; i < i + 1; ++i) { // This is a "creative" loop.
  v.push_back(i);
}
```


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.cpp:84
+                                      hasRHS(expr().bind(LoopEndExprName)))),
+          hasIncrement(unaryOperator(hasOperatorName("++"),
+                                     hasUnaryOperand(RefersToLoopVar))),
----------------
Can you add a test case for post-increment (all of your tests use pre-increment)? Also, count-down loops seem reasonable to support as well, no?
```
for (int i = 10; i >= 0; --i) {
  v.push_back(i);
}
```


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.cpp:86-87
+                                     hasUnaryOperand(RefersToLoopVar))),
+          hasBody(anyOf(compoundStmt(statementCountIs(1), has(PushBackCall)),
+                        PushBackCall)),
+          hasParent(compoundStmt(has(VectorVarDefStmt)).bind(LoopParentName)))
----------------
You should update the documentation to mention that this check only worries about a for loop with a single statement in it. It will be surprising that this code does not trigger the same diagnostic:
```
for (...) {
  std::cout << i;
  v.push_back(i);
}
```


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.cpp:95-96
+    const MatchFinder::MatchResult &Result) {
+  if (Result.Context->getDiagnostics().hasUncompilableErrorOccurred())
+    return;
+
----------------
We don't usually add this test in to our check calls; why are you adding it here?


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.cpp:98
+
+  const SourceManager *SM = Result.SourceManager;
+  const auto *ForLoop = Result.Nodes.getNodeAs<ForStmt>(LoopCounterName);
----------------
Might as well make this a reference rather than a pointer (simplifies code elsewhere).


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.cpp:100-104
+  const auto* PushBackCall =
+      Result.Nodes.getNodeAs<CXXMemberCallExpr>(PushBackCallName);
+  const auto* LoopEndExpr =
+      Result.Nodes.getNodeAs<Expr>(LoopEndExprName);
+  const auto* LoopParent =
----------------
Formatting (I would recommend running clang-format over the patch).


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.cpp:109-111
+  auto AllVectorVarRefs = utils::decl_ref_expr::allDeclRefExprs(
+      *VectorVarDecl, *LoopParent, *Result.Context);
+  for (const auto *Ref : AllVectorVarRefs) {
----------------
I'm not certain what types are being used here. Can you turn `AllVectorVarRefs` into something with an explicit type so that I can know what `Ref`'s type is?


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.cpp:117
+    //
+    // FIXME: make it more intelligent to identified the pre-allocating
+    // operations before the for loop.
----------------
identified -> identify


================
Comment at: clang-tidy/performance/InefficientVectorOperationCheck.h:20
+/// Finds possible inefficient `std::vector` operations (e.g. `push_back`) in
+/// for-loops that may cause unnecessary memory reallocations.
+///
----------------
Drop the hyphen in for loops.


================
Comment at: docs/clang-tidy/checks/performance-inefficient-vector-operation.rst:7
+Finds possible inefficient `std::vector` operations (e.g. `push_back`) that may
+cause unnecessary memory reallocations.
+
----------------
The docs should talk more about the limitations of the check (like how many statements it can contain, etc).


https://reviews.llvm.org/D31757





More information about the cfe-commits mailing list