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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to