From e871a8730ae8bd2a50a47a6c87691078e2e7fff6 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 20 Apr 2008 10:32:55 +0000 Subject: [PATCH] decl.c (gnat_to_gnu_entity): Also promote the alignment of constant objects, but not exceptions. * decl.c (gnat_to_gnu_entity) : 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) : 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 | 10 +++++++++ gcc/ada/decl.c | 21 ++++++++++-------- gcc/ada/trans.c | 2 +- gcc/ada/utils.c | 2 +- gcc/ada/utils2.c | 15 +++++++------ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/alignment6.adb | 32 ++++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/alignment6.adb diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index f70e616a29e..9b825f6ad37 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,13 @@ +2008-04-20 Eric Botcazou + + * decl.c (gnat_to_gnu_entity) : 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) : Also use the padded view of + the type when copying to padded object and the source is a constructor. + 2008-04-18 Eric Botcazou * decl.c (gnat_to_gnu_entity) : When trying to promote the diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c index 9d4412dc358..e60b4434843 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 300ac780f20..a6492c50269 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 cafcc2d9770..e3867fa6912 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 5888bc583c4..877959d946c 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 2d3ab1903f3..d200785acb6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-04-20 Eric Botcazou + + * gnat.dg/alignment6.adb: New test. + 2008-04-19 Paul Thomas PR fortran/35944 diff --git a/gcc/testsuite/gnat.dg/alignment6.adb b/gcc/testsuite/gnat.dg/alignment6.adb new file mode 100644 index 00000000000..f2889a50ecf --- /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" } } -- 2.30.2