diff options
author | Richard Sandiford <richard@codesourcery.com> | 2006-01-19 07:35:47 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2006-01-19 07:35:47 +0000 |
commit | 1f0f7cebf9eccfa3c9bac5c2602a261c487c86d2 (patch) | |
tree | 887b3e85fac5c0dbaab29803fab659be8bc0ce7a /gcc/c-decl.c | |
parent | c888c93b290aeb3f7eb556bd5b7ed4f7564c822a (diff) | |
download | gcc-1f0f7cebf9eccfa3c9bac5c2602a261c487c86d2.zip gcc-1f0f7cebf9eccfa3c9bac5c2602a261c487c86d2.tar.gz gcc-1f0f7cebf9eccfa3c9bac5c2602a261c487c86d2.tar.bz2 |
re PR c/25805 (Incorrect handling of zero-initialized flexible arrays)
PR c/25805
* c-decl.c (add_flexible_array_elts_to_size): New function.
(finish_decl): Use it.
testsuite/
PR c/25805
* gcc.dg/pr25805.c: New file.
From-SVN: r109946
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index a3b56c0..8320aca 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -3068,6 +3068,35 @@ set_array_declarator_inner (struct c_declarator *decl, error ("static or type qualifiers in abstract declarator"); return decl; } + +/* 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. */ + +static void +add_flexible_array_elts_to_size (tree decl, tree init) +{ + unsigned int size; + tree elt, type; + + size = VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)); + if (size == 0) + return; + + elt = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (init), size - 1)->value; + type = TREE_TYPE (elt); + if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_SIZE (type) == NULL_TREE + && TYPE_DOMAIN (type) != NULL_TREE + && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE) + { + 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)); + } +} /* Decode a "typename", such as "int **", returning a ..._TYPE node. */ @@ -3367,6 +3396,9 @@ finish_decl (tree decl, tree init, tree asmspec_tree) if (TREE_CODE (decl) == VAR_DECL) { + if (init && TREE_CODE (init) == CONSTRUCTOR) + add_flexible_array_elts_to_size (decl, init); + if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node && COMPLETE_TYPE_P (TREE_TYPE (decl))) layout_decl (decl, 0); |