<div dir="ltr">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.<div><br></div><div>### Motivation for the attribute</div><div>We have a user who wants to adopt smart pointers to manage lifetime of objects. The current code looks like this:</div><div><br></div><div>struct Object {</div><div>  ...</div><div>  void release();</div><div>};</div><div><br></div><div>Object *getObject();</div><div><br></div><div>void test() {</div><div>  Object *t = getObject();</div><div>  ...</div><div>  // Users have to call 'release' manually.</div><div>  t->release();</div><div>}</div><div><br></div><div>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: </div><div><br></div><div>template<class T></div><div>struct SmartPtr {</div><div>  T *ptr;</div><div>  SmartPtr(T *p);</div><div>  SmartPtr(const SmartPtr &);</div><div>  ~SmartPtr() {</div><div>    ptr->release();</div><div>  }</div><div>};<br></div><div><br></div><div><div>SmartPtr<Object> getObject();</div></div><div><br></div><div>void test() {</div><div>  SmartPtr<Object> t = getObject();</div><div>  ...</div><div>  // The object 't' points to is automatically released when ~SmartPtr is called.</div><div>}<br><div><br></div><div>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.</div><div><br></div></div><div>### The proposed attribute</div><div>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. 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).</div><div><br></div><div>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.</div></div>