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