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

            Bug ID: 121024
           Summary: ranges::destroy and ranges::destroy_n do not end
                    lifetime of trivial types
           Product: gcc
           Version: 15.1.0
            Status: UNCONFIRMED
          Keywords: accepts-invalid
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
                CC: daniel.kruegler at googlemail dot com, de34 at live dot cn,
                    tkaminsk at gcc dot gnu.org, unassigned at gcc dot gnu.org,
                    webrown.cpp at gmail dot com
  Target Milestone: ---

+++ This bug was initially created as a clone of Bug #119754 comment 6 +++

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