aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog8
-rw-r--r--gcc/ada/gcc-interface/utils.c63
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/array17.adb11
-rw-r--r--gcc/testsuite/gnat.dg/array17_pkg.ads8
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;