https://github.com/offsetof updated 
https://github.com/llvm/llvm-project/pull/132779

>From 6c5441fd1e22e93de3a6c681842fe19f6e96fa62 Mon Sep 17 00:00:00 2001
From: offsetof <offse...@mailo.com>
Date: Mon, 24 Mar 2025 16:30:15 +0000
Subject: [PATCH 1/4] [clang] Implement CWG2803 and CWG2958

CWG2803 "Overload resolution for reference binding of similar types"
CWG2958 "Overload resolution involving lvalue transformation and
qualification conversion"
---
 clang/docs/ReleaseNotes.rst              |   2 +
 clang/lib/Sema/SemaOverload.cpp          | 229 ++++++++++++++---------
 clang/test/CXX/drs/cwg28xx.cpp           |  73 ++++++++
 clang/test/CXX/drs/cwg29xx.cpp           |  24 ++-
 clang/test/SemaObjCXX/arc-overloading.mm |  11 ++
 clang/www/cxx_dr_status.html             |  50 ++++-
 6 files changed, 292 insertions(+), 97 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8182bccdd2da8..6cd99243b0f90 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -110,6 +110,8 @@ Resolutions to C++ Defect Reports
   two releases. The improvements to template template parameter matching 
implemented
   in the previous release, as described in P3310 and P3579, made this flag 
unnecessary.
 
+- Implemented `CWG2803 Overload resolution for reference binding of similar 
types <https://cplusplus.github.io/CWG/issues/2803>`_,
+  as amended by the proposed resolution of `CWG2958 Overload resolution 
involving lvalue transformation and qualification conversion 
<https://cplusplus.github.io/CWG/issues/2958>`_
 - Implemented `CWG2918 Consideration of constraints for address of overloaded `
   `function <https://cplusplus.github.io/CWG/issues/2918.html>`_
 
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 6d8006b35dcf4..3bf9b800df1d2 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -116,6 +116,11 @@ CompareQualificationConversions(Sema &S,
                                 const StandardConversionSequence& SCS1,
                                 const StandardConversionSequence& SCS2);
 
+static ImplicitConversionSequence::CompareKind
+CompareReferenceBindingConversions(Sema &S,
+                                   const StandardConversionSequence &SCS1,
+                                   const StandardConversionSequence &SCS2);
+
 static ImplicitConversionSequence::CompareKind
 CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,
                                 const StandardConversionSequence& SCS1,
