[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 17:37:06 PST 2017


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. 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/5d046e29/attachment.html>


More information about the cfe-dev mailing list