diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp index 17e09c2083634..82e55cc2d28ea 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidReferenceCoroutineParametersCheck.cpp @@ -16,17 +16,19 @@ namespace clang::tidy::cppcoreguidelines { void AvoidReferenceCoroutineParametersCheck::registerMatchers( MatchFinder *Finder) { - auto IsCoroMatcher = - hasDescendant(expr(anyOf(coyieldExpr(), coreturnStmt(), coawaitExpr()))); - Finder->addMatcher(parmVarDecl(hasType(type(referenceType())), - hasAncestor(functionDecl(IsCoroMatcher))) - .bind("param"), - this); + Finder->addMatcher( + functionDecl(unless(parameterCountIs(0)), hasBody(coroutineBodyStmt())) + .bind("fnt"), + this); } void AvoidReferenceCoroutineParametersCheck::check( const MatchFinder::MatchResult &Result) { - if (const auto *Param = Result.Nodes.getNodeAs("param")) { + const auto *Function = Result.Nodes.getNodeAs("fnt"); + for (const ParmVarDecl *Param : Function->parameters()) { + if (!Param->getType().getCanonicalType()->isReferenceType()) + continue; + diag(Param->getBeginLoc(), "coroutine parameters should not be references"); } } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 7b00a0a6ddc7f..1bc56023f142a 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -188,6 +188,12 @@ Changes in existing checks to ignore ``static`` variables declared within the scope of ``class``/``struct``. +- Improved :doc:`cppcoreguidelines-avoid-reference-coroutine-parameters + ` + check to ignore false positives related to matching parameters of non + coroutine functions and increase issue detection for cases involving type + aliases with references. + - Improved :doc:`cppcoreguidelines-prefer-member-initializer ` check to ignore delegate constructors. diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp index abeb7fc770155..4df872ee15c6f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-reference-coroutine-parameters.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t +// RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t -- // NOLINTBEGIN namespace std { @@ -82,3 +82,18 @@ void defines_a_lambda() { auto WithReferences2 = [](int&) -> Coro { co_return; }; // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters] } + +void coroInFunctionWithReference(int&) { + auto SampleCoro = [](int x) -> Coro { co_return; }; +} + +Coro lambdaWithReferenceInCoro() { + auto SampleLambda = [](int& x) {}; + co_return; +} + +using MyIntegerRef = int&; +Coro coroWithReferenceBehindTypedef(MyIntegerRef ref) { +// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters] + co_return; +}