PR c++/78039 - fails to compile glibc tests
gcc/cp/ChangeLog:
2016-10-21 Martin Sebor <msebor@redhat.com>
PR c++/78039
* class.c (diagnose_flexarrays): Avoid rejecting an invalid flexible
array member with a hard error when it is followed by anbother member
in a different struct, and instead issue just a pedantic warning.
gcc/testsuite/ChangeLog:
2016-10-21 Martin Sebor <msebor@redhat.com>
PR c++/78039
* g++.dg/ext/flexary18.C: New test.
* g++.dg/ext/flexary19.C: New test.
===================================================================
@@ -6960,7 +6960,20 @@ diagnose_flexarrays (tree t, const flexmems_t *fme
location_t loc = DECL_SOURCE_LOCATION (fmem->array);
diagd = true;
- error_at (loc, msg, fmem->array, t);
+ /* For compatibility with GCC 6.2 and 6.1 reject with an error
+ a flexible array member of a plain struct that's followed
+ by another member only if they are both members of the same
+ struct. Otherwise, issue just a pedantic warning. See bug
+ 71375 for details. */
+ if (fmem->after[0]
+ && (!TYPE_BINFO (t)
+ || 0 == BINFO_N_BASE_BINFOS (TYPE_BINFO (t)))
+ && DECL_CONTEXT (fmem->array) != DECL_CONTEXT (fmem->after[0])
+ && !ANON_AGGR_TYPE_P (DECL_CONTEXT (fmem->array))
+ && !ANON_AGGR_TYPE_P (DECL_CONTEXT (fmem->after[0])))
+ pedwarn (loc, OPT_Wpedantic, msg, fmem->array, t);
+ else
+ error_at (loc, msg, fmem->array, t);
/* In the unlikely event that the member following the flexible
array member is declared in a different class, or the member
===================================================================
@@ -0,0 +1,213 @@
+// PR c++/71912 - [6/7 regression] flexible array in struct in union rejected
+// { dg-do compile }
+// { dg-additional-options "-Wpedantic -Wno-error=pedantic" }
+
+#if __cplusplus
+
+namespace pr71912 {
+
+#endif
+
+struct foo {
+ int a;
+ char s[]; // { dg-message "array member .char pr71912::foo::s \\\[\\\]. declared here" }
+};
+
+struct bar {
+ double d;
+ char t[];
+};
+
+struct baz {
+ union {
+ struct foo f;
+ struct bar b;
+ }
+ // The definition of struct foo is fine but the use of struct foo
+ // in the definition of u below is what's invalid and must be clearly
+ // diagnosed.
+ u; // { dg-warning "invalid use of .struct pr71912::foo. with a flexible array member in .struct pr71912::baz." }
+};
+
+struct xyyzy {
+ union {
+ struct {
+ int a;
+ char s[]; // { dg-message "declared here" }
+ } f;
+ struct {
+ double d;
+ char t[];
+ } b;
+ } u; // { dg-warning "invalid use" }
+};
+
+struct baz b;
+struct xyyzy x;
+
+#if __cplusplus
+
+}
+
+#endif
+
+// The following definitions aren't strictly valid but, like those above,
+// are accepted for compatibility with GCC (in C mode). They are benign
+// in that the flexible array member is at the highest offset within
+// the outermost type and doesn't overlap with other members except for
+// those of the union.
+union UnionStruct1 {
+ struct { int n1, a[]; } s;
+ int n2;
+};
+
+union UnionStruct2 {
+ struct { int n1, a1[]; } s1;
+ struct { int n2, a2[]; } s2;
+ int n3;
+};
+
+union UnionStruct3 {
+ struct { int n1, a1[]; } s1;
+ struct { double n2, a2[]; } s2;
+ char n3;
+};
+
+union UnionStruct4 {
+ struct { int n1, a1[]; } s1;
+ struct { struct { int n2, a2[]; } s2; } s3;
+ char n3;
+};
+
+union UnionStruct5 {
+ struct { struct { int n1, a1[]; } s1; } s2; // { dg-warning "invalid use" }
+ struct { double n2, a2[]; } s3;
+ char n3;
+};
+
+union UnionStruct6 {
+ struct { struct { int n1, a1[]; } s1; } s2; // { dg-warning "invalid use" }
+ struct { struct { int n2, a2[]; } s3; } s4;
+ char n3;
+};
+
+union UnionStruct7 {
+ struct { int n1, a1[]; } s1;
+ struct { double n2, a2[]; } s2;
+ struct { struct { int n3, a3[]; } s3; } s4;
+};
+
+union UnionStruct8 {
+ struct { int n1, a1[]; } s1;
+ struct { struct { int n2, a2[]; } s2; } s3;
+ struct { struct { int n3, a3[]; } s4; } s5;
+};
+
+union UnionStruct9 {
+ struct { struct { int n1, a1[]; } s1; } s2; // { dg-warning "invalid use" }
+ struct { struct { int n2, a2[]; } s3; } s4;
+ struct { struct { int n3, a3[]; } s5; } s6;
+};
+
+struct StructUnion1 {
+ union {
+ struct { int n1, a1[]; } s1; // { dg-message "declared here" }
+ struct { double n2, a2[]; } s2;
+ char n3;
+ } u; // { dg-warning "invalid use" }
+};
+
+// The following are invalid and rejected.
+struct StructUnion2 {
+ union {
+ struct { int n1, a1[]; } s1; // { dg-warning "not at end" }
+ } u;
+ char n3; // { dg-message "next member" }
+};
+
+struct StructUnion3 {
+ union {
+ struct { int n1, a1[]; } s1; // { dg-warning "not at end" }
+ struct { double n2, a2[]; } s2;
+ } u;
+ char n3; // { dg-message "next member" }
+};
+
+struct StructUnion4 {
+ union {
+ struct { int n1, a1[]; } s1; // { dg-warning "not at end" }
+ } u1;
+ union {
+ struct { double n2, a2[]; } s2;
+ } u2; // { dg-message "next member" }
+};
+
+struct StructUnion5 {
+ union {
+ union {
+ struct { int n1, a1[]; } s1; // { dg-message "declared here" }
+ } u1;
+ union { struct { int n2, a2[]; } s2; } u2;
+ } u; // { dg-warning "invalid use" }
+};
+
+struct StructUnion6 {
+ union {
+ struct { int n1, a1[]; } s1; // { dg-message "declared here" }
+ union { struct { int n2, a2[]; } s2; } u2;
+ } u; // { dg-warning "invalid use" }
+};
+
+struct StructUnion7 {
+ union {
+ union {
+ struct { double n2, a2[]; } s2; // { dg-message "declared here" }
+ } u2;
+ struct { int n1, a1[]; } s1;
+ } u; // { dg-warning "invalid use" }
+};
+
+struct StructUnion8 {
+ struct {
+ union {
+ union {
+ struct { int n1, a1[]; } s1; // { dg-warning "not at end" }
+ } u1;
+ union {
+ struct { double n2, a2[]; } s2;
+ } u2;
+ } u;
+ } s1;
+
+ struct {
+ union {
+ union {
+ struct { int n1, a1[]; } s1;
+ } u1;
+ union {
+ struct { double n2, a2[]; } s2;
+ } u2;
+ } u; } s2; // { dg-message "next member" }
+};
+
+struct StructUnion9 { // { dg-message "in the definition" }
+ struct A1 {
+ union B1 {
+ union C1 {
+ struct Sx1 { int n1, a1[]; } sx1; // { dg-warning "not at end" }
+ } c1;
+ union D1 {
+ struct Sx2 { double n2, a2[]; } sx2;
+ } d1;
+ } b1; // { dg-warning "invalid use" }
+ } a1;
+
+ struct A2 {
+ union B2 {
+ union C2 {
+ struct Sx3 { int n3, a3[]; } sx3; // { dg-message "declared here" }
+ } c2;
+ union D2 { struct Sx4 { double n4, a4[]; } sx4; } d2;
+ } b2; // { dg-warning "invalid use" }
+ } a2; // { dg-message "next member" }
+};
===================================================================
@@ -0,0 +1,343 @@
+// { dg-do compile }
+// { dg-additional-options "-Wpedantic -Wno-error=pedantic" }
+
+// Verify that flexible array members are recognized as either valid
+// or invalid in anonymous structs (a G++ extension) and C++ anonymous
+// unions as well as in structs and unions that look anonymous but
+// aren't.
+struct S1
+{
+ int i;
+
+ // The following declares a named data member of an unnamed struct
+ // (i.e., it is not an anonymous struct).
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } s;
+};
+
+struct S2
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } s[1];
+};
+
+struct S3
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } s[];
+};
+
+struct S4
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } s[2];
+};
+
+struct S5
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } s[1][2];
+};
+
+struct S6
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } s[][2];
+};
+
+struct S7
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } *s;
+};
+
+struct S8
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } **s;
+};
+
+struct S9
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } *s[1];
+};
+
+struct S10
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } *s[];
+};
+
+struct S11
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } **s[1];
+};
+
+struct S12
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } **s[];
+};
+
+struct S13
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } **s[2];
+};
+
+struct S14
+{
+ int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } &s;
+};
+
+struct S15
+{
+ int i;
+
+ typedef struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } T15;
+};
+
+struct S16
+{
+ int i;
+
+ struct { // { dg-warning "invalid use" }
+ // A flexible array as a sole member of an anonymous struct is
+ // rejected with an error in C mode but emits just a pedantic
+ // warning in C++. Other than excessive pedantry there is no
+ // reason to reject it.
+ int a[];
+ }; // { dg-warning "anonymous struct" }
+};
+
+struct S17
+{
+ int i;
+
+ union { // anonymous union
+ int a[]; // { dg-error "flexible array member in union" }
+ };
+};
+
+struct S18
+{
+ int i;
+
+ struct {
+ int j, a[]; // { dg-message "declared here" }
+ } s; // { dg-warning "invalid use" }
+};
+
+struct S19
+{
+ int i;
+
+ struct { // { dg-warning "invalid use" }
+ int j, a[]; // { dg-message "declared here" }
+ }; // { dg-warning "anonymous struct" }
+};
+
+struct S20
+{
+ static int i;
+ typedef int A[];
+
+ struct {
+ int j;
+ A a; // { dg-message "declared here" }
+ } s; // { dg-warning "invalid use" }
+};
+
+struct S21
+{
+ static int i;
+ typedef int A[];
+
+ struct { // { dg-warning "invalid use" }
+ int j;
+ A a; // { dg-message "declared here" }
+ }; // { dg-warning "anonymous struct" }
+};
+
+struct S22
+{
+ struct S22S {
+ static int i;
+
+ int a[]; // { dg-error "in an otherwise empty" }
+ } s;
+};
+
+struct S23
+{
+ struct {
+ static int i; // { dg-error "static data member" }
+
+ int a[]; // { dg-error "in an otherwise empty" }
+ }; // { dg-warning "anonymous struct" }
+};
+
+struct S24
+{
+ static int i;
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } s;
+};
+
+struct S25
+{
+ int i;
+
+ struct {
+ int j, a[]; // { dg-message "declared here" }
+ } s; // { dg-warning "invalid use" }
+
+ // Verify that a static data member of the enclosing class doesn't
+ // cause infinite recursion or some such badness.
+ static S25 s2;
+};
+
+struct S26
+{
+ template <class>
+ struct S26S {
+ static int a;
+ };
+
+ struct {
+ int a[]; // { dg-error "in an otherwise empty" }
+ } s;
+};
+
+struct S27
+{
+ S27 *p;
+ int a[];
+};
+
+struct S28
+{
+ struct A {
+ struct B {
+ S28 *ps28;
+ A *pa;
+ B *pb;
+ } b, *pb;
+ A *pa;
+ } a, *pa;
+
+ S28::A *pa2;
+ S28::A::B *pb;
+
+ int flexarray[];
+};
+
+// Verify that the notes printed along with the warnings point to the types
+// or members they should point to and mention the correct relationships
+// with the flexible array members.
+namespace Notes
+{
+union A
+{
+ struct {
+ struct {
+ int i, a[]; // { dg-message "declared here" }
+ } c; // { dg-warning "invalid use" }
+ } d;
+ int j;
+};
+
+union B
+{
+ struct {
+ struct { // { dg-warning "invalid use" }
+ int i, a[]; // { dg-message "declared here" }
+ }; // { dg-warning "anonymous struct" }
+ }; // { dg-warning "anonymous struct" }
+ int j;
+};
+
+}
+
+typedef struct Opaque* P29;
+struct S30 { P29 p; };
+struct S31 { S30 s; };
+
+typedef struct { } S32;
+typedef struct { S32 *ps32; } S33;
+typedef struct
+{
+ S33 *ps33;
+} S34;
+
+struct S35
+{
+ struct A {
+ int i1, a1[];
+ };
+
+ struct B {
+ int i2, a2[];
+ };
+
+ typedef struct {
+ int i3, a3[];
+ } C;
+
+ typedef struct {
+ int i4, a4[];
+ } D;
+
+ typedef A A2;
+ typedef B B2;
+ typedef C C2;
+ typedef D D2;
+};
+