llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> Reorder the precondition checks to move the costly onces last. Also, only evaluate the RHS once to get the integral value. --- Full diff: https://github.com/llvm/llvm-project/pull/141471.diff 1 Files Affected: - (modified) clang/lib/Sema/SemaStmt.cpp (+53-45) ``````````diff diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index ed070649dc1f9..08f77b2e246e9 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, `````````` </details> https://github.com/llvm/llvm-project/pull/141471 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits