[PATCH] libstdc++: library side of C++26 P2786R13 - Trivial Relocatability [PR119064]

Jason Merrill jason@redhat.com
Thu Aug 28 12:08:12 GMT 2025


On 8/28/25 5:19 AM, Jakub Jelinek wrote:
> On Thu, Aug 28, 2025 at 10:49:36AM +0200, Jason Merrill wrote:
>>> I know, but P2590R2 is not implemented yet and as written in
>>> https://gcc.gnu.org/PR106658 I have actually no idea what needs to be done
>>> if anything on the compiler side.  Because at least the GIMPLE model
>>> basically allows placement new anywhere without anything in the IL marking
>>> up that the dynamic type has changed.  Though perhaps for constant
>>> expression evaluation we want something...
>>
>> Note this is fixed by PR121068 (r16-3022).
> 
> So, do you think for P2590R2 we want a purely library implementation which
> does nothing (well, define the needed templates)?
> Or do you prefer some builtin which will do nothing initially but might be
> changed to do something when needed?
> The first version actually clears the array, not sure if that is desirable
> (especially for the const, volatile and const volatile overloads).

It seems undesirable: "The object representation
of a is the contents of the storage prior to the call to 
start_lifetime_as." https://eel.is/c++draft/obj.lifetime#3

So if we want to represent this somehow, it needs a different 
representation than the clobbers I used for placement new.

> And we apparently even don't have std::is_implicit_lifetime trait.
> Guess I should implement that first (C++23 P2674R1).  clang uses
> __builtin_is_implicit_lifetime for that.

Sounds good.

> void *operator new(__SIZE_TYPE__ __sz, void *__p) { return __p; }
> void *operator new[](__SIZE_TYPE__ __sz, void *__p) { return __p; }
> namespace std {
> template <typename T>
> [[nodiscard]] T* start_lifetime_as1(void* __p) noexcept
> {
> //  static_assert(__is_implicit_lifetime(T));
>    auto __b = new (__p) unsigned char[sizeof(T)];
>    auto __r = reinterpret_cast<T*>(__b);
>    (void)*__r;
>    return __r;
> }
> template <typename T>
> [[nodiscard]] T* start_lifetime_as2(void* __p) noexcept
> {
> //  static_assert(__is_implicit_lifetime(T));
>    return reinterpret_cast<T*>(__p);
> }
> }
> struct S { int a; long long b; };
> S *f1 (void *p) { return std::start_lifetime_as1<S>(p); }
> S *f2 (void *p) { return std::start_lifetime_as2<S>(p); }
> long double *f3 (void *p) { return std::start_lifetime_as1<long double>(p); }
> long double *f4 (void *p) { return std::start_lifetime_as2<long double>(p); }
> 
> 	Jakub
> 



More information about the Libstdc++ mailing list