struct A
{
   int i, ar[];
};

int main()
{
   int k = 24;
   struct A a = { 1, 2, 3, 4 };
   int j = 42;
   return a.ar[1];
}

G++ accepts this testcase and happily puts k and j in the same stack
slots as elements of a.ar[], while GCC rejects it.  We shouldn't accept
it.  In any case, we should usually follow the C front end's lead on
this C compatibility feature.

I agree with that approach.  Going forward, after the 6.0 release,
I'd like to get back to this area and fix these remaining problems
and where it makes sense tighten up the C++ requirements to bring
them closer to C's.

But since GCC does allow global/static objects of structs with
flexible array members to be initialized, and (presumably) will
continue to even after the above is rejected in C++, the code
in the patch that detects overflowing such variables will continue
to serve its purpose.  By way of an example, I this is diagnosed
with the patch and should continue to be:

  typedef __typeof__ (sizeof 0) size_t;

  void* operator new (size_t, void *p) { return p; }
  void* operator new[] (size_t, void *p) { return p; }

  struct Ax { char n, a []; } ax = { 1, { 2, 3, 4 } };

  void foo () {
    new (ax.a) short;
    new (ax.a) int;
  }
  t.c:6:51: warning: initialization of a flexible array member [-Wpedantic]
   struct Ax { char n, a []; } ax = { 1, { 2, 3, 4 } };
                                                   ^
  t.c: In function ‘void foo()’:
t.c:10:16: warning: placement new constructing an object of type ‘int’ and size ‘4’ in a region of type ‘char []’ and size ‘3’ [-Wplacement-new=]
       new (ax.a) int;
                  ^~~

That said, I'm interested in improving the -Wplacement-new warning
after 6.0 is done.  But unless there is a problem with the patch,
I would like to (need to) get back to my other projects that have
been put on hold to help with the release.

Martin

PS As an aside, I believe the root cause of the bug in your test
case is the same as in 28865 that was fixed in the C front end
just a couple of years ago by rejecting initialization of auto
variables with flexible array members(*).  An alternate solution
would have been to correct the .size directive to reflect the
size of the object rather than the size of the type and continue
to accept the construct.

[*] GCC in C mode still allows the following which has the same
problem as 28865.

struct A
{
  int i, ar[];
} aa = { 1, 2, 3, 4 };

int main()
{
  int k = 24;
  struct A a = aa;
  int j = 42;
  return a.ar[1];
}

Reply via email to