[clang] 2340a4e - [clang][Sema] Cleanup and optimize DiagnoseAssignmentEnum (#141471)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 27 21:02:05 PDT 2025
Author: Timm Baeder
Date: 2025-05-28T06:02:02+02:00
New Revision: 2340a4e902367ec4571d450158c728e5f11b8964
URL: https://github.com/llvm/llvm-project/commit/2340a4e902367ec4571d450158c728e5f11b8964
DIFF: https://github.com/llvm/llvm-project/commit/2340a4e902367ec4571d450158c728e5f11b8964.diff
LOG: [clang][Sema] Cleanup and optimize DiagnoseAssignmentEnum (#141471)
Reorder the precondition checks to move the costly onces last. Also,
only evaluate the RHS once to get the integral value.
Added:
Modified:
clang/lib/Sema/SemaStmt.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index c943645c3ab9d..1fc96664dd87c 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -1741,57 +1741,65 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
void
Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
Expr *SrcExpr) {
+
+ const auto *ET = DstType->getAs<EnumType>();
+ if (!ET)
+ return;
+
+ if (!SrcType->isIntegerType() ||
+ Context.hasSameUnqualifiedType(SrcType, DstType))
+ return;
+
+ if (SrcExpr->isTypeDependent() || SrcExpr->isValueDependent())
+ return;
+
+ const EnumDecl *ED = ET->getDecl();
+ if (!ED->isClosed())
+ return;
+
if (Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc()))
return;
- if (const EnumType *ET = DstType->getAs<EnumType>())
- if (!Context.hasSameUnqualifiedType(SrcType, DstType) &&
- SrcType->isIntegerType()) {
- if (!SrcExpr->isTypeDependent() && !SrcExpr->isValueDependent() &&
- SrcExpr->isIntegerConstantExpr(Context)) {
- // Get the bitwidth of the enum value before promotions.
- unsigned DstWidth = Context.getIntWidth(DstType);
- bool DstIsSigned = DstType->isSignedIntegerOrEnumerationType();
+ std::optional<llvm::APSInt> RHSVal = SrcExpr->getIntegerConstantExpr(Context);
+ if (!RHSVal)
+ return;
- llvm::APSInt RhsVal = SrcExpr->EvaluateKnownConstInt(Context);
- AdjustAPSInt(RhsVal, DstWidth, DstIsSigned);
- const EnumDecl *ED = ET->getDecl();
+ // Get the bitwidth of the enum value before promotions.
+ unsigned DstWidth = Context.getIntWidth(DstType);
+ bool DstIsSigned = DstType->isSignedIntegerOrEnumerationType();
+ AdjustAPSInt(*RHSVal, DstWidth, DstIsSigned);
- if (!ED->isClosed())
- return;
+ if (ED->hasAttr<FlagEnumAttr>()) {
+ if (!IsValueInFlagEnum(ED, *RHSVal, /*AllowMask=*/true))
+ Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
+ << DstType.getUnqualifiedType();
+ return;
+ }
- if (ED->hasAttr<FlagEnumAttr>()) {
- if (!IsValueInFlagEnum(ED, RhsVal, true))
- Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
- << DstType.getUnqualifiedType();
- } else {
- typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64>
- EnumValsTy;
- EnumValsTy EnumVals;
-
- // Gather all enum values, set their type and sort them,
- // allowing easier comparison with rhs constant.
- for (auto *EDI : ED->enumerators()) {
- llvm::APSInt Val = EDI->getInitVal();
- AdjustAPSInt(Val, DstWidth, DstIsSigned);
- EnumVals.push_back(std::make_pair(Val, EDI));
- }
- if (EnumVals.empty())
- return;
- llvm::stable_sort(EnumVals, CmpEnumVals);
- EnumValsTy::iterator EIend = llvm::unique(EnumVals, EqEnumVals);
-
- // See which values aren't in the enum.
- EnumValsTy::const_iterator EI = EnumVals.begin();
- while (EI != EIend && EI->first < RhsVal)
- EI++;
- if (EI == EIend || EI->first != RhsVal) {
- Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
- << DstType.getUnqualifiedType();
- }
- }
- }
- }
+ typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64>
+ EnumValsTy;
+ EnumValsTy EnumVals;
+
+ // Gather all enum values, set their type and sort them,
+ // allowing easier comparison with rhs constant.
+ for (auto *EDI : ED->enumerators()) {
+ llvm::APSInt Val = EDI->getInitVal();
+ AdjustAPSInt(Val, DstWidth, DstIsSigned);
+ EnumVals.emplace_back(Val, EDI);
+ }
+ if (EnumVals.empty())
+ return;
+ llvm::stable_sort(EnumVals, CmpEnumVals);
+ EnumValsTy::iterator EIend = llvm::unique(EnumVals, EqEnumVals);
+
+ // See which values aren't in the enum.
+ EnumValsTy::const_iterator EI = EnumVals.begin();
+ while (EI != EIend && EI->first < *RHSVal)
+ EI++;
+ if (EI == EIend || EI->first != *RHSVal) {
+ Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
+ << DstType.getUnqualifiedType();
+ }
}
StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc,
More information about the cfe-commits
mailing list