https://github.com/berkaysahiin updated https://github.com/llvm/llvm-project/pull/188844
>From 939e926a0f72e6620f545ad02de7fe3122a818c1 Mon Sep 17 00:00:00 2001 From: Berkay Sahin <[email protected]> Date: Fri, 27 Mar 2026 00:03:11 +0300 Subject: [PATCH 1/2] [clang][clang-tidy] False-positive with non-const methods on pointer variables --- clang-tools-extra/docs/ReleaseNotes.rst | 4 ++++ .../checkers/misc/const-correctness-parameters.cpp | 7 +++++-- .../misc/const-correctness-pointer-as-values.cpp | 11 +++++++++++ clang/lib/Analysis/ExprMutationAnalyzer.cpp | 4 +++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index f8550e72dcc85..0818eac233c8b 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -289,6 +289,10 @@ Changes in existing checks - Fixed false positive where a pointer used with placement new was incorrectly diagnosed as allowing the pointee to be made ``const``. + - Fixed false positive where calling a non-const member function on a + pointer was incorrectly treated as mutating the pointer, when it only + mutates the pointee. + - Improved :doc:`misc-multiple-inheritance <clang-tidy/checks/misc/multiple-inheritance>` by avoiding false positives when virtual inheritance causes concrete bases to be counted more than once. diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-parameters.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-parameters.cpp index 8ff099eadb5a9..a8d90f1b582bf 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-parameters.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-parameters.cpp @@ -40,6 +40,8 @@ void pointer_param_read_only(Bar* b) { } void pointer_param_mutated_pointee(Bar* b) { + // CHECK-MESSAGES: [[@LINE-1]]:36: warning: variable 'b' of type 'Bar *' can be declared 'const' + // CHECK-FIXES: void pointer_param_mutated_pointee(Bar* const b) { b->mutating_method(); } @@ -505,8 +507,9 @@ void struct_ptr_param(Bar** bp) { } void struct_ptr_param_modified(Bar** bp) { - // CHECK-MESSAGES: [[@LINE-1]]:32: warning: variable 'bp' of type 'Bar **' can be declared 'const' - // CHECK-FIXES: void struct_ptr_param_modified(Bar** const bp) { + // CHECK-MESSAGES: [[@LINE-1]]:32: warning: pointee of variable 'bp' of type 'Bar **' can be declared 'const' + // CHECK-MESSAGES: [[@LINE-2]]:32: warning: variable 'bp' of type 'Bar **' can be declared 'const' + // CHECK-FIXES: void struct_ptr_param_modified(Bar* const* const bp) { (*bp)->mutating_method(); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp index 02d32c0ec73e5..41cf3d8b4aa05 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp @@ -72,3 +72,14 @@ void instantiate() { // CHECK-FIXES: int *const p_local0[4] = {nullptr, nullptr, nullptr, nullptr}; EmitProtocolMethodList(p_local0); } + +struct Mutating { + void mutating_method(); +}; + +void pointer_member_call_not_pointer_mutation() { + Mutating *p = nullptr; + // CHECK-MESSAGES: warning: variable 'p' of type 'Mutating *' can be declared 'const' + // CHECK-FIXES: Mutating *const p = nullptr; + p->mutating_method(); +} diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp index 5def6ba3cac5a..ad7ce91e0f966 100644 --- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp +++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp @@ -404,7 +404,9 @@ ExprMutationAnalyzer::Analyzer::findDirectMutation(const Expr *Exp) { const auto NonConstMethod = cxxMethodDecl(unless(isConst())); const auto AsNonConstThis = expr(anyOf( - cxxMemberCallExpr(on(canResolveToExpr(Exp)), unless(isConstCallee())), + cxxMemberCallExpr( + on(canResolveToExpr(Exp)), + unless(anyOf(isConstCallee(), thisPointerType(pointerType())))), cxxOperatorCallExpr(callee(NonConstMethod), hasArgument(0, canResolveToExpr(Exp))), // In case of a templated type, calling overloaded operators is not >From 37470bd0d95ef863d5d96af0a71ead1704d825b8 Mon Sep 17 00:00:00 2001 From: Berkay Sahin <[email protected]> Date: Sun, 5 Apr 2026 00:00:04 +0300 Subject: [PATCH 2/2] Address PR comments --- .../checkers/misc/const-correctness-pointer-as-values.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp index 41cf3d8b4aa05..0875e79e22f17 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-values.cpp @@ -79,7 +79,7 @@ struct Mutating { void pointer_member_call_not_pointer_mutation() { Mutating *p = nullptr; - // CHECK-MESSAGES: warning: variable 'p' of type 'Mutating *' can be declared 'const' + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'p' of type 'Mutating *' can be declared 'const' // CHECK-FIXES: Mutating *const p = nullptr; p->mutating_method(); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
