Author: Dimitry Andric
Date: 2023-06-14T20:34:19+02:00
New Revision: 69d42eef4bec208a2312bfa0d2194013817eeba0

URL: 
https://github.com/llvm/llvm-project/commit/69d42eef4bec208a2312bfa0d2194013817eeba0
DIFF: 
https://github.com/llvm/llvm-project/commit/69d42eef4bec208a2312bfa0d2194013817eeba0.diff

LOG: [Clang] Show type in enum out of range diagnostic

When the diagnostic for an out of range enum value is printed, it
currently does not show the actual enum type in question, for example:

    v8/src/base/bit-field.h:43:29: error: integer value 7 is outside the valid 
range of values [0, 3] for this enumeration type [-Wenum-constexpr-conversion]
      static constexpr T kMax = static_cast<T>(kNumValues - 1);
                                ^

This can make it cumbersome to find the cause for the problem. Add the
enum type to the diagnostic message, to make it easier.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D152788

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticASTKinds.td
    clang/lib/AST/ExprConstant.cpp
    clang/test/SemaCXX/constant-expression-cxx11.cpp
    clang/test/SemaCXX/cxx2a-consteval.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 32cc7c94a3252..3cfacb07bbaa1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -344,6 +344,9 @@ Improvements to Clang's diagnostics
   (`#42992: <https://github.com/llvm/llvm-project/issues/42992>`_)
 - Clang now diagnoses unused const-qualified variable template as
   "unused variable template" rather than "unused variable".
+- When diagnosing a constant expression where an enum without a fixed 
underlying
+  type is set to a value outside the range of the enum's values, clang will now
+  print the name of the enum in question.
 
 Bug Fixes in This Version
 -------------------------

diff  --git a/clang/include/clang/Basic/DiagnosticASTKinds.td 
b/clang/include/clang/Basic/DiagnosticASTKinds.td
index eb13467317963..73118891c1899 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -395,8 +395,8 @@ 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">>;
+  "integer value %0 is outside the valid range of values [%1, %2] for the "
+  "enumeration type %3">, 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 b88b84a44af0e..5578dfc8f8743 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13708,12 +13708,13 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr 
*E) {
           Info.Ctx.getDiagnostics().Report(
               E->getExprLoc(), diag::warn_constexpr_unscoped_enum_out_of_range)
               << llvm::toString(Result.getInt(), 10) << Min.getSExtValue()
-              << Max.getSExtValue();
+              << Max.getSExtValue() << ED;
         else if (!ED->getNumNegativeBits() && ConstexprVar &&
                  Max.ult(Result.getInt().getZExtValue()))
-          Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
-                                       
diag::warn_constexpr_unscoped_enum_out_of_range)
-           << llvm::toString(Result.getInt(),10) << 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() << ED;
       }
     }
 

diff  --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp 
b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index fa9ad786b289e..f454bba5afd8c 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2440,42 +2440,51 @@ E2 testDefaultArgForParam(E2 e2Param = (E2)-1) { // ok, 
not a constant expressio
 void testValueInRangeOfEnumerationValues() {
   constexpr E1 x1 = static_cast<E1>(-8);
   constexpr E1 x2 = static_cast<E1>(8);
-  // expected-error@-1 {{integer value 8 is outside the valid range of values 
[-8, 7] for this enumeration type}}
+  // expected-error@-1 {{integer value 8 is outside the valid range of values 
[-8, 7] for the enumeration type 'E1'}}
   E1 x2b = static_cast<E1>(8); // ok, not a constant expression context
 
   constexpr E2 x3 = static_cast<E2>(-8);
-  // expected-error@-1 {{integer value -8 is outside the valid range of values 
[0, 7] for this enumeration type}}
+  // expected-error@-1 {{integer value -8 is outside the valid range of values 
[0, 7] for the enumeration type 'E2'}}
   constexpr E2 x4 = static_cast<E2>(0);
   constexpr E2 x5 = static_cast<E2>(8);
