Skip to content

Commit 6cbf15e

Browse files
committed
[clang-tidy] Fix readability-non-const-parameter for parameter referenced by an lvalue
The checker missed a check for a case when the parameter is referenced by an lvalue and this could cause build breakages. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D117090
1 parent b20e80a commit 6cbf15e

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ void NonConstParameterCheck::check(const MatchFinder::MatchResult &Result) {
8383
for (const auto *Arg : CE->arguments()) {
8484
markCanNotBeConst(Arg->IgnoreParenCasts(), true);
8585
}
86+
// Data passed by nonconst reference should not be made const.
87+
unsigned ArgNr = 0U;
88+
if (const auto *CD = CE->getConstructor()) {
89+
for (const auto *Par : CD->parameters()) {
90+
if (ArgNr >= CE->getNumArgs())
91+
break;
92+
const Expr *Arg = CE->getArg(ArgNr++);
93+
// Is this a non constant reference parameter?
94+
const Type *ParType = Par->getType().getTypePtr();
95+
if (!ParType->isReferenceType() || Par->getType().isConstQualified())
96+
continue;
97+
markCanNotBeConst(Arg->IgnoreParenCasts(), false);
98+
}
99+
}
86100
} else if (const auto *R = dyn_cast<ReturnStmt>(S)) {
87101
markCanNotBeConst(R->getRetValue(), true);
88102
} else if (const auto *U = dyn_cast<UnaryOperator>(S)) {
@@ -93,6 +107,9 @@ void NonConstParameterCheck::check(const MatchFinder::MatchResult &Result) {
93107
if ((T->isPointerType() && !T->getPointeeType().isConstQualified()) ||
94108
T->isArrayType())
95109
markCanNotBeConst(VD->getInit(), true);
110+
else if (T->isLValueReferenceType() &&
111+
!T->getPointeeType().isConstQualified())
112+
markCanNotBeConst(VD->getInit(), false);
96113
}
97114
}
98115

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ New check aliases
109109
Changes in existing checks
110110
^^^^^^^^^^^^^^^^^^^^^^^^^^
111111

112+
- Fixed a false positive in :doc:`readability-non-const-parameter
113+
<clang-tidy/checks/readability-non-const-parameter>` when the parameter is referenced by an lvalue
114+
115+
112116
Removed checks
113117
^^^^^^^^^^^^^^
114118

clang-tools-extra/docs/clang-tidy/checks/readability-non-const-parameter.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,8 @@ make the function interface safer.
4444
int f3(struct S *p) {
4545
*(p->a) = 0;
4646
}
47+
48+
// no warning; p is referenced by an lvalue.
49+
void f4(int *p) {
50+
int &x = *p;
51+
}

clang-tools-extra/test/clang-tidy/checkers/readability-non-const-parameter.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,39 @@ char foo(char *s) {
287287
}
288288
char foo(char *s); // 2
289289
// CHECK-FIXES: {{^}}char foo(const char *s); // 2{{$}}
290+
291+
void lvalueReference(int *p) {
292+
// CHECK-MESSAGES-NOT: warning: pointer parameter 'p' can be
293+
int &x = *p;
294+
}
295+
296+
// CHECK-MESSAGES: :[[@LINE+1]]:32: warning: pointer parameter 'p' can be
297+
void constLValueReference(int *p) {
298+
// CHECK-FIXES: {{^}}void constLValueReference(const int *p) {{{$}}
299+
const int &x = *p;
300+
}
301+
302+
void lambdaLVRef(int *p) {
303+
// CHECK-MESSAGES-NOT: warning: pointer parameter 'p' can be
304+
auto foo = [&]() {
305+
int &x = *p;
306+
};
307+
}
308+
309+
// CHECK-MESSAGES: :[[@LINE+1]]:28: warning: pointer parameter 'p' can be
310+
void lambdaConstLVRef(int *p) {
311+
// CHECK-FIXES: {{^}}void lambdaConstLVRef(const int *p) {{{$}}
312+
auto foo = [&]() {
313+
const int &x = *p;
314+
};
315+
}
316+
317+
struct Temp1 {
318+
Temp1(int &i) {
319+
i = 10;
320+
}
321+
};
322+
void constructLVRef(int *p) {
323+
// CHECK-MESSAGES-NOT: warning: pointer parameter 'p' can be
324+
Temp1 t(*p);
325+
}

0 commit comments

Comments
 (0)