re PR c/64768 (internal compiler error: tree check: expected tree that contains ‘decl with RTL’ structure, have ‘field_decl’ in set_decl_rtl, at emit-rtl.c:1274)

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
This commit is contained in:
Marek Polacek 2015-02-14 11:25:19 +00:00 committed by Marek Polacek
parent 952e216e5a
commit 065d214ce4
13 changed files with 205 additions and 0 deletions

View 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> 2015-02-13 Marek Polacek <polacek@redhat.com>
PR c/65050 PR c/65050

View File

@ -6515,6 +6515,19 @@ grokdeclarator (const struct c_declarator *declarator,
error_at (loc, "unnamed field has incomplete type"); error_at (loc, "unnamed field has incomplete type");
type = error_mark_node; 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); type = c_build_qualified_type (type, type_quals);
decl = build_decl (declarator->id_loc, decl = build_decl (declarator->id_loc,
FIELD_DECL, declarator->u.id, type); FIELD_DECL, declarator->u.id, type);

View 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> 2015-02-13 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/60894 PR c++/60894

View File

@ -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 } */

View File

@ -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" } */

View File

@ -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);
}

View File

@ -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)" } */
}

View File

@ -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; };

View File

@ -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" } */
}

View File

@ -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" } */

View File

@ -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" } */

View File

@ -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" } */

View File

@ -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" } */