[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