RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct

H.J. Lu via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 16 13:48:28 PST 2016


On Tue, Feb 16, 2016 at 1:45 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> On Tue, Feb 16, 2016 at 1:21 PM, H.J. Lu <hjl.tools at gmail.com> wrote:
>> On Tue, Feb 16, 2016 at 1:15 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>>> On Tue, Feb 16, 2016 at 1:10 PM, H.J. Lu <hjl.tools at gmail.com> wrote:
>>>> On Tue, Feb 16, 2016 at 1:02 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>>>>> On Tue, Feb 16, 2016 at 12:25 PM, H.J. Lu <hjl.tools at gmail.com> wrote:
>>>>>> On Tue, Feb 16, 2016 at 12:22 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>>>>>>> On Tue, Feb 16, 2016 at 10:24 AM, H.J. Lu <hjl.tools at gmail.com> wrote:
>>>>>>>>
>>>>>>>> On Fri, Feb 12, 2016 at 11:39 AM, H.J. Lu <hjl.tools at gmail.com> wrote:
>>>>>>>> > On Fri, Feb 12, 2016 at 6:58 AM, Matthijs van Duin
>>>>>>>> > <matthijsvanduin at gmail.com> wrote:
>>>>>>>> >> On 11 February 2016 at 16:31, H.J. Lu <hjl.tools at gmail.com> wrote:
>>>>>>>> >>> struct A {
>>>>>>>> >>> static void foo (void) ();
>>>>>>>> >>> static int xxx;
>>>>>>>> >>> };
>>>>>>>> >>
>>>>>>>> >> What about it? It's an empty struct.  (And it declares a function and
>>>>>>>> >> a variable in the namespace of A, which however do not have any
>>>>>>>> >> relevant impact here.)
>>>>>>>> >>
>>>>>>>> >
>>>>>>>> > Thanks for all the feedbacks.  Here is the new proposal:
>>>>>>>> >
>>>>>>>> > 1. "empty type".  An empty type is a trivially-copyable aggregate
>>>>>>>> > occupying zero bytes (excluding any padding).
>>>>>>>> > 2. No memory slot nor register should be used to pass or return an object
>>>>>>>> > of empty type.
>>>>>>>> >
>>>>>>>> > Footnote: Array of empty type can only passed by reference in C/C++.
>>>>>>>> >
>>>>>>>>
>>>>>>>> I updated intel386, x86-64 and IA MCU psABIs:
>>>>>>>>
>>>>>>>> https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
>>>>>>>>
>>>>>>>> to specify:
>>>>>>>>
>>>>>>>> Empty type is defined as a trivially-copyable aggregate occupying zero bytes
>>>>>>>> (excluding any padding).
>>>>>>>
>>>>>>> I think this is now extremely unclear. Does an empty struct in C++
>>>>>>> occupy zero bytes? sizeof applied to it will produce at least 1.
>>>>>>
>>>>>> Can it be considered as padding?
>>>>>
>>>>> Perhaps, but I would contend that that's unclear in at least some
>>>>> cases (when the class is used as the type of a member, ...). What
>>>>> about this case:
>>>>>
>>>>>   struct X { unsigned : 15; };
>>>>>
>>>>> Is that empty or not? Do we have a formal definition somewhere of what
>>>>> does, and does not, count as padding?
>>>>
>>>> How about this?
>>>>
>>>> Empty type is defined as a trivially-copyable aggregate occupying zero bytes
>>>> (excluding any padding or contributing zero bytes to the size of derived
>>>> classes in C++).
>>>>
>>>> This will cover
>>>>
>>>> struct dummy0
>>>> {
>>>>   void bar (void);
>>>> };
>>>> struct dummy1
>>>> {
>>>>   void foo (void);
>>>> };
>>>> struct dummy : dummy0, dummy1 { };
>>>>
>>>> But not
>>>>
>>>> struct dummy0
>>>> {
>>>> };
>>>> struct dummy1
>>>> {
>>>>   unsigned : 15;
>>>> };
>>>> struct dummy : dummy0, dummy1
>>>> {
>>>> };
>>>
>>> Why not? That looks empty to me. The ABI will classify the
>>> corresponding eightbyte as NO_CLASS, as it has no members, so it
>>> should not be passed.
>>
>> Do you have a wording to describe it?
>
> Yes, something like what you had before was fine:
>
>   "empty type". An empty type is a type where it and all of its
> subobjects (recursively) are of class, structure, union, or array
> type.
>
> Or, if you think it makes the intent clearer, reverse the sense:
>
>   A type is non-empty if it or any subobject (recursively) is of any
> type other than class, structure, union, or array type.

Does the above cover

struct dummy0
{
  void bar (void);
};
struct dummy1
{
  void foo (void);
};
struct dummy : dummy0, dummy1 { };

> If you like, you could add notes that a parameter type is never an
> array type, and that unnamed bit-fields are not subobjects, but they
> seem redundant given the wording of the relevant standards. (You don't
> need to say anything about "POD for the purpose of layout", or
> destructors, or whatever else, because the C++ ABI only delegates to
> the C psABI for cases that are valid to pass in registers from a C++
> language semantics point of view.)



-- 
H.J.


More information about the cfe-commits mailing list