diff options
author | hainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-23 16:18:49 +0000 |
---|---|---|
committer | hainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-23 16:18:49 +0000 |
commit | 150edb0704ca198f9f9f37ff133ab6210e2ff3ae (patch) | |
tree | 21e2dd58058f99241fdf55ad680c1c3ebc3dd2e5 /gcc/gimplify.c | |
parent | 457556f88e31daea3fe57e4bdf751528438331ac (diff) | |
download | gcc-150edb0704ca198f9f9f37ff133ab6210e2ff3ae.tar.gz |
* tree.c (max_int_size_in_bytes): New function, inspired from
code in function.c:assign_temp.
* tree.h (max_int_size_in_bytes): Declare.
* function.c (assign_temp): Use it.
* gimplify.c (create_tmp_var): Relax the assertions on the type
properties, not mandating constant size any more.
(force_constant_size): New static function.
(gimple_add_tmp_var): Use it, forcing variable size to a
constant upper bound if it is not constant on entry.
* ada/misc.c (gnat_type_max_size): Look at TYPE_ADA_SIZE if we have
not been able to get a constant upper bound from TYPE_SIZE_UNIT.
* gnat.dg/varsize_temp.adb: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114938 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 08c5caa63d9..965c5f2fa3c 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -479,10 +479,12 @@ create_tmp_var (tree type, const char *prefix) tree tmp_var; /* We don't allow types that are addressable (meaning we can't make copies), - incomplete, or of variable size. */ - gcc_assert (!TREE_ADDRESSABLE (type) - && COMPLETE_TYPE_P (type) - && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST); + or incomplete. We also used to reject every variable size objects here, + but now support those for which a constant upper bound can be obtained. + The processing for variable sizes is performed in gimple_add_tmp_var, + point at which it really matters and possibly reached via paths not going + through this function, e.g. after direct calls to create_tmp_var_raw. */ + gcc_assert (!TREE_ADDRESSABLE (type) && COMPLETE_TYPE_P (type)); tmp_var = create_tmp_var_raw (type, prefix); gimple_add_tmp_var (tmp_var); @@ -688,11 +690,41 @@ declare_vars (tree vars, tree scope, bool debug_info) } } +/* For VAR a VAR_DECL of variable size, try to find a constant upper bound + for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if + no such upper bound can be obtained. */ + +static void +force_constant_size (tree var) +{ + /* The only attempt we make is by querying the maximum size of objects + of the variable's type. */ + + HOST_WIDE_INT max_size; + + gcc_assert (TREE_CODE (var) == VAR_DECL); + + max_size = max_int_size_in_bytes (TREE_TYPE (var)); + + gcc_assert (max_size >= 0); + + DECL_SIZE_UNIT (var) + = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size); + DECL_SIZE (var) + = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT); +} + void gimple_add_tmp_var (tree tmp) { gcc_assert (!TREE_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp)); + /* Later processing assumes that the object size is constant, which might + not be true at this point. Force the use of a constant upper bound in + this case. */ + if (!host_integerp (DECL_SIZE_UNIT (tmp), 1)) + force_constant_size (tmp); + DECL_CONTEXT (tmp) = current_function_decl; DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1; |