diff options
author | Olivier Hainque <hainque@adacore.com> | 2006-06-23 16:18:49 +0000 |
---|---|---|
committer | Olivier Hainque <hainque@gcc.gnu.org> | 2006-06-23 16:18:49 +0000 |
commit | a441447f7f6495bb8a8e6d160d7c095da787e708 (patch) | |
tree | 21e2dd58058f99241fdf55ad680c1c3ebc3dd2e5 /gcc/ada/misc.c | |
parent | a3d536f1c1c0aa3d414c17c4acc44c900b1f1e38 (diff) | |
download | gcc-a441447f7f6495bb8a8e6d160d7c095da787e708.zip gcc-a441447f7f6495bb8a8e6d160d7c095da787e708.tar.gz gcc-a441447f7f6495bb8a8e6d160d7c095da787e708.tar.bz2 |
tree.c (max_int_size_in_bytes): New function, inspired from code in function.c:assign_temp.
* 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.
From-SVN: r114938
Diffstat (limited to 'gcc/ada/misc.c')
-rw-r--r-- | gcc/ada/misc.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c index 2f68e42..47206da 100644 --- a/gcc/ada/misc.c +++ b/gcc/ada/misc.c @@ -745,13 +745,40 @@ gnat_get_alias_set (tree type) return -1; } -/* GNU_TYPE is a type. Return its maxium size in bytes, if known. */ +/* GNU_TYPE is a type. Return its maxium size in bytes, if known, + as a constant when possible. */ static tree -gnat_type_max_size (gnu_type) - tree gnu_type; +gnat_type_max_size (tree gnu_type) { - return max_size (TYPE_SIZE_UNIT (gnu_type), true); + /* First see what we can get from TYPE_SIZE_UNIT, which might not be + constant even for simple expressions if it has already been gimplified + and replaced by a VAR_DECL. */ + + tree max_unitsize = max_size (TYPE_SIZE_UNIT (gnu_type), true); + + /* If we don't have a constant, see what we can get from TYPE_ADA_SIZE, + typically not gimplified. */ + + if (!host_integerp (max_unitsize, 1) + && (TREE_CODE (gnu_type) == RECORD_TYPE + || TREE_CODE (gnu_type) == UNION_TYPE + || TREE_CODE (gnu_type) == QUAL_UNION_TYPE) + && TYPE_ADA_SIZE (gnu_type)) + { + tree max_adasize = max_size (TYPE_ADA_SIZE (gnu_type), true); + + /* If we have succeded in finding a constant, round it up to the + type's alignment and return the result in byte units. */ + + if (host_integerp (max_adasize, 1)) + max_unitsize + = size_binop (CEIL_DIV_EXPR, + round_up (max_adasize, TYPE_ALIGN (gnu_type)), + bitsize_unit_node); + } + + return max_unitsize; } /* GNU_TYPE is a type. Determine if it should be passed by reference by |