@@ -135,7 +135,7 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS,
135
135
const APSInt Val = RHS.toAPSInt ();
136
136
QualType Ty = E->getType ();
137
137
S.CCEDiag (E, diag::note_constexpr_large_shift) << Val << Ty << Bits;
138
- return false ;
138
+ return true ; // We will do the shift anyway but fix up the shift amount.
139
139
}
140
140
141
141
if (LHS.isSigned () && !S.getLangOpts ().CPlusPlus20 ) {
@@ -1798,11 +1798,17 @@ inline bool Shr(InterpState &S, CodePtr OpPC) {
1798
1798
if (!CheckShift (S, OpPC, LHS, RHS, Bits))
1799
1799
return false ;
1800
1800
1801
+ // Limit the shift amount to Bits - 1. If this happened,
1802
+ // it has already been diagnosed by CheckShift() above,
1803
+ // but we still need to handle it.
1801
1804
typename LT::AsUnsigned R;
1802
- LT::AsUnsigned::shiftRight (LT::AsUnsigned::from (LHS),
1803
- LT::AsUnsigned::from (RHS), Bits, &R);
1805
+ if (RHS > RT::from (Bits - 1 , RHS.bitWidth ()))
1806
+ LT::AsUnsigned::shiftRight (LT::AsUnsigned::from (LHS),
1807
+ LT::AsUnsigned::from (Bits - 1 ), Bits, &R);
1808
+ else
1809
+ LT::AsUnsigned::shiftRight (LT::AsUnsigned::from (LHS),
1810
+ LT::AsUnsigned::from (RHS, Bits), Bits, &R);
1804
1811
S.Stk .push <LT>(LT::from (R));
1805
-
1806
1812
return true ;
1807
1813
}
1808
1814
@@ -1817,9 +1823,17 @@ inline bool Shl(InterpState &S, CodePtr OpPC) {
1817
1823
if (!CheckShift (S, OpPC, LHS, RHS, Bits))
1818
1824
return false ;
1819
1825
1826
+ // Limit the shift amount to Bits - 1. If this happened,
1827
+ // it has already been diagnosed by CheckShift() above,
1828
+ // but we still need to handle it.
1820
1829
typename LT::AsUnsigned R;
1821
- LT::AsUnsigned::shiftLeft (LT::AsUnsigned::from (LHS),
1822
- LT::AsUnsigned::from (RHS, Bits), Bits, &R);
1830
+ if (RHS > RT::from (Bits - 1 , RHS.bitWidth ()))
1831
+ LT::AsUnsigned::shiftLeft (LT::AsUnsigned::from (LHS),
1832
+ LT::AsUnsigned::from (Bits - 1 ), Bits, &R);
1833
+ else
1834
+ LT::AsUnsigned::shiftLeft (LT::AsUnsigned::from (LHS),
1835
+ LT::AsUnsigned::from (RHS, Bits), Bits, &R);
1836
+
1823
1837
S.Stk .push <LT>(LT::from (R));
1824
1838
return true ;
1825
1839
}
0 commit comments