diff options
author | Qing Zhao <qing.zhao@oracle.com> | 2024-05-06 16:28:01 +0000 |
---|---|---|
committer | Qing Zhao <qing.zhao@oracle.com> | 2024-05-06 18:35:09 +0000 |
commit | 6634a409124a884ff66b3756568a7daae7d3c295 (patch) | |
tree | ee2176800591f6bd6078c3754f2fe8486ee5f2e6 /gcc/c | |
parent | 93f6a47583f3fa8a1b66856ecb19ec28f26b2ba4 (diff) | |
download | gcc-6634a409124a884ff66b3756568a7daae7d3c295.zip gcc-6634a409124a884ff66b3756568a7daae7d3c295.tar.gz gcc-6634a409124a884ff66b3756568a7daae7d3c295.tar.bz2 |
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.
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/c-decl.cc | 29 |
1 files changed, 23 insertions, 6 deletions
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)); + } } } |