Skip to content

Commit 824084e

Browse files
committed
[Clang] Suggest using std::to_underlying for invalid scoped enum operations in C++23
1 parent 76baf51 commit 824084e

File tree

2 files changed

+20
-14
lines changed

2 files changed

+20
-14
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4405,6 +4405,9 @@ def warn_impcast_int_to_enum : Warning<
44054405
def note_no_implicit_conversion_for_scoped_enum
44064406
: Note<"no implicit conversion for scoped enum; consider casting to "
44074407
"underlying type">;
4408+
def note_no_implicit_conversion_for_scoped_enum_cxx23
4409+
: Note<"no implicit conversion for scoped enum; consider using "
4410+
"std::to_underlying">;
44084411

44094412
def warn_impcast_bool_to_null_pointer : Warning<
44104413
"initialization of pointer of type %0 to null from a constant boolean "

clang/lib/Sema/SemaExpr.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10761,23 +10761,26 @@ static void diagnoseScopedEnums(Sema &S, const SourceLocation Loc,
1076110761
return;
1076210762
if (BinaryOperator::isAssignmentOp(Opc) && LHSIsScoped)
1076310763
return;
10764+
bool isCxx23 = S.getLangOpts().CPlusPlus23;
10765+
unsigned diagID =
10766+
isCxx23 ? diag::note_no_implicit_conversion_for_scoped_enum_cxx23
10767+
: diag::note_no_implicit_conversion_for_scoped_enum;
10768+
auto diagnosticHelper = [&S, isCxx23, diagID](const Expr *expr, const QualType type) {
10769+
SourceLocation beginLoc = expr->getBeginLoc();
10770+
QualType intType =
10771+
type->castAs<EnumType>()->getDecl()->getIntegerType();
10772+
std::string insertionString =
10773+
isCxx23 ? "std::to_underlying("
10774+
: "static_cast<" + intType.getAsString() + ">(";
10775+
S.Diag(beginLoc, diagID)
10776+
<< FixItHint::CreateInsertion(beginLoc, insertionString)
10777+
<< FixItHint::CreateInsertion(expr->getEndLoc(), ")");
10778+
};
1076410779
if (LHSIsScoped) {
10765-
SourceLocation LHSBegin = LHSExpr->getBeginLoc();
10766-
QualType LHSIntType =
10767-
LHSType->castAs<EnumType>()->getDecl()->getIntegerType();
10768-
S.Diag(LHSBegin, diag::note_no_implicit_conversion_for_scoped_enum)
10769-
<< FixItHint::CreateInsertion(
10770-
LHSBegin, "static_cast<" + LHSIntType.getAsString() + ">(")
10771-
<< FixItHint::CreateInsertion(LHSExpr->getEndLoc(), ")");
10780+
diagnosticHelper(LHSExpr, LHSType);
1077210781
}
1077310782
if (RHSIsScoped) {
10774-
SourceLocation RHSBegin = RHSExpr->getBeginLoc();
10775-
QualType RHSIntType =
10776-
RHSType->castAs<EnumType>()->getDecl()->getIntegerType();
10777-
S.Diag(RHSBegin, diag::note_no_implicit_conversion_for_scoped_enum)
10778-
<< FixItHint::CreateInsertion(
10779-
RHSBegin, "static_cast<" + RHSIntType.getAsString() + ">(")
10780-
<< FixItHint::CreateInsertion(RHSExpr->getEndLoc(), ")");
10783+
diagnosticHelper(RHSExpr, RHSType);
1078110784
}
1078210785
}
1078310786

0 commit comments

Comments
 (0)