re PR c/64768 (internal compiler error: tree check: expected tree that contains ...
authorMarek Polacek <polacek@redhat.com>
Sat, 14 Feb 2015 11:25:19 +0000 (11:25 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Sat, 14 Feb 2015 11:25:19 +0000 (11:25 +0000)
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

13 files changed:
gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/array-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/array-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/array-13.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/array-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c99-flex-array-typedef-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c99-flex-array-typedef-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c99-flex-array-typedef-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c99-flex-array-typedef-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c99-flex-array-typedef-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c99-flex-array-typedef-8.c [new file with mode: 0644]

index 08955a4599933cbb159fbc8eeb9cc4278a03f1db..0bb5dc70600b851f029d17f0fa29e5d39f28ee32 100644 (file)
@@ -1,3 +1,9 @@
+2015-02-14  Marek Polacek  <polacek@redhat.com>
+
+       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  <polacek@redhat.com>
 
        PR c/65050
index 4fd3239da89b6773a0047034b45182653c8e2c24..8eeee9c53de29646bb0e61f0d5fb993d2e82959a 100644 (file)
@@ -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);
index f6e5ccc1c3bc920e025001abb66ab3986832ef26..f58cfcc1272b5b3d1051792be90b41dd197c0cf9 100644 (file)
@@ -1,3 +1,17 @@
+2015-02-14  Marek Polacek  <polacek@redhat.com>
+
+       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  <paolo.carlini@oracle.com>
 
        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 (file)
index 0000000..dbf38ae
--- /dev/null
@@ -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 (file)
index 0000000..b3beed5
--- /dev/null
@@ -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 (file)
index 0000000..8335b7a
--- /dev/null
@@ -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 (file)
index 0000000..cb2a347
--- /dev/null
@@ -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 (file)
index 0000000..93f91f8
--- /dev/null
@@ -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 (file)
index 0000000..f869f75
--- /dev/null
@@ -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 (file)
index 0000000..11db886
--- /dev/null
@@ -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 (file)
index 0000000..2d1fbe1
--- /dev/null
@@ -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 (file)
index 0000000..8b954db
--- /dev/null
@@ -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 (file)
index 0000000..26c4a23
--- /dev/null
@@ -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" } */