Handling of flexible arrays vs. old-style zero-length arrays.

Hi all,

If I pass the following code to clang:

// ---
struct A {
  int a0[];
};

struct B : public A {
  int b;
};
// ---

the compiler emits the following error:
"error: base class 'A' has a flexible array member".
I guess that is expected because (quoting the comment in
Sema/SemaDeclCXX) a class which contains a flexible array member is
not suitable for use as a base class.

However, if I replace the flexible array declaration in 'struct A'
with another flexible array declaration where the array length is
explicitly set to zero, then the compiler no longer emits an error
(see below).

// ---
struct A {
  int a0[0];
};

struct B : public A { // no error reported.
  int b;
};
// ---

Shouldn't the compiler error in this case as well?

Also, if B is a non-POD type, then clang asserts in
CGRecordLayoutBuilder.cpp within method 'clipTailPadding'.
In the attempt to lowering B, it triggers the assertion failure
(around line 525):
'Prior->Kind == MemberInfo::Field && !Prior->FD && "Only storage
fields have tail padding!'.

{reproducible}
// ---
struct A {
  int a0[0];
};

struct B : private A { // assertion failure!
  int b;
};
// ---
{end-of-reproducible}

(I plan to raise a bug for this one).

In Sema/SemaDeclCXX.cpp we check if
'CXXBaseDecl>hasFlexibleArrayMember()' and in case, we emit a
diagnostic error.
Should clang also check if the code is using a zero-length array
declaration and in case emit an error?

Thanks,
-Andrea

This is the correct reproducible for the assertion failure.

// ---
struct A {
  int a0[0];
};

struct B : private A { // assertion failure!
  int b;
};

B bb;
// ---