@@ -4408,19 +4413,15 @@ compareStandardConversionSubsets(ASTContext &Context,
 static bool
 isBetterReferenceBindingKind(const StandardConversionSequence &SCS1,
                              const StandardConversionSequence &SCS2) {
-  // C++0x [over.ics.rank]p3b4:
-  //   -- S1 and S2 are reference bindings (8.5.3) and neither refers to an
-  //      implicit object parameter of a non-static member function declared
-  //      without a ref-qualifier, and *either* S1 binds an rvalue reference
-  //      to an rvalue and S2 binds an lvalue reference *or S1 binds an
-  //      lvalue reference to a function lvalue and S2 binds an rvalue
-  //      reference*.
-  //
-  // FIXME: Rvalue references. We're going rogue with the above edits,
-  // because the semantics in the current C++0x working paper (N3225 at the
-  // time of this writing) break the standard definition of std::forward
-  // and std::reference_wrapper when dealing with references to functions.
-  // Proposed wording changes submitted to CWG for consideration.
+  // C++2c [over.ics.rank] p3.2.3 - 3.2.4:
+  //   * S1 and S2 include reference bindings and neither refers to an
+  //     implicit object parameter of a non-static member function
+  //     declared without a ref-qualifier, and S1 binds an rvalue
+  //     reference to an rvalue and S2 binds an lvalue reference
+  //     or, if not that,
+  //   * S1 and S2 include reference bindings and S1 binds an lvalue
+  //     reference to an lvalue of function type and S2 binds an rvalue
+  //     reference to an lvalue of function type
   if (SCS1.BindsImplicitObjectArgumentWithoutRefQualifier ||
       SCS2.BindsImplicitObjectArgumentWithoutRefQualifier)
     return false;
@@ -4580,52 +4581,19 @@ CompareStandardConversionSequences(Sema &S, 
SourceLocation Loc,
     // Check for a better reference binding based on the kind of bindings.
     if (isBetterReferenceBindingKind(SCS1, SCS2))
       return ImplicitConversionSequence::Better;
-    else if (isBetterReferenceBindingKind(SCS2, SCS1))
+    if (isBetterReferenceBindingKind(SCS2, SCS1))
       return ImplicitConversionSequence::Worse;
   }
 
-  // Compare based on qualification conversions (C++ 13.3.3.2p3,
-  // bullet 3).
-  if (ImplicitConversionSequence::CompareKind QualCK
-        = CompareQualificationConversions(S, SCS1, SCS2))
+  // Compare based on qualification conversions
+  // (C++2c [over.ics.rank] p3.2.5).
+  if (auto QualCK = CompareQualificationConversions(S, SCS1, SCS2))
     return QualCK;
 
-  if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) {
-    // C++ [over.ics.rank]p3b4:
-    //   -- S1 and S2 are reference bindings (8.5.3), and the types to
-    //      which the references refer are the same type except for
-    //      top-level cv-qualifiers, and the type to which the reference
-    //      initialized by S2 refers is more cv-qualified than the type
-    //      to which the reference initialized by S1 refers.
-    QualType T1 = SCS1.getToType(2);
-    QualType T2 = SCS2.getToType(2);
-    T1 = S.Context.getCanonicalType(T1);
-    T2 = S.Context.getCanonicalType(T2);
-    Qualifiers T1Quals, T2Quals;
-    QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals);
-    QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals);
-    if (UnqualT1 == UnqualT2) {
-      // Objective-C++ ARC: If the references refer to objects with different
-      // lifetimes, prefer bindings that don't change lifetime.
-      if (SCS1.ObjCLifetimeConversionBinding !=
-                                          SCS2.ObjCLifetimeConversionBinding) {
-        return SCS1.ObjCLifetimeConversionBinding
-                                           ? ImplicitConversionSequence::Worse
-                                           : 
ImplicitConversionSequence::Better;
-      }
-
-      // If the type is an array type, promote the element qualifiers to the
-      // type for comparison.
-      if (isa<ArrayType>(T1) && T1Quals)
-        T1 = S.Context.getQualifiedType(UnqualT1, T1Quals);
-      if (isa<ArrayType>(T2) && T2Quals)
-        T2 = S.Context.getQualifiedType(UnqualT2, T2Quals);
-      if (T2.isMoreQualifiedThan(T1, S.getASTContext()))
-        return ImplicitConversionSequence::Better;
-      if (T1.isMoreQualifiedThan(T2, S.getASTContext()))
-        return ImplicitConversionSequence::Worse;
-    }
-  }
+  // Compare based on target types of reference bindings
+  // (C++2c [over.ics.rank] p3.2.6).
+  if (auto RefCK = CompareReferenceBindingConversions(S, SCS1, SCS2))
+    return RefCK;
 
   // In Microsoft mode (below 19.28), prefer an integral conversion to a
   // floating-to-integral conversion if the integral conversion
@@ -4704,64 +4672,78 @@ CompareStandardConversionSequences(Sema &S, 
SourceLocation Loc,
 
 /// CompareQualificationConversions - Compares two standard conversion
 /// sequences to determine whether they can be ranked based on their
-/// qualification conversions (C++ 13.3.3.2p3 bullet 3).
+/// qualification conversions (C++2c [over.ics.rank] p3.2.5).
 static ImplicitConversionSequence::CompareKind
 CompareQualificationConversions(Sema &S,
                                 const StandardConversionSequence& SCS1,
                                 const StandardConversionSequence& SCS2) {
-  // C++ [over.ics.rank]p3:
-  //  -- S1 and S2 differ only in their qualification conversion and
-  //     yield similar types T1 and T2 (C++ 4.4), respectively, [...]
-  // [C++98]
-  //     [...] and the cv-qualification signature of type T1 is a proper subset
-  //     of the cv-qualification signature of type T2, and S1 is not the
-  //     deprecated string literal array-to-pointer conversion (4.2).
-  // [C++2a]
-  //     [...] where T1 can be converted to T2 by a qualification conversion.
-  if (SCS1.First != SCS2.First || SCS1.Second != SCS2.Second ||
-      SCS1.Third != SCS2.Third || SCS1.Third != ICK_Qualification)
+  // C++2c [over.ics.rank] p3.2.5:
+  //   * S1 and S2 differ only in their qualification conversion
+  //     [CWG2958: ignoring any Lvalue Transformation,] and yield
+  //     similar types T1 and T2, respectively (where a standard
+  //     conversion sequence that is a reference binding is considered to
+  //     yield the cv-unqualified referenced type), where T1 and T2 are
+  //     not the same type, and const T2 is reference-compatible with T1
+  if (SCS1.Second != SCS2.Second || SCS1.Third != SCS2.Third ||
+      SCS1.Third != ICK_Qualification)
     return ImplicitConversionSequence::Indistinguishable;
 
-  // FIXME: the example in the standard doesn't use a qualification
-  // conversion (!)
   QualType T1 = SCS1.getToType(2);
   QualType T2 = SCS2.getToType(2);
   T1 = S.Context.getCanonicalType(T1);
   T2 = S.Context.getCanonicalType(T2);
   assert(!T1->isReferenceType() && !T2->isReferenceType());
-  Qualifiers T1Quals, T2Quals;
-  QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals);
-  QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals);
+  T1 = S.Context.getUnqualifiedArrayType(T1);
+  T2 = S.Context.getUnqualifiedArrayType(T2);
 
   // If the types are the same, we won't learn anything by unwrapping
   // them.
