[clang] [clang][bytecode] Fix delete[] dtor order (PR #128411)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Feb 23 02:00:55 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
As always, call array dtors in reverse order.
---
Full diff: https://github.com/llvm/llvm-project/pull/128411.diff
2 Files Affected:
- (modified) clang/lib/AST/ByteCode/Interp.cpp (+4-1)
- (modified) clang/test/AST/ByteCode/new-delete.cpp (+20)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index dfa59a50b2711..43a062ce0c19b 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1015,11 +1015,14 @@ static bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) {
assert(Desc->isRecord() || Desc->isCompositeArray());
if (Desc->isCompositeArray()) {
+ unsigned N = Desc->getNumElems();
+ if (N == 0)
+ return true;
const Descriptor *ElemDesc = Desc->ElemDesc;
assert(ElemDesc->isRecord());
Pointer RP(const_cast<Block *>(B));
- for (unsigned I = 0; I != Desc->getNumElems(); ++I) {
+ for (int I = static_cast<int>(N) - 1; I >= 0; --I) {
if (!runRecordDestructor(S, OpPC, RP.atIndex(I).narrow(), ElemDesc))
return false;
}
diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp
index 5be1bb944c18c..a85ddaf29caf4 100644
--- a/clang/test/AST/ByteCode/new-delete.cpp
+++ b/clang/test/AST/ByteCode/new-delete.cpp
@@ -942,6 +942,26 @@ namespace ArrayBaseCast {
static_assert(test());
}
+namespace PR45350 {
+ int q;
+ struct V { int n; int *p = &n; constexpr ~V() { *p = *p * 10 + n; }};
+ constexpr int f(int n) {
+ int k = 0;
+ V *p = new V[n];
+ for (int i = 0; i != n; ++i) {
+ if (p[i].p != &p[i].n) return -1;
+ p[i].n = i;
+ p[i].p = &k;
+ }
+ delete[] p;
+ return k;
+ }
+ // [expr.delete]p6:
+ // In the case of an array, the elements will be destroyed in order of
+ // decreasing address
+ static_assert(f(6) == 543210);
+}
+
#else
/// Make sure we reject this prior to C++20
constexpr int a() { // both-error {{never produces a constant expression}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/128411
More information about the cfe-commits
mailing list