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

On Tue, Jan 26, 2016 at 1:40 PM, Jakub Jelinek <ja...@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

Reply via email to