[clang] 9604e5c - [clang][Interp] Allow stepping back from a one-past-the-end pointer

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Wed May 22 03:45:35 PDT 2024


Author: Timm Bäder
Date: 2024-05-22T12:45:17+02:00
New Revision: 9604e5ce8b5607cd88ba130314fc7ae8545542e1

URL: https://github.com/llvm/llvm-project/commit/9604e5ce8b5607cd88ba130314fc7ae8545542e1
DIFF: https://github.com/llvm/llvm-project/commit/9604e5ce8b5607cd88ba130314fc7ae8545542e1.diff

LOG: [clang][Interp] Allow stepping back from a one-past-the-end pointer

... back into range of the array.

Added: 
    

Modified: 
    clang/lib/AST/Interp/Interp.h
    clang/lib/AST/Interp/Pointer.h
    clang/test/AST/Interp/arrays.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index c5607169b25f1..7ef963c810c82 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1555,8 +1555,12 @@ bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
   if (!CheckArray(S, OpPC, Ptr))
     return false;
 
-  uint64_t Index = Ptr.getIndex();
   uint64_t MaxIndex = static_cast<uint64_t>(Ptr.getNumElems());
+  uint64_t Index;
+  if (Ptr.isOnePastEnd())
+    Index = MaxIndex;
+  else
+    Index = Ptr.getIndex();
 
   bool Invalid = false;
   // Helper to report an invalid offset, computed as APSInt.

diff  --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h
index 9468bdbf00cc0..93ca754d04a64 100644
--- a/clang/lib/AST/Interp/Pointer.h
+++ b/clang/lib/AST/Interp/Pointer.h
@@ -537,9 +537,6 @@ class Pointer {
     if (isZero())
       return 0;
 
-    if (isElementPastEnd())
-      return 1;
-
     // narrow()ed element in a composite array.
     if (asBlockPointer().Base > sizeof(InlineDescriptor) &&
         asBlockPointer().Base == Offset)

diff  --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp
index e936ec6dc894b..dd5064d993e66 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -54,6 +54,10 @@ constexpr int derefPtr(const int *d) {
 }
 static_assert(derefPtr(data) == 5, "");
 
+/// Make sure we can refer to the one-past-the-end element
+/// and then return back to the end of the array.
+static_assert((&data[5])[-1] == 1, "");
+
 constexpr int storePtr() {
   int b[] = {1,2,3,4};
   int *c = b;


        


More information about the cfe-commits mailing list