From 065d214ce4129853330cb0c992b981830c950909 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Sat, 14 Feb 2015 11:25:19 +0000 Subject: [PATCH] =?utf8?q?re=20PR=20c/64768=20(internal=20compiler=20error?= =?utf8?q?:=20tree=20check:=20expected=20tree=20that=20contains=20?= =?utf8?q?=E2=80=98decl=20with=20RTL=E2=80=99=20structure,=20have=20?= =?utf8?q?=E2=80=98field=5Fdecl=E2=80=99=20in=20set=5Fdecl=5Frtl,=20at=20e?= =?utf8?q?mit-rtl.c:1274)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit PR c/64768 * c-decl.c (grokdeclarator): Set the range of a flexible array member declared through a typedef name. * gcc.dg/array-11.c: New test. * gcc.dg/array-12.c: New test. * gcc.dg/array-13.c: New test. * gcc.dg/array-14.c: New test. * gcc.dg/c99-flex-array-typedef-1.c: New test. * gcc.dg/c99-flex-array-typedef-2.c: New test. * gcc.dg/c99-flex-array-typedef-3.c: New test. * gcc.dg/c99-flex-array-typedef-5.c: New test. * gcc.dg/c99-flex-array-typedef-7.c: New test. * gcc.dg/c99-flex-array-typedef-8.c: New test. From-SVN: r220708 --- gcc/c/ChangeLog | 6 ++++ gcc/c/c-decl.c | 13 ++++++++ gcc/testsuite/ChangeLog | 14 ++++++++ gcc/testsuite/gcc.dg/array-11.c | 15 +++++++++ gcc/testsuite/gcc.dg/array-12.c | 13 ++++++++ gcc/testsuite/gcc.dg/array-13.c | 28 ++++++++++++++++ gcc/testsuite/gcc.dg/array-14.c | 18 +++++++++++ .../gcc.dg/c99-flex-array-typedef-1.c | 9 ++++++ .../gcc.dg/c99-flex-array-typedef-2.c | 17 ++++++++++ .../gcc.dg/c99-flex-array-typedef-3.c | 32 +++++++++++++++++++ .../gcc.dg/c99-flex-array-typedef-5.c | 6 ++++ .../gcc.dg/c99-flex-array-typedef-7.c | 18 +++++++++++ .../gcc.dg/c99-flex-array-typedef-8.c | 16 ++++++++++ 13 files changed, 205 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/array-11.c create mode 100644 gcc/testsuite/gcc.dg/array-12.c create mode 100644 gcc/testsuite/gcc.dg/array-13.c create mode 100644 gcc/testsuite/gcc.dg/array-14.c create mode 100644 gcc/testsuite/gcc.dg/c99-flex-array-typedef-1.c create mode 100644 gcc/testsuite/gcc.dg/c99-flex-array-typedef-2.c create mode 100644 gcc/testsuite/gcc.dg/c99-flex-array-typedef-3.c create mode 100644 gcc/testsuite/gcc.dg/c99-flex-array-typedef-5.c create mode 100644 gcc/testsuite/gcc.dg/c99-flex-array-typedef-7.c create mode 100644 gcc/testsuite/gcc.dg/c99-flex-array-typedef-8.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 08955a45999..0bb5dc70600 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2015-02-14 Marek Polacek + + PR c/64768 + * c-decl.c (grokdeclarator): Set the range of a flexible array member + declared through a typedef name. + 2015-02-13 Marek Polacek PR c/65050 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 4fd3239da89..8eeee9c53de 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -6515,6 +6515,19 @@ grokdeclarator (const struct c_declarator *declarator, error_at (loc, "unnamed field has incomplete type"); type = error_mark_node; } + else if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_DOMAIN (type) == NULL_TREE) + { + /* We have a flexible array member through a typedef. + Set suitable range. Whether this is a correct position + for a flexible array member will be determined elsewhere. */ + if (!in_system_header_at (input_location)) + pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not " + "support flexible array members"); + type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type)); + TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node, + NULL_TREE); + } type = c_build_qualified_type (type, type_quals); decl = build_decl (declarator->id_loc, FIELD_DECL, declarator->u.id, type); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f6e5ccc1c3b..f58cfcc1272 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2015-02-14 Marek Polacek + + PR c/64768 + * gcc.dg/array-11.c: New test. + * gcc.dg/array-12.c: New test. + * gcc.dg/array-13.c: New test. + * gcc.dg/array-14.c: New test. + * gcc.dg/c99-flex-array-typedef-1.c: New test. + * gcc.dg/c99-flex-array-typedef-2.c: New test. + * gcc.dg/c99-flex-array-typedef-3.c: New test. + * gcc.dg/c99-flex-array-typedef-5.c: New test. + * gcc.dg/c99-flex-array-typedef-7.c: New test. + * gcc.dg/c99-flex-array-typedef-8.c: New test. + 2015-02-13 Paolo Carlini PR c++/60894 diff --git a/gcc/testsuite/gcc.dg/array-11.c b/gcc/testsuite/gcc.dg/array-11.c new file mode 100644 index 00000000000..dbf38ae8ca9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/array-11.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +/* Verify that we can't do things to get ourselves in trouble + with GCC's initialized flexible array member extension. */ + +typedef int T[]; +struct f { int w; T x; }; +struct g { struct f f; }; +struct g g1 = { { 0, { } } }; +struct g g2 = { { 0, { 1 } } }; /* { dg-error "nested context" "nested" } */ + /* { dg-message "near init" "near" { target *-*-* } 11 } */ +struct h { int x[0]; int y; }; +struct h h1 = { { 0 }, 1 }; /* { dg-warning "excess elements" "excess" } */ + /* { dg-message "near init" "before end" { target *-*-* } 14 } */ diff --git a/gcc/testsuite/gcc.dg/array-12.c b/gcc/testsuite/gcc.dg/array-12.c new file mode 100644 index 00000000000..b3beed57d9e --- /dev/null +++ b/gcc/testsuite/gcc.dg/array-12.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +/* ISO C99 flexible array members don't have a size. GCC's zero-length + array extension does. */ + +typedef int T0[0]; +typedef int T[]; +struct f { int w; T0 x; } f; +struct g { int w; T x; } g; + +char test_gcc[sizeof (f.x) ? -1 : 1]; +char test_iso[sizeof (g.x) ? -1 : 1]; /* { dg-error "incomplete type" "iso" } */ diff --git a/gcc/testsuite/gcc.dg/array-13.c b/gcc/testsuite/gcc.dg/array-13.c new file mode 100644 index 00000000000..8335b7a186a --- /dev/null +++ b/gcc/testsuite/gcc.dg/array-13.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "" } */ + +/* Verify that GCC's initialized flexible array member extension + works properly. */ + +extern void abort(void); +extern void exit(int); + +typedef int T[]; +typedef int T0[0]; + +struct f { int w; T x; }; +struct g { int w; T0 x; }; + +static struct f f = { 4, { 0, 1, 2, 3 } }; +static int junk1[] = { -1, -1, -1, -1 }; +static struct g g = { 4, { 0, 1, 2, 3 } }; /* { dg-warning "(excess elements)|(near initialization)" "" } */ +static int junk2[] = { -1, -1, -1, -1 }; + +int main() +{ + int i; + for (i = 0; i < f.w; ++i) + if (f.x[i] != i) + abort (); + exit(0); +} diff --git a/gcc/testsuite/gcc.dg/array-14.c b/gcc/testsuite/gcc.dg/array-14.c new file mode 100644 index 00000000000..cb2a347fbbe --- /dev/null +++ b/gcc/testsuite/gcc.dg/array-14.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +/* Verify that GCC forbids non-static initialization of + flexible array members. */ + +typedef char T[]; +struct str { int len; T s; }; + +struct str a = { 2, "a" }; + +void foo() +{ + static struct str b = { 2, "b" }; + struct str c = { 2, "c" }; /* { dg-error "(non-static)|(near initialization)" } */ + struct str d = (struct str) { 2, "d" }; /* { dg-error "(non-static)|(near initialization)" } */ + struct str e = (struct str) { d.len, "e" }; /* { dg-error "(non-static)|(initialization)" } */ +} diff --git a/gcc/testsuite/gcc.dg/c99-flex-array-typedef-1.c b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-1.c new file mode 100644 index 00000000000..93f91f816a8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-1.c @@ -0,0 +1,9 @@ +/* Test for invalid uses of flexible array members. */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +typedef int A[]; +struct s1 { A x; }; /* { dg-error "empty struct" "empty" } */ +struct s2 { int :1; A x; }; /* { dg-error "empty struct" "empty" } */ +struct s3 { A x; int y; }; /* { dg-error "not at end" "not at end" } */ +struct s4 { int x; A y; }; diff --git a/gcc/testsuite/gcc.dg/c99-flex-array-typedef-2.c b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-2.c new file mode 100644 index 00000000000..f869f75c2bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-2.c @@ -0,0 +1,17 @@ +/* Test for invalid uses of flexible array members. */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +typedef char A[]; + +struct S { + int n; + A a; +}; + +void +foo (void) +{ + struct S s; + s.a = "abc"; /* { dg-error "invalid use of flexible array member" } */ +} diff --git a/gcc/testsuite/gcc.dg/c99-flex-array-typedef-3.c b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-3.c new file mode 100644 index 00000000000..11db8861181 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-3.c @@ -0,0 +1,32 @@ +/* Test for flexible array members. Test for where structures with + such members may not occur. */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +typedef int T[]; +struct flex { int a; T b; }; +union rf1 { struct flex a; int b; }; +union rf2 { int a; struct flex b; }; +union rf3 { int a; union rf1 b; }; +union rf4 { union rf2 a; int b; }; + +/* The above structure and unions may not be members of structures or + elements of arrays (6.7.2.1#2). */ + +struct t0 { struct flex a; }; /* { dg-error "invalid use of structure" } */ +struct t1 { union rf1 a; }; /* { dg-error "invalid use of structure" } */ +struct t2 { union rf2 a; }; /* { dg-error "invalid use of structure" } */ +struct t3 { union rf3 a; }; /* { dg-error "invalid use of structure" } */ +struct t4 { union rf4 a; }; /* { dg-error "invalid use of structure" } */ + +void f0 (struct flex[]); /* { dg-error "invalid use of structure" } */ +void f1 (union rf1[]); /* { dg-error "invalid use of structure" } */ +void f2 (union rf2[]); /* { dg-error "invalid use of structure" } */ +void f3 (union rf3[]); /* { dg-error "invalid use of structure" } */ +void f4 (union rf4[]); /* { dg-error "invalid use of structure" } */ + +struct flex a0[1]; /* { dg-error "invalid use of structure" } */ +union rf1 a1[1]; /* { dg-error "invalid use of structure" } */ +union rf2 a2[1]; /* { dg-error "invalid use of structure" } */ +union rf3 a3[1]; /* { dg-error "invalid use of structure" } */ +union rf4 a4[1]; /* { dg-error "invalid use of structure" } */ diff --git a/gcc/testsuite/gcc.dg/c99-flex-array-typedef-5.c b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-5.c new file mode 100644 index 00000000000..2d1fbe1c130 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-5.c @@ -0,0 +1,6 @@ +/* Test for flexible array members: not permitted in unions. */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +typedef char T[]; +union u { int a; T b; }; /* { dg-error "flexible array member in union" } */ diff --git a/gcc/testsuite/gcc.dg/c99-flex-array-typedef-7.c b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-7.c new file mode 100644 index 00000000000..8b954db4e0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-7.c @@ -0,0 +1,18 @@ +/* Initialization of a flexible array member with a string constant + must be diagnosed. PR 37481. */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +typedef char T[]; +struct s { int a; T b; }; + +struct s a = { 0, "" }; /* { dg-error "initialization of a flexible array member" } */ +/* { dg-message "near init" "near init" { target *-*-* } 9 } */ +struct s b = { 0, { 0 } }; /* { dg-error "initialization of a flexible array member" } */ +/* { dg-message "near init" "near init" { target *-*-* } 11 } */ +struct s c = { 0, { } }; /* { dg-error "ISO C forbids empty initializer braces" } */ +struct s d = { .b = "" }; /* { dg-error "initialization of a flexible array member" } */ +/* { dg-message "near init" "near init" { target *-*-* } 14 } */ +struct s e = { .b = { 0 } }; /* { dg-error "initialization of a flexible array member" } */ +/* { dg-message "near init" "near init" { target *-*-* } 16 } */ +struct s f = { .b = { } }; /* { dg-error "ISO C forbids empty initializer braces" } */ diff --git a/gcc/testsuite/gcc.dg/c99-flex-array-typedef-8.c b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-8.c new file mode 100644 index 00000000000..26c4a23428c --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-flex-array-typedef-8.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +typedef char T[]; +struct foo { int x; T y; }; +struct bar { struct foo f; }; +struct baz { struct bar b; }; + +struct foo a1 = { 1, "abc" }; +struct foo a2 = { 1, { "abc" } }; +struct foo b1[] = { { 1, "abc" } }; /* { dg-error "initialization of flexible array member" } */ +struct foo b2[] = { { 1, { "abc" } } }; /* { dg-error "initialization of flexible array member" } */ +struct bar c1[] = { { { 1, "abc" } } }; /* { dg-error "initialization of flexible array member" } */ +struct bar c2[] = { { { 1, { "abc" } } } }; /* { dg-error "initialization of flexible array member" } */ +struct baz d1[] = { { { { 1, "abc" } } } }; /* { dg-error "initialization of flexible array member" } */ +struct baz d2[] = { { { { 1, { "abc" } } } } }; /* { dg-error "initialization of flexible array member" } */ -- 2.30.2