Skip to content

Commit 319f923

Browse files
efriedma-quictomtor
authored andcommitted
[clang] Check constexpr int->enum conversions consistently. (llvm#143034)
In 8de5137 and related patches, we added some code to avoid triggering -Wenum-constexpr-conversion in some cases. This isn't necessary anymore because -Wenum-constexpr-conversion doesn't exist anymore. And the checks are subtly wrong: they exclude cases where we actually do need to check the conversion. This patch gets rid of the unnecessary checks.
1 parent 8a57899 commit 319f923

File tree

2 files changed

+10
-17
lines changed

2 files changed

+10
-17
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15245,21 +15245,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
1524515245
return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
1524615246
}
1524715247

15248-
if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
15249-
Info.EvalMode == EvalInfo::EM_ConstantExpression &&
15250-
DestType->isEnumeralType()) {
15251-
15252-
bool ConstexprVar = true;
15253-
15254-
// We know if we are here that we are in a context that we might require
15255-
// a constant expression or a context that requires a constant
15256-
// value. But if we are initializing a value we don't know if it is a
15257-
// constexpr variable or not. We can check the EvaluatingDecl to determine
15258-
// if it constexpr or not. If not then we don't want to emit a diagnostic.
15259-
if (const auto *VD = dyn_cast_or_null<VarDecl>(
15260-
Info.EvaluatingDecl.dyn_cast<const ValueDecl *>()))
15261-
ConstexprVar = VD->isConstexpr();
15262-
15248+
if (Info.Ctx.getLangOpts().CPlusPlus && DestType->isEnumeralType()) {
1526315249
const EnumType *ET = dyn_cast<EnumType>(DestType.getCanonicalType());
1526415250
const EnumDecl *ED = ET->getDecl();
1526515251
// Check that the value is within the range of the enumeration values.
@@ -15279,13 +15265,13 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
1527915265
ED->getValueRange(Max, Min);
1528015266
--Max;
1528115267

15282-
if (ED->getNumNegativeBits() && ConstexprVar &&
15268+
if (ED->getNumNegativeBits() &&
1528315269
(Max.slt(Result.getInt().getSExtValue()) ||
1528415270
Min.sgt(Result.getInt().getSExtValue())))
1528515271
Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
1528615272
<< llvm::toString(Result.getInt(), 10) << Min.getSExtValue()
1528715273
<< Max.getSExtValue() << ED;
15288-
else if (!ED->getNumNegativeBits() && ConstexprVar &&
15274+
else if (!ED->getNumNegativeBits() &&
1528915275
Max.ult(Result.getInt().getZExtValue()))
1529015276
Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
1529115277
<< llvm::toString(Result.getInt(), 10) << Min.getZExtValue()

clang/test/SemaCXX/constant-expression-cxx11.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,6 +2513,9 @@ void testValueInRangeOfEnumerationValues() {
25132513
// expected-error@-1 {{constexpr variable 'x2' must be initialized by a constant expression}}
25142514
// expected-note@-2 {{integer value 8 is outside the valid range of values [-8, 7] for the enumeration type 'E1'}}
25152515
E1 x2b = static_cast<E1>(8); // ok, not a constant expression context
2516+
static_assert(static_cast<E1>(8), "");
2517+
// expected-error@-1 {{static assertion expression is not an integral constant expression}}
2518+
// expected-note@-2 {{integer value 8 is outside the valid range of values [-8, 7] for the enumeration type 'E1'}}
25162519

25172520
constexpr E2 x3 = static_cast<E2>(-8);
25182521
// expected-error@-1 {{constexpr variable 'x3' must be initialized by a constant expression}}
@@ -2551,6 +2554,10 @@ void testValueInRangeOfEnumerationValues() {
25512554
// expected-note@-2 {{integer value 2147483648 is outside the valid range of values [-2147483648, 2147483647] for the enumeration type 'EMaxInt'}}
25522555

25532556
const NumberType neg_one = (NumberType) ((NumberType) 0 - (NumberType) 1); // ok, not a constant expression context
2557+
constexpr NumberType neg_one_constexpr = neg_one;
2558+
// expected-error@-1 {{constexpr variable 'neg_one_constexpr' must be initialized by a constant expression}}
2559+
// expected-note@-2 {{initializer of 'neg_one' is not a constant expression}}
2560+
// expected-note@-4 {{declared here}}
25542561

25552562
CONSTEXPR_CAST_TO_SYSTEM_ENUM_OUTSIDE_OF_RANGE;
25562563
// expected-error@-1 {{constexpr variable 'system_enum' must be initialized by a constant expression}}

0 commit comments

Comments
 (0)