https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/128511
This is similar to what we do in the AddOffset instruction when adding an offset to a pointer. >From dd05a8c4c2a8d23b294723c554a33b65080a2367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Mon, 24 Feb 2025 14:27:50 +0100 Subject: [PATCH] [clang][bytecode] Expand subscript base if of pointer type This is similar to what we do in the AddOffset instruction when adding an offset to a pointer. --- clang/lib/AST/ByteCode/Compiler.cpp | 12 ++++++- clang/lib/AST/ByteCode/Interp.h | 5 ++- clang/test/AST/ByteCode/arrays.cpp | 13 +++++++ .../AST/ByteCode/libcxx/pointer-subscript.cpp | 36 +++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 clang/test/AST/ByteCode/libcxx/pointer-subscript.cpp diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index b5745e516174d..74f5d6ebd9ca6 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -1674,6 +1674,7 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { const Expr *LHS = E->getLHS(); const Expr *RHS = E->getRHS(); const Expr *Index = E->getIdx(); + const Expr *Base = E->getBase(); if (DiscardResult) return this->discard(LHS) && this->discard(RHS); @@ -1682,8 +1683,17 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { // side is the base. bool Success = true; for (const Expr *SubExpr : {LHS, RHS}) { - if (!this->visit(SubExpr)) + if (!this->visit(SubExpr)) { Success = false; + continue; + } + + // Expand the base if this is a subscript on a + // pointer expression. + if (SubExpr == Base && Base->getType()->isPointerType()) { + if (!this->emitExpandPtr(E)) + Success = false; + } } if (!Success) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index fa113aa0bb157..db35208a02941 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -2589,7 +2589,10 @@ inline bool NarrowPtr(InterpState &S, CodePtr OpPC) { inline bool ExpandPtr(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop<Pointer>(); - S.Stk.push<Pointer>(Ptr.expand()); + if (Ptr.isBlockPointer()) + S.Stk.push<Pointer>(Ptr.expand()); + else + S.Stk.push<Pointer>(Ptr); return true; } diff --git a/clang/test/AST/ByteCode/arrays.cpp b/clang/test/AST/ByteCode/arrays.cpp index 9204179ad1a46..2ef0cf886b2dc 100644 --- a/clang/test/AST/ByteCode/arrays.cpp +++ b/clang/test/AST/ByteCode/arrays.cpp @@ -662,3 +662,16 @@ namespace InvalidIndex { } static_assert(foo(0) == 1, ""); } + +namespace PointerSubscript { + template<typename T> + constexpr T foo() { + T ss[] = {{}, {}, {}}; + T *s = &ss[0]; + + return s[2]; + } + static_assert(foo<int>() == 0); + struct S{}; + static_assert((foo<S>(), true)); +} diff --git a/clang/test/AST/ByteCode/libcxx/pointer-subscript.cpp b/clang/test/AST/ByteCode/libcxx/pointer-subscript.cpp new file mode 100644 index 0000000000000..68e25dcb17909 --- /dev/null +++ b/clang/test/AST/ByteCode/libcxx/pointer-subscript.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -std=c++2c -fexperimental-new-constant-interpreter -verify=expected,both %s +// RUN: %clang_cc1 -std=c++2c -verify=ref,both %s + +// both-no-diagnostics + +namespace std { +inline namespace __1 { +template <class _Tp> class unique_ptr; +template <class _Tp> class unique_ptr<_Tp[]> { +public: + _Tp* __ptr_; + +public: + constexpr _Tp& + operator[](unsigned i) const { + return __ptr_[i]; + }; +}; +} // namespace __1 +} // namespace std +struct WithTrivialDtor { + int x = 6; + constexpr friend void operator==(WithTrivialDtor const &x, + WithTrivialDtor const &y) { + (void)(x.x == y.x); + } +}; +constexpr bool test() { + + WithTrivialDtor array[50]; + std::unique_ptr<WithTrivialDtor[]> p(&array[0]); + (void)(p[1] == WithTrivialDtor()); + + return true; +} +static_assert(test()); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits