[clang-tools-extra] [clang-tidy] Make range source classes configurable (PR #226193)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 24 21:17:48 PDT 2026
https://github.com/algol83 updated https://github.com/llvm/llvm-project/pull/226193
>From 21d719e473667ea5f33d94699cf75dd0755baf84 Mon Sep 17 00:00:00 2001
From: Algol83 <drom.home at gmail.com>
Date: Thu, 24 Sep 2026 17:29:11 +0300
Subject: [PATCH 1/3] [clang-tidy] Make range source classes configurable
---
.../InefficientVectorOperationCheck.cpp | 21 ++++++++++++-------
.../InefficientVectorOperationCheck.h | 1 +
clang-tools-extra/docs/ReleaseNotes.md | 5 +++++
.../inefficient-vector-operation.rst | 8 +++++++
...nt-vector-operation-vectorlike-classes.cpp | 21 ++++++++++++++++++-
5 files changed, 47 insertions(+), 9 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp
index 93cd3a2229a25a..98dda6476dc5c1 100644
--- a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp
@@ -58,10 +58,9 @@ static constexpr char LoopInitVarName[] = "loop_init_var";
static constexpr char LoopEndExprName[] = "loop_end_expr";
static constexpr char RangeLoopName[] = "for_range_loop";
-static ast_matchers::internal::Matcher<Expr> supportedContainerTypesMatcher() {
- return hasType(cxxRecordDecl(hasAnyName(
- "::std::vector", "::std::set", "::std::unordered_set", "::std::map",
- "::std::unordered_map", "::std::array", "::std::deque")));
+static ast_matchers::internal::Matcher<Expr>
+supportedContainerTypesMatcher(ArrayRef<StringRef> ContainerTypes) {
+ return hasType(cxxRecordDecl(hasAnyName(ContainerTypes)));
}
namespace {
@@ -77,12 +76,18 @@ InefficientVectorOperationCheck::InefficientVectorOperationCheck(
: ClangTidyCheck(Name, Context),
VectorLikeClasses(utils::options::parseStringList(
Options.get("VectorLikeClasses", "::std::vector"))),
+ RangeLikeClasses(utils::options::parseStringList(Options.get(
+ "RangeLikeClasses",
+ "::std::vector;::std::set;::std::unordered_set;::std::map;"
+ "::std::unordered_map;::std::array;::std::deque"))),
EnableProto(Options.get("EnableProto", false)) {}
void InefficientVectorOperationCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "VectorLikeClasses",
utils::options::serializeStringList(VectorLikeClasses));
+ Options.store(Opts, "RangeLikeClasses",
+ utils::options::serializeStringList(RangeLikeClasses));
Options.store(Opts, "EnableProto", EnableProto);
}
@@ -146,10 +151,10 @@ void InefficientVectorOperationCheck::addMatcher(
// FIXME: Support more complex range-expressions.
Finder->addMatcher(
cxxForRangeStmt(
- hasRangeInit(
- anyOf(declRefExpr(supportedContainerTypesMatcher()),
- memberExpr(hasObjectExpression(unless(hasSideEffects())),
- supportedContainerTypesMatcher()))),
+ hasRangeInit(anyOf(
+ declRefExpr(supportedContainerTypesMatcher(RangeLikeClasses)),
+ memberExpr(hasObjectExpression(unless(hasSideEffects())),
+ supportedContainerTypesMatcher(RangeLikeClasses)))),
HasInterestingLoopBody, InInterestingCompoundStmt)
.bind(RangeLoopName),
this);
diff --git a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
index 5f3b88f51d6260..f3ba08667b54fc 100644
--- a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
+++ b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.h
@@ -37,6 +37,7 @@ class InefficientVectorOperationCheck : public ClangTidyCheck {
const ast_matchers::DeclarationMatcher &AppendMethodDecl,
StringRef AppendCallName, ast_matchers::MatchFinder *Finder);
const std::vector<StringRef> VectorLikeClasses;
+ const std::vector<StringRef> RangeLikeClasses;
// If true, also check inefficient operations for proto repeated fields.
bool EnableProto;
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 833638a47abc63..3e955b8e8732c0 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -162,6 +162,11 @@ infrastructure are described first, followed by tool-specific sections.
#### Changes in existing checks
+- Improved {doc}`performance-inefficient-vector-operation
+ <clang-tidy/checks/performance/inefficient-vector-operation>` by adding the
+ `RangeLikeClasses` option to configure container classes that can be used as
+ sources in range-based for loops.
+
- Improved {doc}`bugprone-implicit-widening-of-multiplication-result
<clang-tidy/checks/bugprone/implicit-widening-of-multiplication-result>` check
by suggesting a wider type of the same signedness as the original operands,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/inefficient-vector-operation.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/inefficient-vector-operation.rst
index 75016eb72d279f..8ef9ef7c2f858a 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/performance/inefficient-vector-operation.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/performance/inefficient-vector-operation.rst
@@ -59,6 +59,14 @@ Options
Semicolon-separated list of names of vector-like classes. By default only
``::std::vector`` is considered.
+.. option:: RangeLikeClasses
+
+ Semicolon-separated list of names of container classes that can be used as
+ sources in range-based for loops. By default, ``::std::vector``,
+ ``::std::set``, ``::std::unordered_set``, ``::std::map``,
+ ``::std::unordered_map``, ``::std::array``, and ``::std::deque`` are
+ considered.
+
.. option:: EnableProto
When `true`, the check will also warn on inefficient operations for proto
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation-vectorlike-classes.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation-vectorlike-classes.cpp
index 41d2d3733e07a1..80f38175cea425 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation-vectorlike-classes.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation-vectorlike-classes.cpp
@@ -1,7 +1,9 @@
// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- \
// RUN: -config='{CheckOptions: \
// RUN: {performance-inefficient-vector-operation.VectorLikeClasses: \
-// RUN: "VectorLikeInheritedPushBack;VectorLikeDirectPushBack;VectorLikeInheritedEmplaceBack"}}'
+// RUN: "VectorLikeInheritedPushBack;VectorLikeDirectPushBack;VectorLikeInheritedEmplaceBack", \
+// RUN: performance-inefficient-vector-operation.RangeLikeClasses: \
+// RUN: "RangeLike"}}'
class VectorLikePushBackBase {
public:
@@ -29,6 +31,13 @@ class VectorLikeInheritedEmplaceBack : public VectorLikeEmplaceBackBase {
void reserve(int);
};
+class RangeLike {
+public:
+ int *begin();
+ int *end();
+ int size() const;
+};
+
void testVectorLikeClasses() {
{
VectorLikeInheritedPushBack inheritedPushBackVector;
@@ -56,4 +65,14 @@ void testVectorLikeClasses() {
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'emplace_back' is called inside a loop; consider pre-allocating the container capacity before the loop
}
}
+
+ {
+ RangeLike range;
+ VectorLikeDirectPushBack vector;
+ // CHECK-FIXES: vector.reserve(range.size());
+ for (int value : range) {
+ vector.push_back(value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop
+ }
+ }
}
>From 0604f86efeb6de1e37547f8d8fa5ca3b4af997e0 Mon Sep 17 00:00:00 2001
From: Algol83 <drom.home at gmail.com>
Date: Thu, 24 Sep 2026 18:55:38 +0300
Subject: [PATCH 2/3] [clang-tidy] Improve RangeLikeClasses documentation and
tests
---
clang-tools-extra/docs/ReleaseNotes.md | 10 +++---
.../inefficient-vector-operation.rst | 9 +++---
...nt-vector-operation-vectorlike-classes.cpp | 32 +++++++++++++++++++
3 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 3e955b8e8732c0..c7c02a2ea0ac65 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -162,11 +162,6 @@ infrastructure are described first, followed by tool-specific sections.
#### Changes in existing checks
-- Improved {doc}`performance-inefficient-vector-operation
- <clang-tidy/checks/performance/inefficient-vector-operation>` by adding the
- `RangeLikeClasses` option to configure container classes that can be used as
- sources in range-based for loops.
-
- Improved {doc}`bugprone-implicit-widening-of-multiplication-result
<clang-tidy/checks/bugprone/implicit-widening-of-multiplication-result>` check
by suggesting a wider type of the same signedness as the original operands,
@@ -257,6 +252,11 @@ infrastructure are described first, followed by tool-specific sections.
offered when an argument covers only part of a macro expansion, as it then
has no source text of its own.
+- Improved {doc}`performance-inefficient-vector-operation
+ <clang-tidy/checks/performance/inefficient-vector-operation>` by adding the
+ `RangeLikeClasses` option to configure container classes that can be used as
+ sources in range-based for loops.
+
- Improved {doc}`readability-convert-member-functions-to-static
<clang-tidy/checks/readability/convert-member-functions-to-static>` check by
fixing a crash when checking a const-qualified method declared with the
diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/inefficient-vector-operation.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/inefficient-vector-operation.rst
index 8ef9ef7c2f858a..72d0ceca084d68 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/performance/inefficient-vector-operation.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/performance/inefficient-vector-operation.rst
@@ -62,10 +62,11 @@ Options
.. option:: RangeLikeClasses
Semicolon-separated list of names of container classes that can be used as
- sources in range-based for loops. By default, ``::std::vector``,
- ``::std::set``, ``::std::unordered_set``, ``::std::map``,
- ``::std::unordered_map``, ``::std::array``, and ``::std::deque`` are
- considered.
+ sources in range-based for loops. Each configured class must provide an
+ accessible ``size()`` method whose result is the number of elements visited
+ by the loop. The configured list replaces the default list, which contains
+ ``::std::vector``, ``::std::set``, ``::std::unordered_set``, ``::std::map``,
+ ``::std::unordered_map``, ``::std::array``, and ``::std::deque``.
.. option:: EnableProto
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation-vectorlike-classes.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation-vectorlike-classes.cpp
index 80f38175cea425..ba16d921f84080 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation-vectorlike-classes.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation-vectorlike-classes.cpp
@@ -38,6 +38,18 @@ class RangeLike {
int size() const;
};
+class UnconfiguredRangeLike {
+public:
+ int *begin();
+ int *end();
+ int size() const;
+};
+
+class RangeHolder {
+public:
+ RangeLike range;
+};
+
void testVectorLikeClasses() {
{
VectorLikeInheritedPushBack inheritedPushBackVector;
@@ -75,4 +87,24 @@ void testVectorLikeClasses() {
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop
}
}
+
+ {
+ UnconfiguredRangeLike range;
+ VectorLikeDirectPushBack vector;
+ // CHECK-FIXES-NOT: vector.reserve(range.size());
+ for (int value : range) {
+ vector.push_back(value);
+ // CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop
+ }
+ }
+
+ {
+ RangeHolder holder;
+ VectorLikeDirectPushBack vector;
+ // CHECK-FIXES: vector.reserve(holder.range.size());
+ for (int value : holder.range) {
+ vector.push_back(value);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop
+ }
+ }
}
>From 68946301092a04c31d07729dd45cf0ff39b717c6 Mon Sep 17 00:00:00 2001
From: Algol83 <drom.home at gmail.com>
Date: Thu, 24 Sep 2026 19:06:13 +0300
Subject: [PATCH 3/3] [clang-tidy] Fix RangeLikeClasses release note link
---
clang-tools-extra/docs/ReleaseNotes.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index c7c02a2ea0ac65..75da9d2de93fd7 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -254,7 +254,7 @@ infrastructure are described first, followed by tool-specific sections.
- Improved {doc}`performance-inefficient-vector-operation
<clang-tidy/checks/performance/inefficient-vector-operation>` by adding the
- `RangeLikeClasses` option to configure container classes that can be used as
+ {option}`RangeLikeClasses` to configure container classes that can be used as
sources in range-based for loops.
- Improved {doc}`readability-convert-member-functions-to-static
More information about the cfe-commits
mailing list