diff options
-rw-r--r-- | gcc/ada/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/ada/decl.c | 21 | ||||
-rw-r--r-- | gcc/ada/trans.c | 2 | ||||
-rw-r--r-- | gcc/ada/utils.c | 2 | ||||
-rw-r--r-- | gcc/ada/utils2.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/alignment6.adb | 32 |
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" } } |