File tree Expand file tree Collapse file tree 4 files changed +62
-0
lines changed Expand file tree Collapse file tree 4 files changed +62
-0
lines changed Original file line number Diff line number Diff line change @@ -83,6 +83,20 @@ void NonConstParameterCheck::check(const MatchFinder::MatchResult &Result) {
83
83
for (const auto *Arg : CE->arguments ()) {
84
84
markCanNotBeConst (Arg->IgnoreParenCasts (), true );
85
85
}
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
+ }
86
100
} else if (const auto *R = dyn_cast<ReturnStmt>(S)) {
87
101
markCanNotBeConst (R->getRetValue (), true );
88
102
} else if (const auto *U = dyn_cast<UnaryOperator>(S)) {
@@ -93,6 +107,9 @@ void NonConstParameterCheck::check(const MatchFinder::MatchResult &Result) {
93
107
if ((T->isPointerType () && !T->getPointeeType ().isConstQualified ()) ||
94
108
T->isArrayType ())
95
109
markCanNotBeConst (VD->getInit (), true );
110
+ else if (T->isLValueReferenceType () &&
111
+ !T->getPointeeType ().isConstQualified ())
112
+ markCanNotBeConst (VD->getInit (), false );
96
113
}
97
114
}
98
115
Original file line number Diff line number Diff line change @@ -109,6 +109,10 @@ New check aliases
109
109
Changes in existing checks
110
110
^^^^^^^^^^^^^^^^^^^^^^^^^^
111
111
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
+
112
116
Removed checks
113
117
^^^^^^^^^^^^^^
114
118
Original file line number Diff line number Diff line change @@ -44,3 +44,8 @@ make the function interface safer.
44
44
int f3(struct S *p) {
45
45
*(p->a) = 0;
46
46
}
47
+
48
+ // no warning; p is referenced by an lvalue.
49
+ void f4(int *p) {
50
+ int &x = *p;
51
+ }
Original file line number Diff line number Diff line change @@ -287,3 +287,39 @@ char foo(char *s) {
287
287
}
288
288
char foo (char *s); // 2
289
289
// 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
+ }
You can’t perform that action at this time.
0 commit comments