summaryrefslogtreecommitdiffstats
path: root/gcc/ada/gcc-interface
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-17 12:37:53 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-17 12:37:53 +0000
commita88c860860c898d60be14069b5bf045c8fb19694 (patch)
tree0f84b2c4de3fdba8e07cd150c30e22214ec75896 /gcc/ada/gcc-interface
parent1242bee6bd318640a198f783eff49fcb086e94c5 (diff)
downloadppe42-gcc-a88c860860c898d60be14069b5bf045c8fb19694.tar.gz
ppe42-gcc-a88c860860c898d60be14069b5bf045c8fb19694.zip
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171091 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r--gcc/ada/gcc-interface/gigi.h3
-rw-r--r--gcc/ada/gcc-interface/trans.c25
-rw-r--r--gcc/ada/gcc-interface/utils.c36
3 files changed, 39 insertions, 25 deletions
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
OpenPOWER on IntegriCloud