Timm =?utf-8?q?Bäder?= <[email protected]>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/[email protected]>


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/209496

>From ea324e9379f6cf9f68bebd9e776f0ac7633b0fd4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Tue, 14 Jul 2026 13:11:20 +0200
Subject: [PATCH 1/2] asdf

---
 clang/lib/AST/ByteCode/Interp.h    | 10 ++++++-
 clang/lib/AST/ByteCode/Pointer.cpp | 42 +++++++++++++++++++++++++++---
 clang/lib/AST/ByteCode/Pointer.h   |  2 +-
 clang/test/AST/ByteCode/cxx11.cpp  | 18 +++++++++++++
 4 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 201679017c98b..9893b57d92bac 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2738,7 +2738,7 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC, uint32_t 
ElemSize) {
     return false;
   }
 
-  if (!Pointer::hasSameBase(LHS, RHS) && S.getLangOpts().CPlusPlus) {
+  if (!Pointer::hasSameBase(LHS, RHS)) {
     S.FFDiag(S.Current->getSource(OpPC),
              diag::note_constexpr_pointer_arith_unspecified)
         << LHS.toDiagnosticString(S.getASTContext())
@@ -2762,6 +2762,14 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC, 
uint32_t ElemSize) {
     return true;
   }
 
+  // C++11 [expr.add]p6:
+  //   Unless both pointers point to elements of the same array object, or
+  //   one past the last element of the array object, the behavior is
+  //   undefined.
+  if (LHS.isBlockPointer() && !Pointer::elemsOfSameArray(LHS, RHS))
+    S.CCEDiag(S.Current->getSource(OpPC),
+              diag::note_constexpr_pointer_subtraction_not_same_array);
+
   std::optional<size_t> VL = LHS.computeLayoutOffset(S.getASTContext());
   if (!VL)
     return false;
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index 43af58d7bcb83..844483834b31a 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -815,9 +815,45 @@ bool Pointer::pointToSameBlock(const Pointer &A, const 
Pointer &B) {
   return A.block() == B.block();
 }
 
-bool Pointer::hasSameArray(const Pointer &A, const Pointer &B) {
-  return hasSameBase(A, B) && A.BS.Base == B.BS.Base &&
-         A.getFieldDesc()->IsArray;
+bool Pointer::elemsOfSameArray(const Pointer &A, const Pointer &B) {
+  assert(hasSameBase(A, B));
+  assert(A.isBlockPointer());
+  assert(B.isBlockPointer());
+
+  if (A.BS.Base == B.BS.Base)
+    return true;
+
+  if (A.isBaseClass() || B.isBaseClass())
+    return false;
+
+  if (A.getField() || B.getField())
+    return false;
+
+  auto closestArray = [](const Pointer &P) -> PtrView {
+    if (P.isArrayRoot())
+      return P.view();
+
+    PtrView V = P.view();
+    if (V.isArrayElement() || V.isOnePastEnd())
+      V = V.expand().getArray();
+
+    if (P.isRoot())
+      return P.view();
+
+    while (!V.isRoot() && !V.getFieldDesc()->IsArray) {
+      if (V.isArrayElement()) {
+        V = V.expand().getArray();
+        break;
+      }
+      V = V.getBase();
+    }
+    return V;
+  };
+
+  if (closestArray(A) != closestArray(B))
+    return false;
+
+  return true;
 }
 
 bool Pointer::pointsToLiteral() const {
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index dda5ac61ef126..75d3d8d51df6f 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -1015,7 +1015,7 @@ class Pointer {
   /// Checks if two pointers are comparable.
   static bool hasSameBase(const Pointer &A, const Pointer &B);
   /// Checks if two pointers can be subtracted.
-  static bool hasSameArray(const Pointer &A, const Pointer &B);
+  static bool elemsOfSameArray(const Pointer &A, const Pointer &B);
   /// Checks if both given pointers point to the same block.
   static bool pointToSameBlock(const Pointer &A, const Pointer &B);
 
diff --git a/clang/test/AST/ByteCode/cxx11.cpp 
b/clang/test/AST/ByteCode/cxx11.cpp
index 3553ab3ba68ad..9a879e14912ba 100644
--- a/clang/test/AST/ByteCode/cxx11.cpp
+++ b/clang/test/AST/ByteCode/cxx11.cpp
@@ -475,3 +475,21 @@ namespace SubobjectCompare {
                                                     // both-note {{comparison 
of addresses of subobjects of different base classes has unspecified value}}
   static_assert((void*)(X*)&z != (void*)(Y*)&z, "");
 }
+
+namespace SubPtr {
+  struct A {};
+  struct B : A { int n; int m; };
+  B a[3][3];
+
+  constexpr int diff1 = &a[2] - &a[0];
+  constexpr int diff2 = &a[1][3] - &a[1][0];
+  constexpr int diff3 = &a[2][0] - &a[1][0]; // both-error {{constant 
expression}} \
+                                             // both-note {{subtracted 
pointers are not elements of the same array}}
+  // static_assert(&a[2][0] == &a[1][3], ""); FIXME
+  constexpr int diff4 = (&b + 1) - &b;
+  constexpr int diff5 = &a[1][2].n - &a[1][0].n; // both-error {{constant 
expression}} \
+                                                 // both-note {{subtracted 
pointers are not elements of the same array}}
+  constexpr int diff6 = &a[1][2].n - &a[1][2].n;
+  constexpr int diff7 = (A*)&a[0][1] - (A*)&a[0][0]; // both-error {{constant 
expression}} \
+                                                     // both-note {{subtracted 
pointers are not elements of the same array}}
+}

>From d4085310b9b6707c643753311abd7d47403a6338 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Wed, 15 Jul 2026 07:49:21 +0200
Subject: [PATCH 2/2] Another test

---
 clang/test/AST/ByteCode/cxx11.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/test/AST/ByteCode/cxx11.cpp 
b/clang/test/AST/ByteCode/cxx11.cpp
index 9a879e14912ba..b001a53a97499 100644
--- a/clang/test/AST/ByteCode/cxx11.cpp
+++ b/clang/test/AST/ByteCode/cxx11.cpp
@@ -492,4 +492,5 @@ namespace SubPtr {
   constexpr int diff6 = &a[1][2].n - &a[1][2].n;
   constexpr int diff7 = (A*)&a[0][1] - (A*)&a[0][0]; // both-error {{constant 
expression}} \
                                                      // both-note {{subtracted 
pointers are not elements of the same array}}
+  constexpr auto diff8 = &a[1][2].n - (&a[1][2].n + 1);
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to