-  if (UnqualT1 == UnqualT2)
+  if (T1 == T2)
     return ImplicitConversionSequence::Indistinguishable;
 
   // Don't ever prefer a standard conversion sequence that uses the deprecated
-  // string literal array to pointer conversion.
+  // string literal array to pointer conversion (C++03 [over.ics.rank] p3.1.3).
   bool CanPick1 = !SCS1.DeprecatedStringLiteralToCharPtr;
   bool CanPick2 = !SCS2.DeprecatedStringLiteralToCharPtr;
 
   // Objective-C++ ARC:
   //   Prefer qualification conversions not involving a change in lifetime
   //   to qualification conversions that do change lifetime.
-  if (SCS1.QualificationIncludesObjCLifetime &&
-      !SCS2.QualificationIncludesObjCLifetime)
-    CanPick1 = false;
-  if (SCS2.QualificationIncludesObjCLifetime &&
-      !SCS1.QualificationIncludesObjCLifetime)
-    CanPick2 = false;
+  if (SCS1.QualificationIncludesObjCLifetime !=
+      SCS2.QualificationIncludesObjCLifetime) {
+    CanPick1 &= SCS2.QualificationIncludesObjCLifetime;
+    CanPick2 &= SCS1.QualificationIncludesObjCLifetime;
+  }
+
+  // If exactly one of T1 and T2 is an array of unknown bound,
+  // the other type is not reference-compatible with it.
+  bool T1IsIncompleteArray = T1->isIncompleteArrayType();
+  bool T2IsIncompleteArray = T2->isIncompleteArrayType();
+  if (T1IsIncompleteArray != T2IsIncompleteArray) {
+    CanPick1 &= T2IsIncompleteArray;
+    CanPick2 &= T1IsIncompleteArray;
+  }
 
+  bool PrevT1QualsIncludeConst = true;
+  bool PrevT2QualsIncludeConst = true;
+  bool IsTopLevel = true;
   bool ObjCLifetimeConversion;
-  if (CanPick1 &&
-      !S.IsQualificationConversion(T1, T2, false, ObjCLifetimeConversion))
-    CanPick1 = false;
-  // FIXME: In Objective-C ARC, we can have qualification conversions in both
-  // directions, so we can't short-cut this second check in general.
-  if (CanPick2 &&
-      !S.IsQualificationConversion(T2, T1, false, ObjCLifetimeConversion))
-    CanPick2 = false;
+  while ((CanPick1 || CanPick2) && S.Context.UnwrapSimilarTypes(T1, T2) &&
+         (T1 != T2)) {
+    CanPick1 = CanPick1 &&
+               isQualificationConversionStep(
+                   T1, T2, /*CStyle=*/false, IsTopLevel,
+                   PrevT2QualsIncludeConst, ObjCLifetimeConversion, S.Context);
+    CanPick2 = CanPick2 &&
+               isQualificationConversionStep(
+                   T2, T1, /*CStyle=*/false, IsTopLevel,
+                   PrevT1QualsIncludeConst, ObjCLifetimeConversion, S.Context);
+    IsTopLevel = false;
+  }
+
+  if (!S.Context.hasSameUnqualifiedType(T1, T2))
+    // T1 and T2 are not similar.
+    return ImplicitConversionSequence::Indistinguishable;
 
   if (CanPick1 != CanPick2)
     return CanPick1 ? ImplicitConversionSequence::Better
@@ -4769,6 +4751,73 @@ CompareQualificationConversions(Sema &S,
   return ImplicitConversionSequence::Indistinguishable;
 }
 
