Hi!
This patch prevents init values of STRING_CST and braced array initializers to reach the middle-end with incomplete type. This will allow further simplifications in the middle-end, and address existing issues with STRING_CST in a correct way. Bootstrapped and reg-tested on x86_64-pc-linux-gnu. Is it OK for trunk? Thanks Bernd.
gcc: 2018-08-24 Bernd Edlinger <bernd.edlin...@hotmail.de> * varasm.c (output_constructor_regular_field): Check TYPE_SIZE_UNIT of the init value. c-family: 2018-08-24 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-24 Bernd Edlinger <bernd.edlin...@hotmail.de> * c-decl.c (finish_decl): Call complete_flexible_array_elts. cp: 2018-08-24 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-24 12:06:21.377892252 +0200 @@ -6528,6 +6528,8 @@ check_initializer (tree decl, tree init, init_code = store_init_value (decl, init, cleanups, flags); + complete_flexible_array_elts (DECL_INITIAL (decl)); + 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));