@@ -15682,7 +15682,21 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
1568215682 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
1568315683 }
1568415684
15685- if (Info.Ctx.getLangOpts().CPlusPlus && DestType->isEnumeralType()) {
15685+ if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
15686+ Info.EvalMode == EvalInfo::EM_ConstantExpression &&
15687+ DestType->isEnumeralType()) {
15688+
15689+ bool ConstexprVar = true;
15690+
15691+ // We know if we are here that we are in a context that we might require
15692+ // a constant expression or a context that requires a constant
15693+ // value. But if we are initializing a value we don't know if it is a
15694+ // constexpr variable or not. We can check the EvaluatingDecl to determine
15695+ // if it constexpr or not. If not then we don't want to emit a diagnostic.
15696+ if (const auto *VD = dyn_cast_or_null<VarDecl>(
15697+ Info.EvaluatingDecl.dyn_cast<const ValueDecl *>()))
15698+ ConstexprVar = VD->isConstexpr();
15699+
1568615700 const EnumType *ET = dyn_cast<EnumType>(DestType.getCanonicalType());
1568715701 const EnumDecl *ED = ET->getDecl();
1568815702 // Check that the value is within the range of the enumeration values.
@@ -15702,13 +15716,13 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
1570215716 ED->getValueRange(Max, Min);
1570315717 --Max;
1570415718
15705- if (ED->getNumNegativeBits() &&
15719+ if (ED->getNumNegativeBits() && ConstexprVar &&
1570615720 (Max.slt(Result.getInt().getSExtValue()) ||
1570715721 Min.sgt(Result.getInt().getSExtValue())))
1570815722 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
1570915723 << llvm::toString(Result.getInt(), 10) << Min.getSExtValue()
1571015724 << Max.getSExtValue() << ED;
15711- else if (!ED->getNumNegativeBits() &&
15725+ else if (!ED->getNumNegativeBits() && ConstexprVar &&
1571215726 Max.ult(Result.getInt().getZExtValue()))
1571315727 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
1571415728 << llvm::toString(Result.getInt(), 10) << Min.getZExtValue()
0 commit comments