blob: b31e84b5fce81760a1ef208728d67273b0f86837 [file] [log] [blame]
// { dg-do compile }
// { dg-options "-Wpedantic -Wno-error=pedantic" }
#include "flexary.h"
struct Sx {
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
};
// Verify that non-data members or static data members either before
// or after a zero-length array in an otherwise empty struct don't
// suppress the diagnostic.
struct Sx2 {
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
typedef int I;
};
struct Sx3 {
typedef int I;
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
};
struct Sx4 {
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
enum E { e };
};
struct Sx5 {
enum E { e };
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
};
struct Sx6 {
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
static int i;
};
struct Sx7 {
static int i;
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
};
struct Sx8 {
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
Sx8 () { }
};
struct Sx9 {
Sx9 () { }
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
};
struct Sx10 {
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
virtual ~Sx10 () { }
};
struct Sx11 {
virtual ~Sx11 () { }
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
};
struct Sx12 {
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
virtual void foo () = 0;
};
struct Sx13 {
virtual void foo () = 0;
int a[0]; // { dg-warning "zero-size|in an otherwise empty" }
};
struct Sx14 {
int a[0][1]; // { dg-warning "zero-size|in an otherwise empty" }
};
struct Sx15 {
typedef int A[0]; // { dg-warning "zero-size" }
A a; // { dg-warning "in an otherwise empty" }
};
// Verify also that a zero-size array doesn't suppress the diagnostic.
struct Sx16 {
int a_0 [0]; // { dg-warning "zero-size|in an otherwise empty" }
int a_x [0]; // { dg-warning "zero-size array" }
};
struct Sx17 {
int a_x [0]; // { dg-warning "zero-size|in an otherwise empty" }
int a_0 [0]; // { dg-warning "zero-size array" }
};
// Empty structs are a GCC extension that (in C++ only) is treated
// as if it had a single member of type char. Therefore, a struct
// containing a zero-length array followed by an empty struct
// is diagnosed to prevent the former subobject from sharing space
// with the latter.
struct Sx18 {
int a_x [0]; // { dg-warning "zero-size array" }
struct S { };
};
// Anonymous structs and unions are another GCC extension. Since
// they cannot be named and thus used to store the size of a zero
// length array member, a struct containing both is diagnosed as
// if the zero-length array appeared alone.
struct Sx19 {
struct S { };
union U { };
int a_x [0]; // { dg-warning "zero-size|in an otherwise empty" }
};
// Unlike in the case above, a named member of an anonymous struct
// prevents a subsequent zero-length array from being diagnosed.
struct Sx20 {
struct S { } s;
int a_x [0]; // { dg-warning "zero-size array" }
};
struct Sx21 {
int a_x [0]; // { dg-warning "zero-size array|not at end" }
struct S { } s;
};
struct Sx22 {
int a_x [0]; // { dg-warning "zero-size array|not at end" }
union { int i; };
};
struct Sx23 {
union { int i; };
int a_x [0]; // { dg-warning "zero-size array" }
};
// The following causes an incomplete type error error and a zero-size
// array warning.
struct Sx24 {
struct S;
S a_x [0]; // { dg-error "5:field .a_x. has incomplete type" }
// { dg-warning "zero-size array" "" { target *-*-* } .-1 }
};
struct Sx25 {
struct S { };
S a_x [0]; // { dg-warning "zero-size array" }
};
struct Sx26 {
struct { }
a_x [0]; // { dg-warning "zero-size array" }
};
struct Sx27 {
int i;
struct { }
a_x [0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (Sx27, a_x);
struct Sx28 {
struct { }
a_x [0]; // { dg-warning "zero-size array|not at end" }
int i;
};
struct Sx29 {
// Pointer to an array of zero size.
int (*a_x)[0]; // { dg-warning "zero-size array" }
};
struct Sx30 {
// Reference to an array of zero size.
int (&a_x)[0]; // { dg-warning "zero-size array" }
};
struct Sx31 {
int a [0]; // { dg-warning "zero-size array|not at end" }
unsigned i: 1;
};
struct Sx32 {
unsigned i: 1;
int a [0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (Sx32, a);
struct Sx33 {
int a [0]; // { dg-warning "zero-size array|otherwise empty" }
friend int foo ();
};
struct Sx34 {
friend int foo ();
int a [0]; // { dg-warning "zero-size array|otherwise empty" }
};
// Verify that intervening non-field declarations of members other
// than non-static data members don't affect the diagnostics.
struct Sx35 {
int a[0]; // { dg-warning "zero-size array|not at end" }
typedef int I;
int n;
};
struct Sx36 {
int n;
typedef int I;
int a[0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (Sx36, a);
struct Sx37 {
int a[0]; // { dg-warning "zero-size array|not at end" }
enum E { };
int n;
};
struct Sx38 {
int n;
enum E { };
int a[0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (Sx38, a);
struct Sx39 {
int a[0]; // { dg-warning "zero-size array|not at end" }
struct S;
int n;
};
struct Sx40 {
int n;
struct S;
int a[0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (Sx40, a);
struct Sx41 {
int a[0]; // { dg-warning "zero-size array|not at end" }
static int i;
int n;
};
struct Sx42 {
int n;
static int i;
int a[0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (Sx42, a);
struct Sx43 {
int a[0]; // { dg-warning "zero-size array|not at end" }
Sx43 ();
int n;
};
struct Sx44 {
int n;
Sx44 ();
int a[0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (Sx44, a);
struct S_S_S_x {
struct A {
struct B {
int a[0]; // { dg-warning "zero-size array" }
} b;
} a;
};
// Since members of an anonymous struct or union are considered to be
// members of the enclosing union the below defintions are valid and
// must be accepted.
struct Anon1 {
int n;
struct { // { dg-warning "10:ISO C\\+\\+ prohibits anonymous struct|invalid use \[^\n\r\]* with a zero-size array" }
int good[0]; // { dg-warning "forbids zero-size array" }
};
};
ASSERT_AT_END (Anon1, good);
struct Anon2 {
struct { // { dg-warning "10:ISO C\\+\\+ prohibits anonymous struct|invalid use" }
int n;
struct { // { dg-warning "12:ISO C\\+\\+ prohibits anonymous struct" }
int good[0]; // { dg-warning "zero-size array" }
};
};
};
ASSERT_AT_END (Anon2, good);
struct Anon3 {
struct { // { dg-warning "10:ISO C\\+\\+ prohibits anonymous struct|invalid use" }
struct { // { dg-warning "12:ISO C\\+\\+ prohibits anonymous struct" }
int n;
int good[0]; // { dg-warning "zero-size array" }
};
};
};
ASSERT_AT_END (Anon3, good);
struct Anon4 {
struct { // { dg-warning "10:ISO C\\+\\+ prohibits anonymous struct" }
int in_empty_struct[0]; // { dg-warning "zero-size array|in an otherwise empty" }
};
};
struct Anon5 {
struct { // { dg-warning "10:ISO C\\+\\+ prohibits anonymous struct" }
int not_at_end[0]; // { dg-warning "zero-size array|not at end" }
};
int n;
};
struct Anon6 {
struct { // { dg-warning "10:ISO C\\+\\+ prohibits anonymous struct" }
struct { // { dg-warning "12:ISO C\\+\\+ prohibits anonymous struct" }
int not_at_end[0]; // { dg-warning "zero-size array|not at end" }
};
int n;
};
};
struct Anon7 {
struct { // { dg-warning "10:ISO C\\+\\+ prohibits anonymous struct" }
struct { // { dg-warning "12:ISO C\\+\\+ prohibits anonymous struct" }
int not_at_end[0]; // { dg-warning "zero-size array|not at end" }
};
};
int n;
};
struct Six {
int i;
int a[0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (Six, a);
class Cx {
int a[0]; // { dg-warning "zero-size array" }
};
class Cix {
int i;
int a[0]; // { dg-warning "zero-size array" }
};
struct Sxi {
int a[0]; // { dg-warning "zero-size array|not at end" }
int i;
};
struct S0 {
int a[0]; // { dg-warning "zero-size array" }
};
struct S0i {
int a[0]; // { dg-warning "zero-size array" }
int i;
};
struct S_a0_ax {
int a1[0]; // { dg-warning "zero-size array" }
int ax[0]; // { dg-warning "zero-size array" }
};
struct S_a0_i_ax {
int a1[0]; // { dg-warning "zero-size array" }
int i;
int ax[0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (S_a0_i_ax, ax);
struct Si_a0_ax {
int i;
int a1[0]; // { dg-warning "zero-size array" }
int ax[0]; // { dg-warning "zero-size array" }
};
ASSERT_AT_END (Si_a0_ax, ax);
struct S_u0_ax {
union { } u[0]; // { dg-warning "zero-size array" }
int ax[0]; // { dg-warning "zero-size array" }
};
struct S_a1_s2 {
int a[1];
int b[2];
};