From bb1f792960e1dd896529286d2d2302491959d591 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 17 Mar 2011 12:37:53 +0000 Subject: [PATCH] gigi.h (smaller_form_type_p): Declare. * gcc-interface/gigi.h (smaller_form_type_p): Declare. * gcc-interface/trans.c (smaller_form_type_p): Make global and move... * gcc-interface/utils.c (smaller_form_type_p): ...to here. (convert): Deal with conversions from a smaller form type specially. From-SVN: r171091 --- gcc/ada/ChangeLog | 7 +++++++ gcc/ada/gcc-interface/gigi.h | 3 +++ gcc/ada/gcc-interface/trans.c | 25 ------------------------ gcc/ada/gcc-interface/utils.c | 36 +++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index defad830e15..73f85e23238 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2011-03-17 Eric Botcazou + + * gcc-interface/gigi.h (smaller_form_type_p): Declare. + * gcc-interface/trans.c (smaller_form_type_p): Make global and move... + * gcc-interface/utils.c (smaller_form_type_p): ...to here. + (convert): Deal with conversions from a smaller form type specially. + 2011-02-14 Eric Botcazou * gcc-interface/misc.c (gnat_init_options): Do not concatenate -I and diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index e45cf138337..2605533a8bb 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -756,6 +756,9 @@ extern bool is_double_scalar_or_array (Entity_Id gnat_type, component of an aggregate type. */ extern bool type_for_nonaliased_component_p (tree gnu_type); +/* Return true if TYPE is a smaller form of ORIG_TYPE. */ +extern bool smaller_form_type_p (tree type, tree orig_type); + /* Return the base type of TYPE. */ extern tree get_base_type (tree type); diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index e438960ee3b..f4d31d52651 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -205,7 +205,6 @@ static tree emit_check (tree, tree, int, Node_Id); static tree build_unary_op_trapv (enum tree_code, tree, tree, Node_Id); static tree build_binary_op_trapv (enum tree_code, tree, tree, tree, Node_Id); static tree convert_with_check (Entity_Id, tree, bool, bool, bool, Node_Id); -static bool smaller_form_type_p (tree, tree); static bool addressable_p (tree, tree); static tree assoc_to_constructor (Entity_Id, Node_Id, tree); static tree extract_values (tree, tree); @@ -7222,30 +7221,6 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflowp, return convert (gnu_type, gnu_result); } -/* Return true if TYPE is a smaller form of ORIG_TYPE. */ - -static bool -smaller_form_type_p (tree type, tree orig_type) -{ - tree size, osize; - - /* We're not interested in variants here. */ - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig_type)) - return false; - - /* Like a variant, a packable version keeps the original TYPE_NAME. */ - if (TYPE_NAME (type) != TYPE_NAME (orig_type)) - return false; - - size = TYPE_SIZE (type); - osize = TYPE_SIZE (orig_type); - - if (!(TREE_CODE (size) == INTEGER_CST && TREE_CODE (osize) == INTEGER_CST)) - return false; - - return tree_int_cst_lt (size, osize) != 0; -} - /* Return true if GNU_EXPR can be directly addressed. This is the case unless it is an expression involving computation or if it involves a reference to a bitfield or to an object not sufficiently aligned for diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index eac87e0bbc9..4d40f867447 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -4043,6 +4043,18 @@ convert (tree type, tree expr) } while (TREE_CODE (child_etype) == RECORD_TYPE); } + /* If we are converting from a smaller form of record type back to it, just + make a VIEW_CONVERT_EXPR. But first pad the expression to have the same + size on both sides. */ + else if (ecode == RECORD_TYPE && code == RECORD_TYPE + && smaller_form_type_p (etype, type)) + { + expr = convert (maybe_pad_type (etype, TYPE_SIZE (type), 0, Empty, + false, false, false, true), + expr); + return build1 (VIEW_CONVERT_EXPR, type, expr); + } + /* In all other cases of related types, make a NOP_EXPR. */ else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (etype)) return fold_convert (type, expr); @@ -4672,6 +4684,30 @@ type_for_nonaliased_component_p (tree gnu_type) return true; } +/* Return true if TYPE is a smaller form of ORIG_TYPE. */ + +bool +smaller_form_type_p (tree type, tree orig_type) +{ + tree size, osize; + + /* We're not interested in variants here. */ + if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig_type)) + return false; + + /* Like a variant, a packable version keeps the original TYPE_NAME. */ + if (TYPE_NAME (type) != TYPE_NAME (orig_type)) + return false; + + size = TYPE_SIZE (type); + osize = TYPE_SIZE (orig_type); + + if (!(TREE_CODE (size) == INTEGER_CST && TREE_CODE (osize) == INTEGER_CST)) + return false; + + return tree_int_cst_lt (size, osize) != 0; +} + /* Perform final processing on global variables. */ void -- 2.30.2