https://github.com/zeyi2 updated 
https://github.com/llvm/llvm-project/pull/202490

>From b28426d8567105b757d4767f418d91aad1530449 Mon Sep 17 00:00:00 2001
From: Zeyi Xu <[email protected]>
Date: Tue, 9 Jun 2026 11:20:49 +0800
Subject: [PATCH 1/3] [clang-tidy] Avoid non-const-parameter fix-it conflicts
 with overloads

---
 .../readability/NonConstParameterCheck.cpp    | 29 +++++++++++++
 clang-tools-extra/docs/ReleaseNotes.rst       |  3 ++
 .../readability/non-const-parameter.cpp       | 41 +++++++++++++++++++
 3 files changed, 73 insertions(+)

diff --git 
a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
index fa9184a290273..f5abe02eb2674 100644
--- a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
@@ -23,6 +23,32 @@ AST_MATCHER_P(VarDecl, hasOwnInitializer, 
ast_matchers::internal::Matcher<Expr>,
 }
 } // namespace
 
+static bool wouldConflictWithOverload(const FunctionDecl &Function,
+                                      unsigned ParamIndex) {
+  ASTContext &Context = Function.getASTContext();
+  const auto *Proto = Function.getType()->getAs<FunctionProtoType>();
+  if (!Proto)
+    return false;
+
+  // Simulate applying the fix-it to compare against existing overloads.
+  SmallVector<QualType> ParamTypes(Proto->getParamTypes());
+  ParamTypes[ParamIndex] = Context.getPointerType(
+      ParamTypes[ParamIndex]->getPointeeType().withConst());
+
+  return llvm::any_of(
+      Function.getParent()->lookup(Function.getDeclName()), [&](const Decl *D) 
{
+        const FunctionDecl *Overload = D->getAsFunction();
+        if (!Overload ||
+            Overload->getCanonicalDecl() == Function.getCanonicalDecl())
+          return false;
+
+        QualType ConstParamFunctionType = Context.getFunctionType(
+            Overload->getReturnType(), ParamTypes, Proto->getExtProtoInfo());
+        return Context.hasSameFunctionTypeIgnoringExceptionSpec(
+            ConstParamFunctionType, Overload->getType());
+      });
+}
+
 void NonConstParameterCheck::registerMatchers(MatchFinder *Finder) {
   // Add parameters to Parameters.
   Finder->addMatcher(parmVarDecl().bind("Parm"), this);
@@ -185,6 +211,9 @@ void NonConstParameterCheck::diagnoseNonConstParameters() {
     if (!Function)
       continue;
     const unsigned Index = Par->getFunctionScopeIndex();
+    if (wouldConflictWithOverload(*Function, Index))
+      continue;
+
     for (FunctionDecl *FnDecl : Function->redecls()) {
       if (FnDecl->getNumParams() <= Index)
         continue;
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 9703bb8f17208..8f4e2cf251e94 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -785,6 +785,9 @@ Changes in existing checks
   - Fixed a false positive in array subscript expressions where the types are
     not yet resolved.
 
+  - Fixed a false positive when adding ``const`` to a pointer parameter would
+    conflict with an existing overload.
+
   - Fixed a crash when analyzing a redeclaration whose initializer is attached
     to another declaration.
 
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 b4918df347e5c..9639b40ae4d16 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
@@ -449,3 +449,44 @@ struct StaticDepOutOfClassInit {
 
 template <class T>
 const T StaticDepOutOfClassInit<T>::X = 0;
+
+double overloadConflict(double *overloadConflictPtr) {
+  return *overloadConflictPtr;
+}
+
+double overloadConflict(const double *overloadConflictPtr) {
+  return *overloadConflictPtr;
+}
+
+template <int>
+int templateOverloadConflict(int *templateConflictPtr) {
+  return *templateConflictPtr;
+}
+
+template <int>
+int templateOverloadConflict(const int *templateConflictPtr) {
+  return *templateConflictPtr;
+}
+
+struct ConstructorOverloadConflict {
+  ConstructorOverloadConflict(int *ctorConflictPtr) {
+    (void)*ctorConflictPtr;
+  }
+  ConstructorOverloadConflict(const int *ctorConflictPtr) {}
+};
+
+struct MemberOverloadConflict {
+  void withConflictingOverload(int *memberConflictPtr) {
+    (void)*memberConflictPtr;
+  }
+  void withConflictingOverload(const int *memberConflictPtr) {}
+};
+
+struct QualifiedMemberOverload {
+  // CHECK-MESSAGES: :[[@LINE+1]]:32: warning: pointer parameter 
'qualifiedMemberPtr' can be pointer to const
+  void withConstQualifier(int *qualifiedMemberPtr) const {
+    // CHECK-FIXES: void withConstQualifier(const int *qualifiedMemberPtr) 
const {
+    (void)*qualifiedMemberPtr;
+  }
+  void withConstQualifier(const int *qualifiedMemberPtr) {}
+};

>From aa62fb323c4bbdfbd29f2284ff7d7b3969ce931f Mon Sep 17 00:00:00 2001
From: Zeyi Xu <[email protected]>
Date: Tue, 9 Jun 2026 11:29:34 +0800
Subject: [PATCH 2/3] make tidy happy

---
 .../clang-tidy/readability/NonConstParameterCheck.cpp           | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
index f5abe02eb2674..5aaf28a22a776 100644
--- a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp
@@ -42,7 +42,7 @@ static bool wouldConflictWithOverload(const FunctionDecl 
&Function,
             Overload->getCanonicalDecl() == Function.getCanonicalDecl())
           return false;
 
-        QualType ConstParamFunctionType = Context.getFunctionType(
+        const QualType ConstParamFunctionType = Context.getFunctionType(
             Overload->getReturnType(), ParamTypes, Proto->getExtProtoInfo());
         return Context.hasSameFunctionTypeIgnoringExceptionSpec(
             ConstParamFunctionType, Overload->getType());

>From 88eb638083704e28ea33916b9efdf3ad8bfd2d16 Mon Sep 17 00:00:00 2001
From: Zeyi Xu <[email protected]>
Date: Tue, 9 Jun 2026 14:56:33 +0800
Subject: [PATCH 3/3] add more test cases

---
 .../readability/non-const-parameter.cpp       | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

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 9639b40ae4d16..2d28ef904282a 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
@@ -458,6 +458,28 @@ double overloadConflict(const double *overloadConflictPtr) 
{
   return *overloadConflictPtr;
 }
 
+double topLevelConstPointerOverload(double *topLevelConstPtr) {
+  return *topLevelConstPtr;
+}
+
+double topLevelConstPointerOverload(const double *const topLevelConstPtr) {
+  return *topLevelConstPtr;
+}
+
+void arrayOverloadConflict(double arrayOut[2],
+                           double arrayConflictParam[2]) {
+  arrayOut[0] = arrayConflictParam[0];
+}
+
+void arrayOverloadConflict(double arrayOut[2],
+                           const double arrayConflictParam[2]) {
+  arrayOut[0] = arrayConflictParam[0];
+}
+
+int returnTypeConflict(int *returnTypePtr) { return *returnTypePtr; }
+
+long returnTypeConflict(const int *returnTypePtr) { return *returnTypePtr; }
+
 template <int>
 int templateOverloadConflict(int *templateConflictPtr) {
   return *templateConflictPtr;
@@ -482,6 +504,11 @@ struct MemberOverloadConflict {
   void withConflictingOverload(const int *memberConflictPtr) {}
 };
 
+struct OperatorCallConflict {
+  int operator()(int *operatorCallPtr) { return *operatorCallPtr; }
+  int operator()(const int *operatorCallPtr) { return *operatorCallPtr; }
+};
+
 struct QualifiedMemberOverload {
   // CHECK-MESSAGES: :[[@LINE+1]]:32: warning: pointer parameter 
'qualifiedMemberPtr' can be pointer to const
   void withConstQualifier(int *qualifiedMemberPtr) const {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to