[cxx-abi-dev] Transfer modes for parameters and return values
John McCall
rjmccall at apple.com
Wed May 7 18:23:29 UTC 2014
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”.
John.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20140507/fbcf8319/attachment.html>
More information about the cxx-abi-dev
mailing list