+/// CompareReferenceBindingConversions - Compare two standard conversion
+/// sequences involving reference bindings to determine whether they can
+/// be ranked based on the referenced types (C++2c [over.ics.rank] p3.2.6).
+static ImplicitConversionSequence::CompareKind
+CompareReferenceBindingConversions(Sema &S,
+                                   const StandardConversionSequence &SCS1,
+                                   const StandardConversionSequence &SCS2) {
+  // C++2c [over.ics.rank] p3.2.6:
+  //   * S1 and S2 bind "reference to T1" and "reference to T2",
+  //     respectively, where T1 and T2 are not the same type,
+  //     and T2 is reference-compatible with T1
+  // Derived-to-base and qualification conversions are handled by previous
+  // bullets; this bullet only applies when T1 and T2 differ solely in their
+  // top-level cv-qualifiers and/or the presence of a major array bound.
+  if (!SCS1.ReferenceBinding || !SCS2.ReferenceBinding)
+    return ImplicitConversionSequence::Indistinguishable;
+
+  QualType T1 = SCS1.getToType(2);
+  QualType T2 = SCS2.getToType(2);
+
+  Qualifiers T1Quals, T2Quals;
+  T1 = S.Context.getUnqualifiedArrayType(T1, T1Quals);
+  T2 = S.Context.getUnqualifiedArrayType(T2, T2Quals);
+  int Result = 0;
+
+  // Compare array bounds.
+  if (auto *T1Arr = S.Context.getAsArrayType(T1)) {
+    auto *T2Arr = S.Context.getAsArrayType(T2);
+    if (!T2Arr)
+      return ImplicitConversionSequence::Indistinguishable;
+
+    bool T1IsIncomplete = isa<IncompleteArrayType>(T1Arr);
+    bool T2IsIncomplete = isa<IncompleteArrayType>(T2Arr);
+    if (T1IsIncomplete || T2IsIncomplete) {
+      T1 = T1Arr->getElementType();
+      T2 = T2Arr->getElementType();
+      Result = T2IsIncomplete - T1IsIncomplete;
+    }
+  }
+
+  if (!S.Context.hasSameType(T1, T2))
+    return ImplicitConversionSequence::Indistinguishable;
+
+  // Objective-C++ ARC: If the references refer to objects with different
+  // lifetimes, prefer bindings that don't change lifetime.
+  if (SCS1.ObjCLifetimeConversionBinding !=
+      SCS2.ObjCLifetimeConversionBinding) {
+    return SCS1.ObjCLifetimeConversionBinding
+               ? ImplicitConversionSequence::Worse
+               : ImplicitConversionSequence::Better;
+  }
+
+  // Compare cv-qualifiers.
+  bool T1Compatible = T1Quals.compatiblyIncludes(T2Quals, S.Context);
+  bool T2Compatible = T2Quals.compatiblyIncludes(T1Quals, S.Context);
+  if (!T1Compatible && !T2Compatible)
+    return ImplicitConversionSequence::Indistinguishable;
+
+  Result += T2Compatible - T1Compatible;
+
+  if (Result > 0)
+    return ImplicitConversionSequence::Better;
+  if (Result < 0)
+    return ImplicitConversionSequence::Worse;
+  return ImplicitConversionSequence::Indistinguishable;
+}
+
 /// CompareDerivedToBaseConversions - Compares two standard conversion
 /// sequences to determine whether they can be ranked based on their
 /// various kinds of derived-to-base conversions (C++
@@ -5239,9 +5288,6 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
                                     ? ICK_Compatible_Conversion
                                     : ICK_Identity;
     ICS.Standard.Dimension = ICK_Identity;
-    // FIXME: As a speculative fix to a defect introduced by CWG2352, we rank
-    // a reference binding that performs a non-top-level qualification
-    // conversion as a qualification conversion, not as an identity conversion.
     ICS.Standard.Third = (RefConv &
                               Sema::ReferenceConversions::NestedQualification)
                              ? ICK_Qualification
@@ -5250,6 +5296,9 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
     ICS.Standard.setToType(0, T2);
     ICS.Standard.setToType(1, T1);
     ICS.Standard.setToType(2, T1);
+    ICS.Standard.QualificationIncludesObjCLifetime =
+        RefConv & Sema::ReferenceConversions::NestedQualification &&
+        RefConv & Sema::ReferenceConversions::ObjCLifetime;
     ICS.Standard.ReferenceBinding = true;
     ICS.Standard.DirectBinding = BindsDirectly;
     ICS.Standard.IsLvalueReference = !isRValRef;
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index b32e649374893..ed07081765053 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -6,6 +6,79 @@
 // RUN: %clang_cc1 -std=c++23 -pedantic-errors 
-verify=expected,since-cxx11,cxx11-23,since-cxx20,since-cxx23 %s
 // RUN: %clang_cc1 -std=c++2c -pedantic-errors 
-verify=expected,since-cxx11,since-cxx20,since-cxx23,since-cxx26 %s
 
