https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/128411
As always, call array dtors in reverse order. >From c8d9fba32d6c97e89d320533fd680f6fa2f80a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Sun, 23 Feb 2025 10:57:47 +0100 Subject: [PATCH] [clang][bytecode] Fix delete[] dtor order As always, call array dtors in reverse order. --- clang/lib/AST/ByteCode/Interp.cpp | 5 ++++- clang/test/AST/ByteCode/new-delete.cpp | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) 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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits