Author: Timm Baeder
Date: 2025-04-19T16:48:49+02:00
New Revision: 6196b4ee8c47dc4a2267b7c704d1811e68c7f1c1

URL: 
https://github.com/llvm/llvm-project/commit/6196b4ee8c47dc4a2267b7c704d1811e68c7f1c1
DIFF: 
https://github.com/llvm/llvm-project/commit/6196b4ee8c47dc4a2267b7c704d1811e68c7f1c1.diff

LOG: [clang][bytecode] Don't set OnePastEnd bit for array elements (#136422)

If we refer to arr[N], don't set the OnePastEnd bit of the APValue,
since that is already encoded in the array index.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Pointer.cpp
    clang/test/AST/ByteCode/arrays.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index 686ec381d232a..059503cae3561 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -223,6 +223,7 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
     UsePath = false;
 
   // Build the path into the object.
+  bool OnePastEnd = isOnePastEnd();
   Pointer Ptr = *this;
   while (Ptr.isField() || Ptr.isArrayElement()) {
 
@@ -251,9 +252,10 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const 
{
       Ptr = Ptr.expand();
       const Descriptor *Desc = Ptr.getFieldDesc();
       unsigned Index;
-      if (Ptr.isOnePastEnd())
+      if (Ptr.isOnePastEnd()) {
         Index = Ptr.getArray().getNumElems();
-      else
+        OnePastEnd = false;
+      } else
         Index = Ptr.getIndex();
 
       QualType ElemType = Desc->getElemQualType();
@@ -304,8 +306,7 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
   std::reverse(Path.begin(), Path.end());
 
   if (UsePath)
-    return APValue(Base, Offset, Path,
-                   /*IsOnePastEnd=*/!isElementPastEnd() && isOnePastEnd());
+    return APValue(Base, Offset, Path, OnePastEnd);
 
   return APValue(Base, Offset, APValue::NoLValuePath());
 }

diff  --git a/clang/test/AST/ByteCode/arrays.cpp 
b/clang/test/AST/ByteCode/arrays.cpp
index e50839e0f0877..934c3a3e7aff1 100644
--- a/clang/test/AST/ByteCode/arrays.cpp
+++ b/clang/test/AST/ByteCode/arrays.cpp
@@ -761,3 +761,13 @@ namespace PointerSubscript {
   struct S{};
   static_assert((foo<S>(), true));
 }
+
+namespace OnePastEndDiag {
+
+  constexpr int a(const int *b) {
+    return *b; // both-note {{read of dereferenced one-past-the-end pointer}}
+  }
+  constexpr int foo[] = {1,2};
+  constexpr int k = a(foo + 2); // both-error {{must be initialized by a 
constant expression}} \
+                                // both-note {{in call to 'a(&foo[2])'}}
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to