@@ -159,8 +159,10 @@ bool CallBI(InterpState &S, CodePtr OpPC, const Function *Func,
159159bool CallPtr (InterpState &S, CodePtr OpPC, uint32_t ArgSize,
160160 const CallExpr *CE);
161161
162+ enum class ShiftDir { Left, Right };
163+
162164// / Checks if the shift operation is legal.
163- template <typename LT, typename RT>
165+ template <ShiftDir Dir, typename LT, typename RT>
164166bool CheckShift (InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS,
165167 unsigned Bits) {
166168 if (RHS.isNegative ()) {
@@ -181,19 +183,21 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS,
181183 return false ;
182184 }
183185
184- if (LHS.isSigned () && !S.getLangOpts ().CPlusPlus20 ) {
185- const Expr *E = S.Current ->getExpr (OpPC);
186- // C++11 [expr.shift]p2: A signed left shift must have a non-negative
187- // operand, and must not overflow the corresponding unsigned type.
188- if (LHS.isNegative ()) {
189- S.CCEDiag (E, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt ();
190- if (!S.noteUndefinedBehavior ())
191- return false ;
192- } else if (LHS.toUnsigned ().countLeadingZeros () <
193- static_cast <unsigned >(RHS)) {
194- S.CCEDiag (E, diag::note_constexpr_lshift_discards);
195- if (!S.noteUndefinedBehavior ())
196- return false ;
186+ if constexpr (Dir == ShiftDir::Left) {
187+ if (LHS.isSigned () && !S.getLangOpts ().CPlusPlus20 ) {
188+ const Expr *E = S.Current ->getExpr (OpPC);
189+ // C++11 [expr.shift]p2: A signed left shift must have a non-negative
190+ // operand, and must not overflow the corresponding unsigned type.
191+ if (LHS.isNegative ()) {
192+ S.CCEDiag (E, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt ();
193+ if (!S.noteUndefinedBehavior ())
194+ return false ;
195+ } else if (LHS.toUnsigned ().countLeadingZeros () <
196+ static_cast <unsigned >(RHS)) {
197+ S.CCEDiag (E, diag::note_constexpr_lshift_discards);
198+ if (!S.noteUndefinedBehavior ())
199+ return false ;
200+ }
197201 }
198202 }
199203
@@ -2394,7 +2398,6 @@ inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
23942398// ===----------------------------------------------------------------------===//
23952399// Shr, Shl
23962400// ===----------------------------------------------------------------------===//
2397- enum class ShiftDir { Left, Right };
23982401
23992402template <class LT , class RT , ShiftDir Dir>
24002403inline bool DoShift (InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) {
@@ -2431,7 +2434,7 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) {
24312434 }
24322435 }
24332436
2434- if (!CheckShift (S, OpPC, LHS, RHS, Bits))
2437+ if (!CheckShift<Dir> (S, OpPC, LHS, RHS, Bits))
24352438 return false ;
24362439
24372440 // Limit the shift amount to Bits - 1. If this happened,
0 commit comments