aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2011-09-08 21:12:37 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2011-09-08 21:12:37 +0000
commit416de7d54948f6a493fa0ea9476a045ee2d35cb8 (patch)
treed576fe6f01cff202e1a0b2a1d8cea0750707bd45
parentc3c5a1ccc0c0db8f4a1432c293135895343970d5 (diff)
downloadgcc-416de7d54948f6a493fa0ea9476a045ee2d35cb8.zip
gcc-416de7d54948f6a493fa0ea9476a045ee2d35cb8.tar.gz
gcc-416de7d54948f6a493fa0ea9476a045ee2d35cb8.tar.bz2
utils.c (unchecked_convert): Use a field of the right precision when converting to or from an integral type...
* gcc-interface/utils.c (unchecked_convert): Use a field of the right precision when converting to or from an integral type whose precision is not equal to its size. From-SVN: r178711
-rw-r--r--gcc/ada/ChangeLog13
-rw-r--r--gcc/ada/gcc-interface/utils.c37
2 files changed, 38 insertions, 12 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index d1c5204..74b3cfb 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,11 +1,16 @@
+2011-09-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/utils.c (unchecked_convert): Use a field of the right
+ precision when converting to or from an integral type whose precision
+ is not equal to its size.
+
2011-09-08 Iain Sandoe <iains@gcc.gnu.org>
- * traceback.c (Darwin) USE_GCC_UNWINDER for Darwin
- versions >= 8.
+ * traceback.c (Darwin) USE_GCC_UNWINDER for Darwin versions >= 8.
2011-09-07 Iain Sandoe <iains@gcc.gnu.org>
- * gcc-interface/Makefile.in (darwin): Provide powerpc64 system
+ * gcc-interface/Makefile.in (darwin): Provide powerpc64 system
implementation.
* system-darwin-ppc64.ads: New file.
@@ -21,7 +26,7 @@
2011-09-06 Iain Sandoe <iains@gcc.gnu.org>
- * gcc-interface/Makefile.in (x86_64 darwin arch): Adjust
+ * gcc-interface/Makefile.in (x86_64 darwin arch): Adjust
LIBGNAT_TARGET_PAIRS for x86 and x86_64 variants.
2011-09-06 Arnaud Charlet <charlet@adacore.com>
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 1ea34b1..1a10347 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -4403,39 +4403,60 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
}
/* If we are converting to an integral type whose precision is not equal
- to its size, first unchecked convert to a record that contains an
- object of the output type. Then extract the field. */
+ to its size, first unchecked convert to a record type that contains an
+ field of the given precision. Then extract the field. */
else if (INTEGRAL_TYPE_P (type)
&& TYPE_RM_SIZE (type)
&& 0 != compare_tree_int (TYPE_RM_SIZE (type),
GET_MODE_BITSIZE (TYPE_MODE (type))))
{
tree rec_type = make_node (RECORD_TYPE);
- tree field = create_field_decl (get_identifier ("OBJ"), type, rec_type,
- NULL_TREE, NULL_TREE, 1, 0);
+ unsigned HOST_WIDE_INT prec = TREE_INT_CST_LOW (TYPE_RM_SIZE (type));
+ tree field_type, field;
+
+ if (TYPE_UNSIGNED (type))
+ field_type = make_unsigned_type (prec);
+ else
+ field_type = make_signed_type (prec);
+ SET_TYPE_RM_SIZE (field_type, TYPE_RM_SIZE (type));
+
+ field = create_field_decl (get_identifier ("OBJ"), field_type, rec_type,
+ NULL_TREE, NULL_TREE, 1, 0);
TYPE_FIELDS (rec_type) = field;
layout_type (rec_type);
expr = unchecked_convert (rec_type, expr, notrunc_p);
expr = build_component_ref (expr, NULL_TREE, field, false);
+ expr = fold_build1 (NOP_EXPR, type, expr);
}
- /* Similarly if we are converting from an integral type whose precision
- is not equal to its size. */
+ /* Similarly if we are converting from an integral type whose precision is
+ not equal to its size, first copy into a field of the given precision
+ and unchecked convert the record type. */
else if (INTEGRAL_TYPE_P (etype)
&& TYPE_RM_SIZE (etype)
&& 0 != compare_tree_int (TYPE_RM_SIZE (etype),
GET_MODE_BITSIZE (TYPE_MODE (etype))))
{
tree rec_type = make_node (RECORD_TYPE);
- tree field = create_field_decl (get_identifier ("OBJ"), etype, rec_type,
- NULL_TREE, NULL_TREE, 1, 0);
+ unsigned HOST_WIDE_INT prec = TREE_INT_CST_LOW (TYPE_RM_SIZE (etype));
VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 1);
+ tree field_type, field;
+
+ if (TYPE_UNSIGNED (etype))
+ field_type = make_unsigned_type (prec);
+ else
+ field_type = make_signed_type (prec);
+ SET_TYPE_RM_SIZE (field_type, TYPE_RM_SIZE (etype));
+
+ field = create_field_decl (get_identifier ("OBJ"), field_type, rec_type,
+ NULL_TREE, NULL_TREE, 1, 0);
TYPE_FIELDS (rec_type) = field;
layout_type (rec_type);
+ expr = fold_build1 (NOP_EXPR, field_type, expr);
CONSTRUCTOR_APPEND_ELT (v, field, expr);
expr = gnat_build_constructor (rec_type, v);
expr = unchecked_convert (type, expr, notrunc_p);