Skip to content

Commit e183090

Browse files
committed
[Clang] Implement P28646R2 Remove Deprecated Arithmetic Conversion on Enumerations
https://isocpp.org/files/papers/P2864R2.pdf
1 parent 740f14e commit e183090

File tree

5 files changed

+32
-6
lines changed

5 files changed

+32
-6
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ C++2c Feature Support
182182
This is applied to both C++ standard attributes, and other attributes supported by Clang.
183183
This completes the implementation of `P2361R6 Unevaluated Strings <https://wg21.link/P2361R6>`_
184184

185+
- Implemented `P2864R2 Remove Deprecated Arithmetic Conversion on Enumerations From C++26 <https://wg21.link/P2864R2>`_.
186+
185187

186188
Resolutions to C++ Defect Reports
187189
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7220,6 +7220,11 @@ def warn_arith_conv_enum_float_cxx20 : Warning<
72207220
"%plural{2:with|4:from|:and}0 "
72217221
"%select{enumeration|floating-point}1 type %3 is deprecated">,
72227222
InGroup<DeprecatedEnumFloatConversion>;
7223+
def err_arith_conv_enum_float_cxx26 : Error<
7224+
"invalid %sub{select_arith_conv_kind}0 "
7225+
"%select{floating-point|enumeration}1 type %2 "
7226+
"%plural{2:with|4:from|:and}0 "
7227+
"%select{enumeration|floating-point}1 type %3">;
72237228
def warn_arith_conv_mixed_enum_types : Warning<
72247229
"%sub{select_arith_conv_kind}0 "
72257230
"different enumeration types%diff{ ($ and $)|}1,2">,
@@ -7228,6 +7233,10 @@ def warn_arith_conv_mixed_enum_types_cxx20 : Warning<
72287233
"%sub{select_arith_conv_kind}0 "
72297234
"different enumeration types%diff{ ($ and $)|}1,2 is deprecated">,
72307235
InGroup<DeprecatedEnumEnumConversion>;
7236+
def err_conv_mixed_enum_types_cxx26 : Error<
7237+
"invalid %sub{select_arith_conv_kind}0 "
7238+
"different enumeration types%diff{ ($ and $)|}1,2">;
7239+
72317240
def warn_arith_conv_mixed_anon_enum_types : Warning<
72327241
warn_arith_conv_mixed_enum_types.Summary>,
72337242
InGroup<AnonEnumEnumConversion>, DefaultIgnore;

clang/lib/Sema/SemaExpr.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,16 +1503,22 @@ static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS,
15031503
bool IsCompAssign = ACK == Sema::ACK_CompAssign;
15041504
if ((!IsCompAssign && LEnum && R->isFloatingType()) ||
15051505
(REnum && L->isFloatingType())) {
1506-
S.Diag(Loc, S.getLangOpts().CPlusPlus20
1506+
S.Diag(Loc, S.getLangOpts().CPlusPlus26
1507+
? diag::err_arith_conv_enum_float_cxx26
1508+
: S.getLangOpts().CPlusPlus20
15071509
? diag::warn_arith_conv_enum_float_cxx20
15081510
: diag::warn_arith_conv_enum_float)
1509-
<< LHS->getSourceRange() << RHS->getSourceRange()
1510-
<< (int)ACK << LEnum << L << R;
1511+
<< LHS->getSourceRange() << RHS->getSourceRange() << (int)ACK << LEnum
1512+
<< L << R;
15111513
} else if (!IsCompAssign && LEnum && REnum &&
15121514
!S.Context.hasSameUnqualifiedType(L, R)) {
15131515
unsigned DiagID;
1514-
if (!L->castAs<EnumType>()->getDecl()->hasNameForLinkage() ||
1515-
!R->castAs<EnumType>()->getDecl()->hasNameForLinkage()) {
1516+
// In C++ 26, usual arithmetic conversions between 2 different enum types
1517+
// are ill-formed.
1518+
if (S.getLangOpts().CPlusPlus26)
1519+
DiagID = diag::err_conv_mixed_enum_types_cxx26;
1520+
else if (!L->castAs<EnumType>()->getDecl()->hasNameForLinkage() ||
1521+
!R->castAs<EnumType>()->getDecl()->hasNameForLinkage()) {
15161522
// If either enumeration type is unnamed, it's less likely that the
15171523
// user cares about this, but this situation is still deprecated in
15181524
// C++2a. Use a different warning group.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -verify -triple %itanium_abi_triple
2+
3+
enum E1 { e };
4+
enum E2 { f };
5+
void test() {
6+
int b = e <= 3.7; // expected-error {{invalid comparison of enumeration type 'E1' with floating-point type 'double'}}
7+
int k = f - e; // expected-error {{invalid arithmetic between different enumeration types ('E2' and 'E1')}}
8+
int x = 1 ? e : f; // expected-error {{invalid conditional expression between different enumeration types ('E1' and 'E2')}}
9+
}

clang/www/cxx_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ <h2 id="cxx26">C++2c implementation status</h2>
161161
<tr>
162162
<td>Remove Deprecated Arithmetic Conversion on Enumerations</td>
163163
<td><a href="https://wg21.link/P2864R2">P2864R2</a></td>
164-
<td class="none" align="center">No</td>
164+
<td class="unreleased" align="center">Clang 18</td>
165165
</tr>
166166

167167
</table>

0 commit comments

Comments
 (0)