+namespace cwg2803 { // cwg2803: 21
+
+int a[1], *p, *ap[1];
+
+void f1(void*);
+int f1(const volatile int* const&);
+int i1 = f1((int*)0);
+
+void f2(const volatile void* const&);
+int f2(void*);
+int i2 = f2((int*)0);
+
+void f3(const volatile int*);
+int f3(const int*);
+int i3 = f3((int*)0);
+
+void f4(const volatile int* const&);
+int f4(const int* const volatile&);
+int i4 = f4(p);
+
+void f5(const int* const volatile&);
+int f5(const int* const&);
+int i5 = f5(p);
+
+void f6(const volatile int* const (&)[1]);
+int f6(const int* const volatile (&)[1]);
+int i6 = f6(ap);
+
+void f7(const int* const volatile (&)[1]);
+int f7(const int* const (&)[1]);
+int i7 = f7(ap);
+
+int f8(const int* const (&)[]);           // since-cxx20-note {{candidate 
function}}
+int f8(const volatile int* const (&)[1]); // since-cxx20-note {{candidate 
function}}
+int i8 = f8(ap); // since-cxx20-error {{ambiguous}}
+
+void f9(const volatile int* const (&)[]);
+int f9(const int* const volatile (&)[1]);
+int i9 = f9(ap);
+
+void f10(int (&)[]);
+int f10(int (&)[1]);
+int i10 = f10(a);
+
+int f11(int (&)[]);        // since-cxx20-note {{candidate function}}
+int f11(const int (&)[1]); // since-cxx20-note {{candidate function}}
+int i11 = f11(a); // since-cxx20-error {{ambiguous}}
+
+int f12(const int (&)[]);     // since-cxx20-note {{candidate function}}
+int f12(volatile int (&)[1]); // since-cxx20-note {{candidate function}}
+int i12 = f12(a); // since-cxx20-error {{ambiguous}}
+
+#if __cpp_rvalue_references >= 200610
+void f13(const int* const&&);
+int f13(int* const&);
+int i13 = f13((int*)0);
+
+void f14(const int* const&);
+int f14(const volatile int* const volatile&&);
+int i14 = f14((int*)0);
+
+constexpr int f15(const volatile int (&&)[]) {
+       return 1;
+}
+constexpr int f15(const int (&)[1]) {
+       return 2;
+}
+constexpr int i15 = f15(static_cast<int (&&)[1]>(a));
+static_assert(i15 == 2, ""); // since-cxx20-error {{static assertion failed}}
+// since-cxx20-note@-1 {{expression evaluates to '1 == 2'}}
+#endif
+
+} // namespace cwg2803
 
 int main() {} // required for cwg2811
 
diff --git a/clang/test/CXX/drs/cwg29xx.cpp b/clang/test/CXX/drs/cwg29xx.cpp
index f9c2e9ecf4618..2ccded1e45524 100644
--- a/clang/test/CXX/drs/cwg29xx.cpp
+++ b/clang/test/CXX/drs/cwg29xx.cpp
@@ -6,8 +6,6 @@
 // RUN: %clang_cc1 -std=c++23 -pedantic-errors 
-verify=expected,since-cxx11,since-cxx20,since-cxx23 %s
 // RUN: %clang_cc1 -std=c++2c -pedantic-errors 
-verify=expected,since-cxx11,since-cxx20,since-cxx23,since-cxx26 %s
 
-// cxx98-no-diagnostics
-
 namespace cwg2913 { // cwg2913: 20
 
 #if __cplusplus >= 202002L
@@ -171,3 +169,25 @@ constexpr U _ = nondeterministic(true);
 //   since-cxx26-note@-3 {{in call to 'nondeterministic(true)'}}
 #endif
 } // namespace cwg2922
+
+namespace cwg2958 { // cwg2958: 21 open 2024-11-10
+
+int *ap[1];
+
+void f1(const volatile int*);
+int f1(const int* const&);
+int i1 = f1((int*)0);
+
+void f2(const volatile int* const&);
+int f2(const int*);
+int i2 = f2((int*)0);
+
+int f3(const int* const*);                // expected-note {{candidate 
function}}
+int f3(const volatile int* const (&)[1]); // expected-note {{candidate 
function}}
+int i3 = f3(ap); // expected-error {{ambiguous}}
+
+int f4(const volatile int* const*); // expected-note {{candidate function}}
+int f4(const int* const (&)[1]);    // expected-note {{candidate function}}
+int i4 = f4(ap); // expected-error {{ambiguous}}
+
+} // namespace cwg2958
diff --git a/clang/test/SemaObjCXX/arc-overloading.mm 
b/clang/test/SemaObjCXX/arc-overloading.mm
index 8ee01ad46c675..7fe1454de6c8f 100644
--- a/clang/test/SemaObjCXX/arc-overloading.mm
+++ b/clang/test/SemaObjCXX/arc-overloading.mm
@@ -204,6 +204,17 @@ void test_f11() {
   float &fr2a = f11(weak_id); // expected-error {{no match}}
 }
 
+int &f12(const __strong id *);
+float &f12(const __autoreleasing id *const &);
+
+void test_f12() {
+  __strong id *strong_id;
+  __autoreleasing id *autoreleasing_id;
+
+  int &ir = f12(strong_id);
+  float &fr = f12(autoreleasing_id);
+}
+
 void f9790531(void *inClientData); // expected-note {{candidate function not 
viable: cannot implicitly convert argument of type 'MixerEQGraphTestDelegate 
*const __strong' to 'void *' for 1st argument under ARC}}
 void f9790531_1(struct S*inClientData); // expected-note {{candidate function 
not viable}}
 void f9790531_2(char * inClientData); // expected-note {{candidate function 
