@@ -1741,57 +1741,65 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
1741
1741
void
1742
1742
Sema::DiagnoseAssignmentEnum (QualType DstType, QualType SrcType,
1743
1743
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
+
1744
1760
if (Diags.isIgnored (diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc ()))
1745
1761
return ;
1746
1762
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 ;
1755
1766
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);
1759
1771
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
+ }
1762
1778
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
+ }
1795
1803
}
1796
1804
1797
1805
StmtResult Sema::ActOnWhileStmt (SourceLocation WhileLoc,
0 commit comments