On 09/04/18 16:30, Jeff Law wrote: > On 09/03/2018 06:35 AM, Bernd Edlinger wrote: > [ Big snip, dropping lots of context ] > >>>>> >>>> >>>> No I don't think so, because at that time BRACE_ENCLOSED_INITIALIZER_P >>>> property does no longer work, as I explained in the previous mail. >>>> >>>> And cp_complete_array_type does use that property: >>> [ ... ] >>> Jason's the expert here. I'll defer to his expertise. It just seemed >>> a bit odd to me that we have a routine to "complete" an array that does >>> any special C++ handling (cp_complete_array_type) and we're not using it. >>> >> >> Agreed, I have posted an update which uses cp_complete_array_type, since >> Jason raised the same point. >> >> But since C++ does not need the recursion here, things are a lot more easy. >> The patch still completes the array type _after_ the FE is completely done >> with the >> parsing, since I want to avoid to destroy the information too early, since >> the FE is looking >> at the TYPE_DOMAIN==NULL at various places. > FYI, I don't see a follow-up for this patch? Did I miss it? Or is it > under a different subject line? > > jeff >
Yes, thanks for reminding me. I had forgotten to post the updated patch. So here is my latest version of the flexible array patch. Bootstrapped and reg-tested on x86_64-pc-linux-gnu (together with the other STRING_CST-v2 patches). Is it OK for trunk? Thanks Bernd.
gcc: 2018-08-30 Bernd Edlinger <bernd.edlin...@hotmail.de> * varasm.c (output_constructor_regular_field): Check TYPE_SIZE_UNIT of the init value. c-family: 2018-08-30 Bernd Edlinger <bernd.edlin...@hotmail.de> * c-common.c (complete_flexible_array_elts): New helper function. * c-common.h (complete_flexible_array_elts): Declare. c: 2018-08-30 Bernd Edlinger <bernd.edlin...@hotmail.de> * c-decl.c (finish_decl): Call complete_flexible_array_elts. cp: 2018-08-30 Bernd Edlinger <bernd.edlin...@hotmail.de> * decl.c (check_initializer): Call complete_flexible_array_elts. diff -Npur gcc/c/c-decl.c gcc/c/c-decl.c --- gcc/c/c-decl.c 2018-08-21 08:17:41.000000000 +0200 +++ gcc/c/c-decl.c 2018-08-24 12:06:21.374892294 +0200 @@ -5035,6 +5035,8 @@ finish_decl (tree decl, location_t init_ if (init && TREE_CODE (init) == CONSTRUCTOR) add_flexible_array_elts_to_size (decl, init); + complete_flexible_array_elts (DECL_INITIAL (decl)); + if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node && COMPLETE_TYPE_P (TREE_TYPE (decl))) layout_decl (decl, 0); diff -Npur gcc/c-family/c-common.c gcc/c-family/c-common.c --- gcc/c-family/c-common.c 2018-08-17 05:02:11.000000000 +0200 +++ gcc/c-family/c-common.c 2018-08-24 12:45:56.559011703 +0200 @@ -6427,6 +6427,28 @@ complete_array_type (tree *ptype, tree i return failure; } +/* INIT is an constructor of a structure with a flexible array member. + Complete the flexible array member with a domain based on it's value. */ +void +complete_flexible_array_elts (tree init) +{ + tree elt, type; + + if (init == NULL_TREE || TREE_CODE (init) != CONSTRUCTOR) + return; + + if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init))) + return; + + elt = CONSTRUCTOR_ELTS (init)->last ().value; + type = TREE_TYPE (elt); + if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_SIZE (type) == NULL_TREE) + complete_array_type (&TREE_TYPE (elt), elt, false); + else + complete_flexible_array_elts (elt); +} + /* Like c_mark_addressable but don't check register qualifier. */ void c_common_mark_addressable_vec (tree t) diff -Npur gcc/c-family/c-common.h gcc/c-family/c-common.h --- gcc/c-family/c-common.h 2018-08-17 05:02:11.000000000 +0200 +++ gcc/c-family/c-common.h 2018-08-24 12:06:21.375892280 +0200 @@ -1038,6 +1038,7 @@ extern tree fold_offsetof (tree, tree = tree_code ctx = ERROR_MARK); extern int complete_array_type (tree *, tree, bool); +extern void complete_flexible_array_elts (tree); extern tree builtin_type_for_size (int, bool); diff -Npur gcc/cp/decl.c gcc/cp/decl.c --- gcc/cp/decl.c 2018-08-22 22:35:38.000000000 +0200 +++ gcc/cp/decl.c 2018-08-30 12:06:21.377892252 +0200 @@ -6530,6 +6530,16 @@ check_initializer (tree decl, tree init, init_code = store_init_value (decl, init, cleanups, flags); + if (DECL_INITIAL (decl) + && TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR + && !vec_safe_is_empty (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)))) + { + tree elt = CONSTRUCTOR_ELTS (DECL_INITIAL (decl))->last ().value; + if (TREE_CODE (TREE_TYPE (elt)) == ARRAY_TYPE + && TYPE_SIZE (TREE_TYPE (elt)) == NULL_TREE) + cp_complete_array_type (&TREE_TYPE (elt), elt, false); + } + if (pedantic && TREE_CODE (type) == ARRAY_TYPE && DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST diff -Npur gcc/varasm.c gcc/varasm.c --- gcc/varasm.c 2018-08-16 17:28:11.000000000 +0200 +++ gcc/varasm.c 2018-08-24 12:06:21.378892238 +0200 @@ -5161,6 +5161,8 @@ output_constructor_regular_field (oc_loc on the chain is a TYPE_DECL of the enclosing struct. */ const_tree next = DECL_CHAIN (local->field); gcc_assert (!fieldsize || !next || TREE_CODE (next) != FIELD_DECL); + tree size = TYPE_SIZE_UNIT (TREE_TYPE (local->val)); + gcc_checking_assert (compare_tree_int (size, fieldsize) == 0); } else fieldsize = tree_to_uhwi (DECL_SIZE_UNIT (local->field));