[clang] a0d6105 - [Clang] Fix handling of Max from getValueRange(...) in IntExprEvaluator::VisitCastExpr(...)

Shafik Yaghmour via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 29 19:20:18 PDT 2022


Author: Shafik Yaghmour
Date: 2022-07-29T19:17:42-07:00
New Revision: a0d61051628825e2f394240dc442ad5d81fa78bc

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

LOG: [Clang] Fix handling of Max from getValueRange(...) in IntExprEvaluator::VisitCastExpr(...)

This is a follow-up to D130058 to fix how we handle the Max value we obtain from
getValueRange(...) in IntExprEvaluator::VisitCastExpr(...) which in the case of
an enum that contains an enumerator with the max integer value will overflow by
one.

The fix is to decrement the value of Max and use slt and ult for comparison Vs
sle and ule.`

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3d72bf8f6521c..f3d8200c0d1a8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -60,7 +60,7 @@ 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
-  of the enumerations values. Fixes
+  the enumeration's values. Fixes
   `Issue 50055: <https://github.com/llvm/llvm-project/issues/50055>`_.
 
 Non-comprehensive list of changes in this release

diff  --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 93e4dfecc49c1..8a8a088e52a23 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -367,7 +367,7 @@ def note_constexpr_unsupported_layout : Note<
 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 "
+  "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">;

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d02ca2de4a750..32a04ca9e3de3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -13537,14 +13537,15 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
         llvm::APInt Max;
 
         ED->getValueRange(Max, Min);
+        --Max;
 
         if (ED->getNumNegativeBits() &&
-            (Max.sle(Result.getInt().getSExtValue()) ||
+            (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();
         else if (!ED->getNumNegativeBits() &&
-                 Max.ule(Result.getInt().getZExtValue()))
+                 Max.ult(Result.getInt().getZExtValue()))
           CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
               << Result.getInt() << Min.getZExtValue() << Max.getZExtValue();
       }

diff  --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index d97c27426b94a..fec853747862c 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2414,35 +2414,41 @@ enum EFixed : int {efixed1=-4, efixed2=4};
 // Enum with fixed underlying type because it is scoped
 enum class EScoped {escoped1=-4, escoped2=4};
 
+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, 8) for this enumeration type}}
+  // expected-note 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, 8) for this enumeration type}}
+  // expected-note 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, 8) for this enumeration type}}
+  // expected-note 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, 2048) for this enumeration type}}
+  // expected-note 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, 2) for this enumeration type}}
+  // expected-note 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, 2) for this enumeration type}}
+  // expected-note 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}}
 }
 }


        


More information about the cfe-commits mailing list