* gcc-interface/gigi.h (smaller_form_type_p): Declare.
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Mar 2011 12:37:53 +0000 (12:37 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 17 Mar 2011 12:37:53 +0000 (12:37 +0000)
* 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

gcc/ada/ChangeLog
gcc/ada/gcc-interface/gigi.h
gcc/ada/gcc-interface/trans.c
gcc/ada/gcc-interface/utils.c

index defad83..73f85e2 100644 (file)
@@ -1,3 +1,10 @@
+2011-03-17  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * 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  <ebotcazou@adacore.com>
 
        * gcc-interface/misc.c (gnat_init_options): Do not concatenate -I and
index e45cf13..2605533 100644 (file)
@@ -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);
 
index e438960..f4d31d5 100644 (file)
@@ -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);
 }
 \f
-/* 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
index eac87e0..4d40f86 100644 (file)
@@ -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