@@ -1741,57 +1741,65 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
17411741void
17421742Sema::DiagnoseAssignmentEnum (QualType DstType, QualType SrcType,
17431743 Expr *SrcExpr) {
1744+
1745+ const auto *ET = DstType->getAs <EnumType>();
1746+ if (!ET)
1747+ return ;
1748+
1749+ if (!SrcType->isIntegerType () ||
1750+ Context.hasSameUnqualifiedType (SrcType, DstType))
1751+ return ;
1752+
1753+ if (SrcExpr->isTypeDependent () || SrcExpr->isValueDependent ())
1754+ return ;
1755+
1756+ const EnumDecl *ED = ET->getDecl ();
1757+ if (!ED->isClosed ())
1758+ return ;
1759+
17441760 if (Diags.isIgnored (diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc ()))
17451761 return ;
17461762
1747- if (const EnumType *ET = DstType->getAs <EnumType>())
1748- if (!Context.hasSameUnqualifiedType (SrcType, DstType) &&
1749- SrcType->isIntegerType ()) {
1750- if (!SrcExpr->isTypeDependent () && !SrcExpr->isValueDependent () &&
1751- SrcExpr->isIntegerConstantExpr (Context)) {
1752- // Get the bitwidth of the enum value before promotions.
1753- unsigned DstWidth = Context.getIntWidth (DstType);
1754- bool DstIsSigned = DstType->isSignedIntegerOrEnumerationType ();
1763+ std::optional<llvm::APSInt> RHSVal = SrcExpr->getIntegerConstantExpr (Context);
1764+ if (!RHSVal)
1765+ return ;
17551766
1756- llvm::APSInt RhsVal = SrcExpr->EvaluateKnownConstInt (Context);
1757- AdjustAPSInt (RhsVal, DstWidth, DstIsSigned);
1758- const EnumDecl *ED = ET->getDecl ();
1767+ // Get the bitwidth of the enum value before promotions.
1768+ unsigned DstWidth = Context.getIntWidth (DstType);
1769+ bool DstIsSigned = DstType->isSignedIntegerOrEnumerationType ();
1770+ AdjustAPSInt (*RHSVal, DstWidth, DstIsSigned);
17591771
1760- if (!ED->isClosed ())
1761- return ;
1772+ if (ED->hasAttr <FlagEnumAttr>()) {
1773+ if (!IsValueInFlagEnum (ED, *RHSVal, /* AllowMask=*/ true ))
1774+ Diag (SrcExpr->getExprLoc (), diag::warn_not_in_enum_assignment)
1775+ << DstType.getUnqualifiedType ();
1776+ return ;
1777+ }
17621778
1763- if (ED->hasAttr <FlagEnumAttr>()) {
1764- if (!IsValueInFlagEnum (ED, RhsVal, true ))
1765- Diag (SrcExpr->getExprLoc (), diag::warn_not_in_enum_assignment)
1766- << DstType.getUnqualifiedType ();
1767- } else {
1768- typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64 >
1769- EnumValsTy;
1770- EnumValsTy EnumVals;
1771-
1772- // Gather all enum values, set their type and sort them,
1773- // allowing easier comparison with rhs constant.
1774- for (auto *EDI : ED->enumerators ()) {
1775- llvm::APSInt Val = EDI->getInitVal ();
1776- AdjustAPSInt (Val, DstWidth, DstIsSigned);
1777- EnumVals.push_back (std::make_pair (Val, EDI));
1778- }
1779- if (EnumVals.empty ())
1780- return ;
1781- llvm::stable_sort (EnumVals, CmpEnumVals);
1782- EnumValsTy::iterator EIend = llvm::unique (EnumVals, EqEnumVals);
1783-
1784- // See which values aren't in the enum.
1785- EnumValsTy::const_iterator EI = EnumVals.begin ();
1786- while (EI != EIend && EI->first < RhsVal)
1787- EI++;
1788- if (EI == EIend || EI->first != RhsVal) {
1789- Diag (SrcExpr->getExprLoc (), diag::warn_not_in_enum_assignment)
1790- << DstType.getUnqualifiedType ();
1791- }
1792- }
1793- }
1794- }
1779+ typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64 >
1780+ EnumValsTy;
1781+ EnumValsTy EnumVals;
1782+
1783+ // Gather all enum values, set their type and sort them,
1784+ // allowing easier comparison with rhs constant.
1785+ for (auto *EDI : ED->enumerators ()) {
1786+ llvm::APSInt Val = EDI->getInitVal ();
1787+ AdjustAPSInt (Val, DstWidth, DstIsSigned);
1788+ EnumVals.emplace_back (Val, EDI);
1789+ }
1790+ if (EnumVals.empty ())
1791+ return ;
1792+ llvm::stable_sort (EnumVals, CmpEnumVals);
1793+ EnumValsTy::iterator EIend = llvm::unique (EnumVals, EqEnumVals);
1794+
1795+ // See which values aren't in the enum.
1796+ EnumValsTy::const_iterator EI = EnumVals.begin ();
1797+ while (EI != EIend && EI->first < *RHSVal)
1798+ EI++;
1799+ if (EI == EIend || EI->first != *RHSVal) {
1800+ Diag (SrcExpr->getExprLoc (), diag::warn_not_in_enum_assignment)
1801+ << DstType.getUnqualifiedType ();
1802+ }
17951803}
17961804
17971805StmtResult Sema::ActOnWhileStmt (SourceLocation WhileLoc,
0 commit comments