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

            Bug ID: 69338
           Summary: incorrect ctor initialization of a flexible array
                    member
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

While working on a fix for bug 69253 I noticed an outstanding problem with
flexible array members that I don't think is being tracked yet.  This is most
likely post-6.0 material.

G++ accepts but doesn't correctly initialize flexible array members in ctor
initializer lists.  5.1 accepts the code below with -fpermissive but eliminates
the initialization in all cases.  At least it issues "warning:
initializer-string for array of chars is too long" pointing out the problem.

6.0 accepts the same code even without -fpermissive (this was changed in
response to bug 68490) and doesn't issue a diagnostic in any of the four cases.
 It gets the aggregate ctor initialization right (again, as a result of a fix
for bug 68490) but it still discards the initializer in the ctor initializer
list.

The ctor initialization should either be rejected if the initialization is not
honored or the initializers should be copied.

As a data point, Clang rejects everything.

$ cat a.c && ~/bin/gcc-5.1.0/bin/g++ -Wall -Wextra -Wpedantic -fpermissive a.c
&& ./a.out
struct A { char i, a[]; };

struct A a1 = { 3, "AB" };                  // wrong in 5, okay in 6
struct A a2 = (struct A){ 3, "AB" };        // wrong in 5, okay in 6

struct B1 {
    A a3;
    B1 (): a3 { 3, "AB" } { }               // wrong in 5 and 6
} b1;

struct B2 {
    A a4;
    B2 (): a4 ((struct A){ 3, "AB" }) { }   // wrong in 5 and 6
} b2;

int main ()
{
#define PA(x) \
    __builtin_printf ("%i, { %i, %i, %i }\n", \
                      x.i, x.a[0], x.a[1], x.a[2])

  PA (a1);
  PA (a2);
  PA (b1.a3);
  PA (b2.a4);
}

a.c:1:22: warning: ISO C++ forbids zero-size array ‘a’ [-Wpedantic]
 struct A { char i, a[]; };
                      ^
a.c:3:25: warning: initializer-string for array of chars is too long
[-fpermissive]
 struct A a1 = { 3, "AB" };
                         ^
a.c:4:35: warning: ISO C++ forbids compound-literals [-Wpedantic]
 struct A a2 = (struct A){ 3, "AB" };
                                   ^
a.c:4:35: warning: initializer-string for array of chars is too long
[-fpermissive]
a.c: In constructor ‘B1::B1()’:
a.c:8:15: warning: extended initializer lists only available with -std=c++11 or
-std=gnu++11
     B1 (): a3 { 3, "AB" } { }
               ^
a.c:8:25: warning: initializer-string for array of chars is too long
[-fpermissive]
     B1 (): a3 { 3, "AB" } { }
                         ^
a.c: In constructor ‘B2::B2()’:
a.c:13:36: warning: ISO C++ forbids compound-literals [-Wpedantic]
     B2 (): a4 ((struct A){ 3, "AB" }) { }
                                    ^
a.c:13:36: warning: initializer-string for array of chars is too long
[-fpermissive]
3, { 3, 0, 3 }
3, { 0, 3, 3 }
3, { 3, 0, 0 }
3, { 0, 0, 0 }



$ /home/msebor/build/gcc-trunk-svn/gcc/xgcc
-B/home/msebor/build/gcc-trunk-svn/gcc -Wall -Wextra -Wpedantic -fpermissive
-xc++ a.c && ./a.out
a.c:3:25: warning: initialization of a flexible array member [-Wpedantic]
 struct A a1 = { 3, "AB" };
                         ^

a.c:4:35: warning: ISO C++ forbids compound-literals [-Wpedantic]
 struct A a2 = (struct A){ 3, "AB" };
                                   ^

a.c:4:35: warning: initialization of a flexible array member [-Wpedantic]
a.c: In constructor ‘B1::B1()’:
a.c:8:25: warning: initialization of a flexible array member [-Wpedantic]
     B1 (): a3 { 3, "AB" } { }
                         ^

a.c: In constructor ‘B2::B2()’:
a.c:13:36: warning: ISO C++ forbids compound-literals [-Wpedantic]
     B2 (): a4 ((struct A){ 3, "AB" }) { }
                                    ^

a.c:13:36: warning: initialization of a flexible array member [-Wpedantic]
3, { 65, 66, 0 }
3, { 65, 66, 0 }
3, { 3, 0, 0 }
3, { 0, 0, 0 }

Reply via email to