PING^1: [PATCH] Add TYPE_EMPTY_RECORD for C++ empty class

Marc Glisse marc.glisse@inria.fr
Wed Jan 27 08:10:00 GMT 2016


On Tue, 26 Jan 2016, H.J. Lu wrote:

> On Tue, Jan 26, 2016 at 1:40 PM, Jakub Jelinek <jakub@redhat.com> wrote:
>> On Tue, Jan 26, 2016 at 01:21:52PM -0800, H.J. Lu wrote:
>>> Like this:
>>>
>>> /* Returns true if TYPE is POD for the purpose of layout and an empty
>>>    class or an class with empty classes.  */
>>>
>>> static bool
>>> is_empty_record (tree type)
>>> {
>>>   if (type == error_mark_node)
>>>     return false;
>>>
>>>   if (!CLASS_TYPE_P (type))
>>>     return false;
>>>
>>>   if (CLASSTYPE_NON_LAYOUT_POD_P (type))
>>>     return false;
>>>
>>>   gcc_assert (COMPLETE_TYPE_P (type));
>>>
>>>   if (CLASSTYPE_EMPTY_P (type))
>>>     return true;
>>>
>>>   tree field;
>>>
>>>   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
>>>     if (TREE_CODE (field) == FIELD_DECL
>>>         && !DECL_ARTIFICIAL (field)
>>>         && !is_empty_record (TREE_TYPE (field)))
>>>       return false;
>>>
>>>   return true;
>>> }
>>
>> So you say that K1 in e.g.:
>>
>> struct A1 {}; struct A2 {};
>> struct B1 { A1 a; A2 b; }; struct B2 { A1 a; A2 b; };
>> struct C1 { B1 a; B2 b; }; struct C2 { B1 a; B2 b; };
>> struct D1 { C1 a; C2 b; }; struct D2 { C1 a; C2 b; };
>> struct E1 { D1 a; D2 b; }; struct E2 { D1 a; D2 b; };
>> struct F1 { E1 a; E2 b; }; struct F2 { E1 a; E2 b; };
>> struct G1 { F1 a; F2 b; }; struct G2 { F1 a; F2 b; };
>> struct H1 { G1 a; G2 b; }; struct H2 { G1 a; G2 b; };
>> struct I1 { H1 a; H2 b; }; struct I2 { H1 a; H2 b; };
>> struct J1 { I1 a; I2 b; }; struct J2 { I1 a; I2 b; };
>> struct K1 { J1 a; J2 b; };
>> int v;
>> __attribute__((noinline, noclone))
>> K1 foo (int a, K1 x, int b)
>> {
>>   v = a + b;
>>   return x;
>> }
>> K1 k, m;
>> void
>> bar (void)
>> {
>>   m = foo (1, k, 2);
>> }
>>
>> is empty class?  What does clang do with this?
>>
>>         Jakub
>
> Revised:
>
> /* Returns true if TYPE is POD of one-byte or less in size for the purpose
>   of layout and an empty class or an class with empty classes.  */
>
> static bool
> is_empty_record (tree type)
> {
>  if (type == error_mark_node)
>    return false;
>
>  if (!CLASS_TYPE_P (type))
>    return false;
>
>  if (CLASSTYPE_NON_LAYOUT_POD_P (type))
>    return false;
>
>  gcc_assert (COMPLETE_TYPE_P (type));
>
>  if (CLASSTYPE_EMPTY_P (type))
>    return true;
>
>  if (int_size_in_bytes (type) > 1)
>    return false;

That's completely arbitrary :-(

If we are defining a new ABI, I preferred your previous version (at least 
the idea, I didn't check the code). If we are trying to follow clang, then 
we need either a clear English definition from a clang developer or at 
least someone should check what conditions they use in the code. Trying to 
infer it from a couple examples sounds too fragile for an ABI decision.

>  tree field;
>
>  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
>    if (TREE_CODE (field) == FIELD_DECL
>        && !DECL_ARTIFICIAL (field)
>        && !is_empty_record (TREE_TYPE (field)))
>      return false;
>
>  return true;
> }

-- 
Marc Glisse



More information about the Gcc-patches mailing list