This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 2/3] Avoid creating an initializer for a flexible array member


On 12/31/2015 08:40 AM, Patrick Palka wrote:
If we do create such an initializer, we end up with an error_mark_node
during gimplification, because in cp-gimplify.c we pass this
VEC_INIT_EXPR of the flexible array member to build_vec_init, for which
it spits on an error_mark_node.  This happens in e.g. the test case
g++.dg/ext/array1.C.

This patch makes it so that we avoid generating an initializer for a
flexible array member, thus avoiding to end up with an error_mark_node
during gimplification.  The same kind of thing is done ~90 lines down
from the code I changed.

I don't think this change is correct (or complete).  We could
decide that the kind of code it's meant to allow should be
accepted in general but if we did, this change alone would not
be sufficient.

In the way of background, the existing special treatment for
flexible array members was added to prevent rejecting cases
like this one:

  struct A { A (int); };
  struct B {
      B ();
      int n;
      A a[];
  };

Since B's ctor above doesn't initialize the flexible array
member it's well-formed.  Ditto if B's ctor is defined but
avoids initializing B::a.

The proposed change has the effect of also accepting the
following modified version of the example above that is
currently rejected:

  struct A { A (int); };
  struct B {
      B (): n (), a () { }
      int n;
      A a[];
  };

In this modified example, B's ctor attempts to default-initialize
the flexible array member and its elements using their respective
default ctors even though no such ctor for the latter exists.

Since C++ flexible array members are a GCC extension whose C++
specific aspects are essentially undocumented it's open to
discussion whether or not code like this should be accepted.
Clang rejects it, but one could make the argument that since
the flexible array member has no elements, default initializing
it should be allowed even if the same initialization would be
ill-formed if the array wasn't empty.

If the code should be accepted as written above then it should
also be accepted if B's ctor were omitted or defaulted. I.e.,
the following should be treated the same as the above:

  struct A { A (int); };
  struct B {
      // ditto with B() = default;
      int n;
      A a[];
  } b;

The patch doesn't handle either of these cases and the code
is rejected both with and without it.

Martin

PS While looking at this I experimented with zero-length
arrays to see if they might serve as a precedent.
Unfortunately, I discovered that those aren't currently
handled entirely consistently either.  I opened bug 69127
with the details.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]