https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/192018

>From 7124eafc69f02363f9289e6bb83d4d95dbf5138d Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Tue, 14 Apr 2026 09:57:57 +0200
Subject: [PATCH 1/2] [Clang] Fix handling of overloads differing only by
 constraints and ref-qualifiers.

We ashould only error about inconsistent qualifiers
if the functions are actually overloads.

Fixes #120812
---
 clang/docs/ReleaseNotes.rst     |  1 +
 clang/lib/Sema/SemaOverload.cpp | 26 +++++++++++++++++---------
 clang/test/CXX/drs/cwg24xx.cpp  | 11 +++++++++++
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3e2d287d1eb1f..9e4699d642332 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -434,6 +434,7 @@ Bug Fixes to C++ Support
 - We no longer caches invalid variable specializations. (#GH132592)
 - Fixed an incorrect template argument deduction when matching packs of 
template
   template parameters when one of its parameters is also a pack. (#GH181166)
+- Clang no longer errors on overloads with different ref-qualifiers and 
constraints. (#GH120812)
 - Fixed a crash when a default argument is passed to an explicit object 
parameter. (#GH176639)
 - Fixed an alias template CTAD crash.
 - Fixed a crash when diagnosing an invalid static member function with an 
explicit object parameter (#GH177741)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 11e771bc240f1..170699085ea11 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1521,6 +1521,12 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, 
FunctionDecl *New,
     return false;
   };
 
+  // We look at the parameters first, as it is the common case.
+  // However we should not emit diagnostic before checking
+  // the overloads do not differ by constraints or other discriminant.
+  bool ShouldDiagnoseInconsistentRefQualifiers = false;
+  bool HaveInconsistentQualifiers = false;
+
   if (OldMethod && OldMethod->isExplicitObjectMemberFunction())
     OldParamsOffset++;
   if (NewMethod && NewMethod->isExplicitObjectMemberFunction())
@@ -1557,17 +1563,20 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, 
FunctionDecl *New,
     }(OldMethod, NewMethod);
 
     if (!HaveCorrespondingObjectParameters) {
-      if (DiagnoseInconsistentRefQualifiers())
-        return true;
+      ShouldDiagnoseInconsistentRefQualifiers = true;
       // CWG2554
       // and, if at least one is an explicit object member function, ignoring
       // object parameters
       if (!UseOverrideRules || (!NewMethod->isExplicitObjectMemberFunction() &&
                                 !OldMethod->isExplicitObjectMemberFunction()))
-        return true;
+        HaveInconsistentQualifiers = true;
     }
   }
 
+  if (NewMethod && OldMethod && OldMethod->isImplicitObjectMemberFunction() &&
+      NewMethod->isImplicitObjectMemberFunction())
+    ShouldDiagnoseInconsistentRefQualifiers = true;
+
   if (!UseOverrideRules &&
       New->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) {
     AssociatedConstraint NewRC = New->getTrailingRequiresClause(),
@@ -1582,12 +1591,6 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, 
FunctionDecl *New,
       return true;
   }
 
-  if (NewMethod && OldMethod && OldMethod->isImplicitObjectMemberFunction() &&
-      NewMethod->isImplicitObjectMemberFunction()) {
-    if (DiagnoseInconsistentRefQualifiers())
-      return true;
-  }
-
   // Though pass_object_size is placed on parameters and takes an argument, we
   // consider it to be a function-level modifier for the sake of function
   // identity. Either the function has one or more parameters with
@@ -1612,6 +1615,11 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, 
FunctionDecl *New,
       return true;
   }
 
+  if ((ShouldDiagnoseInconsistentRefQualifiers &&
+       DiagnoseInconsistentRefQualifiers()) ||
+      HaveInconsistentQualifiers)
+    return true;
+
   // At this point, it is known that the two functions have the same signature.
   if (SemaRef.getLangOpts().CUDA && ConsiderCudaAttrs) {
     // Don't allow overloading of destructors.  (In theory we could, but it
diff --git a/clang/test/CXX/drs/cwg24xx.cpp b/clang/test/CXX/drs/cwg24xx.cpp
index b27c6b823940c..0a6a05c125451 100644
--- a/clang/test/CXX/drs/cwg24xx.cpp
+++ b/clang/test/CXX/drs/cwg24xx.cpp
@@ -212,5 +212,16 @@ struct T : S {
     virtual void k() &;
     virtual void l() &&;
 };
+#if __cplusplus >= 202002L
+
+// We should not error on inconsistent ref-qualifiers if the functions
+// have different constraints.
+template <unsigned R> struct type {
+    void func() const requires(R == 0);
+    void func() & requires(R == 1);
+};
+
+#endif
+
 #endif
 }

>From 213b47c591caebf61477a44d9a3930e47da55645 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <[email protected]>
Date: Tue, 14 Apr 2026 16:38:16 +0200
Subject: [PATCH 2/2] [Clang] Add default arguments to the parameter mapping.

We were not adding default argument to the parameter mapping
as such, two constraint which only differed by the mapping of
a parameter only referenced in a default argument were considered
identical.

Fixes #188640
---
 clang/docs/ReleaseNotes.rst          |  2 +-
 clang/include/clang/AST/ASTContext.h |  4 +++
 clang/lib/AST/ASTContext.cpp         |  4 +--
 clang/lib/Sema/SemaConcept.cpp       | 19 ++++++++++++
 clang/test/SemaTemplate/concepts.cpp | 45 ++++++++++++++++++++++++++++
 5 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9e4699d642332..e5040109edcf3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -386,7 +386,7 @@ Bug Fixes in This Version
 -------------------------
 
 - Fixed atomic boolean compound assignment; the conversion back to atomic bool 
would be miscompiled. (#GH33210)
-
+- Correctly handle default template argument when establishing subsumption. 
(#GH188640)
 - Fixed a failed assertion in the preprocessor when ``__has_embed`` parameters 
are missing parentheses. (#GH175088)
 - Fix lifetime extension of temporaries in for-range-initializers in 
templates. (#GH165182)
 - Fixed a preprocessor crash in ``__has_cpp_attribute`` on incomplete scoped 
attributes. (#GH178098)
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index ba1b58489c327..a412ef91ef16d 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -3071,6 +3071,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
   TemplateName getCanonicalTemplateName(TemplateName Name,
                                         bool IgnoreDeduced = false) const;
 
+  /// Return the default argument of a template parameter, if one exists.
+  const TemplateArgument *
+  getDefaultTemplateArgumentOrNone(const NamedDecl *P) const;
+
   /// Determine whether the given template names refer to the same
   /// template.
   bool hasSameTemplateName(const TemplateName &X, const TemplateName &Y,
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index ee7f823b014b2..f73f613a2d35a 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -7305,8 +7305,8 @@ ASTContext::getNameForTemplate(TemplateName Name,
   llvm_unreachable("bad template name kind!");
 }
 
-static const TemplateArgument *
-getDefaultTemplateArgumentOrNone(const NamedDecl *P) {
+const TemplateArgument *
+ASTContext::getDefaultTemplateArgumentOrNone(const NamedDecl *P) const {
   auto handleParam = [](auto *TP) -> const TemplateArgument * {
     if (!TP->hasDefaultArgument())
       return nullptr;
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 3f04922a5647e..dfab7c919a303 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -2105,6 +2105,25 @@ void SubstituteParameterMappings::buildParameterMapping(
       SemaRef.MarkUsedTemplateParameters(Args->arguments(),
                                          /*Depth=*/0, OccurringIndices);
   }
+
+  // If a parameter is only referenced in a default template argument,
+  // we need to add it to the mapping explicitly.
+  {
+    llvm::SmallVector<TemplateArgument> DefaultArgs;
+    for (unsigned I = TemplateParams->getMinRequiredArguments();
+         I < TemplateParams->size(); I++) {
+      const NamedDecl *Param = TemplateParams->getParam(I);
+      if (Param->isParameterPack())
+        break;
+      const TemplateArgument *Arg =
+          SemaRef.getASTContext().getDefaultTemplateArgumentOrNone(Param);
+      assert(Arg && "expected a default argument");
+      DefaultArgs.emplace_back(std::move(*Arg));
+    }
+    SemaRef.MarkUsedTemplateParameters(DefaultArgs, /*Depth=*/0,
+                                       OccurringIndices);
+  }
+
   unsigned Size = OccurringIndices.count();
   // When the constraint is independent of any template parameters,
   // we build an empty mapping so that we can distinguish these cases
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index ac80d16b4ccf8..c8b5cbac82f89 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1835,3 +1835,48 @@ namespace GH191016 {
   };
   void test(){ S<int> s; }
 }
+
+
+namespace GH188640 {
+
+namespace Ex1 {
+template <typename T> constexpr bool CC = true;
+
+template <typename V, typename U = V>
+concept C = CC<U>;
+
+template <typename T>
+constexpr int f()
+    requires C<T> && C<T *>
+{
+    return 21;
+}
+
+template <typename T>
+void f()
+    requires C<T>;
+
+void g() { static_assert(f<void>() == 21); }
+
+} // namespace Ex1
+
+namespace VAR {
+template <auto N> constexpr bool CC = true;
+template <auto V, auto U = V>
+concept C = CC<U>;
+
+template <auto V>
+constexpr int f()
+    requires C<V> && C<V + 1>
+{
+    return 42;
+}
+
+template <auto N>
+int f()
+    requires C<N>;
+
+void g() { static_assert(f<1>() == 42); }
+} // namespace VAR
+
+} // namespace GH188640

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

Reply via email to