https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/177906
We could get here for array roots, for which the assertion doesn't necessarily hold. >From 20fa9a6a3e69b03e42dee016dc7680475847fb43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Mon, 26 Jan 2026 09:16:52 +0100 Subject: [PATCH] [clang][bytecode] Relax assertions in Pointer::{begin,end}Lifetime We could get here for array roots, for which the assertion doesn't necessarily hold. --- clang/lib/AST/ByteCode/Pointer.cpp | 4 +- .../end-primitive-array-root-lifetime.cpp | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 clang/test/AST/ByteCode/libcxx/end-primitive-array-root-lifetime.cpp diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index 4a773d83b76f6..a1ab492e5cb37 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -521,7 +521,7 @@ void Pointer::startLifetime() const { IM.setInitMap(new InitMap(Desc->getNumElems(), IM.allInitialized())); IM->startElementLifetime(getIndex()); - assert(this->getLifetime() == Lifetime::Started); + assert(isArrayRoot() || (this->getLifetime() == Lifetime::Started)); return; } @@ -541,7 +541,7 @@ void Pointer::endLifetime() const { IM.setInitMap(new InitMap(Desc->getNumElems(), IM.allInitialized())); IM->endElementLifetime(getIndex()); - assert(this->getLifetime() == Lifetime::Ended); + assert(isArrayRoot() || (this->getLifetime() == Lifetime::Ended)); return; } diff --git a/clang/test/AST/ByteCode/libcxx/end-primitive-array-root-lifetime.cpp b/clang/test/AST/ByteCode/libcxx/end-primitive-array-root-lifetime.cpp new file mode 100644 index 0000000000000..f5ba94d429960 --- /dev/null +++ b/clang/test/AST/ByteCode/libcxx/end-primitive-array-root-lifetime.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -std=c++2c -fexperimental-new-constant-interpreter -verify=expected,both %s +// RUN: %clang_cc1 -std=c++2c -verify=ref,both %s + +// both-no-diagnostics + +namespace std { +inline namespace { +template <bool, class _IfRes, class> using conditional_t = _IfRes; +template <class _Ip> +concept input_iterator = requires { typename _Ip; }; +auto end = int{}; +namespace ranges { +template <class> +concept range = requires { end; }; +template <class _Tp> +concept input_range = input_iterator<_Tp>; +template <class> +concept forward_range = false; +template <range _Rp> struct owning_view { + _Rp __r_; +}; +} // namespace ranges +template <int _Size> struct array { + int __elems_[_Size]; +}; +template <class> struct allocator { + constexpr array<2> *allocate(decltype(sizeof(int))) { + return static_cast<array<2> *>(operator new(sizeof(array<2>))); + } +}; +namespace ranges { +template <input_range _View, forward_range _Pattern> struct join_with_view { + join_with_view(_View, _Pattern); +}; +} // namespace ranges +template <class> struct vector { + constexpr ~vector() { + (__end_ - 1)->~array<2>(); + } + constexpr vector() { + __end_ = __alloc_.allocate(0); + _ConstructTransaction __tx(*this); + ++__tx.__pos_; + } + array<2>* __end_; + allocator<array<2>> __alloc_; + struct _ConstructTransaction { + constexpr _ConstructTransaction(vector &__v) + : __v_(__v), __pos_(__v.__end_) {} + constexpr ~_ConstructTransaction() { __v_.__end_ = __pos_; } + vector __v_; + array<2>* __pos_; + }; +}; +} // namespace +} // namespace std +template <bool RefIsGlvalue, class Inner> +using VRange = std::conditional_t<RefIsGlvalue, std::vector<Inner>, Inner>; +template <int RefIsGlvalue> void test_pre_increment() { + using V = VRange<RefIsGlvalue, std::array<2>>; + using Pattern = std::array<2>; + using JWV = std::ranges::join_with_view<std::ranges::owning_view<V>, + std::ranges::owning_view<Pattern>>; + JWV jwv({}, {}); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
