Skip to content

Commit 4764091

Browse files
committed
Added option IsAllowedInCoroutines
1 parent 6f53984 commit 4764091

File tree

5 files changed

+20
-8
lines changed

5 files changed

+20
-8
lines changed

clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ UnnecessaryValueParamCheck::UnnecessaryValueParamCheck(
5050
utils::IncludeSorter::IS_LLVM),
5151
areDiagsSelfContained()),
5252
AllowedTypes(
53-
utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}
53+
utils::options::parseStringList(Options.get("AllowedTypes", ""))),
54+
IsAllowedInCoroutines(Options.get("IsAllowedInCoroutines", false)) {}
5455

5556
void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) {
5657
const auto ExpensiveValueParamDecl = parmVarDecl(
@@ -65,7 +66,6 @@ void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) {
6566
TK_AsIs,
6667
functionDecl(hasBody(stmt()), isDefinition(), unless(isImplicit()),
6768
unless(cxxMethodDecl(anyOf(isOverride(), isFinal()))),
68-
unless(hasBody(coroutineBodyStmt())),
6969
has(typeLoc(forEach(ExpensiveValueParamDecl))),
7070
decl().bind("functionDecl"))),
7171
this);
@@ -74,6 +74,10 @@ void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) {
7474
void UnnecessaryValueParamCheck::check(const MatchFinder::MatchResult &Result) {
7575
const auto *Param = Result.Nodes.getNodeAs<ParmVarDecl>("param");
7676
const auto *Function = Result.Nodes.getNodeAs<FunctionDecl>("functionDecl");
77+
if (!IsAllowedInCoroutines) {
78+
if (auto Body = Function->getBody(); Body && isa<CoroutineBodyStmt>(Body))
79+
return;
80+
}
7781

7882
TraversalKindScope RAII(*Result.Context, TK_AsIs);
7983

@@ -124,6 +128,7 @@ void UnnecessaryValueParamCheck::storeOptions(
124128
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
125129
Options.store(Opts, "AllowedTypes",
126130
utils::options::serializeStringList(AllowedTypes));
131+
Options.store(Opts, "IsAllowedInCoroutines", IsAllowedInCoroutines);
127132
}
128133

129134
void UnnecessaryValueParamCheck::onEndOfTranslationUnit() {

clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class UnnecessaryValueParamCheck : public ClangTidyCheck {
4646
ExprMutationAnalyzer::Memoized MutationAnalyzerCache;
4747
utils::IncludeInserter Inserter;
4848
const std::vector<StringRef> AllowedTypes;
49+
bool IsAllowedInCoroutines;
4950
};
5051

5152
} // namespace clang::tidy::performance

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,8 @@ Changes in existing checks
265265
<clang-tidy/checks/performance/unnecessary-value-param>` check performance by
266266
tolerating fix-it breaking compilation when functions is used as pointers
267267
to avoid matching usage of functions within the current compilation unit.
268-
Also suppressed this check for coroutine functions because it may not be safe
269-
and suggested fixes may result in hard-to-find bugs and crashes.
268+
Added an option `IsAllowedInCoroutines` with the default value ``false`` to
269+
suppress this check for coroutines where passing by reference may be unsafe.
270270

271271
- Improved :doc:`readability-convert-member-functions-to-static
272272
<clang-tidy/checks/readability/convert-member-functions-to-static>` check by

clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,6 @@ Because the fix-it needs to change the signature of the function, it may break
5858
builds if the function is used in multiple translation units or some codes
5959
depends on function signatures.
6060

61-
Note: This check does not suggest passing parameters by reference in coroutines
62-
because, after a coroutine suspend point, references could be dangling and no
63-
longer valid, so suggested changes may result in hard-to-find bugs and crashes.
64-
6561
Options
6662
-------
6763

@@ -78,3 +74,9 @@ Options
7874
default is empty. If a name in the list contains the sequence `::`, it is
7975
matched against the qualified type name (i.e. ``namespace::Type``),
8076
otherwise it is matched against only the type name (i.e. ``Type``).
77+
78+
.. option:: IsAllowedInCoroutines
79+
80+
A boolean specifying whether the check should suggest passing parameters by
81+
reference in coroutines. The default is `false`. Passing parameters by reference
82+
in coroutines may not be safe.

clang-tools-extra/test/clang-tidy/checkers/performance/unnecessary-value-param-coroutine.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
// RUN: %check_clang_tidy -std=c++20-or-later %s performance-unnecessary-value-param %t -- -fix-errors
2+
// RUN: %check_clang_tidy -std=c++20-or-later %s performance-unnecessary-value-param %t -- \
3+
// RUN: -config='{CheckOptions: {performance-unnecessary-value-param.IsAllowedInCoroutines: false}}' -fix-errors
4+
// RUN: not %check_clang_tidy -std=c++20-or-later %s performance-unnecessary-value-param %t -- \
5+
// RUN: -config='{CheckOptions: {performance-unnecessary-value-param.IsAllowedInCoroutines: true}}' -fix-errors
26

37
namespace std {
48

0 commit comments

Comments
 (0)