aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2017-02-15 20:28:32 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2017-02-15 13:28:32 -0700
commit945c17d8c1fd5e2299fb17becac9b35ec45db3e6 (patch)
tree52131b88d2ff4908aacdbff0f1b0da777996ad69 /gcc/cp
parent8daddba8be98919c11a14d5afa8489f9b9bbd801 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/init.c48
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));