Skip to content

c++23: constexpr std::unique_ptr::~unique_ptr()/std::default_delete<T> instantiation too strict #111185

Open
@jdrouhard

Description

@jdrouhard
#include <memory>

class Foo {
  inline static std::unique_ptr<Foo> instance_;
};

See: https://godbolt.org/z/MqMxs9nzr

This fails to compile due to unique_ptr<T>::~unique_ptr() (and thus default_delete<T>::operator()) being instantiated at the point of the variable declaration (when the class isn't fully defined yet). Since c++23, unique_ptr and default_delete::operator() are constexpr, but the declaration of the unique_ptr should not attempt to fully instantiate the destructor or std::default_delete::operator() yet. Or at least the above usage pattern should be allowed, as this is a valid pattern for singletons (that aren't Meyers style). Should this fall back to non-constexpr unique_ptr/default_delete?

This fails using both libc++ and libstdc++. gcc and msvc both compile it fine.

In file included from test.cpp:1:
In file included from /builds/clang-19.1.0/bin/../include/c++/v1/memory:944:
In file included from /builds/clang-19.1.0/bin/../include/c++/v1/__memory/inout_ptr.h:16:
In file included from /builds/clang-19.1.0/bin/../include/c++/v1/__memory/shared_ptr.h:32:
/builds/clang-19.1.0/bin/../include/c++/v1/__memory/unique_ptr.h:78:19: error: invalid application of 'sizeof' to an incomplete type 'Foo'
   78 |     static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type");
      |                   ^~~~~~~~~~~
/builds/clang-19.1.0/bin/../include/c++/v1/__memory/unique_ptr.h:292:7: note: in instantiation of member function 'std::default_delete<Foo>::operator()' requested here
  292 |       __ptr_.second()(__tmp);
      |       ^
/builds/clang-19.1.0/bin/../include/c++/v1/__memory/unique_ptr.h:261:71: note: in instantiation of member function 'std::unique_ptr<Foo>::reset' requested here
  261 |   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
      |                                                                       ^
simple.cpp:4:38: note: in instantiation of member function 'std::unique_ptr<Foo>::~unique_ptr' requested here
    4 |   inline static std::unique_ptr<Foo> instance;
      |                                      ^
simple.cpp:3:7: note: definition of 'Foo' is not complete until the closing '}'
    3 | class Foo {

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++23clang:frontendLanguage frontend issues, e.g. anything involving "Sema"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions