> 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

Reply via email to