@@ -159,8 +159,10 @@ bool CallBI(InterpState &S, CodePtr OpPC, const Function *Func,
159
159
bool CallPtr (InterpState &S, CodePtr OpPC, uint32_t ArgSize,
160
160
const CallExpr *CE);
161
161
162
+ enum class ShiftDir { Left, Right };
163
+
162
164
// / Checks if the shift operation is legal.
163
- template <typename LT, typename RT>
165
+ template <ShiftDir Dir, typename LT, typename RT>
164
166
bool CheckShift (InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS,
165
167
unsigned Bits) {
166
168
if (RHS.isNegative ()) {
@@ -181,19 +183,21 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS,
181
183
return false ;
182
184
}
183
185
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
+ }
197
201
}
198
202
}
199
203
@@ -2394,7 +2398,6 @@ inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
2394
2398
// ===----------------------------------------------------------------------===//
2395
2399
// Shr, Shl
2396
2400
// ===----------------------------------------------------------------------===//
2397
- enum class ShiftDir { Left, Right };
2398
2401
2399
2402
template <class LT , class RT , ShiftDir Dir>
2400
2403
inline 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) {
2431
2434
}
2432
2435
}
2433
2436
2434
- if (!CheckShift (S, OpPC, LHS, RHS, Bits))
2437
+ if (!CheckShift<Dir> (S, OpPC, LHS, RHS, Bits))
2435
2438
return false ;
2436
2439
2437
2440
// Limit the shift amount to Bits - 1. If this happened,
0 commit comments