[clang] [clang] Implement CWG2815 (PR #132778)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 2 07:41:05 PDT 2025
https://github.com/offsetof updated https://github.com/llvm/llvm-project/pull/132778
>From 0aa1e7b83888bde7112327fba7db9bdcb71c43d9 Mon Sep 17 00:00:00 2001
From: offsetof <offsetof at mailo.com>
Date: Mon, 24 Mar 2025 16:28:28 +0000
Subject: [PATCH 1/4] [clang] Implement CWG2815
CWG2815 "Overload resolution for references/pointers to `noexcept`
functions"
---
clang/docs/ReleaseNotes.rst | 4 +++
clang/lib/Sema/SemaExprCXX.cpp | 3 ++-
clang/lib/Sema/SemaOverload.cpp | 34 +++++++++++++++----------
clang/test/CXX/drs/cwg28xx.cpp | 22 +++++++++++++++++
clang/www/cxx_dr_status.html | 44 ++++++++++++++++++++++++++++++---
5 files changed, 89 insertions(+), 18 deletions(-)
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>
>From 9871e7f38739bf4e3d47d6f30b6cad8cfd8a808a Mon Sep 17 00:00:00 2001
From: offsetof <offsetof at mailo.com>
Date: Tue, 25 Mar 2025 13:19:42 +0000
Subject: [PATCH 2/4] fixup! [clang] Implement CWG2815
---
clang/lib/Sema/SemaOverload.cpp | 12 +++++-----
clang/www/cxx_dr_status.html | 42 +++------------------------------
2 files changed, 9 insertions(+), 45 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index aa55bf03edaa0..8335c320ad79b 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -5255,12 +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::Function)
- ? ICK_Function_Conversion
- : (RefConv & Sema::ReferenceConversions::NestedQualification)
- ? ICK_Qualification
- : ICK_Identity;
+ if (RefConv & Sema::ReferenceConversions::Function)
+ ICS.Standard.Third = ICK_Function_Conversion;
+ else if (RefConv & Sema::ReferenceConversions::NestedQualification)
+ ICS.Standard.Third = ICK_Qualification;
+ else
+ ICS.Standard.Third = ICK_Identity;
ICS.Standard.setFromType(T2);
ICS.Standard.setToType(0, T2);
ICS.Standard.setToType(1, T1);
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 4590bcec6df9e..4216f71ace448 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>
@@ -17909,42 +17909,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 01345001802cff1e7e490ae4ca34a8c14535f2d0 Mon Sep 17 00:00:00 2001
From: offsetof <offsetof at mailo.com>
Date: Tue, 25 Mar 2025 16:04:56 +0000
Subject: [PATCH 3/4] fixup! [clang] Implement CWG2815
---
clang/docs/ReleaseNotes.rst | 5 +----
clang/lib/Sema/SemaOverload.cpp | 2 +-
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a3af19f79d9c3..05a8045e33da6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -110,16 +110,13 @@ 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 `CWG2815 Overload resolution for references/pointers to noexcept functions <https://cplusplus.github.io/CWG/issues/2815>`_
- 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/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 8335c320ad79b..a7abdf4c6186d 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -5229,7 +5229,7 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
S.CompareReferenceRelationship(DeclLoc, T1, T2, &RefConv);
auto SetAsReferenceBinding = [&](bool BindsDirectly) {
- // C++2c [over.ics.ref] p1:
+ // C++26 [over.ics.ref] p1 (per CWG2803 and CWG2815):
// 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
>From 404fd0fd02c6cd4f598640e177b35e341a734e4d Mon Sep 17 00:00:00 2001
From: offsetof <offsetof at mailo.com>
Date: Wed, 2 Apr 2025 14:31:28 +0000
Subject: [PATCH 4/4] fixup! [clang] Implement CWG2815
Replace feature-test macro with `__cplusplus`
---
clang/test/CXX/drs/cwg28xx.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index 3f65b7b7e46da..91fa212010c16 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -48,7 +48,7 @@ void f() {
} // namespace cwg2813
namespace cwg2815 { // cwg2815: 21
-#if __cpp_noexcept_function_type >= 201510
+#if __cplusplus >= 201703L
int arg() noexcept;
int f(int (&)() noexcept);
More information about the cfe-commits
mailing list