[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