[clang] [Clang] Implement P2864R2 Remove Deprecated Arithmetic Conversion on… (PR #73105)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 29 08:01:09 PST 2023
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/73105
>From a835d36f3051daf4d7e20493860a7a104c9640b5 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Wed, 22 Nov 2023 12:25:20 +0100
Subject: [PATCH] [Clang] Implement P28646R2 Remove Deprecated Arithmetic
Conversion on Enumerations
https://isocpp.org/files/papers/P2864R2.pdf
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/include/clang/Basic/DiagnosticSemaKinds.td | 9 +++++++++
clang/lib/Sema/SemaExpr.cpp | 16 +++++++++++-----
clang/test/SemaCXX/cxx2c-enum-compare.cpp | 9 +++++++++
clang/www/cxx_status.html | 2 +-
5 files changed, 32 insertions(+), 6 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-enum-compare.cpp
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e4beeee0a2cb5e0..2ee946af32bf197 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -182,6 +182,8 @@ C++2c Feature Support
This is applied to both C++ standard attributes, and other attributes supported by Clang.
This completes the implementation of `P2361R6 Unevaluated Strings <https://wg21.link/P2361R6>`_
+- Implemented `P2864R2 Remove Deprecated Arithmetic Conversion on Enumerations From C++26 <https://wg21.link/P2864R2>`_.
+
Resolutions to C++ Defect Reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d164177251e4db7..ed9bd929c6c4816 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7220,6 +7220,11 @@ def warn_arith_conv_enum_float_cxx20 : Warning<
"%plural{2:with|4:from|:and}0 "
"%select{enumeration|floating-point}1 type %3 is deprecated">,
InGroup<DeprecatedEnumFloatConversion>;
+def err_arith_conv_enum_float_cxx26 : Error<
+ "invalid %sub{select_arith_conv_kind}0 "
+ "%select{floating-point|enumeration}1 type %2 "
+ "%plural{2:with|4:from|:and}0 "
+ "%select{enumeration|floating-point}1 type %3">;
def warn_arith_conv_mixed_enum_types : Warning<
"%sub{select_arith_conv_kind}0 "
"different enumeration types%diff{ ($ and $)|}1,2">,
@@ -7228,6 +7233,10 @@ def warn_arith_conv_mixed_enum_types_cxx20 : Warning<
"%sub{select_arith_conv_kind}0 "
"different enumeration types%diff{ ($ and $)|}1,2 is deprecated">,
InGroup<DeprecatedEnumEnumConversion>;
+def err_conv_mixed_enum_types_cxx26 : Error<
+ "invalid %sub{select_arith_conv_kind}0 "
+ "different enumeration types%diff{ ($ and $)|}1,2">;
+
def warn_arith_conv_mixed_anon_enum_types : Warning<
warn_arith_conv_mixed_enum_types.Summary>,
InGroup<AnonEnumEnumConversion>, DefaultIgnore;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index fc39d6149c1cc65..d1b2b8084b8ffea 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1503,16 +1503,22 @@ static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS,
bool IsCompAssign = ACK == Sema::ACK_CompAssign;
if ((!IsCompAssign && LEnum && R->isFloatingType()) ||
(REnum && L->isFloatingType())) {
- S.Diag(Loc, S.getLangOpts().CPlusPlus20
+ S.Diag(Loc, S.getLangOpts().CPlusPlus26
+ ? diag::err_arith_conv_enum_float_cxx26
+ : S.getLangOpts().CPlusPlus20
? diag::warn_arith_conv_enum_float_cxx20
: diag::warn_arith_conv_enum_float)
- << LHS->getSourceRange() << RHS->getSourceRange()
- << (int)ACK << LEnum << L << R;
+ << LHS->getSourceRange() << RHS->getSourceRange() << (int)ACK << LEnum
+ << L << R;
} else if (!IsCompAssign && LEnum && REnum &&
!S.Context.hasSameUnqualifiedType(L, R)) {
unsigned DiagID;
- if (!L->castAs<EnumType>()->getDecl()->hasNameForLinkage() ||
- !R->castAs<EnumType>()->getDecl()->hasNameForLinkage()) {
+ // In C++ 26, usual arithmetic conversions between 2 different enum types
+ // are ill-formed.
+ if (S.getLangOpts().CPlusPlus26)
+ DiagID = diag::err_conv_mixed_enum_types_cxx26;
+ else if (!L->castAs<EnumType>()->getDecl()->hasNameForLinkage() ||
+ !R->castAs<EnumType>()->getDecl()->hasNameForLinkage()) {
// If either enumeration type is unnamed, it's less likely that the
// user cares about this, but this situation is still deprecated in
// C++2a. Use a different warning group.
diff --git a/clang/test/SemaCXX/cxx2c-enum-compare.cpp b/clang/test/SemaCXX/cxx2c-enum-compare.cpp
new file mode 100644
index 000000000000000..f47278a60725e8e
--- /dev/null
+++ b/clang/test/SemaCXX/cxx2c-enum-compare.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -verify -triple %itanium_abi_triple
+
+enum E1 { e };
+enum E2 { f };
+void test() {
+ int b = e <= 3.7; // expected-error {{invalid comparison of enumeration type 'E1' with floating-point type 'double'}}
+ int k = f - e; // expected-error {{invalid arithmetic between different enumeration types ('E2' and 'E1')}}
+ int x = 1 ? e : f; // expected-error {{invalid conditional expression between different enumeration types ('E1' and 'E2')}}
+}
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 621439d0bae9666..9fb6b0cda4da50d 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -161,7 +161,7 @@ <h2 id="cxx26">C++2c implementation status</h2>
<tr>
<td>Remove Deprecated Arithmetic Conversion on Enumerations</td>
<td><a href="https://wg21.link/P2864R2">P2864R2</a></td>
- <td class="none" align="center">No</td>
+ <td class="unreleased" align="center">Clang 18</td>
</tr>
</table>
More information about the cfe-commits
mailing list