llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Akshay Kumar Dubey (akshaydubey05)

<details>
<summary>Changes</summary>

When reconstructing an LValue from an APValue, findMostDerivedSubobject was 
resetting ArraySize = 0 and IsArray = false when encountering a base class path 
entry.

A base class subobject is not a most-derived object and should inherit the 
most-derived object's properties (IsArray, ArraySize, MostDerivedType, and 
MostDerivedPathLength) from the containing most-derived object, matching 
SubobjectDesignator::addDeclUnchecked.

Fixes #<!-- -->223064

---
Full diff: https://github.com/llvm/llvm-project/pull/223663.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+2) 
- (modified) clang/lib/AST/ExprConstant.cpp (+3-4) 
- (modified) clang/test/SemaCXX/constant-expression-cxx11.cpp (+22) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 043a0ddae2a6c..875f59ff9853a 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -554,6 +554,8 @@ features cannot lower the translation-unit ABI level;
 
 #### Bug Fixes to C++ Support
 
+- Fixed a bug where constant evaluation lost track of most-derived array 
information
+  when reconstructing an lvalue referring to a base subobject of an array 
element. (#GH223064)
 - Fixed false-positive module ODR diagnostics when a type is found through a
   using-declaration in one definition and directly in another. ODR hashing also
   now distinguishes differently qualified uses of types found through
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 1286c77ad1c69..014d1a6b1b0e6 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -235,11 +235,10 @@ namespace {
         ArraySize = 0;
         MostDerivedLength = I + 1;
         IsArray = false;
-      } else {
-        // Path[I] describes a base class.
-        ArraySize = 0;
-        IsArray = false;
       }
+      // Otherwise, Path[I] describes a base class. It inherits the 
most-derived
+      // properties (IsArray, ArraySize, Type, MostDerivedLength) from the
+      // containing most-derived object.
     }
     return MostDerivedLength;
   }
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp 
b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 7b483a4238652..dc5d2def4aebd 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2747,3 +2747,25 @@ namespace GH154567 {
   constexpr S s{};
   static_assert(s.val.i == 0, "");
 }
+
+namespace GH223064 {
+  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, "");
+
+  struct Base1 { int x; };
+  struct Base2 : Base1 { int y; };
+  struct Derived : Base2 { int z; } arr[3];
+
+  constexpr int *g() {
+    Base1 *p = arr;
+    return &static_cast<Derived*>(p)[2].z;
+  }
+  static_assert(g() == &arr[2].z, "");
+}
+

``````````

</details>


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

Reply via email to