On Fri, 10 Jul 2026 at 13:01, Tomasz Kaminski <[email protected]> wrote:
>
>
>
> On Fri, Jul 10, 2026 at 1:33 PM Jonathan Wakely <[email protected]> wrote:
>>
>> On Fri, 10 Jul 2026 at 12:25, Tomasz Kamiński <[email protected]> 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.

Agreed.

>>
>>
>> >
>> >  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
>> >
>>

Reply via email to