diff options
author | Martin Sebor <msebor@redhat.com> | 2017-02-15 20:28:32 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2017-02-15 13:28:32 -0700 |
commit | 945c17d8c1fd5e2299fb17becac9b35ec45db3e6 (patch) | |
tree | 52131b88d2ff4908aacdbff0f1b0da777996ad69 /gcc/cp | |
parent | 8daddba8be98919c11a14d5afa8489f9b9bbd801 (diff) | |
download | gcc-945c17d8c1fd5e2299fb17becac9b35ec45db3e6.zip gcc-945c17d8c1fd5e2299fb17becac9b35ec45db3e6.tar.gz gcc-945c17d8c1fd5e2299fb17becac9b35ec45db3e6.tar.bz2 |
PR c++/79363 - ICE with NSDMI and array
gcc/cp/ChangeLog:
PR c++/79363
* init.c (maybe_reject_flexarray_init): New function.
(perform_member_init): Call it.
gcc/testsuite/ChangeLog:
PR c++/79363
* g++.dg/ext/flexary12.C: Adjust.
* g++.dg/ext/flexary20.C: Same.
* g++.dg/ext/flexary21.C: Same.
* g++.dg/ext/flexary22.C: New test.
From-SVN: r245494
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 48 |
2 files changed, 44 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b281f0b..4d4f1a0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-02-15 Martin Sebor <msebor@redhat.com> + + PR c++/79363 + * init.c (maybe_reject_flexarray_init): New function. + (perform_member_init): Call it. + 2017-02-15 Jakub Jelinek <jakub@redhat.com> PR c++/79301 diff --git a/gcc/cp/init.c b/gcc/cp/init.c index c8fb3399..fa74226 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -597,6 +597,33 @@ get_nsdmi (tree member, bool in_ctor) return init; } +/* Diagnose the flexible array MEMBER if its INITializer is non-null + and return true if so. Otherwise return false. */ + +static bool +maybe_reject_flexarray_init (tree member, tree init) +{ + tree type = TREE_TYPE (member); + + if (!init + || TREE_CODE (type) != ARRAY_TYPE + || TYPE_DOMAIN (type)) + return false; + + /* Point at the flexible array member declaration if it's initialized + in-class, and at the ctor if it's initialized in a ctor member + initializer list. */ + location_t loc; + if (DECL_INITIAL (member) == init + || DECL_DEFAULTED_FN (current_function_decl)) + loc = DECL_SOURCE_LOCATION (member); + else + loc = DECL_SOURCE_LOCATION (current_function_decl); + + error_at (loc, "initializer for flexible array member %q#D", member); + return true; +} + /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of arguments. If TREE_LIST is void_type_node, an empty initializer list was given; if NULL_TREE no initializer was given. */ @@ -722,10 +749,18 @@ perform_member_init (tree member, tree init) { if (init) { - if (TREE_CHAIN (init)) + /* Check to make sure the member initializer is valid and + something like a CONSTRUCTOR in: T a[] = { 1, 2 } and + if it isn't, return early to avoid triggering another + error below. */ + if (maybe_reject_flexarray_init (member, init)) + return; + + if (TREE_CODE (init) != TREE_LIST || TREE_CHAIN (init)) init = error_mark_node; else init = TREE_VALUE (init); + if (BRACE_ENCLOSED_INITIALIZER_P (init)) init = digest_init (type, init, tf_warning_or_error); } @@ -800,16 +835,9 @@ perform_member_init (tree member, tree init) in that case. */ init = build_x_compound_expr_from_list (init, ELK_MEM_INIT, tf_warning_or_error); - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == NULL_TREE - && init != NULL_TREE) - { - error_at (DECL_SOURCE_LOCATION (current_function_decl), - "member initializer for flexible array member"); - inform (DECL_SOURCE_LOCATION (member), "%q#D initialized", member); - } - if (init) + /* Reject a member initializer for a flexible array member. */ + if (init && !maybe_reject_flexarray_init (member, init)) finish_expr_stmt (cp_build_modify_expr (input_location, decl, INIT_EXPR, init, tf_warning_or_error)); |