[clang] [Clang][Sema] Preserve most derived array info across base class path entries. Add regression tests for primary and non primary base subobjects. (PR #223184)

Lakshay Chauhan via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 13 09:21:05 PDT 2026


================
@@ -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
----------------
nos1dot618 wrote:

**Nit**
```suggestion
// indexing
```

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


More information about the cfe-commits mailing list