-  // expected-error@-1 {{integer value 8 is outside the valid range of values 
[0, 7] for this enumeration type}}
+  // expected-error@-1 {{integer value 8 is outside the valid range of values 
[0, 7] for the enumeration type 'E2'}}
 
   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@-1 {{integer value 2048 is outside the valid range of 
values [-2048, 2047] for this enumeration type}}
+  // expected-error@-1 {{integer value 2048 is outside the valid range of 
values [-2048, 2047] for the enumeration type 'E3'}}
 
   constexpr E4 x11 = static_cast<E4>(0);
   constexpr E4 x12 = static_cast<E4>(1);
   constexpr E4 x13 = static_cast<E4>(2);
-  // expected-error@-1 {{integer value 2 is outside the valid range of values 
[0, 1] for this enumeration type}}
+  // expected-error@-1 {{integer value 2 is outside the valid range of values 
[0, 1] for the enumeration type 'E4'}}
 
   constexpr EEmpty x14 = static_cast<EEmpty>(0);
   constexpr EEmpty x15 = static_cast<EEmpty>(1);
   constexpr EEmpty x16 = static_cast<EEmpty>(2);
-  // expected-error@-1 {{integer value 2 is outside the valid range of values 
[0, 1] for this enumeration type}}
+  // expected-error@-1 {{integer value 2 is outside the valid range of values 
[0, 1] for the enumeration type 'EEmpty'}}
 
   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@-1 {{integer value 2147483648 is outside the valid range 
of values [-2147483648, 2147483647] for this enumeration type}}
+  // expected-error@-1 {{integer value 2147483648 is outside the valid range 
of values [-2147483648, 2147483647] for the enumeration type 'EMaxInt'}}
 
   const NumberType neg_one = (NumberType) ((NumberType) 0 - (NumberType) 1); 
// ok, not a constant expression context
 }
 
+template<class T, unsigned size> struct Bitfield {
+  static constexpr T max = static_cast<T>((1 << size) - 1); // #enum
+};
+
+void testValueInRangeOfEnumerationValuesViaTemplate() {
+  Bitfield<E2, 3> good;
+  Bitfield<E2, 4> bad; // cxx11-error@#enum {{integer value 15 is outside the 
valid range of values [0, 7] for the enumeration type 'E2'}}
+}
+
 enum SortOrder {
   AscendingOrder,
   DescendingOrder
@@ -2494,4 +2503,4 @@ void A::f(SortOrder order) {
 GH50055::E2 GlobalInitNotCE1 = (GH50055::E2)-1; // ok, not a constant 
expression context
 GH50055::E2 GlobalInitNotCE2 = GH50055::testDefaultArgForParam(); // ok, not a 
constant expression context
 constexpr GH50055::E2 GlobalInitCE = (GH50055::E2)-1;
-// expected-error@-1 {{integer value -1 is outside the valid range of values 
[0, 7] for this enumeration type}}
+// expected-error@-1 {{integer value -1 is outside the valid range of values 
[0, 7] for the enumeration type 'E2'}}

diff  --git a/clang/test/SemaCXX/cxx2a-consteval.cpp 
b/clang/test/SemaCXX/cxx2a-consteval.cpp
index d25eda926aff7..1a949a286a00b 100644
--- a/clang/test/SemaCXX/cxx2a-consteval.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -900,7 +900,7 @@ consteval int aConstevalFunction() { // expected-error 
{{consteval function neve
 namespace GH50055 {
 enum E {e1=0, e2=1};
 consteval int testDefaultArgForParam(E eParam = (E)-1) {
-// expected-error@-1 {{integer value -1 is outside the valid range of values 
[0, 1] for this enumeration type}}
+// expected-error@-1 {{integer value -1 is outside the valid range of values 
[0, 1] for the enumeration type 'E'}}
   return (int)eParam;
 }
 


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to