diff options
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f8de0f2..3df0e4292 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13536,6 +13536,18 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext && Info.EvalMode == EvalInfo::EM_ConstantExpression && DestType->isEnumeralType()) { + + bool ConstexprVar = true; + + // We know if we are here that we are in a context that we might require + // a constant expression or a context that requires a constant + // value. But if we are initializing a value we don't know if it is a + // constexpr variable or not. We can check the EvaluatingDecl to determine + // if it constexpr or not. If not then we don't want to emit a diagnostic. + if (const auto *VD = dyn_cast_or_null<VarDecl>( + Info.EvaluatingDecl.dyn_cast<const ValueDecl *>())) + ConstexprVar = VD->isConstexpr(); + const EnumType *ET = dyn_cast<EnumType>(DestType.getCanonicalType()); const EnumDecl *ED = ET->getDecl(); // Check that the value is within the range of the enumeration values. @@ -13555,13 +13567,14 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { ED->getValueRange(Max, Min); --Max; - if (ED->getNumNegativeBits() && + if (ED->getNumNegativeBits() && ConstexprVar && (Max.slt(Result.getInt().getSExtValue()) || Min.sgt(Result.getInt().getSExtValue()))) - Info.Ctx.getDiagnostics().Report(E->getExprLoc(), - diag::warn_constexpr_unscoped_enum_out_of_range) - << llvm::toString(Result.getInt(),10) << Min.getSExtValue() << Max.getSExtValue(); - else if (!ED->getNumNegativeBits() && + Info.Ctx.getDiagnostics().Report( + E->getExprLoc(), diag::warn_constexpr_unscoped_enum_out_of_range) + << llvm::toString(Result.getInt(), 10) << Min.getSExtValue() + << Max.getSExtValue(); + else if (!ED->getNumNegativeBits() && ConstexprVar && Max.ult(Result.getInt().getZExtValue())) Info.Ctx.getDiagnostics().Report(E->getExprLoc(), diag::warn_constexpr_unscoped_enum_out_of_range) |