* gcc-interface/utils.c (maybe_unconstrained_array): Declare TYPE local
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Sep 2011 09:03:52 +0000 (09:03 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 26 Sep 2011 09:03:52 +0000 (09:03 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179186 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/ChangeLog
gcc/ada/gcc-interface/utils.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/array17.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/array17_pkg.ads [new file with mode: 0644]

index b9b3051..4a4b64e 100644 (file)
@@ -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.
index 553ca3f..feae636 100644 (file)
@@ -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:
index 1a39c28..8f11de1 100644 (file)
@@ -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 (file)
index 0000000..8814ee2
--- /dev/null
@@ -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 (file)
index 0000000..11ad79f
--- /dev/null
@@ -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;