[PATCH] libstdc++: Mandate complete type for start_lifetime_as_array.
Tomasz Kaminski
tkaminsk@redhat.com
Fri Jul 10 12:01:10 GMT 2026
On Fri, Jul 10, 2026 at 1:33 PM Jonathan Wakely <jwakely@redhat.com> wrote:
> On Fri, 10 Jul 2026 at 12:25, Tomasz Kamiński <tkaminsk@redhat.com> wrote:
> >
> > This implements remaining part of P2679R2, "Fixing std::start_lifetime_as
> > and std::start_lifetime_as_array".
> >
> > For incomplete type _Tp, the is_implicit_lifetime_v<_Tp> check inside
> > start_lifetime_as already leads to following "invalid use of incomplete
> > type 'struct Incomplete'" error.
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/bits/stl_construct.h (std::start_lifetime_as_array):
> > static_assert that _Tp is complete type.
> > * testsuite/std/memory/start_lifetime_as/neg.cc: New test.
> > ---
> > Testing on x86_64-linux. *start_lifetime* test already passed.
> > OK for trunk when all tests passes?
>
> OK
As start_lifetime_as_array compiled before with incomplete types, I do not
see a reason to backport this to 16. It would only break code that relies
on that,
but it does not enable any new functionality.
>
> >
> > libstdc++-v3/include/bits/stl_construct.h | 8 ++++
> > .../std/memory/start_lifetime_as/neg.cc | 45 +++++++++++++++++++
> > 2 files changed, 53 insertions(+)
> > create mode 100644
> libstdc++-v3/testsuite/std/memory/start_lifetime_as/neg.cc
> >
> > diff --git a/libstdc++-v3/include/bits/stl_construct.h
> b/libstdc++-v3/include/bits/stl_construct.h
> > index 4a0650f3cb8..9608d7fd8ca 100644
> > --- a/libstdc++-v3/include/bits/stl_construct.h
> > +++ b/libstdc++-v3/include/bits/stl_construct.h
> > @@ -346,6 +346,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > inline _Tp*
> > start_lifetime_as_array(void* __p, size_t __n) noexcept
> > {
> > + static_assert(sizeof(_Tp), "template argument must be a complete
> type");
> > +
> > auto __q = reinterpret_cast<_Tp*>(__p);
> > if (!__n)
> > return __q;
> > @@ -360,6 +362,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > inline const _Tp*
> > start_lifetime_as_array(const void* __p, size_t __n) noexcept
> > {
> > + static_assert(sizeof(_Tp), "template argument must be a complete
> type");
> > +
> > auto __q = reinterpret_cast<const _Tp*>(__p);
> > if (!__n)
> > return __q;
> > @@ -376,6 +380,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > inline volatile _Tp*
> > start_lifetime_as_array(volatile void* __p, size_t __n) noexcept
> > {
> > + static_assert(sizeof(_Tp), "template argument must be a complete
> type");
> > +
> > auto __q = reinterpret_cast<volatile _Tp*>(__p);
> > if (!__n)
> > return __q;
> > @@ -392,6 +398,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > inline const volatile _Tp*
> > start_lifetime_as_array(const volatile void* __p, size_t __n)
> noexcept
> > {
> > + static_assert(sizeof(_Tp), "template argument must be a complete
> type");
> > +
> > auto __q = reinterpret_cast<const volatile _Tp*>(__p);
> > if (!__n)
> > return __q;
> > diff --git a/libstdc++-v3/testsuite/std/memory/start_lifetime_as/neg.cc
> b/libstdc++-v3/testsuite/std/memory/start_lifetime_as/neg.cc
> > new file mode 100644
> > index 00000000000..1adbd2f266d
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/std/memory/start_lifetime_as/neg.cc
> > @@ -0,0 +1,45 @@
> > +// { dg-do compile { target c++23 } }
> > +
> > +#include <bit>
> > +#include <memory>
> > +
> > +#include <testsuite_hooks.h>
> > +#include <testsuite_allocator.h>
> > +
> > +struct Incomplete;
> > +struct NonTrivial
> > +{
> > + NonTrivial() {}
> > + ~NonTrivial() {}
> > +};
> > +
> > +void test(void* p)
> > +{
> > + (void)std::start_lifetime_as<Incomplete>(p); // { dg-error
> "here" }
> > + (void)std::start_lifetime_as_array<Incomplete>(p, 2); // { dg-error
> "here" }
> > + (void)std::start_lifetime_as<NonTrivial>(p); // { dg-error
> "here" }
> > + // Array are implicit-lifetime regardless of they element type
> > + (void)std::start_lifetime_as_array<NonTrivial>(p, 2);
> > +
> > + const void* cp = p;
> > + (void)std::start_lifetime_as<Incomplete>(cp); // { dg-error
> "here" }
> > + (void)std::start_lifetime_as_array<Incomplete>(cp, 2); // { dg-error
> "here" }
> > + (void)std::start_lifetime_as<NonTrivial>(cp); // { dg-error
> "here" }
> > + (void)std::start_lifetime_as_array<NonTrivial>(cp, 2);
> > +
> > + volatile void* vp = p;
> > + (void)std::start_lifetime_as<Incomplete>(vp); // { dg-error
> "here" }
> > + (void)std::start_lifetime_as_array<Incomplete>(vp, 2); // { dg-error
> "here" }
> > + (void)std::start_lifetime_as<NonTrivial>(vp); // { dg-error
> "here" }
> > + (void)std::start_lifetime_as_array<NonTrivial>(vp, 2);
> > +
> > + const volatile void* cvp = vp;
> > + (void)std::start_lifetime_as<Incomplete>(cvp); // {
> dg-error "here" }
> > + (void)std::start_lifetime_as_array<Incomplete>(cvp, 2); // {
> dg-error "here" }
> > + (void)std::start_lifetime_as<NonTrivial>(cvp); // {
> dg-error "here" }
> > + (void)std::start_lifetime_as_array<NonTrivial>(cvp, 2);
> > +}
> > +
> > +// { dg-prune-output "invalid use of incomplete type" }
> > +// { dg-prune-output "template argument must be a complete type" }
> > +// { dg-prune-output "static assertion" }
> > --
> > 2.54.0
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260710/774de1dc/attachment.htm>
More information about the Libstdc++
mailing list