[Ada] Small tweak to conversion to padding types

Message ID 8316785.RfypTi7oKd@polaris
State New
Headers show
Series
  • [Ada] Small tweak to conversion to padding types
Related show

Commit Message

Eric Botcazou Sept. 9, 2017, 10:36 a.m.
While investigating another issue, I came across a case where a simple 
assignment gives rise to the creation of two CONSTRUCTORS in a row when a 
padding type is involved.  I think we can get away with only one.

Tested on x86_64-suse-linux, applied on the mainline.


2017-09-09  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/utils.c (convert): When converting to a padding type,
	reuse an existing CONSTRUCTOR if it has got the right size.

Patch

Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 251906)
+++ gcc-interface/utils.c	(working copy)
@@ -4219,8 +4219,6 @@  convert (tree type, tree expr)
      constructor to build the record, unless a variable size is involved.  */
   else if (code == RECORD_TYPE && TYPE_PADDING_P (type))
     {
-      vec<constructor_elt, va_gc> *v;
-
       /* If we previously converted from another type and our type is
 	 of variable size, remove the conversion to avoid the need for
 	 variable-sized temporaries.  Likewise for a conversion between
@@ -4272,9 +4270,21 @@  convert (tree type, tree expr)
 					   expr),
 				  false);
 
+      tree t = convert (TREE_TYPE (TYPE_FIELDS (type)), expr);
+
+      /* If converting to the inner type has already created a CONSTRUCTOR with
+         the right size, then reuse it instead of creating another one.  This
+         can happen for the padding type built to overalign local variables.  */
+      if (TREE_CODE (t) == VIEW_CONVERT_EXPR
+	  && TREE_CODE (TREE_OPERAND (t, 0)) == CONSTRUCTOR
+	  && TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (t, 0))))
+	  && tree_int_cst_equal (TYPE_SIZE (type),
+				 TYPE_SIZE (TREE_TYPE (TREE_OPERAND (t, 0)))))
+	return build1 (VIEW_CONVERT_EXPR, type, TREE_OPERAND (t, 0));
+
+      vec<constructor_elt, va_gc> *v;
       vec_alloc (v, 1);
-      CONSTRUCTOR_APPEND_ELT (v, TYPE_FIELDS (type),
-			      convert (TREE_TYPE (TYPE_FIELDS (type)), expr));
+      CONSTRUCTOR_APPEND_ELT (v, TYPE_FIELDS (type), t);
       return gnat_build_constructor (type, v);
     }