[cxx-abi-dev] Transfer modes for parameters and return values

Gabriel Dos Reis gdr at integrable-solutions.net
Mon Nov 26 05:33:40 UTC 2012


On Sun, Nov 25, 2012 at 11:03 PM, Richard Smith <richardsmith at google.com> wrote:
> On Fri, Nov 23, 2012 at 12:37 PM, Jason Merrill <jason at redhat.com> wrote:
>>
>> On 06/03/2009 04:59 PM, David Vandevoorde wrote:
>>>
>>> In 3.1.1 and 3.1.4, the ABI specifies that "by value" class type
>>> parameters and class type return values are passed via the address of a
>>> reference if the class type has
>>>      (a) a nontrivial destructor, or
>>>      (b) a nontrivial copy constructor.
>>>
>>> Should we now also add to that:
>>>      (c) a (nontrivial) move constructor
>>> ?
>>
>>
>> This change doesn't seem to have been applied to the ABI, though G++
>> implements it.  What are other compilers doing?
>
>
> I happened to be looking into this very recently... Clang implements the ABI
> as currently specified (along with the corresponding miscompiles). However,
> the proposed approach doesn't appear to remove all the miscompiles, for at
> least two reasons:
>
> 1) A parameter can be passed or a return value constructed by calling a
> constructor which is not a copy or move constructor. This can happen when a
> templated constructor is selected:
>
> struct A {
>   A(const A&) = default; // suppress implicit move constructor, still
> trivial
>   template<typename T> A(T &&); // chosen for copies from non-const objects
> and for moves, not a copy constructor nor a move constructor
> };
>
> 2) A parameter can be passed or a return value constructed by
> copy-list-initialization with no copy or move occurring:
>
> struct B {
>   B(int);
>   B(const B&) = delete; // deleted, but still trivial
>   B(B&&) = delete; // likewise
>   B *p = this;
> };
> B f(B x) {
>   return { 1 };
> }
> void g() {
>   f({2});
> }
>
> Both of these cases can lead to miscompiles with both g++ 4.7 and Clang
> trunk due to the ABI's rules. Both problems can also arise for classes with
> no user-declared special members.
>
> The second issue in particular seems unsolvable without a major ABI break or
> a core language change (we cannot pass types in registers if they have any
> non-trivial constructors).

The examples also suggest that in-class non-static data
member initialization is potentially ABI-breaking.

Whatever the changes are, we should not lose efficient
value transfer modes as we have today.

-- Gaby


More information about the cxx-abi-dev mailing list