[PATCH 3/6] libstdc++: port bitwise relocatable away from is_trivial

Giuseppe D'Angelo giuseppe.dangelo@kdab.com
Tue Dec 10 10:48:16 GMT 2024


Hi,

On 10/12/2024 10:56, Jonathan Wakely wrote:
> We need this to depend on is_trivially_copyable too, so we can use memcpy.
> 
> I'm testing a fix now to fix bootstrap.

There's a broader question I think, which is how much we want to "bend" 
the language rules.

[basic] isn't really super-explicit at giving us the rights to bit-blast 
bytes into uninitialized storage, and pretend there are objects there. 
There are a couple of provisions that deal with trivially copyable types:

https://eel.is/c++draft/basic.types.general#2
https://eel.is/c++draft/basic.types.general#3

which guarantee that one can memcpy the representation of an live object 
onto another live object, possibly itself. However, they don't 
necessarily talk about creating/starting the lifetime of new objects 
elsewhere.

That could be achieved through implicit-lifetime, but trivially copyable 
doesn't imply implicit-lifetime, AFAICS; consider the corner case of a 
type with deleted constructors but only trivial assignments and 
destruction, which is TC but not IL. This is why I think the facilities 
in P2590R2 talk about "trivially-copyable implicit-lifetime" types.

Maybe however the relocate functions are only called on types that we 
know are move constructible (e.g. from std::vector) so if they're TC we 
also know they're IL?

(The only thing missing is possibly a call to an abstract machine "magic 
function", such as start_lifetime_as?)

Explicitly checking for a trivial move constructor + trivial destructor 
(that is, the code after my patch) implies that the type is IL, but that 
doesn't really gives us the rights to assume that the object in the new 
storage have the same values than the old ones, as that's only 
guaranteed for TC types.

In short it looks like a bit of a lose-lose situation. I hope P3279 will 
bring clarity in the area.


Then, if the problem is just suppressing the warning, this does it:

> diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
> index 916288352d7..374f30ee645 100644
> --- a/libstdc++-v3/include/bits/stl_uninitialized.h
> +++ b/libstdc++-v3/include/bits/stl_uninitialized.h
> @@ -1294,7 +1294,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>               return __out.base();
>             }
>  #endif
> -         __builtin_memcpy(__result, __first, __count * sizeof(_Tp));
> +         // Cast to void* in order to suppress -Wclass-memaccess.
> +         __builtin_memcpy(static_cast<void *>(__result), static_cast<const void *>(__first), __count * sizeof(_Tp));
>         }
>        return __result + __count;
>      }

It's the trick we use in Qt; or similarly just suppressing the warning 
via #pragmas, however I'm not sure if Clang likes that.

What do you think?

Thank you,
-- 
Giuseppe D'Angelo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4244 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20241210/73b12d02/attachment.p7s>


More information about the Libstdc++ mailing list