From 6634a409124a884ff66b3756568a7daae7d3c295 Mon Sep 17 00:00:00 2001 From: Qing Zhao Date: Mon, 6 May 2024 16:28:01 +0000 Subject: Update the C FE routine "add_flexible_array_elts_to_size" C++ FE routine "layout_var_decl" to handle the cases when the DECL is union. PR c/53548 Add testing cases to test the _bos for flexible array members in unions or alone in structures. gcc/c/ChangeLog: PR c/53548 * c-decl.cc (add_flexible_array_elts_to_size): Handle the cases when the DECL is union. gcc/cp/ChangeLog: PR c/53548 * decl.cc (layout_var_decl): Handle the cases when the DECL is union with a flexible array member initializer. gcc/testsuite/ChangeLog: PR c/53548 * c-c++-common/fam-in-union-alone-in-struct-bos-1.c: New test. * c-c++-common/fam-in-union-alone-in-struct-bos.c: New test. --- gcc/c/c-decl.cc | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 9ef2ab2..b691b91 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -5339,8 +5339,9 @@ zero_length_array_type_p (const_tree type) } /* INIT is a constructor that forms DECL's initializer. If the final - element initializes a flexible array field, add the size of that - initializer to DECL's size. */ + element initializes a flexible array field, adjust the size of the + DECL with the initializer based on whether the DECL is a union or + a structure. */ static void add_flexible_array_elts_to_size (tree decl, tree init) @@ -5355,10 +5356,26 @@ add_flexible_array_elts_to_size (tree decl, tree init) if (flexible_array_member_type_p (type)) { complete_array_type (&type, elt, false); - DECL_SIZE (decl) - = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type)); - DECL_SIZE_UNIT (decl) - = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl), TYPE_SIZE_UNIT (type)); + /* For a structure, add the size of the initializer to the DECL's + size. */ + if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE) + { + DECL_SIZE (decl) + = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (type)); + DECL_SIZE_UNIT (decl) + = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl), + TYPE_SIZE_UNIT (type)); + } + /* For a union, the DECL's size is the maximum of the current size + and the size of the initializer. */ + else + { + DECL_SIZE (decl) + = size_binop (MAX_EXPR, DECL_SIZE (decl), TYPE_SIZE (type)); + DECL_SIZE_UNIT (decl) + = size_binop (MAX_EXPR, DECL_SIZE_UNIT (decl), + TYPE_SIZE_UNIT (type)); + } } } -- cgit v1.1