File tree 4 files changed +41
-12
lines changed 4 files changed +41
-12
lines changed Original file line number Diff line number Diff line change @@ -1282,21 +1282,31 @@ bool Compiler<Emitter>::VisitImplicitValueInitExpr(
1282
1282
1283
1283
template <class Emitter >
1284
1284
bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
1285
- const Expr *Base = E->getBase ();
1285
+ const Expr *LHS = E->getLHS ();
1286
+ const Expr *RHS = E->getRHS ();
1286
1287
const Expr *Index = E->getIdx ();
1287
1288
1288
1289
if (DiscardResult)
1289
- return this ->discard (Base ) && this ->discard (Index );
1290
+ return this ->discard (LHS ) && this ->discard (RHS );
1290
1291
1291
- // Take pointer of LHS, add offset from RHS.
1292
- // What's left on the stack after this is a pointer.
1293
- if (!this ->visit (Base))
1294
- return false ;
1292
+ // C++17's rules require us to evaluate the LHS first, regardless of which
1293
+ // side is the base.
1294
+ bool Success = true ;
1295
+ for (const Expr *SubExpr : {LHS, RHS}) {
1296
+ if (!this ->visit (SubExpr))
1297
+ Success = false ;
1298
+ }
1295
1299
1296
- if (!this -> visit (Index) )
1300
+ if (!Success )
1297
1301
return false ;
1298
1302
1299
1303
PrimType IndexT = classifyPrim (Index->getType ());
1304
+ // If the index is first, we need to change that.
1305
+ if (LHS == Index) {
1306
+ if (!this ->emitFlip (PT_Ptr, IndexT, E))
1307
+ return false ;
1308
+ }
1309
+
1300
1310
return this ->emitArrayElemPtrPop (IndexT, E);
1301
1311
}
1302
1312
Original file line number Diff line number Diff line change @@ -1158,6 +1158,21 @@ bool Pop(InterpState &S, CodePtr OpPC) {
1158
1158
return true ;
1159
1159
}
1160
1160
1161
+ // / [Value1, Value2] -> [Value2, Value1]
1162
+ template <PrimType TopName, PrimType BottomName>
1163
+ bool Flip (InterpState &S, CodePtr OpPC) {
1164
+ using TopT = typename PrimConv<TopName>::T;
1165
+ using BottomT = typename PrimConv<BottomName>::T;
1166
+
1167
+ const auto &Top = S.Stk .pop <TopT>();
1168
+ const auto &Bottom = S.Stk .pop <BottomT>();
1169
+
1170
+ S.Stk .push <TopT>(Top);
1171
+ S.Stk .push <BottomT>(Bottom);
1172
+
1173
+ return true ;
1174
+ }
1175
+
1161
1176
// ===----------------------------------------------------------------------===//
1162
1177
// Const
1163
1178
// ===----------------------------------------------------------------------===//
Original file line number Diff line number Diff line change @@ -729,6 +729,11 @@ def Dup : Opcode {
729
729
let HasGroup = 1 ;
730
730
}
731
731
732
+ def Flip : Opcode {
733
+ let Types = [AllTypeClass, AllTypeClass];
734
+ let HasGroup = 1 ;
735
+ }
736
+
732
737
// [] -> []
733
738
def Invalid : Opcode {}
734
739
def Unsupported : Opcode {}
Original file line number Diff line number Diff line change @@ -45,7 +45,7 @@ namespace EvalOrder {
45
45
}
46
46
template <typename T> constexpr T &&b(T &&v) {
47
47
if (!done_a)
48
- throw " wrong" ; // expected-note 7 {{not valid}}
48
+ throw " wrong" ; // expected-note 5 {{not valid}}
49
49
done_b = true ;
50
50
return (T &&)v;
51
51
}
@@ -95,10 +95,9 @@ namespace EvalOrder {
95
95
constexpr int arr[3 ] = {};
96
96
SEQ (A(arr)[B(0 )]);
97
97
SEQ (A(+arr)[B(0 )]);
98
- SEQ (A(0 )[B(arr)]); // expected-error {{not an integral constant expression}} FIXME \
99
- // expected-note 2{{in call to}}
100
- SEQ (A(0 )[B(+arr)]); // expected-error {{not an integral constant expression}} FIXME \
101
- // expected-note 2{{in call to}}
98
+ SEQ (A(0 )[B(arr)]);
99
+ SEQ (A(0 )[B(+arr)]);
100
+
102
101
SEQ (A(ud)[B(0 )]);
103
102
104
103
// Rule 7: a << b
You can’t perform that action at this time.
0 commit comments