diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ada/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 63 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/array17.adb | 11 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/array17_pkg.ads | 8 |
5 files changed, 63 insertions, 32 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b9b3051..4a4b64e 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,13 @@ 2011-09-26 Eric Botcazou <ebotcazou@adacore.com> + * gcc-interface/utils.c (maybe_unconstrained_array): Declare TYPE local + variable and use it throughout. + <UNCONSTRAINED_ARRAY_TYPE>: Add 'break' at the end. + <RECORD_TYPE>: Do not unconditionally convert to the unpadded type as a + first step. Also convert to the unpadded type as a last step. + +2011-09-26 Eric Botcazou <ebotcazou@adacore.com> + * gcc-interface/gigi.h (create_subprog_decl): Replace TREE_CHAIN with DECL_CHAIN in comment. * gcc-interface/trans.c (gigi): Likewise. diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 553ca3f..feae636 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -4264,8 +4264,9 @@ tree maybe_unconstrained_array (tree exp) { enum tree_code code = TREE_CODE (exp); + tree type = TREE_TYPE (exp); - switch (TREE_CODE (TREE_TYPE (exp))) + switch (TREE_CODE (type)) { case UNCONSTRAINED_ARRAY_TYPE: if (code == UNCONSTRAINED_ARRAY_REF) @@ -4274,68 +4275,66 @@ maybe_unconstrained_array (tree exp) const bool no_trap = TREE_THIS_NOTRAP (exp); exp = TREE_OPERAND (exp, 0); + type = TREE_TYPE (exp); + if (TREE_CODE (exp) == COND_EXPR) { tree op1 = build_unary_op (INDIRECT_REF, NULL_TREE, build_component_ref (TREE_OPERAND (exp, 1), NULL_TREE, - TYPE_FIELDS - (TREE_TYPE (exp)), + TYPE_FIELDS (type), false)); tree op2 = build_unary_op (INDIRECT_REF, NULL_TREE, build_component_ref (TREE_OPERAND (exp, 2), NULL_TREE, - TYPE_FIELDS - (TREE_TYPE (exp)), + TYPE_FIELDS (type), false)); exp = build3 (COND_EXPR, - TREE_TYPE (TREE_TYPE (TYPE_FIELDS - (TREE_TYPE (exp)))), + TREE_TYPE (TREE_TYPE (TYPE_FIELDS (type))), TREE_OPERAND (exp, 0), op1, op2); } else { exp = build_unary_op (INDIRECT_REF, NULL_TREE, build_component_ref (exp, NULL_TREE, - TYPE_FIELDS - (TREE_TYPE (exp)), + TYPE_FIELDS (type), false)); TREE_READONLY (exp) = read_only; TREE_THIS_NOTRAP (exp) = no_trap; } - - return exp; } else if (code == NULL_EXPR) - return build1 (NULL_EXPR, - TREE_TYPE (TREE_TYPE (TYPE_FIELDS - (TREE_TYPE (TREE_TYPE (exp))))), - TREE_OPERAND (exp, 0)); + exp = build1 (NULL_EXPR, + TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))), + TREE_OPERAND (exp, 0)); + break; case RECORD_TYPE: - /* If this is a padded type, convert to the unpadded type and see if - it contains a template. */ - if (TYPE_PADDING_P (TREE_TYPE (exp))) + /* If this is a padded type and it contains a template, convert to the + unpadded type first. */ + if (TYPE_PADDING_P (type) + && TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == RECORD_TYPE + && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (TYPE_FIELDS (type)))) { - tree new_exp - = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (exp))), exp); - if (TREE_CODE (TREE_TYPE (new_exp)) == RECORD_TYPE - && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (new_exp))) - return - build_component_ref (new_exp, NULL_TREE, - DECL_CHAIN - (TYPE_FIELDS (TREE_TYPE (new_exp))), - false); + exp = convert (TREE_TYPE (TYPE_FIELDS (type)), exp); + type = TREE_TYPE (exp); + } + + if (TYPE_CONTAINS_TEMPLATE_P (type)) + { + exp = build_component_ref (exp, NULL_TREE, + DECL_CHAIN (TYPE_FIELDS (type)), + false); + type = TREE_TYPE (exp); + + /* If the array type is padded, convert to the unpadded type. */ + if (TYPE_IS_PADDING_P (type)) + exp = convert (TREE_TYPE (TYPE_FIELDS (type)), exp); } - else if (TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (exp))) - return - build_component_ref (exp, NULL_TREE, - DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (exp))), - false); break; default: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1a39c28..8f11de1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-09-26 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/array17.adb: New test. + * gnat.dg/array17_pkg.ads: New helper. + 2011-09-25 Jason Merrill <jason@redhat.com> * g++.dg/cpp0x/nsdmi-defer4.C: New. diff --git a/gcc/testsuite/gnat.dg/array17.adb b/gcc/testsuite/gnat.dg/array17.adb new file mode 100644 index 0000000..8814ee2 --- /dev/null +++ b/gcc/testsuite/gnat.dg/array17.adb @@ -0,0 +1,11 @@ +-- { dg-do compile } + +with Array17_Pkg; use Array17_Pkg; + +procedure Array17 is + X : aliased Varray := (1 .. 8 => 1.0); + Y : Varray (1 .. 8) := (others => -1.0); + R : Varray (1 .. 8); +begin + R (1 .. 4) := Y (1 .. 4) + X (1 .. 4); +end; diff --git a/gcc/testsuite/gnat.dg/array17_pkg.ads b/gcc/testsuite/gnat.dg/array17_pkg.ads new file mode 100644 index 0000000..11ad79f --- /dev/null +++ b/gcc/testsuite/gnat.dg/array17_pkg.ads @@ -0,0 +1,8 @@ +package Array17_Pkg is + + type Varray is array (Integer range <>) of Long_Float; + for Varray'Alignment use 16; + + function "+" (X, Y : Varray) return Varray; + +end Array17_Pkg; |