> On Mar 6, 2015, at 4:32 PM, Richard Smith <[email protected]> wrote:
>
> On 6 March 2015 at 12:40, David Vandevoorde <[email protected]
> <mailto:[email protected]>> wrote:
>> On Mar 6, 2015, at 2:52 PM, Richard Smith <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> On 6 March 2015 at 09:35, David Vandevoorde <[email protected]
>> <mailto:[email protected]>> wrote:
>> At some point, the C++ standard changed to cause volatile nonstatic data
>> members to make a generated copy/move constructor nontrivial.
>>
>> To save anyone else looking, this was
>> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#496
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#496>
>>
>> Unfortunately, that would change the parameter passing mechanism if we stuck
>> to letter of the ABI; see 3.1.1/1:
>>
>> 1. In the special case where the parameter type has a non-trivial copy
>> constructor or destructor, the caller must allocate space
>> for a temporary copy, and pass the resulting copy by reference (below).
>> Specifically, ...
>>
>> AFAICT, recent versions of GCC and Clang do implement the language aspects
>> of nontriviality of copy/move constructors in such cases (e.g., causing
>> union constructors to become deleted), but not this ABI aspect of it.
>>
>> Clang does not implement this (http://clang.llvm.org/cxx_dr_status.html#496
>> <http://clang.llvm.org/cxx_dr_status.html#496>); I'm not sure about GCC
>> trunk. We still accept
>>
>> struct A { volatile int v; };
>> union U { A a; };
>> extern U u1;
>> U u2(u1);
>>
>> (for example).
>
>
> Ah yes, I misinterpreted Clang/GCC behavior because I was using a volatile
> _class_ type. Even there, though (as illustrated by the example below),
> there is an ABI breakage lurking, I think.
>
>
>>
>> For example:
>>
>> typedef struct { int value; } TypeA;
>> typedef struct { TypeA volatile value; } TypeB;
>> typedef struct { TypeA value; } TypeC;
>>
>> int foo(TypeB p) { return p.value.value; }
>> int foo(TypeC p) { return p.value.value; }
>>
>> Identical code is being generated for these two definitions of foo, even
>> though TypeB has a nontrivial copy constructor and TypeC has a trivial copy
>> constructor.
>>
>> If that is right, should the 3.1.1/1 words above be edited to read:
>>
>> 1. In the special case where the parameter type has a non-trivial copy
>> constructor (with the exception of a generated copy constructor that is
>> nontrivial only because one or more nonstatic data member are trivial) or
>> destructor, the caller must allocate space for a temporary copy,
>> and pass the resulting copy by reference (below). Specifically, ...
>>
>> ?
>>
>> No strong preference here, but...
>>
>> Do you have any feeling about how much code would be broken if we don't do
>> this? If we were starting from a clean sheet, I think I'd prefer the rule as
>> it is (volatile subobjects prevent a class from being passed in registers),
>> so if this doesn't actually happen in practice, I'd prefer for us to leave
>> the ABI alone.
>
> I don’t have a strong sense, but we have one customer that ran into this (and
> that’s only for the class type case, we don’t implement 496 either yet).
>
> And it’s also a C-ABI compatibility issue…
>
> The proposed ABI change would be non-conforming even under the proposed
> resolution of
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1590
> <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1590>, because
> we are not permitted to make additional technical copies of a parameter
> unless it has a trivial copy/move constructor. Consider:
>
> struct A { A *volatile p = this; };
> void f(A a) { assert(&a == a.p); }
> int main() { f({}); }
>
Ow!
> We are not permitted to fabricate an extra copy of the A object here because
> its constructor is non-trivial. Thus the assertion must not fail, and we
> cannot pass the object in registers.
>
> I see three ways out: extend 1590 to also include this "volatile members
> don't count" clause, or allow a constructor to make an additional copy of a
> parameter object in all cases of copy-initialization, or revert the
> resolution of 496.
>
> Reverting 496 seems most palatable to me right now, but in any case this
> seems like something for CWG to decide rather than something for us to work
> around in the ABI.
Agreed.
Daveed
_______________________________________________
cxx-abi-dev mailing list
[email protected]
http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev