[cfe-dev] [RFC] Attribute that can be used to instruct clang to pass and return non-trivial structs directly

Akira Hatanaka via cfe-dev cfe-dev at lists.llvm.org
Mon Nov 13 21:32:27 PST 2017

On Mon, Nov 13, 2017 at 5:37 PM, Akira Hatanaka <ahatanak at gmail.com> wrote:

> I'd like to propose an attribute that can be used to instruct clang to
> pass and return non-trivial C++ structs directly when it's possible to do
> so. Any feedback would be greatly appreciated.
> ### Motivation for the attribute
> We have a user who wants to adopt smart pointers to manage lifetime of
> objects. The current code looks like this:
> struct Object {
>   ...
>   void release();
> };
> Object *getObject();
> void test() {
>   Object *t = getObject();
>   ...
>   // Users have to call 'release' manually.
>   t->release();
> }
> The smart pointer the user plans to use is a thin C++ template wrapper
> whose only data member is the raw pointer that points to the object being
> managed:
> template<class T>
> struct SmartPtr {
>   T *ptr;
>   SmartPtr(T *p);
>   SmartPtr(const SmartPtr &);
>   ~SmartPtr() {
>     ptr->release();
>   }
> };
> SmartPtr<Object> getObject();
> void test() {
>   SmartPtr<Object> t = getObject();
>   ...
>   // The object 't' points to is automatically released when ~SmartPtr is
> called.
> }
> The problem with the code above is that, since SmartPtr is considered to
> be non-trivial for the purpose of calls according to the C++ ABI, function
> getObject now returns its return value indirectly via an implicit pointer
> parameter passed to the function even though the struct has the same
> in-memory representation as a raw pointer. This breaks ABI compatibility
> for users who use getObject in their code but cannot rewrite their code to
> use the new API.
> ### The proposed attribute
> The attribute (tentatively named "trivial_abi") will be used to annotate
> C++ structs and instruct clang to pass and return the struct indirectly
> when it's possible to do so.

I meant to say "instruct clang to pass and return the struct directly" here.

> This means that the presence of a non-trivial destructor or copy
> constructor will not force the struct to be passed or returned indirectly,
> but it doesn't guarantee the struct will always be passed or returned
> directly (the struct have to be passed indirectly if its size is too large
> or there is another data member that is non-trivial, for example).
> Besides avoiding ABI breakage, the attribute can potentially improve
> performance since the extra load instruction to get the value of the
> pointer isn't needed when the struct is passed or returned directly.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20171113/581b715c/attachment.html>

More information about the cfe-dev mailing list