@@ -1082,11 +1082,9 @@ bool InitElemPop(InterpState &S, CodePtr OpPC, uint32_t Idx) {
1082
1082
// AddOffset, SubOffset
1083
1083
// ===----------------------------------------------------------------------===//
1084
1084
1085
- template <class T , bool Add> bool OffsetHelper (InterpState &S, CodePtr OpPC) {
1086
- // Fetch the pointer and the offset.
1087
- const T &Offset = S.Stk .pop <T>();
1088
- const Pointer &Ptr = S.Stk .pop <Pointer>();
1089
-
1085
+ template <class T , ArithOp Op>
1086
+ bool OffsetHelper (InterpState &S, CodePtr OpPC, const T &Offset,
1087
+ const Pointer &Ptr) {
1090
1088
if (!CheckRange (S, OpPC, Ptr, CSK_ArrayToPointer))
1091
1089
return false ;
1092
1090
@@ -1113,7 +1111,8 @@ template <class T, bool Add> bool OffsetHelper(InterpState &S, CodePtr OpPC) {
1113
1111
const unsigned Bits = Offset.bitWidth ();
1114
1112
APSInt APOffset (Offset.toAPSInt ().extend (Bits + 2 ), false );
1115
1113
APSInt APIndex (Index.toAPSInt ().extend (Bits + 2 ), false );
1116
- APSInt NewIndex = Add ? (APIndex + APOffset) : (APIndex - APOffset);
1114
+ APSInt NewIndex =
1115
+ (Op == ArithOp::Add) ? (APIndex + APOffset) : (APIndex - APOffset);
1117
1116
S.CCEDiag (S.Current ->getSource (OpPC), diag::note_constexpr_array_index)
1118
1117
<< NewIndex
1119
1118
<< /* array*/ static_cast <int >(!Ptr.inArray ())
@@ -1122,7 +1121,7 @@ template <class T, bool Add> bool OffsetHelper(InterpState &S, CodePtr OpPC) {
1122
1121
};
1123
1122
1124
1123
unsigned MaxOffset = MaxIndex - Ptr.getIndex ();
1125
- if constexpr (Add) {
1124
+ if constexpr (Op == ArithOp:: Add) {
1126
1125
// If the new offset would be negative, bail out.
1127
1126
if (Offset.isNegative () && (Offset.isMin () || -Offset > Index))
1128
1127
return InvalidOffset ();
@@ -1144,7 +1143,7 @@ template <class T, bool Add> bool OffsetHelper(InterpState &S, CodePtr OpPC) {
1144
1143
int64_t WideIndex = static_cast <int64_t >(Index);
1145
1144
int64_t WideOffset = static_cast <int64_t >(Offset);
1146
1145
int64_t Result;
1147
- if constexpr (Add)
1146
+ if constexpr (Op == ArithOp:: Add)
1148
1147
Result = WideIndex + WideOffset;
1149
1148
else
1150
1149
Result = WideIndex - WideOffset;
@@ -1155,12 +1154,16 @@ template <class T, bool Add> bool OffsetHelper(InterpState &S, CodePtr OpPC) {
1155
1154
1156
1155
template <PrimType Name, class T = typename PrimConv<Name>::T>
1157
1156
bool AddOffset (InterpState &S, CodePtr OpPC) {
1158
- return OffsetHelper<T, true >(S, OpPC);
1157
+ const T &Offset = S.Stk .pop <T>();
1158
+ const Pointer &Ptr = S.Stk .pop <Pointer>();
1159
+ return OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr);
1159
1160
}
1160
1161
1161
1162
template <PrimType Name, class T = typename PrimConv<Name>::T>
1162
1163
bool SubOffset (InterpState &S, CodePtr OpPC) {
1163
- return OffsetHelper<T, false >(S, OpPC);
1164
+ const T &Offset = S.Stk .pop <T>();
1165
+ const Pointer &Ptr = S.Stk .pop <Pointer>();
1166
+ return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr);
1164
1167
}
1165
1168
1166
1169
template <ArithOp Op>
@@ -1172,10 +1175,9 @@ static inline bool IncDecPtrHelper(InterpState &S, CodePtr OpPC) {
1172
1175
S.Stk .push <Pointer>(Ptr.deref <Pointer>());
1173
1176
1174
1177
// Now the current Ptr again and a constant 1.
1175
- // FIXME: We shouldn't have to push these two on the stack.
1176
- S.Stk .push <Pointer>(Ptr.deref <Pointer>());
1177
- S.Stk .push <OneT>(OneT::from (1 ));
1178
- if (!OffsetHelper<OneT, Op == ArithOp::Add>(S, OpPC))
1178
+ Pointer P = Ptr.deref <Pointer>();
1179
+ OneT One = OneT::from (1 );
1180
+ if (!OffsetHelper<OneT, Op>(S, OpPC, One, P))
1179
1181
return false ;
1180
1182
1181
1183
// Store the new value.
0 commit comments