[clang] cc10411 - [Clang] Allow downgrading to a warning the diagnostic for setting a non fixed enum to a value outside the range of the enumeration values
Shafik Yaghmour via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 8 16:23:16 PDT 2022
Author: Shafik Yaghmour
Date: 2022-08-08T16:23:07-07:00
New Revision: cc104113ddecbdcec2cca848adbb6afa1214e9de
URL: https://github.com/llvm/llvm-project/commit/cc104113ddecbdcec2cca848adbb6afa1214e9de
DIFF: https://github.com/llvm/llvm-project/commit/cc104113ddecbdcec2cca848adbb6afa1214e9de.diff
LOG: [Clang] Allow downgrading to a warning the diagnostic for setting a non fixed enum to a value outside the range of the enumeration values
In D130058 we diagnose the undefined behavior of setting the value outside the
range of the enumerations values for an enum without a fixed underlying type.
Based on feedback we will provide users to the ability to downgrade this
diagnostic to a waring to allow for a transition period. We expect to turn this
diagnostic to an error in the next release.
Differential Revision: https://reviews.llvm.org/D131307
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/MicrosoftCompatibility.cpp
clang/test/SemaCXX/compare.cpp
clang/test/SemaCXX/constant-expression-cxx11.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4f34b2f946b6e..d830928a13d4d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -71,7 +71,11 @@ Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Clang will now correctly diagnose as ill-formed a constant expression where an
enum without a fixed underlying type is set to a value outside the range of
- the enumeration's values. Fixes
+ the enumeration's values. Due to the extended period of time this bug was
+ present in major C++ implementations (including Clang), this error has the
+ ability to be downgraded into a warning (via: -Wno-error=enum-constexpr-conversion)
+ to provide a transition period for users. This diagnostic is expected to turn
+ into an error-only diagnostic in the next Clang release. Fixes
`Issue 50055: <https://github.com/llvm/llvm-project/issues/50055>`_.
- Clang will now check compile-time determinable string literals as format strings.
Fixes `Issue 55805: <https://github.com/llvm/llvm-project/issues/55805>`_.
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 8a8a088e52a23..02b0cf01aa057 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -366,9 +366,6 @@ def note_constexpr_unsupported_layout : Note<
"type %0 has unexpected layout">;
def note_constexpr_unsupported_flexible_array : Note<
"flexible array initialization is not yet supported">;
-def note_constexpr_unscoped_enum_out_of_range : Note<
- "integer value %0 is outside the valid range of values [%1, %2] for this "
- "enumeration type">;
def err_experimental_clang_interp_failed : Error<
"the experimental clang interpreter failed to evaluate an expression">;
@@ -378,6 +375,9 @@ def warn_integer_constant_overflow : Warning<
def warn_fixedpoint_constant_overflow : Warning<
"overflow in expression; result is %0 with type %1">,
InGroup<DiagGroup<"fixed-point-overflow">>;
+def warn_constexpr_unscoped_enum_out_of_range : Warning<
+ "integer value %0 is outside the valid range of values [%1, %2] for this "
+ "enumeration type">, DefaultError, InGroup<DiagGroup<"enum-constexpr-conversion">>;
// This is a temporary diagnostic, and shall be removed once our
// implementation is complete, and like the preceding constexpr notes belongs
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 538de3f81b0db..bb4ee3327537a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13534,7 +13534,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
}
- if (DestType->isEnumeralType()) {
+ if (Info.Ctx.getLangOpts().CPlusPlus && DestType->isEnumeralType()) {
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.
@@ -13557,12 +13557,14 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
if (ED->getNumNegativeBits() &&
(Max.slt(Result.getInt().getSExtValue()) ||
Min.sgt(Result.getInt().getSExtValue())))
- CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
- << Result.getInt() << Min.getSExtValue() << Max.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() &&
Max.ult(Result.getInt().getZExtValue()))
- CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
- << Result.getInt() << Min.getZExtValue() << Max.getZExtValue();
+ Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
+ diag::warn_constexpr_unscoped_enum_out_of_range)
+ << llvm::toString(Result.getInt(),10) << Min.getZExtValue() << Max.getZExtValue();
}
}
diff --git a/clang/test/SemaCXX/MicrosoftCompatibility.cpp b/clang/test/SemaCXX/MicrosoftCompatibility.cpp
index 83177b1b1f8e6..8513177b4fc25 100644
--- a/clang/test/SemaCXX/MicrosoftCompatibility.cpp
+++ b/clang/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -239,14 +239,14 @@ template void function_missing_typename<D>(const D::Type param);
//MSVC allows forward enum declaration
enum ENUM; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}
ENUM *var = 0;
-ENUM var2 = (ENUM)3;
+ENUM var2 = (ENUM)0;
enum ENUM1* var3 = 0;// expected-warning {{forward references to 'enum' types are a Microsoft extension}}
enum ENUM1 { kA };
enum ENUM1; // This way round is fine.
enum ENUM2 {
- ENUM2_a = (enum ENUM2) 4,
+ ENUM2_a = (enum ENUM2) 0,
ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
ENUM2_c = 0x100000000 // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
};
diff --git a/clang/test/SemaCXX/compare.cpp b/clang/test/SemaCXX/compare.cpp
index 55b01e3dc348b..cfddf2142f308 100644
--- a/clang/test/SemaCXX/compare.cpp
+++ b/clang/test/SemaCXX/compare.cpp
@@ -428,11 +428,6 @@ namespace templates {
namespace tautological_enum {
enum E { a, b, c } e;
- // FIXME: We should warn about constructing this out-of-range numeration value.
- const E invalid = (E)-1;
- // ... but we should not warn about comparing against it.
- bool x = e == invalid;
-
// We should not warn about relational comparisons for enumerators, even if
// they're tautological.
bool y = e >= a && e <= b;
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index fec853747862c..e145ca982cdd0 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2418,37 +2418,37 @@ enum EMaxInt {emaxint1=-1, emaxint2=__INT_MAX__};
void testValueInRangeOfEnumerationValues() {
constexpr E1 x1 = static_cast<E1>(-8);
- constexpr E1 x2 = static_cast<E1>(8); // expected-error {{must be initialized by a constant expression}}
- // expected-note at -1 {{integer value 8 is outside the valid range of values [-8, 7] for this enumeration type}}
+ constexpr E1 x2 = static_cast<E1>(8);
+ // expected-error at -1 {{integer value 8 is outside the valid range of values [-8, 7] for this enumeration type}}
- constexpr E2 x3 = static_cast<E2>(-8); // expected-error {{must be initialized by a constant expression}}
- // expected-note at -1 {{integer value -8 is outside the valid range of values [0, 7] for this enumeration type}}
+ constexpr E2 x3 = static_cast<E2>(-8);
+ // expected-error at -1 {{integer value -8 is outside the valid range of values [0, 7] for this enumeration type}}
constexpr E2 x4 = static_cast<E2>(0);
- constexpr E2 x5 = static_cast<E2>(8); // expected-error {{must be initialized by a constant expression}}
- // expected-note at -1 {{integer value 8 is outside the valid range of values [0, 7] for this enumeration type}}
+ constexpr E2 x5 = static_cast<E2>(8);
+ // expected-error at -1 {{integer value 8 is outside the valid range of values [0, 7] for this enumeration type}}
constexpr E3 x6 = static_cast<E3>(-2048);
constexpr E3 x7 = static_cast<E3>(-8);
constexpr E3 x8 = static_cast<E3>(0);
constexpr E3 x9 = static_cast<E3>(8);
- constexpr E3 x10 = static_cast<E3>(2048); // expected-error {{must be initialized by a constant expression}}
- // expected-note at -1 {{integer value 2048 is outside the valid range of values [-2048, 2047] for this enumeration type}}
+ constexpr E3 x10 = static_cast<E3>(2048);
+ // expected-error at -1 {{integer value 2048 is outside the valid range of values [-2048, 2047] for this enumeration type}}
constexpr E4 x11 = static_cast<E4>(0);
constexpr E4 x12 = static_cast<E4>(1);
- constexpr E4 x13 = static_cast<E4>(2); // expected-error {{must be initialized by a constant expression}}
- // expected-note at -1 {{integer value 2 is outside the valid range of values [0, 1] for this enumeration type}}
+ constexpr E4 x13 = static_cast<E4>(2);
+ // expected-error at -1 {{integer value 2 is outside the valid range of values [0, 1] for this enumeration type}}
constexpr EEmpty x14 = static_cast<EEmpty>(0);
constexpr EEmpty x15 = static_cast<EEmpty>(1);
- constexpr EEmpty x16 = static_cast<EEmpty>(2); // expected-error {{must be initialized by a constant expression}}
- // expected-note at -1 {{integer value 2 is outside the valid range of values [0, 1] for this enumeration type}}
+ constexpr EEmpty x16 = static_cast<EEmpty>(2);
+ // expected-error at -1 {{integer value 2 is outside the valid range of values [0, 1] for this enumeration type}}
constexpr EFixed x17 = static_cast<EFixed>(100);
constexpr EScoped x18 = static_cast<EScoped>(100);
constexpr EMaxInt x19 = static_cast<EMaxInt>(__INT_MAX__-1);
- constexpr EMaxInt x20 = static_cast<EMaxInt>((long)__INT_MAX__+1); // expected-error {{must be initialized by a constant expression}}
- // expected-note at -1 {{integer value 2147483648 is outside the valid range of values [-2147483648, 2147483647] for this enumeration type}}
+ constexpr EMaxInt x20 = static_cast<EMaxInt>((long)__INT_MAX__+1);
+ // expected-error at -1 {{integer value 2147483648 is outside the valid range of values [-2147483648, 2147483647] for this enumeration type}}
}
}
More information about the cfe-commits
mailing list