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

            Bug ID: 97388
           Summary: constexpr evaluator incorrectly claims double delete
                    with function parameter
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: david at doublewise dot net
  Target Milestone: ---

The following translation unit

```
struct S {
        int * m_ptr;

        constexpr S():
                m_ptr(new int())
        {
        }
        constexpr S(S && other) noexcept:
                m_ptr(other.m_ptr)
        {
                other.m_ptr = nullptr;
        }
        constexpr ~S() noexcept {
                delete m_ptr;
        }
};

constexpr bool test(S v) {
        auto x = static_cast<S &&>(v);
        return true;
}

static_assert(test(S()));
```

is rejected with 

```
<source>:23:19: error: non-constant condition for static assertion

   23 | static_assert(test(S()));

      |               ~~~~^~~~~

Compiler returned: 1
```

This problem does not occur if `v` is turned into a local variable instead of a
function parameter.

The error message is also not helpful in this case. It gives a much more
helpful (but still erroneous) error message if `std::allocator` is used instead
of `new` and `delete`:

```
<source>:28:19: error: non-constant condition for static assertion

   28 | static_assert(test(S()));

      |               ~~~~^~~~~

In file included from
/opt/compiler-explorer/gcc-trunk-20201012/include/c++/11.0.0/memory:64,

                 from <source>:1:

<source>:28:25:   in 'constexpr' expansion of '(&<anonymous>)->S::~S()'

<source>:17:36:   in 'constexpr' expansion of
'std::allocator<int>().std::allocator<int>::deallocate(((S*)this)->S::m_ptr,
1)'

/opt/compiler-explorer/gcc-trunk-20201012/include/c++/11.0.0/bits/allocator.h:183:30:
error: deallocation of already deallocated storage

  183 |             ::operator delete(__p);

      |             ~~~~~~~~~~~~~~~~~^~~~~

Compiler returned: 1
```

See it live: https://godbolt.org/z/hcv88h

Reply via email to