[clang-tools-extra] 5548b24 - [clang-tidy] Fix false positive for generic lambda parameters in readability-non-const-parameter (#179051)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 14 20:39:34 PST 2026
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);
+ };
+}
More information about the cfe-commits
mailing list