[cxx-abi-dev] Volatile nonstatic data members
David Vandevoorde
daveed at edg.com
Fri Mar 6 20:40:07 UTC 2015
> On Mar 6, 2015, at 2:52 PM, Richard Smith <richardsmith at googlers.com> wrote:
>
> On 6 March 2015 at 09:35, David Vandevoorde <daveed at edg.com <mailto:daveed at edg.com>> 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…
Daveed
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20150306/31578dfd/attachment.html>
More information about the cxx-abi-dev
mailing list