[clang] [clang][Sema] Track trivial-relocatability as a type trait (PR #84621)

Marcin Kowalczyk via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 16 08:43:44 PDT 2024


QrczakMK wrote:

I think that if Clang chooses to support both variants of the type trait, it should provide both variants of `[[clang::trivial_abi]]`, so that a type like `std::unique_ptr<T>` is trivially relocatable including assignment (and can be annotated as such), while a type like `std::tuple<int&>` is trivially relocatable only for construction (and can be annotated as such if its move constructor cannot be trivial for some reason).

[Riegeli](https://github.com/google/riegeli) would benefit from the type trait, with no difference in how it treats types with non-trivial or not-relocating or missing assignment operator.

It provides a type-erasing holder called [AnyDependency](https://github.com/google/riegeli/blob/master/riegeli/base/any_dependency.h). When not requested to reserve inline storage, it stores a type inline if it fits in a pointer and [is trivially relocatable](https://github.com/google/riegeli/blob/5d75119232cd4f6db8dfa69a1503289f050e9643/riegeli/base/any_dependency_internal.h#L109-L113), otherwise allocates it on the heap. This constraint is in turn used to optimize [move constructor and assignment](https://github.com/google/riegeli/blob/5d75119232cd4f6db8dfa69a1503289f050e9643/riegeli/base/any_dependency.h#L498-L506) to skip a call through a function pointer, as well as to mark `AnyDependency` itself trivially relocatable (even though it is not trivially movable: it marks the moved-from object as empty).

The optimization of storing the type inline should be applicable not only to trivially copyable types but also to `std::unique_ptr` (if tagged with `__attribute__((trivial_abi))`) and to types with `std::unique_ptr` as a sole member.

`AnyDependency` does not use the assignment operator of the stored type (assigning a new stored value always destroys and recreates the stored value, because its type may change and it is not worth the effort to detect when it happens to not change). It is rarely used with types which are move constructible but not move assignable (or with an atypical semantics of assignment). Hence either variant of the semantics of the type trait would work equally well here.

https://github.com/llvm/llvm-project/pull/84621


More information about the cfe-commits mailing list