not viable}}
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 16a9b26052f87..6ea66bcb7c286 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -12529,11 +12529,11 @@ <h2 id="cxxdr">C++ defect report implementation 
status</h2>
     <td>Direct or copy initialization for omitted aggregate initializers</td>
     <td class="unknown" align="center">Unknown</td>
   </tr>
-  <tr class="open" id="2117">
+  <tr id="2117">
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2117.html";>2117</a></td>
-    <td>open</td>
+    <td>NAD</td>
     <td>Explicit specializations and <TT>constexpr</TT> function templates</td>
-    <td align="center">Not resolved</td>
+    <td class="unknown" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2118">
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2118.html";>2118</a></td>
@@ -16666,7 +16666,7 @@ <h2 id="cxxdr">C++ defect report implementation 
status</h2>
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2803.html";>2803</a></td>
     <td>DRWP</td>
     <td>Overload resolution for reference binding of similar types</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="unreleased" align="center">Clang 21</td>
   </tr>
   <tr class="open" id="2804">
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2804.html";>2804</a></td>
@@ -17608,7 +17608,11 @@ <h2 id="cxxdr">C++ defect report implementation 
status</h2>
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2958.html";>2958</a></td>
     <td>open</td>
     <td>Overload resolution involving lvalue transformation and qualification 
conversion</td>
-    <td align="center">Not resolved</td>
+    <td align="center">
+      <details>
+        <summary>Not resolved</summary>
+        Clang 21 implements 2024-11-10 resolution
+      </details></td>
   </tr>
   <tr class="open" id="2959">
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2959.html";>2959</a></td>
@@ -17909,6 +17913,42 @@ <h2 id="cxxdr">C++ defect report implementation 
status</h2>
     <td>open</td>
     <td>Missing Annex C entry for <TT>void</TT> object declarations</td>
     <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="3009">
+    <td><a 
href="https://cplusplus.github.io/CWG/issues/3009.html";>3009</a></td>
+    <td>open</td>
+    <td>Unclear rules for constant initialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="3010">
+    <td><a 
href="https://cplusplus.github.io/CWG/issues/3010.html";>3010</a></td>
+    <td>open</td>
+    <td>constexpr placement-new should require transparent replaceability</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="3011">
+    <td><a 
href="https://cplusplus.github.io/CWG/issues/3011.html";>3011</a></td>
+    <td>open</td>
+    <td>Parenthesized aggregate initialization for <I>new-expression</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="3012">
+    <td><a 
href="https://cplusplus.github.io/CWG/issues/3012.html";>3012</a></td>
+    <td>open</td>
+    <td>Deviating <TT>constexpr</TT> or <TT>consteval</TT> across translation 
units</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="3013">
+    <td><a 
href="https://cplusplus.github.io/CWG/issues/3013.html";>3013</a></td>
+    <td>open</td>
+    <td>Disallowing macros for <TT>#embed</TT> parameters</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="3014">
+    <td><a 
href="https://cplusplus.github.io/CWG/issues/3014.html";>3014</a></td>
+    <td>open</td>
+    <td>Comma-delimited vs. comma-separated output for <TT>#embed</TT></td>
+    <td align="center">Not resolved</td>
   </tr></table>
 
 </div>

>From f0335e4c22ea81769424509355d2479211a59c50 Mon Sep 17 00:00:00 2001
From: offsetof <offse...@mailo.com>
Date: Tue, 25 Mar 2025 13:20:53 +0000
Subject: [PATCH 2/4] fixup! [clang] Implement CWG2803 and CWG2958

Revert unrelated changes to cxx_dr_status.html
---
 clang/www/cxx_dr_status.html | 42 +++---------------------------------
 1 file changed, 3 insertions(+), 39 deletions(-)

diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 6ea66bcb7c286..8eaef850c775e 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -12529,11 +12529,11 @@ <h2 id="cxxdr">C++ defect report implementation 
status</h2>
     <td>Direct or copy initialization for omitted aggregate initializers</td>
     <td class="unknown" align="center">Unknown</td>
   </tr>
-  <tr id="2117">
+  <tr class="open" id="2117">
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2117.html";>2117</a></td>
-    <td>NAD</td>
+    <td>open</td>
     <td>Explicit specializations and <TT>constexpr</TT> function templates</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td align="center">Not resolved</td>
   </tr>
   <tr class="open" id="2118">
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2118.html";>2118</a></td>
@@ -17913,42 +17913,6 @@ <h2 id="cxxdr">C++ defect report implementation 
status</h2>
     <td>open</td>
     <td>Missing Annex C entry for <TT>void</TT> object declarations</td>
     <td align="center">Not resolved</td>
