decl.c (gnat_to_gnu_entity): Also promote the alignment of constant objects, but...
authorEric Botcazou <ebotcazou@adacore.com>
Sun, 20 Apr 2008 10:32:55 +0000 (10:32 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 20 Apr 2008 10:32:55 +0000 (10:32 +0000)
* decl.c (gnat_to_gnu_entity) <object>: Also promote the alignment of
constant objects, but not exceptions.
* trans.c (add_decl_expr): Use gnat_types_compatible_p for type
compatibility test.
* utils.c (create_var_decl_1): Likewise.
* utils2.c (build_binary_op) <MODIFY_EXPR>: Also use the padded view of
the type when copying to padded object and the source is a constructor.

From-SVN: r134483

gcc/ada/ChangeLog
gcc/ada/decl.c
gcc/ada/trans.c
gcc/ada/utils.c
gcc/ada/utils2.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/alignment6.adb [new file with mode: 0644]

index f70e616a29e0fe982a46191eb592ba9b8f5bfeff..9b825f6ad37e6669e560865628deb065406ff9a9 100644 (file)
@@ -1,3 +1,13 @@
+2008-04-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * decl.c (gnat_to_gnu_entity) <object>: Also promote the alignment of
+       constant objects, but not exceptions.
+       * trans.c (add_decl_expr): Use gnat_types_compatible_p for type
+       compatibility test.
+       * utils.c (create_var_decl_1): Likewise.
+       * utils2.c (build_binary_op) <MODIFY_EXPR>: Also use the padded view of
+       the type when copying to padded object and the source is a constructor.
+
 2008-04-18  Eric Botcazou  <ebotcazou@adacore.com>
 
        * decl.c (gnat_to_gnu_entity) <object>: When trying to promote the
index 9d4412dc35851873fe551b401649202592ff4ce7..e60b44348436ae8e409f5709f38afd4a67ce96e6 100644 (file)
@@ -673,18 +673,21 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
            && !Present (Address_Clause (gnat_entity)))
          gnu_size = bitsize_unit_node;
 
