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

Reply via email to