llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: None (offsetof)

<details>
<summary>Changes</summary>

CWG2815 "Overload resolution for references/pointers to `noexcept` functions"

---
Full diff: https://github.com/llvm/llvm-project/pull/132778.diff


5 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+4) 
- (modified) clang/lib/Sema/SemaExprCXX.cpp (+2-1) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+21-13) 
- (modified) clang/test/CXX/drs/cwg28xx.cpp (+22) 
- (modified) clang/www/cxx_dr_status.html (+40-4) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8182bccdd2da8..a3af19f79d9c3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -110,12 +110,16 @@ 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 |CWG2815|_
 - 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>`_.
 
+.. |CWG2815| replace:: CWG2815 Overload resolution for references/pointers to 
``noexcept`` functions
+.. _CWG2815: https://cplusplus.github.io/CWG/issues/2815
+
 C Language Changes
 ------------------
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 856b505e92214..da13c9c7db401 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -4907,7 +4907,8 @@ Sema::PerformImplicitConversion(Expr *From, QualType 
ToType,
     if (CheckExceptionSpecCompatibility(From, ToType))
       return ExprError();
 
-    From = ImpCastExprToType(From, ToType, CK_NoOp, VK_PRValue,
+    From = ImpCastExprToType(From, ToType.getNonReferenceType(), CK_NoOp,
+                             From->getValueKind(),
                              /*BasePath=*/nullptr, CCK)
                .get();
     break;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 6d8006b35dcf4..aa55bf03edaa0 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -5229,10 +5229,23 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
       S.CompareReferenceRelationship(DeclLoc, T1, T2, &RefConv);
 
   auto SetAsReferenceBinding = [&](bool BindsDirectly) {
+    // C++2c [over.ics.ref] p1:
+    //   When a parameter of type "reference to cv T" binds directly
+    //   to an argument expression:
+    //   * If the argument expression has a type that is a derived class
+    //     of the parameter type, the implicit conversion sequence is a
+    //     derived-to-base conversion.
+    //   * Otherwise, if the type of the argument is possibly cv-qualified T,
+    //     or if T is an array type of unknown bound with element type U
+    //     and the argument has an array type of known bound whose element
+    //     type is possibly cv-qualified U, the implicit conversion
+    //     sequence is the identity conversion.
+    //   * Otherwise, if T is a function type, the implicit conversion
+    //     sequence is a function pointer conversion.
+    //   * Otherwise, the implicit conversion sequence is a qualification
+    //     conversion.
     ICS.setStandard();
     ICS.Standard.First = ICK_Identity;
-    // FIXME: A reference binding can be a function conversion too. We should
-    // consider that when ordering reference-to-function bindings.
     ICS.Standard.Second = (RefConv & Sema::ReferenceConversions::DerivedToBase)
                               ? ICK_Derived_To_Base
                               : (RefConv & Sema::ReferenceConversions::ObjC)
@@ -5242,10 +5255,12 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
     // 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
-                             : ICK_Identity;
+    ICS.Standard.Third =
+        (RefConv & Sema::ReferenceConversions::Function)
+            ? ICK_Function_Conversion
+        : (RefConv & Sema::ReferenceConversions::NestedQualification)
+            ? ICK_Qualification
+            : ICK_Identity;
     ICS.Standard.setFromType(T2);
     ICS.Standard.setToType(0, T2);
     ICS.Standard.setToType(1, T1);
@@ -5273,13 +5288,6 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
     //
     // Per C++ [over.ics.ref]p4, we don't check the bit-field property here.
     if (InitCategory.isLValue() && RefRelationship == Sema::Ref_Compatible) {
-      // C++ [over.ics.ref]p1:
-      //   When a parameter of reference type binds directly (8.5.3)
-      //   to an argument expression, the implicit conversion sequence
-      //   is the identity conversion, unless the argument expression
-      //   has a type that is a derived class of the parameter type,
-      //   in which case the implicit conversion sequence is a
-      //   derived-to-base Conversion (13.3.3.1).
       SetAsReferenceBinding(/*BindsDirectly=*/true);
 
       // Nothing more to do: the inaccessibility/ambiguity check for
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index b32e649374893..3f65b7b7e46da 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -47,6 +47,28 @@ void f() {
 #endif
 } // namespace cwg2813
 
+namespace cwg2815 { // cwg2815: 21
+#if __cpp_noexcept_function_type >= 201510
+int arg() noexcept;
+
+int f(int (&)() noexcept);
+void f(int (&)());
+int i = f(arg);
+
+int g(int (*)() noexcept);
+void g(int (&)());
+int j = g(arg);
+
+int h(int (&)() noexcept);
+void h(int (*)());
+int k = h(arg);
+
+int a(int (*)()); // expected-note {{candidate function}}
+int a(int (&)()); // expected-note {{candidate function}}
+int x = a(arg); // expected-error {{call to 'a' is ambiguous}}
+#endif
+} // namespace cwg2815
+
 namespace cwg2819 { // cwg2819: 19 c++26
 #if __cplusplus >= 201103L
   // CWG 2024-04-19: This issue is not a DR.
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 16a9b26052f87..4590bcec6df9e 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>
@@ -16738,7 +16738,7 @@ <h2 id="cxxdr">C++ defect report implementation 
status</h2>
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2815.html";>2815</a></td>
     <td>DR</td>
     <td>Overload resolution for references/pointers to <TT>noexcept</TT> 
functions</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="unreleased" align="center">Clang 21</td>
   </tr>
   <tr class="open" id="2816">
     <td><a 
href="https://cplusplus.github.io/CWG/issues/2816.html";>2816</a></td>
@@ -17909,6 +17909,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>

``````````

</details>


https://github.com/llvm/llvm-project/pull/132778
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to