From 2cc901dcb29e15e06bfeab82a9834b6254b4ae0f Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 7 Jan 2015 08:19:48 +0000 Subject: [PATCH] re PR c/64417 ([SH] FAIL: gcc.c-torture/compile/pr28865.c -O0 (test for excess errors)) PR c/64417 c/ * c-typeck.c (process_init_element): Disallow initialization of a flexible array member with a string constant if the structure is in an array. testsuite/ * gcc.c-torture/compile/pr28865.c: Add dg-errors. * gcc.dg/pr64417.c: New test. From-SVN: r219278 --- gcc/c/ChangeLog | 7 +++++ gcc/c/c-typeck.c | 27 +++++++++++++++++++ gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gcc.c-torture/compile/pr28865.c | 12 ++++----- gcc/testsuite/gcc.dg/pr64417.c | 16 +++++++++++ 5 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr64417.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index d6b228902f9..357d2c4d376 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2015-01-07 Marek Polacek + + PR c/64417 + * c-typeck.c (process_init_element): Disallow initialization of + a flexible array member with a string constant if the structure + is in an array. + 2015-01-05 Jakub Jelinek PR sanitizer/64344 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 0db43cc1b63..38ba9b8ede6 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -8809,6 +8809,33 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, break; } + /* Error for initialization of a flexible array member with + a string constant if the structure is in an array. E.g.: + struct S { int x; char y[]; }; + struct S s[] = { { 1, "foo" } }; + is invalid. */ + if (string_flag + && fieldcode == ARRAY_TYPE + && constructor_depth > 1 + && TYPE_SIZE (fieldtype) == NULL_TREE + && DECL_CHAIN (constructor_fields) == NULL_TREE) + { + bool in_array_p = false; + for (struct constructor_stack *p = constructor_stack; + p && p->type; p = p->next) + if (TREE_CODE (p->type) == ARRAY_TYPE) + { + in_array_p = true; + break; + } + if (in_array_p) + { + error_init (loc, "initialization of flexible array " + "member in a nested context"); + break; + } + } + /* Accept a string constant to initialize a subarray. */ if (value.value != 0 && fieldcode == ARRAY_TYPE diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5e0d7d52181..214cfd682c0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-01-07 Marek Polacek + + PR c/64417 + * gcc.c-torture/compile/pr28865.c: Add dg-errors. + * gcc.dg/pr64417.c: New test. + 2015-01-06 Michael Meissner PR target/64505 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr28865.c b/gcc/testsuite/gcc.c-torture/compile/pr28865.c index aa6ae078aca..ef0eba5492d 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr28865.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr28865.c @@ -5,12 +5,12 @@ struct var_len }; /* Note - strictly speaking this array declaration is illegal - since each element has a variable length. GCC allows it - (for the moment) because it is used in existing code, such - as glibc. */ + since each element has a variable length. We used to allow + this because it was used in existing code. + Since PR64417 we reject this code. */ static const struct var_len var_array[] = { - { 1, "Long exposure noise reduction" }, - { 2, "Shutter/AE lock buttons" }, - { 3, "Mirror lockup" } + { 1, "Long exposure noise reduction" }, /* { dg-error "initialization of flexible array member" } */ + { 2, "Shutter/AE lock buttons" }, /* { dg-error "initialization of flexible array member" } */ + { 3, "Mirror lockup" } /* { dg-error "initialization of flexible array member" } */ }; diff --git a/gcc/testsuite/gcc.dg/pr64417.c b/gcc/testsuite/gcc.dg/pr64417.c new file mode 100644 index 00000000000..1e98b22d641 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr64417.c @@ -0,0 +1,16 @@ +/* PR c/64417 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +struct foo { int x; char 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