-  </tr>
-  <tr class="open" id="3009">
-    <td><a 
href="https://cplusplus.github.io/CWG/issues/3009.html";>3009</a></td>
-    <td>open</td>
-    <td>Unclear rules for constant initialization</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr class="open" id="3010">
-    <td><a 
href="https://cplusplus.github.io/CWG/issues/3010.html";>3010</a></td>
-    <td>open</td>
-    <td>constexpr placement-new should require transparent replaceability</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr class="open" id="3011">
-    <td><a 
href="https://cplusplus.github.io/CWG/issues/3011.html";>3011</a></td>
-    <td>open</td>
-    <td>Parenthesized aggregate initialization for <I>new-expression</I>s</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr class="open" id="3012">
-    <td><a 
href="https://cplusplus.github.io/CWG/issues/3012.html";>3012</a></td>
-    <td>open</td>
-    <td>Deviating <TT>constexpr</TT> or <TT>consteval</TT> across translation 
units</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr class="open" id="3013">
-    <td><a 
href="https://cplusplus.github.io/CWG/issues/3013.html";>3013</a></td>
-    <td>open</td>
-    <td>Disallowing macros for <TT>#embed</TT> parameters</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr class="open" id="3014">
-    <td><a 
href="https://cplusplus.github.io/CWG/issues/3014.html";>3014</a></td>
-    <td>open</td>
-    <td>Comma-delimited vs. comma-separated output for <TT>#embed</TT></td>
-    <td align="center">Not resolved</td>
   </tr></table>
 
 </div>

>From 558de243ea755d526eb675f416095310bac69986 Mon Sep 17 00:00:00 2001
From: offsetof <offse...@mailo.com>
Date: Tue, 25 Mar 2025 16:12:17 +0000
Subject: [PATCH 3/4] fixup! [clang] Implement CWG2803 and CWG2958

---
 clang/docs/ReleaseNotes.rst    |  5 ++---
 clang/test/CXX/drs/cwg28xx.cpp | 32 +++++++++++++++++++++-----------
 clang/test/CXX/drs/cwg29xx.cpp | 22 ++++++++++++++--------
 3 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6cd99243b0f90..8627852488e8a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -111,9 +111,8 @@ Resolutions to C++ Defect Reports
   in the previous release, as described in P3310 and P3579, made this flag 
unnecessary.
 
 - Implemented `CWG2803 Overload resolution for reference binding of similar 
types <https://cplusplus.github.io/CWG/issues/2803>`_,
-  as amended by the proposed resolution of `CWG2958 Overload resolution 
involving lvalue transformation and qualification conversion 
<https://cplusplus.github.io/CWG/issues/2958>`_
-- Implemented `CWG2918 Consideration of constraints for address of overloaded `
-  `function <https://cplusplus.github.io/CWG/issues/2918.html>`_
+  as amended by the possible resolution of `CWG2958 Overload resolution 
involving lvalue transformation and qualification conversion 
<https://cplusplus.github.io/CWG/issues/2958>`_
+- Implemented `CWG2918 Consideration of constraints for address of overloaded 
function <https://cplusplus.github.io/CWG/issues/2918.html>`_
 
 - Bumped the ``__cpp_constexpr`` feature-test macro to ``202002L`` in C++20 
mode as indicated in
   `P2493R0 <https://wg21.link/P2493R0>`_.
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index ed07081765053..7d2473e90ce0c 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -38,9 +38,12 @@ void f7(const int* const volatile (&)[1]);
 int f7(const int* const (&)[1]);
 int i7 = f7(ap);
 
-int f8(const int* const (&)[]);           // since-cxx20-note {{candidate 
function}}
-int f8(const volatile int* const (&)[1]); // since-cxx20-note {{candidate 
function}}
-int i8 = f8(ap); // since-cxx20-error {{ambiguous}}
+int f8(const int* const (&)[]);
+int f8(const volatile int* const (&)[1]);
+int i8 = f8(ap);
+// since-cxx20-error@-1 {{ambiguous}}
+//   since-cxx20-note@-4 {{candidate function}}
+//   since-cxx20-note@-4 {{candidate function}}
 
 void f9(const volatile int* const (&)[]);
 int f9(const int* const volatile (&)[1]);
@@ -50,13 +53,19 @@ void f10(int (&)[]);
 int f10(int (&)[1]);
 int i10 = f10(a);
 
-int f11(int (&)[]);        // since-cxx20-note {{candidate function}}
-int f11(const int (&)[1]); // since-cxx20-note {{candidate function}}
-int i11 = f11(a); // since-cxx20-error {{ambiguous}}
+int f11(int (&)[]);
+int f11(const int (&)[1]);
+int i11 = f11(a);
+// since-cxx20-error@-1 {{ambiguous}}
+//   since-cxx20-note@-4 {{candidate function}}
+//   since-cxx20-note@-4 {{candidate function}}
 
