
This breaks a ton of libc++ tests otherwise, since calling std::destroy_at will currently end the lifetime of the entire array not just the given element. See https://github.com/llvm/llvm-project/issues/147528
67 lines
1.5 KiB
C++
67 lines
1.5 KiB
C++
// RUN: %clang_cc1 -verify=expected,both -std=c++26 %s -fexperimental-new-constant-interpreter
|
|
// RUN: %clang_cc1 -verify=ref,both -std=c++26 %s
|
|
|
|
// both-no-diagnostics
|
|
|
|
namespace std {
|
|
struct type_info;
|
|
struct destroying_delete_t {
|
|
explicit destroying_delete_t() = default;
|
|
} inline constexpr destroying_delete{};
|
|
struct nothrow_t {
|
|
explicit nothrow_t() = default;
|
|
} inline constexpr nothrow{};
|
|
using size_t = decltype(sizeof(0));
|
|
enum class align_val_t : size_t {};
|
|
};
|
|
|
|
constexpr void *operator new(std::size_t, void *p) { return p; }
|
|
namespace std {
|
|
template<typename T> constexpr T *construct_at(T *p) { return new (p) T; }
|
|
template<typename T> constexpr void destroy_at(T *p) { p->~T(); }
|
|
}
|
|
|
|
constexpr bool foo() {
|
|
using T = bool;
|
|
bool b = true;
|
|
b.~T();
|
|
new (&b) bool(false);
|
|
return b;
|
|
}
|
|
static_assert(!foo());
|
|
|
|
struct S {};
|
|
constexpr bool foo2() {
|
|
S s;
|
|
s.~S();
|
|
new (&s) S{};
|
|
return true;
|
|
}
|
|
static_assert(foo2());
|
|
|
|
constexpr void destroy_pointer() {
|
|
using T = int*;
|
|
T p;
|
|
p.~T();
|
|
std::construct_at(&p);
|
|
}
|
|
static_assert((destroy_pointer(), true));
|
|
|
|
|
|
namespace DestroyArrayElem {
|
|
/// This is proof that std::destroy_at'ing an array element
|
|
/// ends the lifetime of the entire array.
|
|
/// See https://github.com/llvm/llvm-project/issues/147528
|
|
/// Using destroy_at on array elements is currently a no-op due to this.
|
|
constexpr int test() {
|
|
int a[4] = {};
|
|
|
|
std::destroy_at(&a[3]);
|
|
int r = a[1];
|
|
std::construct_at(&a[3]);
|
|
|
|
return r;
|
|
}
|
|
static_assert(test() == 0);
|
|
}
|