[Bug c++/88578] New: Static C++ objects with flexible array members overlap when initializes are non-const

bernd.edlinger at hotmail dot de gcc-bugzilla@gcc.gnu.org
Sat Dec 22 18:34:00 GMT 2018


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88578

            Bug ID: 88578
           Summary: Static C++ objects with flexible array members overlap
                    when initializes are non-const
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bernd.edlinger at hotmail dot de
  Target Milestone: ---

A modified version of flexary13.C fails an assertion when compiled with -O0

$ cat flexary13.C
// { dg-do compile }
// { dg-options -Wno-pedantic }

#define STR(s) #s
#define ASSERT(exp) \
  ((exp) ? (void)0 : (void)(__builtin_printf ("%s:%i: assertion %s failed\n", \
                     __FILE__, __LINE__, STR(exp)), \
                      __builtin_abort ()))

struct Ax { int n, a[]; };
struct AAx { int i; Ax ax; };

int i = 12345678;

int main ()
{
  {
    Ax s = { 0 };
    ASSERT (s.n == 0);
  }
  {
    static Ax s =
      { 0, { } };   // dg-warning "initialization of a flexible array member" }
    ASSERT (s.n == 0);
  }
  {
    static Ax s =
      { 1, { 2 } };   // dg-warning "initialization of a flexible array member"
}
    ASSERT (s.n == 1 && s.a [0] == 2);
  }
  {
    static Ax s =
      { 2, { 3, 4 } }; // dg-warning "initialization of a flexible array
member" }
    ASSERT (s.n = 2 && s.a [0] == 3 && s.a [1] == 4);
  }
  {
    static Ax s =
      { 123, i };   // dg-warning "initialization of a flexible array member" }
    ASSERT (s.n == 123 && s.a [0] == i);
  }
  {
    static Ax s =
      { 456, { i } }; // dg-warning "initialization of a flexible array member"
}
    ASSERT (s.n == 456 && s.a [0] == i);
  }
  {
    int j = i + 1, k = j + 1;
    static Ax s =
      { 3, { i, j, k } }; // dg-warning "initialization of a flexible array
member" }
    ASSERT (s.n == 3 && s.a [0] == i && s.a [1] == j && s.a [2] == k);
  }

  {
    AAx s =
      { 1, { 2 } };   // dg-warning "initialization of a flexible array member"
}
    ASSERT (s.i == 1 && s.ax.n == 2);
  }
}
$ g++ -O0 flexary13.C
$ ./a.out
flexary13.C:44: assertion s.n == 456 && s.a [0] == i failed
Aborted (core dumped)

debugging shows that s.n == 12345678
reason is that in the case where flexible array members are initialized
with non-constant values (a C++ extension over C which rejects such code)

The static objects are allocated without the flexible part:
_ZZ4mainE1s_2:
        .long   123
        .local  _ZGVZ4mainE1s_2
        .comm   _ZGVZ4mainE1s_2,8,8
        .align 4
        .type   _ZZ4mainE1s_3, @object
        .size   _ZZ4mainE1s_3, 4
_ZZ4mainE1s_3:
        .long   456
        .local  _ZGVZ4mainE1s_3
        .comm   _ZGVZ4mainE1s_3,8,8
        .align 4
        .type   _ZZ4mainE1s_4, @object
        .size   _ZZ4mainE1s_4, 4

In higher optimization levels the objects still overlap,
but the assertion does not fire, which probably indicates
that it is ineffective (optimized away).


More information about the Gcc-bugs mailing list