From: Eric Botcazou <ebotca...@adacore.com> When the allocator is of an unconstrained array type and has an initializing expression, the copy of the initializing expression must be done separately from that of the bounds.
gcc/ada/ * gcc-interface/utils2.cc (build_allocator): For unconstrained array types with a storage model and an initializing expression, copy the initialization expression separately from the bounds. In all cases with a storage model, pass the locally computed size for the store. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/gcc-interface/utils2.cc | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc index ef81f8dd56a..80d550c91e1 100644 --- a/gcc/ada/gcc-interface/utils2.cc +++ b/gcc/ada/gcc-interface/utils2.cc @@ -2439,8 +2439,8 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc, tree storage_ptr_type = build_pointer_type (storage_type); tree lhs, rhs; - size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (storage_type), - init); + size = TYPE_SIZE_UNIT (storage_type); + size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, init); /* If the size overflows, pass -1 so Storage_Error will be raised. */ if (TREE_CODE (size) == INTEGER_CST && !valid_constant_size_p (size)) @@ -2454,8 +2454,10 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc, /* If there is an initializing expression, then make a constructor for the entire object including the bounds and copy it into the object. - If there is no initializing expression, just set the bounds. */ - if (init) + If there is no initializing expression, just set the bounds. Note + that, if we have a storage model, we need to copy the initializing + expression separately from the bounds. */ + if (init && !pool_is_storage_model) { vec<constructor_elt, va_gc> *v; vec_alloc (v, 2); @@ -2472,11 +2474,28 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc, { lhs = build_component_ref (storage_deref, TYPE_FIELDS (storage_type), false); - rhs = build_template (template_type, type, NULL_TREE); + rhs = build_template (template_type, type, init); } if (pool_is_storage_model) - storage_init = build_storage_model_store (gnat_pool, lhs, rhs); + { + storage_init = build_storage_model_store (gnat_pool, lhs, rhs); + if (init) + { + start_stmt_group (); + add_stmt (storage_init); + lhs + = build_component_ref (storage_deref, + DECL_CHAIN (TYPE_FIELDS (storage_type)), + false); + rhs = init; + size = TYPE_SIZE_UNIT (TREE_TYPE (lhs)); + size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, init); + tree t = build_storage_model_store (gnat_pool, lhs, rhs, size); + add_stmt (t); + storage_init = end_stmt_group (); + } + } else storage_init = build_binary_op (INIT_EXPR, NULL_TREE, lhs, rhs); @@ -2520,7 +2539,7 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc, TREE_THIS_NOTRAP (storage_deref) = 1; if (pool_is_storage_model) storage_init - = build_storage_model_store (gnat_pool, storage_deref, init); + = build_storage_model_store (gnat_pool, storage_deref, init, size); else storage_init = build_binary_op (INIT_EXPR, NULL_TREE, storage_deref, init); -- 2.34.1