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

Richard Smith richardsmith at google.com
Wed May 7 18:35:05 UTC 2014


On 7 May 2014 11:23, "John McCall" <rjmccall at apple.com> wrote:
>
> On May 7, 2014, at 12:11 AM, Richard Smith <richardsmith at google.com>
wrote:
>>
>> On 6 May 2014 19:57, Jason Merrill <jason at redhat.com> wrote:
>>>
>>> On 05/06/2014 09:31 PM, Richard Smith wrote:
>>>>
>>>> The core language part of this (core issue 1590) is now in 'ready'
>>>> status. Time to go ahead with the corresponding ABI change?
>>>
>>>
>>> On 11/26/2012 04:09 PM, Richard Smith wrote:> Suggestion for Itanium >
Suggestion for Itanium ABI:
>>>
>>>>
>>>> [parameters and return values are passed by address if] the type has a
non-trivial copy constructor, move constructor or destructor, or if neither
the copy constructor nor the move constructor is public and non-deleted.
>>>
>>>
>>> I disagree with the latter part of this; passing by invisible reference
should based on triviality, not on callability.
>>
>>
>> I think it would be *extremely* surprising if we implicitly added a call
to a function that is deleted or inaccessible, that the original code
didn't call. What alternative do you suggest?
>>
>> Backstory:
>>
>> struct A {
>>   A(void*);
>>   A(const A&) = delete;
>>   A(A&&) = default;
>>   void *p;
>> };
>>
>> Here, A should "obviously" be passed by value, not by pointer (you don't
want to pass unique_ptr indirectly). And here we have a trivial copy ctor,
a trivial deleted move ctor, and a trivial dtor. But if the copy ctor is
*also* deleted:
>>
>> struct B {
>>   B(void*);
>>   B(const B&) = delete;
>>   B(B&&) = delete;
>>   void *p;
>> };
>>
>> ... then I think it's equally obvious that this should *not* be passed
by value, and must be passed by "invisible reference". Eg:
>>
>>   B::B(void*) : p(this) {}
>>   void f(B b) { assert(b.p == &b); } // this assert should hold!
>>   int main() { f({0}); }
>>
>> The only difference between these two is whether the copy ctor is
deleted (it's trivial either way). So it seems to me that we /must/
consider that.
>>
>> Access checking probably doesn't have as compelling a story, but as with
deletedness checking, the fundamental point seems to be that we should not
implicitly *add* a call to a function that the code in question couldn't
originally call.
>
>
> I continue to think that making the ABI dependent on access control is
not a good idea.  I agree that it’s problematic that this means we might
use a private copy constructor, but frankly, I’m a lot less worried about
violating the standard in this corner case than I am about making the ABI
dependent on access control.
>
> I’d be okay with the rule “if the type has a non-trivial copy
constructor, move constructor, or destructor, or if all its copy and move
constructors are declared as deleted”.

I could live with that (but the currently-proposed language change doesn't
allow it; we'd need to remove the accessibility check there). Drop the
"declared as", though - I don't think it should matter how the functions
came to be deleted.

I think I'd also prefer to phrase this in a way that's not dependent on
whether a deleted function is trivial.

"[Pass an object of class type by value if] every copy constructor and move
constructor is deleted or trivial and at least one of them is not deleted,
and the destructor is trivial."
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20140507/253381e0/attachment-0001.html>


More information about the cxx-abi-dev mailing list