Author: Timm Bäder
Date: 2024-07-14T07:28:02+02:00
New Revision: ed304b6790ba0391211bffe66856b00d0a949670

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

LOG: [clang][Interp] Diagnose left shifts of negative values

Added: 
    

Modified: 
    clang/lib/AST/Interp/Interp.h
    clang/test/AST/Interp/shifts.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 8502b7ca136e..60e1d78f7405 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2234,6 +2234,20 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT 
&LHS, RT &RHS) {
                                  : ShiftDir::Left > (S, OpPC, LHS, RHS);
   }
 
+  if constexpr (Dir == ShiftDir::Left) {
+    if (LHS.isNegative() && !S.getLangOpts().CPlusPlus20) {
+      // C++11 [expr.shift]p2: A signed left shift must have a non-negative
+      // operand, and must not overflow the corresponding unsigned type.
+      // C++2a [expr.shift]p2: E1 << E2 is the unique value congruent to
+      // E1 x 2^E2 module 2^N.
+      const SourceInfo &Loc = S.Current->getSource(OpPC);
+      S.CCEDiag(Loc, diag::note_constexpr_lshift_of_negative) << 
LHS.toAPSInt();
+      if (S.getLangOpts().CPlusPlus11 && S.getEvalStatus().Diag &&
+          !S.getEvalStatus().Diag->empty())
+        return false;
+    }
+  }
+
   if (!CheckShift(S, OpPC, LHS, RHS, Bits))
     return false;
 

diff  --git a/clang/test/AST/Interp/shifts.cpp 
b/clang/test/AST/Interp/shifts.cpp
index ce17fabc7833..c5abdb7dd8a1 100644
--- a/clang/test/AST/Interp/shifts.cpp
+++ b/clang/test/AST/Interp/shifts.cpp
@@ -203,3 +203,10 @@ enum shiftof {
     X = (1<<-29) // all-error {{expression is not an integral constant 
expression}} \
                  // all-note {{negative shift count -29}}
 };
+
+enum shiftof2 {
+    X2 = (-1<<29) // cxx17-error {{expression is not an integral constant 
expression}} \
+                  // cxx17-note {{left shift of negative value -1}} \
+                  // ref-cxx17-error {{expression is not an integral constant 
expression}} \
+                  // ref-cxx17-note {{left shift of negative value -1}}
+};


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

Reply via email to