https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119754

--- Comment #6 from Jiang An <de34 at live dot cn> ---
Consider this example (https://godbolt.org/z/dGGE6o5qY):

```
#include <memory>

using namespace std;

template <auto>
struct require_valid_constant;

template <class Fn>
constexpr int consteval_validate_destruction(Fn op) {
    struct S {
        int n;
    };

    S arr[1]{{42}};
    op(arr);
    return arr[0].n;
}

template <auto Fn>
constexpr bool CanWellDefinedlyAccessAfterOperation =
    requires { typename
require_valid_constant<consteval_validate_destruction(Fn)>; };

static_assert(CanWellDefinedlyAccessAfterOperation<[](auto&) {}>);
static_assert(!CanWellDefinedlyAccessAfterOperation<[](auto& arr) { destroy(arr
+ 0, arr + 1); }>);
static_assert(!CanWellDefinedlyAccessAfterOperation<[](auto& arr) {
destroy_at(arr + 0); }>);
static_assert(!CanWellDefinedlyAccessAfterOperation<[](auto& arr) {
destroy_at(&arr); }>);
static_assert(!CanWellDefinedlyAccessAfterOperation<[](auto& arr) {
destroy_n(arr + 0, 1); }>);
static_assert(!CanWellDefinedlyAccessAfterOperation<[](auto& arr) {
ranges::destroy(arr + 0, arr + 1); }>);
static_assert(!CanWellDefinedlyAccessAfterOperation<[](auto& arr) {
ranges::destroy(arr); }>);
static_assert(!CanWellDefinedlyAccessAfterOperation<[](auto& arr) {
ranges::destroy_at(arr + 0); }>);
static_assert(!CanWellDefinedlyAccessAfterOperation<[](auto& arr) {
ranges::destroy_at(&arr); }>);
static_assert(!CanWellDefinedlyAccessAfterOperation<[](auto& arr) {
ranges::destroy_n(arr + 0, 1); }>);
```

It seems that algorithms in std properly destroy trivially destructible
objects, but those in std::ranges don't.

Although the difference is only observable by Clang due to Bug 102284.

Reply via email to