|
21 | 21 | #error "huh?"
|
22 | 22 | #endif
|
23 | 23 |
|
| 24 | + |
| 25 | +inline constexpr void* operator new(__SIZE_TYPE__, void* p) noexcept { return p; } |
| 26 | +namespace std { |
| 27 | + using size_t = decltype(sizeof(0)); |
| 28 | + template<typename T> struct allocator { |
| 29 | + constexpr T *allocate(size_t N) { |
| 30 | + return (T*)__builtin_operator_new(sizeof(T) * N); // #alloc |
| 31 | + } |
| 32 | + constexpr void deallocate(void *p, __SIZE_TYPE__) { |
| 33 | + __builtin_operator_delete(p); |
| 34 | + } |
| 35 | + }; |
| 36 | +template<typename T, typename... Args> |
| 37 | +constexpr T* construct_at(T* p, Args&&... args) { return ::new((void*)p) T(static_cast<Args&&>(args)...); } |
| 38 | + |
| 39 | + template<typename T> |
| 40 | + constexpr void destroy_at(T* p) { |
| 41 | + p->~T(); |
| 42 | + } |
| 43 | +} |
| 44 | + |
24 | 45 | extern "C" {
|
25 | 46 | typedef decltype(sizeof(int)) size_t;
|
26 | 47 | extern size_t wcslen(const wchar_t *p);
|
@@ -1767,6 +1788,28 @@ namespace WithinLifetime {
|
1767 | 1788 | }
|
1768 | 1789 | } xstd; // both-error {{is not a constant expression}} \
|
1769 | 1790 | // both-note {{in call to}}
|
| 1791 | + |
| 1792 | + consteval bool test_dynamic(bool read_after_deallocate) { |
| 1793 | + std::allocator<int> a; |
| 1794 | + int* p = a.allocate(1); |
| 1795 | + // a.allocate starts the lifetime of an array, |
| 1796 | + // the complete object of *p has started its lifetime |
| 1797 | + if (__builtin_is_within_lifetime(p)) |
| 1798 | + return false; |
| 1799 | + std::construct_at(p); |
| 1800 | + if (!__builtin_is_within_lifetime(p)) |
| 1801 | + return false; |
| 1802 | + std::destroy_at(p); |
| 1803 | + if (__builtin_is_within_lifetime(p)) |
| 1804 | + return false; |
| 1805 | + a.deallocate(p, 1); |
| 1806 | + if (read_after_deallocate) |
| 1807 | + __builtin_is_within_lifetime(p); // both-note {{read of heap allocated object that has been deleted}} |
| 1808 | + return true; |
| 1809 | + } |
| 1810 | + static_assert(test_dynamic(false)); |
| 1811 | + static_assert(test_dynamic(true)); // both-error {{not an integral constant expression}} \ |
| 1812 | + // both-note {{in call to}} |
1770 | 1813 | }
|
1771 | 1814 |
|
1772 | 1815 | #ifdef __SIZEOF_INT128__
|
|
0 commit comments