Author: Timm Bäder
Date: 2024-07-12T17:18:26+02:00
New Revision: 840c7c6e1fba52748e3ceccd2842e5d96f658f2e

URL: 
https://github.com/llvm/llvm-project/commit/840c7c6e1fba52748e3ceccd2842e5d96f658f2e
DIFF: 
https://github.com/llvm/llvm-project/commit/840c7c6e1fba52748e3ceccd2842e5d96f658f2e.diff

LOG: [clang][Interp] Fix Pointer::expand() checking for metadata size

The == 0 check here was used before blocks had metadata, but doesn't
work anymore today.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h
index 7785da1d68f63..0ebac1ba04551 100644
--- a/clang/lib/AST/Interp/Pointer.h
+++ b/clang/lib/AST/Interp/Pointer.h
@@ -211,6 +211,9 @@ class Pointer {
 
   /// Expands a pointer to the containing array, undoing narrowing.
   [[nodiscard]] Pointer expand() const {
+    assert(isBlockPointer());
+    Block *Pointee = asBlockPointer().Pointee;
+
     if (isElementPastEnd()) {
       // Revert to an outer one-past-end pointer.
       unsigned Adjust;
@@ -218,7 +221,7 @@ class Pointer {
         Adjust = sizeof(InitMapPtr);
       else
         Adjust = sizeof(InlineDescriptor);
-      return Pointer(asBlockPointer().Pointee, asBlockPointer().Base,
+      return Pointer(Pointee, asBlockPointer().Base,
                      asBlockPointer().Base + getSize() + Adjust);
     }
 
@@ -228,15 +231,17 @@ class Pointer {
 
     // If at base, point to an array of base types.
     if (isRoot())
-      return Pointer(asBlockPointer().Pointee, RootPtrMark, 0);
+      return Pointer(Pointee, RootPtrMark, 0);
 
     // Step into the containing array, if inside one.
     unsigned Next = asBlockPointer().Base - getInlineDesc()->Offset;
     const Descriptor *Desc =
-        Next == 0 ? getDeclDesc() : getDescriptor(Next)->Desc;
+        (Next == Pointee->getDescriptor()->getMetadataSize())
+            ? getDeclDesc()
+            : getDescriptor(Next)->Desc;
     if (!Desc->IsArray)
       return *this;
-    return Pointer(asBlockPointer().Pointee, Next, Offset);
+    return Pointer(Pointee, Next, Offset);
   }
 
   /// Checks if the pointer is null.

diff  --git a/clang/test/AST/Interp/arrays.cpp 
b/clang/test/AST/Interp/arrays.cpp
index 933437c3401c4..612bd552aed48 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -625,3 +625,10 @@ constexpr int *get2() {
   return same_entity_2;
 }
 static_assert(get2() == same_entity_2, "failed to find previous decl");
+
+constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
14, 15, 16 };
+constexpr int fail(const int &p) {
+  return (&p)[64]; // both-note {{cannot refer to element 64 of array of 2 
elements}}
+}
+static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2)) == 11, 
""); // both-error {{not an integral constant expression}} \
+                                                                               
     // both-note {{in call to}}


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

Reply via email to