aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ada/ChangeLog10
-rw-r--r--gcc/ada/decl.c21
-rw-r--r--gcc/ada/trans.c2
-rw-r--r--gcc/ada/utils.c2
-rw-r--r--gcc/ada/utils2.c15
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/alignment6.adb32
7 files changed, 69 insertions, 17 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index f70e616..9b825f6 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -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
diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c
index 9d4412d..e60b443 100644
--- a/gcc/ada/decl.c
+++ b/gcc/ada/decl.c
@@ -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
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index 300ac78..a6492c5 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -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)))))
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c
index cafcc2d..e3867fa 100644
--- a/gcc/ada/utils.c
+++ b/gcc/ada/utils.c
@@ -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)));
diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c
index 5888bc5..877959d 100644
--- a/gcc/ada/utils2.c
+++ b/gcc/ada/utils2.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2d3ab19..d200785 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..f2889a5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/alignment6.adb
@@ -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" } }