-       /* If this is an object with no specified size and alignment, and if
-          either it is atomic or we are not optimizing alignment for space
-          and it is a non-scalar variable, and the size of its type is a
-          constant, set the alignment to the smallest not less than the
-          size, or to the biggest meaningful one, whichever is smaller.  */
+       /* If this is an object with no specified size and alignment, and
+          if either it is atomic or we are not optimizing alignment for
+          space and it is composite and not an exception, an Out parameter
+          or a reference to another object, and the size of its type is a
+          constant, set the alignment to the smallest one which is not
+          smaller than the size, with an appropriate cap.  */
        if (!gnu_size && align == 0
            && (Is_Atomic (gnat_entity)
                || (!Optimize_Alignment_Space (gnat_entity)
-                   && kind == E_Variable
-                   && AGGREGATE_TYPE_P (gnu_type)
-                   && !const_flag && No (Renamed_Object (gnat_entity))
-                   && !imported_p && No (Address_Clause (gnat_entity))))
+                   && kind != E_Exception
+                   && kind != E_Out_Parameter
+                   && Is_Composite_Type (Etype (gnat_entity))
+                   && !imported_p
+                   && No (Renamed_Object (gnat_entity))
+                   && No (Address_Clause (gnat_entity))))
            && TREE_CODE (TYPE_SIZE (gnu_type)) == INTEGER_CST)
          {
            /* No point in jumping through all the hoops needed in order
index 300ac780f200ab211af54208764a41d0f172fb13..a6492c50269ec2b4485503675c4f93082b98a7e8 100644 (file)
@@ -5098,7 +5098,7 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
      valid for the context.  Similar to init_const in create_var_decl_1.  */
   if (TREE_CODE (gnu_decl) == VAR_DECL
       && (gnu_init = DECL_INITIAL (gnu_decl)) != NULL_TREE
-      && (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (gnu_init))
+      && (!gnat_types_compatible_p (type, TREE_TYPE (gnu_init))
          || (TREE_STATIC (gnu_decl)
              && !initializer_constant_valid_p (gnu_init,
                                                TREE_TYPE (gnu_init)))))
index cafcc2d9770858a1f82a1e44aac53706716dd340..e3867fa69127c070de82f34091c6d75087462358 100644 (file)
@@ -1447,7 +1447,7 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init,
 {
   bool init_const
     = (var_init != 0
-       && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (var_init))
+       && gnat_types_compatible_p (type, TREE_TYPE (var_init))
        && (global_bindings_p () || static_flag
           ? initializer_constant_valid_p (var_init, TREE_TYPE (var_init)) != 0
           : TREE_CONSTANT (var_init)));
index 5888bc583c47ad3b4f26edb0b0c21ad075fedb59..877959d946cc3dfdf81b79d3bc81e47964ffa2cc 100644 (file)
@@ -695,16 +695,19 @@ build_binary_op (enum tree_code op_code, tree result_type,
 
       /* If we are copying between padded objects of the same underlying
         type with a non-zero size, use the padded view of the type, this
-        is very likely more efficient.  */
+        is very likely more efficient; but gnat_to_gnu will have removed
+        the padding on the RHS so we have to make sure that we can safely
+        put it back.  */
       else if (TREE_CODE (left_type) == RECORD_TYPE
               && TYPE_IS_PADDING_P (left_type)
               && TREE_TYPE (TYPE_FIELDS (left_type)) == right_type
               && !integer_zerop (TYPE_SIZE (right_type))
-              && TREE_CODE (right_operand) == COMPONENT_REF
-              && TREE_CODE (TREE_TYPE (TREE_OPERAND (right_operand, 0)))
-                 == RECORD_TYPE
-              && TYPE_IS_PADDING_P
-                 (TREE_TYPE (TREE_OPERAND (right_operand, 0))))
+              && ((TREE_CODE (right_operand) == COMPONENT_REF
+                   && TREE_CODE (TREE_TYPE (TREE_OPERAND (right_operand, 0)))
+                      == RECORD_TYPE
+                   && TYPE_IS_PADDING_P
+                      (TREE_TYPE (TREE_OPERAND (right_operand, 0))))
+                  || TREE_CODE (right_operand) == CONSTRUCTOR))
        operation_type = left_type;
 
       /* Find the best type to use for copying between aggregate types.  */
index 2d3ab1903f3fcf8ff6eec0f3a755e621f8383ac5..d200785acb6a1d363c871d4480fd4e3006b6f84b 100644 (file)
@@ -1,3 +1,7 @@
+2008-04-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/alignment6.adb: New test.
+
 2008-04-19  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/35944
diff --git a/gcc/testsuite/gnat.dg/alignment6.adb b/gcc/testsuite/gnat.dg/alignment6.adb
new file mode 100644 (file)
index 0000000..f2889a5
--- /dev/null
@@ -0,0 +1,32 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws -fdump-tree-gimple" }
+
+procedure Alignment6 is
+
+   type MY_REC is
+     record
+       A1 : INTEGER range -3 .. 3 ; -- symmetric
+       A2 : BOOLEAN ;
+       A3 : INTEGER range 0 .. 15 ; -- positive
+       A4 : INTEGER range 10 .. 100 ; -- arbitrary
+       A5 : BOOLEAN ;  --5
+     end record ;
+
+   for MY_REC use
+     record
+       A1 at 0 range 0 .. 2 ;
+       A2 at 0 range 3 .. 3 ;
+       A3 at 0 range 4 .. 7 ;
+       A4 at 0 range 8 .. 15 ;
+       A5 at 0 range 16 .. 16 ;
+     end record ;
+
+   A_REC : MY_REC := ( 1 , TRUE , 7 , 11 , FALSE );
+   B_REC : MY_REC;
+
+begin
+   B_REC := A_REC;
+end;
+
+-- { dg-final { scan-tree-dump-not "VIEW_CONVERT_EXPR" "gimple" } }
+-- { dg-final { cleanup-tree-dump "gimple" } }