[clang] [clang][bytecode] Expand subscript base if of pointer type (PR #128511)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 24 05:30:40 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
This is similar to what we do in the AddOffset instruction when adding an offset to a pointer.
---
Full diff: https://github.com/llvm/llvm-project/pull/128511.diff
4 Files Affected:
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+11-1)
- (modified) clang/lib/AST/ByteCode/Interp.h (+4-1)
- (modified) clang/test/AST/ByteCode/arrays.cpp (+13)
- (added) clang/test/AST/ByteCode/libcxx/pointer-subscript.cpp (+36)
``````````diff
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());
``````````
</details>
https://github.com/llvm/llvm-project/pull/128511
More information about the cfe-commits
mailing list