-int f12(const int (&)[]);     // since-cxx20-note {{candidate function}}
-int f12(volatile int (&)[1]); // since-cxx20-note {{candidate function}}
-int i12 = f12(a); // since-cxx20-error {{ambiguous}}
+int f12(const int (&)[]);
+int f12(volatile int (&)[1]);
+int i12 = f12(a);
+// since-cxx20-error@-1 {{ambiguous}}
+//   since-cxx20-note@-4 {{candidate function}}
+//   since-cxx20-note@-4 {{candidate function}}
 
 #if __cpp_rvalue_references >= 200610
 void f13(const int* const&&);
@@ -74,8 +83,9 @@ constexpr int f15(const int (&)[1]) {
        return 2;
 }
 constexpr int i15 = f15(static_cast<int (&&)[1]>(a));
-static_assert(i15 == 2, ""); // since-cxx20-error {{static assertion failed}}
-// since-cxx20-note@-1 {{expression evaluates to '1 == 2'}}
+static_assert(i15 == 2, "");
+// since-cxx20-error@-1 {{static assertion failed}}
+//   since-cxx20-note@-2 {{expression evaluates to '1 == 2'}}
 #endif
 
 } // namespace cwg2803
diff --git a/clang/test/CXX/drs/cwg29xx.cpp b/clang/test/CXX/drs/cwg29xx.cpp
index 2ccded1e45524..c67b973f601cb 100644
--- a/clang/test/CXX/drs/cwg29xx.cpp
+++ b/clang/test/CXX/drs/cwg29xx.cpp
@@ -104,7 +104,7 @@ void test() {
   constexpr auto y = &X<false>::f;
   static_assert(__is_same(decltype(y), int(*const)(short)));
   static_assert(y(0) == 24, "");
-  
+
   constexpr auto z = &f<int>;
   static_assert(__is_same(decltype(z), int(*const)(int)));
   static_assert(z(0) == 2, "");
@@ -182,12 +182,18 @@ void f2(const volatile int* const&);
 int f2(const int*);
 int i2 = f2((int*)0);
 
-int f3(const int* const*);                // expected-note {{candidate 
function}}
-int f3(const volatile int* const (&)[1]); // expected-note {{candidate 
function}}
-int i3 = f3(ap); // expected-error {{ambiguous}}
-
-int f4(const volatile int* const*); // expected-note {{candidate function}}
-int f4(const int* const (&)[1]);    // expected-note {{candidate function}}
-int i4 = f4(ap); // expected-error {{ambiguous}}
+int f3(const int* const*);
+int f3(const volatile int* const (&)[1]);
+int i3 = f3(ap);
+// expected-error@-1 {{ambiguous}}
+//   expected-note@-4 {{candidate function}}
+//   expected-note@-4 {{candidate function}}
+
+int f4(const volatile int* const*);
+int f4(const int* const (&)[1]);
+int i4 = f4(ap);
+// expected-error@-1 {{ambiguous}}
+//   expected-note@-4 {{candidate function}}
+//   expected-note@-4 {{candidate function}}
 
 } // namespace cwg2958

>From f6634d226db0e4a5aeca686aa19fbf2479ee363c Mon Sep 17 00:00:00 2001
From: offsetof <offse...@mailo.com>
Date: Wed, 2 Apr 2025 14:26:40 +0000
Subject: [PATCH 4/4] fixup! [clang] Implement CWG2803 and CWG2958

---
 clang/test/CXX/drs/cwg28xx.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index 7d2473e90ce0c..cd052845b2a68 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -41,7 +41,7 @@ int i7 = f7(ap);
 int f8(const int* const (&)[]);
 int f8(const volatile int* const (&)[1]);
 int i8 = f8(ap);
-// since-cxx20-error@-1 {{ambiguous}}
+// since-cxx20-error@-1 {{call to 'f8' is ambiguous}}
 //   since-cxx20-note@-4 {{candidate function}}
 //   since-cxx20-note@-4 {{candidate function}}
 
@@ -56,18 +56,18 @@ int i10 = f10(a);
 int f11(int (&)[]);
 int f11(const int (&)[1]);
 int i11 = f11(a);
-// since-cxx20-error@-1 {{ambiguous}}
+// since-cxx20-error@-1 {{call to 'f11' is ambiguous}}
 //   since-cxx20-note@-4 {{candidate function}}
 //   since-cxx20-note@-4 {{candidate function}}
 
 int f12(const int (&)[]);
 int f12(volatile int (&)[1]);
 int i12 = f12(a);
-// since-cxx20-error@-1 {{ambiguous}}
+// since-cxx20-error@-1 {{call to 'f12' is ambiguous}}
 //   since-cxx20-note@-4 {{candidate function}}
 //   since-cxx20-note@-4 {{candidate function}}
 
-#if __cpp_rvalue_references >= 200610
+#if __cplusplus >= 201103L
 void f13(const int* const&&);
 int f13(int* const&);
 int i13 = f13((int*)0);

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to