https://github.com/anandkvinu updated 
https://github.com/llvm/llvm-project/pull/223184

>From 74fa096819b826be252610c21e38458a2925f555 Mon Sep 17 00:00:00 2001
From: Anand K Vinu <[email protected]>
Date: Sun, 13 Sep 2026 02:16:52 +0530
Subject: [PATCH 1/2] [Clang][Sema] Preserve most derived array info across
 base class path entries, Add regression tests for primary and non primary
 base subobjects. format using git clang-format

---
 clang/lib/AST/ExprConstant.cpp                |  4 -
 .../SemaCXX/constant-expression-cxx1z.cpp     | 83 +++++++++++++++++++
 2 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 1286c77ad1c69..00568d1d029e3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -235,10 +235,6 @@ namespace {
         ArraySize = 0;
         MostDerivedLength = I + 1;
         IsArray = false;
-      } else {
-        // Path[I] describes a base class.
-        ArraySize = 0;
-        IsArray = false;
       }
     }
     return MostDerivedLength;
diff --git a/clang/test/SemaCXX/constant-expression-cxx1z.cpp 
b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
index c0766f70cf881..f985065009a19 100644
--- a/clang/test/SemaCXX/constant-expression-cxx1z.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
@@ -178,6 +178,89 @@ namespace LambdaCallOp {
   }
 }
 
+// Regression tests for https://github.com/llvm/llvm-project/issues/223064
+//
+// The constant evaluator loses track of an lvalue's most-derived array
+// information when an APValue containing a base-class path entry is
+// reconstructed into an LValue/SubobjectDesignator. A base-class path
+// entry does not advance the most-derived path length, so it must not
+// clobber the most-derived array size/flag either; those fields belong
+// to the entry at MostDerivedPathLength, not to whatever entry was
+// processed last.
+namespace GH223064 {
+
+// Original reproducer: 
+
+namespace BasicBaseSubobject {
+  struct A { int n; };
+  struct B : A {} b[2];
+
+  constexpr int *f() {
+    A *p = b;
+    return &static_cast<B*>(p)[1].n;
+  }
+  static_assert(f() == &b[1].n, "");
+}
+
+// Same shape, but through the second of two non-virtual bases, so the
+// base subobject sits at a non-zero offset within the derived object.
+namespace NonPrimaryBase {
+  struct A  { int n; };
+  struct A2 { int m; };
+  struct B : A, A2 {} b[2];
+
+  constexpr int *f() {
+    A2 *p = &b[0];
+    return &static_cast<B*>(p)[1].m;
+  }
+  static_assert(f() == &b[1].m, "");
+}
+
+// Two trailing base-class path entries in a row (C -> B -> A), rather than
+// just one
+namespace MultipleTrailingBaseEntries {
+  struct A { int n; };
+  struct B : A {};
+  struct C : B {} c[2];
+
+  constexpr int *f() {
+    A *p = &c[0];
+    return &static_cast<C*>(p)[1].n;
+  }
+  static_assert(f() == &c[1].n, "");
+}
+
+// Pointer arithmetic performed directly on the downcast pointer, rather
+// than array subscripting, must also see the correct bounds.
+namespace ArithmeticOnDowncastPointer {
+  struct A { int n; };
+  struct B : A {} b[3];
+
+  constexpr int *f() {
+    A *p = b;
+    B *q = static_cast<B*>(p) + 2;
+    return &q->n;
+  }
+  static_assert(f() == &b[2].n, "");
+}
+
+//  indexing
+// past the end of the array through the same base-subobject pattern
+// should still be rejected.
+namespace OutOfBoundsStillRejected {
+  struct A { int n; };
+  struct B : A {} b[2];
+
+  constexpr int *f(int i) {
+    A *p = b;
+    return &static_cast<B*>(p)[i].n; // expected-note {{cannot refer to 
element 5 of array of 2 elements in a constant expression}}
+  }
+  static_assert(f(5) == nullptr, ""); // expected-error {{not an integral 
constant expression}} \
+                                       // expected-note {{in call to 'f(5)'}}
+}
+
+} // namespace GH223064
+
 // This used to crash due to an assertion failure,
 // see gh#67690
 namespace {

>From 92e4d3d25f8b3111afb1fd4e1ebe2cdd959a19bb Mon Sep 17 00:00:00 2001
From: "Anand.k.vinu" <[email protected]>
Date: Mon, 14 Sep 2026 13:16:10 +0530
Subject: [PATCH 2/2] Update clang/test/SemaCXX/constant-expression-cxx1z.cpp

Co-authored-by: Lakshay Chauhan <[email protected]>
---
 clang/test/SemaCXX/constant-expression-cxx1z.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/SemaCXX/constant-expression-cxx1z.cpp 
b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
index f985065009a19..f31efdbf5798b 100644
--- a/clang/test/SemaCXX/constant-expression-cxx1z.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
@@ -244,7 +244,7 @@ namespace ArithmeticOnDowncastPointer {
   static_assert(f() == &b[2].n, "");
 }
 
-//  indexing
+// indexing
 // past the end of the array through the same base-subobject pattern
 // should still be rejected.
 namespace OutOfBoundsStillRejected {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to