Skip to content

Commit dfa3af9

Browse files
authored
[clang][bytecode] Expand subscript base if of pointer type (#128511)
This is similar to what we do in the AddOffset instruction when adding an offset to a pointer.
1 parent 25c19eb commit dfa3af9

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,7 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
16741674
const Expr *LHS = E->getLHS();
16751675
const Expr *RHS = E->getRHS();
16761676
const Expr *Index = E->getIdx();
1677+
const Expr *Base = E->getBase();
16771678

16781679
if (DiscardResult)
16791680
return this->discard(LHS) && this->discard(RHS);
@@ -1682,8 +1683,17 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
16821683
// side is the base.
16831684
bool Success = true;
16841685
for (const Expr *SubExpr : {LHS, RHS}) {
1685-
if (!this->visit(SubExpr))
1686+
if (!this->visit(SubExpr)) {
16861687
Success = false;
1688+
continue;
1689+
}
1690+
1691+
// Expand the base if this is a subscript on a
1692+
// pointer expression.
1693+
if (SubExpr == Base && Base->getType()->isPointerType()) {
1694+
if (!this->emitExpandPtr(E))
1695+
Success = false;
1696+
}
16871697
}
16881698

16891699
if (!Success)

clang/lib/AST/ByteCode/Interp.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2589,7 +2589,10 @@ inline bool NarrowPtr(InterpState &S, CodePtr OpPC) {
25892589

25902590
inline bool ExpandPtr(InterpState &S, CodePtr OpPC) {
25912591
const Pointer &Ptr = S.Stk.pop<Pointer>();
2592-
S.Stk.push<Pointer>(Ptr.expand());
2592+
if (Ptr.isBlockPointer())
2593+
S.Stk.push<Pointer>(Ptr.expand());
2594+
else
2595+
S.Stk.push<Pointer>(Ptr);
25932596
return true;
25942597
}
25952598

clang/test/AST/ByteCode/arrays.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,3 +662,16 @@ namespace InvalidIndex {
662662
}
663663
static_assert(foo(0) == 1, "");
664664
}
665+
666+
namespace PointerSubscript {
667+
template<typename T>
668+
constexpr T foo() {
669+
T ss[] = {{}, {}, {}};
670+
T *s = &ss[0];
671+
672+
return s[2];
673+
}
674+
static_assert(foo<int>() == 0);
675+
struct S{};
676+
static_assert((foo<S>(), true));
677+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %clang_cc1 -std=c++2c -fexperimental-new-constant-interpreter -verify=expected,both %s
2+
// RUN: %clang_cc1 -std=c++2c -verify=ref,both %s
3+
4+
// both-no-diagnostics
5+
6+
namespace std {
7+
inline namespace __1 {
8+
template <class _Tp> class unique_ptr;
9+
template <class _Tp> class unique_ptr<_Tp[]> {
10+
public:
11+
_Tp* __ptr_;
12+
13+
public:
14+
constexpr _Tp&
15+
operator[](unsigned i) const {
16+
return __ptr_[i];
17+
};
18+
};
19+
} // namespace __1
20+
} // namespace std
21+
struct WithTrivialDtor {
22+
int x = 6;
23+
constexpr friend void operator==(WithTrivialDtor const &x,
24+
WithTrivialDtor const &y) {
25+
(void)(x.x == y.x);
26+
}
27+
};
28+
constexpr bool test() {
29+
30+
WithTrivialDtor array[50];
31+
std::unique_ptr<WithTrivialDtor[]> p(&array[0]);
32+
(void)(p[1] == WithTrivialDtor());
33+
34+
return true;
35+
}
36+
static_assert(test());

0 commit comments

Comments
 (0)