Author: Aditya Singh Date: 2026-02-15T12:39:29+08:00 New Revision: 5548b24d18ad9e856bcb354a17b52c15fa37bf73
URL: https://github.com/llvm/llvm-project/commit/5548b24d18ad9e856bcb354a17b52c15fa37bf73 DIFF: https://github.com/llvm/llvm-project/commit/5548b24d18ad9e856bcb354a17b52c15fa37bf73.diff LOG: [clang-tidy] Fix false positive for generic lambda parameters in readability-non-const-parameter (#179051) Fixes #177354 ### Summary The `readability-non-const-parameter` check produces false positives on generic lambda parameters, not fully resolved by #177345. ### Problem Generic lambdas with explicit template parameters create dependent contexts that cannot be analyzed at parse time: ```cpp auto lambda = []<typename T>(int *p) { T x(*p); // No longer warns }; ``` Added: Modified: clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/test/clang-tidy/checkers/readability/non-const-parameter.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp index 2ecde56cd7af8..9950eca3fa7bd 100644 --- a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp @@ -95,8 +95,7 @@ void NonConstParameterCheck::check(const MatchFinder::MatchResult &Result) { } } } else if (const auto *CE = dyn_cast<CXXUnresolvedConstructExpr>(S)) { - for (const auto *Arg : CE->arguments()) - markCanNotBeConst(Arg->IgnoreParenCasts(), true); + markCanNotBeConst(CE, true); } else if (const auto *R = dyn_cast<ReturnStmt>(S)) { markCanNotBeConst(R->getRetValue(), true); } else if (const auto *U = dyn_cast<UnaryOperator>(S)) { @@ -104,8 +103,10 @@ void NonConstParameterCheck::check(const MatchFinder::MatchResult &Result) { } } else if (const auto *VD = Result.Nodes.getNodeAs<VarDecl>("Mark")) { const QualType T = VD->getType(); - if ((T->isPointerType() && !T->getPointeeType().isConstQualified()) || - T->isArrayType() || T->isRecordType()) + if (T->isDependentType()) + markCanNotBeConst(VD->getInit(), false); + else if ((T->isPointerType() && !T->getPointeeType().isConstQualified()) || + T->isArrayType() || T->isRecordType()) markCanNotBeConst(VD->getInit(), true); else if (T->isLValueReferenceType() && !T->getPointeeType().isConstQualified()) @@ -221,9 +222,17 @@ void NonConstParameterCheck::markCanNotBeConst(const Expr *E, for (const auto *Arg : Constr->arguments()) if (const auto *M = dyn_cast<MaterializeTemporaryExpr>(Arg)) markCanNotBeConst(cast<Expr>(M->getSubExpr()), CanNotBeConst); + else + markCanNotBeConst(Arg, CanNotBeConst); + } else if (const auto *CE = dyn_cast<CXXUnresolvedConstructExpr>(E)) { + for (const auto *Arg : CE->arguments()) + markCanNotBeConst(Arg, CanNotBeConst); } else if (const auto *ILE = dyn_cast<InitListExpr>(E)) { for (unsigned I = 0U; I < ILE->getNumInits(); ++I) - markCanNotBeConst(ILE->getInit(I), true); + markCanNotBeConst(ILE->getInit(I), CanNotBeConst); + } else if (const auto *PLE = dyn_cast<ParenListExpr>(E)) { + for (unsigned I = 0U; I < PLE->getNumExprs(); ++I) + markCanNotBeConst(PLE->getExpr(I), CanNotBeConst); } else if (CanNotBeConst) { // Referencing parameter. if (const auto *D = dyn_cast<DeclRefExpr>(E)) { diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 6799b2c136f38..0c487524390e3 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -229,7 +229,8 @@ Changes in existing checks - Improved :doc:`readability-non-const-parameter <clang-tidy/checks/readability/non-const-parameter>` check by avoiding false - positives on parameters used in dependent expressions. + positives on parameters used in dependent expressions (e.g. inside generic + lambdas). - Improved :doc:`readability-simplify-boolean-expr <clang-tidy/checks/readability/simplify-boolean-expr>` check to provide valid diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/non-const-parameter.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/non-const-parameter.cpp index 0079fa9e96434..c07312f989cea 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/non-const-parameter.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/non-const-parameter.cpp @@ -360,6 +360,15 @@ class B final { }; void gh176623() { + // CHECK-MESSAGES-NOT: warning: auto const V1 = []<bool tc>(char* p) { auto X = A<tc>(p); }; + // CHECK-MESSAGES-NOT: warning: auto const V2 = []<bool tc>(char* p) { auto Y = B(p); }; } + +void testGenericLambdaIssue177354() { + // CHECK-MESSAGES-NOT: warning: pointer parameter 'p' can be pointer to const + auto genericLambda = []<typename T>(int *p) { + T x(*p); + }; +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
