From 59dbb04df76da41f26192c2c219584fc3d6017cc Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 10 Feb 2020 00:47:34 +0100 Subject: [PATCH] c++: Fix flexible array with synthesized constructor. We were already rejecting initialization of a flexible array member in a constructor; we similarly shouldn't try to clean it up. PR c++/93618 * tree.c (array_of_unknown_bound_p): New. * init.c (perform_member_init): Do nothing for flexible arrays. --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/init.c | 7 +++++-- gcc/cp/tree.c | 9 +++++++++ gcc/testsuite/g++.dg/ext/flexary35.C | 18 ++++++++++++++++++ 5 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/flexary35.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 90f26c9..876e2eb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-02-10 Jason Merrill + + PR c++/93618 + * tree.c (array_of_unknown_bound_p): New. + * init.c (perform_member_init): Do nothing for flexible arrays. + 2020-02-09 Jakub Jelinek PR c++/93633 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 037d3b6..043bc40 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7424,6 +7424,7 @@ extern tree build_exception_variant (tree, tree); extern tree bind_template_template_parm (tree, tree); extern tree array_type_nelts_total (tree); extern tree array_type_nelts_top (tree); +extern bool array_of_unknown_bound_p (const_tree); extern tree break_out_target_exprs (tree, bool = false); extern tree build_ctor_subob_ref (tree, tree, tree); extern tree replace_placeholders (tree, tree, bool * = NULL); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 625062b..d480660 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -801,8 +801,11 @@ perform_member_init (tree member, tree init) member); } - if (maybe_reject_flexarray_init (member, init)) - return; + if (array_of_unknown_bound_p (type)) + { + maybe_reject_flexarray_init (member, init); + return; + } if (init && TREE_CODE (init) == TREE_LIST && (DIRECT_LIST_INIT_P (TREE_VALUE (init)) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index fda6307..eb540f8 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1135,6 +1135,15 @@ build_array_of_n_type (tree elt, int n) return build_cplus_array_type (elt, build_index_type (size_int (n - 1))); } +/* True iff T is an array of unknown bound. */ + +bool +array_of_unknown_bound_p (const_tree t) +{ + return (TREE_CODE (t) == ARRAY_TYPE + && !TYPE_DOMAIN (t)); +} + /* True iff T is an N3639 array of runtime bound (VLA). These were approved for C++14 but then removed. This should only be used for N3639 specifically; code wondering more generally if something is a VLA should use diff --git a/gcc/testsuite/g++.dg/ext/flexary35.C b/gcc/testsuite/g++.dg/ext/flexary35.C new file mode 100644 index 0000000..b62c718 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary35.C @@ -0,0 +1,18 @@ +// PR c++/93618 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +template +struct C { + ~C () = default; + T *p = nullptr; +}; + +class A { + struct B { + int c; + C d[]; + }; + void foo (int f) { B s; s.c = f; } + B e; +}; -- 2.7.4