<div dir="ltr">Yes, this idea has been kicking around for a long time. We should definitely have an attribute for this.<div><br></div><div>We talked for a long time about the idea that this attribute marks a type as not having address identity, kind of like unnamed_addr works for globals. However, I think some identity-related name would probably be confusing to users. Most people don't understand the vagaries of why std::unique_ptr<T*> isn't passed the same as T*, and they want a fix that says something like "pass_in_registers" or "shut_up_compiler_do_what_I_want", even though pass_in_registers is kind of meaningless when you're out of or never had any parameter registers.</div><div><br></div><div>Anyway, trivial_abi sounds fine. At least, as someone who has worked in clang call lowering, I understand what it means.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 13, 2017 at 5:37 PM, Akira Hatanaka via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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>
<br>______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>