[clang] [Clang] Implement P2864R2 Remove Deprecated Arithmetic Conversion on… (PR #73105)

via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 29 09:01:30 PST 2023


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

>From e18309057cb6977b665ba2d7fcbd313a578eaad5 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