PR c/53548
gcc/c/ChangeLog:
PR c/53548
* c-decl.cc (finish_struct): Change errors to pedwarns for the cases
flexible array members in union or alone in structures.
gcc/cp/ChangeLog:
PR c/53548
* class.cc (diagnose_flexarrays): Change error to pdewarn for the case
flexible array members alone in structures.
* decl.cc (grokdeclarator): Change error to pdewarn for the case
flexible array members in unions.
gcc/ChangeLog:
PR c/53548
* stor-layout.cc (place_union_field): Use zero sizes for flexible array
member fields.
gcc/testsuite/ChangeLog:
PR c/53548
* c-c++-common/builtin-clear-padding-3.c: Adjust testcase.
* g++.dg/ext/flexary12.C: Likewise.
* g++.dg/ext/flexary19.C: Likewise.
* g++.dg/ext/flexary2.C: Likewise.
* g++.dg/ext/flexary3.C: Likewise.
* g++.dg/ext/flexary36.C: Likewise.
* g++.dg/ext/flexary4.C: Likewise.
* g++.dg/ext/flexary5.C: Likewise.
* g++.dg/ext/flexary8.C: Likewise.
* g++.dg/torture/pr64280.C: Likewise.
* gcc.dg/
20050620-1.c: Likewise.
* gcc.dg/940510-1.c: Likewise.
if (flexible_array_member_type_p (TREE_TYPE (x)))
{
if (TREE_CODE (t) == UNION_TYPE)
- {
- error_at (DECL_SOURCE_LOCATION (x),
- "flexible array member in union");
- TREE_TYPE (x) = error_mark_node;
- }
+ pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
+ "flexible array member in union is a GCC extension");
else if (!is_last_field)
{
error_at (DECL_SOURCE_LOCATION (x),
TREE_TYPE (x) = error_mark_node;
}
else if (!saw_named_field)
- {
- error_at (DECL_SOURCE_LOCATION (x),
- "flexible array member in a struct with no named "
- "members");
- TREE_TYPE (x) = error_mark_node;
- }
+ pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
+ "flexible array member in a struct with no named "
+ "members is a GCC extension");
}
if (pedantic && TREE_CODE (t) == RECORD_TYPE
bool diagd = false;
const char *msg = 0;
+ const char *msg_fam = 0;
if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
{
if (fmem->after[0])
msg = G_("flexible array member %qD not at end of %q#T");
else if (!fmem->first)
- msg = G_("flexible array member %qD in an otherwise empty %q#T");
+ msg_fam = G_("flexible array member %qD in an otherwise"
+ " empty %q#T is a GCC extension");
- if (msg)
+ if (msg || msg_fam)
{
location_t loc = DECL_SOURCE_LOCATION (fmem->array);
diagd = true;
auto_diagnostic_group d;
- error_at (loc, msg, fmem->array, t);
+ if (msg)
+ error_at (loc, msg, fmem->array, t);
+ else
+ pedwarn (loc, OPT_Wpedantic, msg_fam, fmem->array, t);
/* In the unlikely event that the member following the flexible
array member is declared in a different class, or the member
if (ctype
&& (TREE_CODE (ctype) == UNION_TYPE
|| TREE_CODE (ctype) == QUAL_UNION_TYPE))
- {
- error_at (id_loc, "flexible array member in union");
- type = error_mark_node;
- }
+ pedwarn (id_loc, OPT_Wpedantic,
+ "flexible array member in union is a GCC extension");
+
else
{
/* Array is a flexible member. */
&& TYPE_TYPELESS_STORAGE (TREE_TYPE (field)))
TYPE_TYPELESS_STORAGE (rli->t) = 1;
+ /* We might see a flexible array member field (with no DECL_SIZE_UNIT), use
+ zero size for such field. */
+ tree field_size_unit = DECL_SIZE_UNIT (field)
+ ? DECL_SIZE_UNIT (field)
+ : build_int_cst (sizetype, 0);
/* We assume the union's size will be a multiple of a byte so we don't
bother with BITPOS. */
if (TREE_CODE (rli->t) == UNION_TYPE)
- rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
+ rli->offset = size_binop (MAX_EXPR, rli->offset, field_size_unit);
else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
rli->offset = fold_build3 (COND_EXPR, sizetype, DECL_QUALIFIER (field),
- DECL_SIZE_UNIT (field), rli->offset);
+ field_size_unit, rli->offset);
}
/* A bitfield of SIZE with a required access alignment of ALIGN is allocated
/* { dg-do compile } */
/* { dg-options "" } */
-union U { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); }; /* { dg-error "flexible array member in union" } */
+union U { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); };
struct V { int a; union U b; };
-struct W { int a; union U b; int c; };
void
-foo (union U *u, struct V *v, struct W *w)
+foo (union U *u, struct V *v)
{
- __builtin_clear_padding (u);
- __builtin_clear_padding (v);
- __builtin_clear_padding (w);
+ __builtin_clear_padding (u); /* { dg-error "flexible array member" "does not have well defined padding bits" } */
+ __builtin_clear_padding (v); /* { dg-error "flexible array member" "does not have well defined padding bits" } */
}
// { dg-options "-Wno-pedantic" }
struct A {
- int a []; // { dg-error "flexible array member .A::a. in an otherwise empty .struct A." }
+ int a [];
};
void f1 ()
}
struct D {
- int a []; // { dg-error "flexible array member .D::a. in an otherwise empty .struct D." }
+ int a [];
D ();
};
template <class T>
struct C {
- T a []; // { dg-error "flexible array member" }
+ T a [];
};
void f3 ()
// 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" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} s;
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} s[1];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} s[];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} s[2];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} s[1][2];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} s[][2];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} *s;
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} **s;
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} *s[1];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} *s[];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} **s[1];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} **s[];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} **s[2];
};
int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} &s;
};
int i;
typedef struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} T15;
};
{
int i;
- union { // anonymous union
- int a[]; // { dg-error "flexible array member in union" }
+ union { // { dg-warning "invalid use" }
+ int a[]; // { dg-warning "flexible array member in union" }
};
};
struct S22S {
static int i;
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} s;
};
struct { // { dg-warning "10:ISO C\\+\\+ prohibits anonymous struct" }
static int i; // { dg-error "static data member" }
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
};
};
static int i;
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} s;
};
};
struct {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[]; // { dg-warning "in an otherwise empty" }
} s;
};
struct B {
B() {}
- A a[]; // { dg-error "extension|flexible array .* in an otherwise empty" }
+ A a[];
};
struct C {
// { dg-options "" }
struct s {
- char c[]; // { dg-error "flexible array member .* in an otherwise empty" }
+ char c[];
};
int main()
union {
- int a[]; // { dg-error "flexible array member in union" }
+ int a[];
int b;
} du = { 1 };
#include "flexary.h"
struct Sx {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
};
// Verify that non-data members or static data members either before
// or after a flexible array member in an otherwise empty struct don't
// suppress the diagnostic.
struct Sx2 {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
typedef int I;
};
struct Sx3 {
typedef int I;
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
};
struct Sx4 {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
enum E { e };
};
struct Sx5 {
enum E { e };
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
};
struct Sx6 {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
static int i;
};
struct Sx7 {
static int i;
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
};
struct Sx8 {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
Sx8 () { }
};
struct Sx9 {
Sx9 () { }
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
};
struct Sx10 {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
virtual ~Sx10 () { }
};
struct Sx11 {
virtual ~Sx11 () { }
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
};
struct Sx12 {
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
virtual void foo () = 0;
};
struct Sx13 {
virtual void foo () = 0;
- int a[]; // { dg-error "in an otherwise empty" }
+ int a[];
};
struct Sx14 {
- int a[][1]; // { dg-error "in an otherwise empty" }
+ int a[][1];
};
struct Sx15 {
typedef int A[];
- A a; // { dg-error "in an otherwise empty" }
+ A a;
};
// Verify also that a zero-size array doesn't suppress the diagnostic.
// a_0 below is diagnosed with -Wpedantic only and emits
// warning: ISO C++ forbids zero-size arrays
int a_0 [0];
- int a_x []; // { dg-error "in an otherwise empty" }
+ int a_x [];
};
struct Sx17 {
// so doesn't contribute its member to that of the enclosing struct.
struct Sx20 {
struct S { int i; };
- int a_x []; // { dg-error "in an otherwise empty" }
+ int a_x [];
};
struct Sx21 {
struct Sx25 {
struct S { };
- S a_x []; // { dg-error "flexible array member" }
+ S a_x [];
};
struct Sx26 {
struct { }
- a_x []; // { dg-error "flexible array member" }
+ a_x [];
};
struct Sx27 {
ASSERT_AT_END (Sx32, a);
struct Sx33 {
- int a []; // { dg-error "otherwise empty" }
+ int a [];
friend int foo ();
};
struct Sx34 {
friend int foo ();
- int a []; // { dg-error "otherwise empty" }
+ int a [];
};
// Verify that intervening non-field declarations of members other
struct S_S_S_x {
struct A {
struct B {
- int a[]; // { dg-error "flexible array member" }
+ int a[];
} b;
} a;
};
// The following is not an anonymous struct -- the type is unnamed
// but the object has a name.
struct {
- int bad[]; // { dg-error "otherwise empty" }
+ int bad[];
} name;
};
struct Anon4 {
struct {
- int in_empty_struct[]; // { dg-error "in an otherwise empty" }
+ int in_empty_struct[];
};
};
ASSERT_AT_END (Six, a);
class Cx {
- int a[]; // { dg-error "flexible array member" }
+ int a[];
};
class Cix {
struct S_a0_ax {
int a0[0];
- int ax[]; // { dg-error "flexible array member" }
+ int ax[];
};
struct S_a0_i_ax {
struct S_u0_ax {
union { } u[0];
- int ax[]; // { dg-error "flexible array member" }
+ int ax[];
};
struct S_a1_s2 {
template <class T>
struct STx_1: T {
- char a[]; // { dg-error "flexible array member" }
+ char a[];
};
template <class T, int I>
struct E2: E<2>, E<3> { };
struct D1: E1, E2
{
- char a[]; // { dg-error "flexible array member" }
+ char a[];
};
struct NE { size_t i; };
union U_i_ax {
int i;
- int a[]; // { dg-error "flexible array member in union" }
+ int a[];
};
struct SU1 {
union {
- int a[]; // { dg-error "flexible array member in union" }
+ int a[];
};
};
struct SU2 {
int n;
union {
- int a[]; // { dg-error "flexible array member in union" }
+ int a[];
};
};
struct SU3 {
union {
int n;
- int a[]; // { dg-error "flexible array member in union" }
+ int a[];
};
};
typedef int jmp_buf[];
struct C
{
- jmp_buf cond_; // { dg-error "flexible array member" }
+ jmp_buf cond_;
};
class F
{
void
foo (void)
{
- struct { int i[]; } u; /* { dg-error "flexible array member" } */
+ struct { int i[]; } u;
}
void
/* { dg-do compile } */
/* { dg-options "-std=c89 -pedantic" } */
struct { int a[]; } x = { 0 }; /* { dg-warning "ISO C90 does not support flexible array members" } */
-/* { dg-error "flexible array member in a struct with no named members" "" { target *-*-* } .-1 } */
-
+/* { dg-warning "flexible array member in a struct with no named members is a GCC extension" "" { target *-*-* } .-1 } */
+/* { dg-warning "initialization of a flexible array member" "" { target *-*-* } .-2 } */