[clang] [clang][bytecode] Diagnose subtracting pointers to array elements... (PR #150407)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 24 04:39:54 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

... if the elements are in different arrays.

---
Full diff: https://github.com/llvm/llvm-project/pull/150407.diff


2 Files Affected:

- (modified) clang/lib/AST/ByteCode/Interp.h (+19) 
- (modified) clang/test/AST/ByteCode/arrays.cpp (+21) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index b42c7665c3a35..a37cacedb627b 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2383,6 +2383,25 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC) {
     return false;
   }
 
+  // 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.isRoot() && !RHS.isRoot() && LHS.isBlockPointer() &&
+      RHS.isBlockPointer()) {
+    Pointer A = LHS;
+    if (LHS.isArrayElement())
+      A = LHS.expand().getArray();
+
+    Pointer B = RHS;
+    if (RHS.isArrayElement())
+      B = RHS.expand().getArray();
+
+    if (A != B)
+      S.CCEDiag(S.Current->getSource(OpPC),
+                diag::note_constexpr_pointer_subtraction_not_same_array);
+  }
+
   if (LHS == RHS) {
     S.Stk.push<T>();
     return true;
diff --git a/clang/test/AST/ByteCode/arrays.cpp b/clang/test/AST/ByteCode/arrays.cpp
index 2dd51c2fa6711..1329071c7188d 100644
--- a/clang/test/AST/ByteCode/arrays.cpp
+++ b/clang/test/AST/ByteCode/arrays.cpp
@@ -779,3 +779,24 @@ namespace DiscardedSubScriptExpr {
     return true;
   }
 }
+
+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 {{must be initialized by a constant expression}} \
+                                             // both-note {{subtracted pointers are not elements of the same array}}
+  struct S {
+    int a;
+    int b;
+    constexpr S() : a(1), b(2) {}
+  };
+
+  constexpr int  f5() { // both-error {{never produces a constant expression}}
+    struct S s;
+    int d = &s.b - &s.a; // both-note {{subtracted pointers are not elements of the same array}}
+    return d;
+  }
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/150407


More information about the cfe-commits mailing list