decl.c (gnat_to_gnu_entity): Retrofit handling of unconstrained array types as design...
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 29 Feb 2016 09:30:09 +0000 (09:30 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 29 Feb 2016 09:30:09 +0000 (09:30 +0000)
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Access_Type>: Retrofit
handling of unconstrained array types as designated types into common
processing.  Also handle array types as incomplete designated types.

From-SVN: r233807

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/testsuite/gnat.dg/incomplete4.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/incomplete4_pkg.ads [new file with mode: 0644]

index ebb7b0e45d83a8485a209705581cd83f62cbcf78..cda8be6e122c5fe2c595de9df4ad3c588d46ff3c 100644 (file)
@@ -1,3 +1,9 @@
+2016-02-29  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Access_Type>: Retrofit
+       handling of unconstrained array types as designated types into common
+       processing.  Also handle array types as incomplete designated types.
+
 2016-02-29  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/decl.c (gnat_to_gnu_entity) <Concurrent types>: In
index af85e8080afd804d33faec581ae233695c48fa1a..7ea5ff869e6cde94b8df5da93f51afad2b07e666 100644 (file)
@@ -3855,8 +3855,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
        /* The type actually used to represent the designated type, either
           gnat_desig_full or gnat_desig_equiv.  */
        Entity_Id gnat_desig_rep;
-       /* True if this is a pointer to an unconstrained array.  */
-       bool is_unconstrained_array;
        /* We want to know if we'll be seeing the freeze node for any
           incomplete type we may be pointing to.  */
        bool in_main_unit
@@ -3890,62 +3888,26 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                    && Ekind (Etype (gnat_desig_full)) == E_Record_Type)))
          gnat_desig_full = Etype (gnat_desig_full);
 
-       /* Set the type that's actually the representation of the designated
-          type and also flag whether we have a unconstrained array.  */
+       /* Set the type that's the representation of the designated type.  */
        gnat_desig_rep
          = Present (gnat_desig_full) ? gnat_desig_full : gnat_desig_equiv;
-       is_unconstrained_array
-         = Is_Array_Type (gnat_desig_rep) && !Is_Constrained (gnat_desig_rep);
-
-       /* If we are pointing to an incomplete type whose completion is an
-          unconstrained array, make dummy fat and thin pointer types to it.
-          Likewise if the type itself is dummy or an unconstrained array.  */
-       if (is_unconstrained_array
-           && (Present (gnat_desig_full)
-               || (present_gnu_tree (gnat_desig_equiv)
-                   && TYPE_IS_DUMMY_P
-                      (TREE_TYPE (get_gnu_tree (gnat_desig_equiv))))
-               || (!in_main_unit
-                   && defer_incomplete_level != 0
-                   && !present_gnu_tree (gnat_desig_equiv))
-               || (in_main_unit
-                   && is_from_limited_with
-                   && Present (Freeze_Node (gnat_desig_equiv)))))
-         {
-           if (present_gnu_tree (gnat_desig_rep))
-             gnu_desig_type = TREE_TYPE (get_gnu_tree (gnat_desig_rep));
-           else
-             {
-               gnu_desig_type = make_dummy_type (gnat_desig_rep);
-               made_dummy = true;
-             }
-
-           /* If the call above got something that has a pointer, the pointer
-              is our type.  This could have happened either because the type
-              was elaborated or because somebody else executed the code.  */
-           if (!TYPE_POINTER_TO (gnu_desig_type))
-             build_dummy_unc_pointer_types (gnat_desig_equiv, gnu_desig_type);
-           gnu_type = TYPE_POINTER_TO (gnu_desig_type);
-         }
 
        /* If we already know what the full type is, use it.  */
-       else if (Present (gnat_desig_full)
-                && present_gnu_tree (gnat_desig_full))
+       if (Present (gnat_desig_full) && present_gnu_tree (gnat_desig_full))
          gnu_desig_type = TREE_TYPE (get_gnu_tree (gnat_desig_full));
 
        /* Get the type of the thing we are to point to and build a pointer to
           it.  If it is a reference to an incomplete or private type with a
-          full view that is a record, make a dummy type node and get the
-          actual type later when we have verified it is safe.  */
+          full view that is a record or an array, make a dummy type node and
+          get the actual type later when we have verified it is safe.  */
        else if ((!in_main_unit
                  && !present_gnu_tree (gnat_desig_equiv)
                  && Present (gnat_desig_full)
-                 && !present_gnu_tree (gnat_desig_full)
-                 && Is_Record_Type (gnat_desig_full))
+                 && (Is_Record_Type (gnat_desig_full)
+                     || Is_Array_Type (gnat_desig_full)))
                 /* Likewise if we are pointing to a record or array and we are
                    to defer elaborating incomplete types.  We do this as this
-                   access type may be the full view of a private type.  Note
-                   that the unconstrained array case is handled above.  */
+                   access type may be the full view of a private type.  */
                 || ((!in_main_unit || imported_p)
                     && defer_incomplete_level != 0
                     && !present_gnu_tree (gnat_desig_equiv)
@@ -3958,11 +3920,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                    in which case we make the dummy type and it will be reused
                    when the declaration is finally processed.  In both cases,
                    the pointer eventually created below will be automatically
-                   adjusted when the freeze node is processed.  Note that the
-                   unconstrained array case is handled above.  */
-                ||  (in_main_unit
-                     && is_from_limited_with
-                     && Present (Freeze_Node (gnat_desig_rep))))
+                   adjusted when the freeze node is processed.  */
+                || (in_main_unit
+                    && is_from_limited_with
+                    && Present (Freeze_Node (gnat_desig_rep))))
          {
            gnu_desig_type = make_dummy_type (gnat_desig_equiv);
            made_dummy = true;
@@ -3995,8 +3956,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
            break;
          }
 
+       /* For an unconstrained array, make dummy fat & thin pointer types.  */
+       if (Is_Array_Type (gnat_desig_rep) && !Is_Constrained (gnat_desig_rep))
+         {
+           /* If the processing above got something that has a pointer, then
+              we are done.  This could have happened either because the type
+              was elaborated or because somebody else executed the code.  */
+           if (!TYPE_POINTER_TO (gnu_desig_type))
+             build_dummy_unc_pointer_types (gnat_desig_equiv, gnu_desig_type);
+           gnu_type = TYPE_POINTER_TO (gnu_desig_type);
+         }
+
        /* If we haven't done it yet, build the pointer type the usual way.  */
-       if (!gnu_type)
+       else if (!gnu_type)
          {
            /* Modify the designated type if we are pointing only to constant
               objects, but don't do it for unconstrained arrays.  */
diff --git a/gcc/testsuite/gnat.dg/incomplete4.adb b/gcc/testsuite/gnat.dg/incomplete4.adb
new file mode 100644 (file)
index 0000000..2191d38
--- /dev/null
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+
+with Incomplete4_Pkg; use Incomplete4_Pkg;
+with System;
+
+procedure Incomplete4 is
+  L : System.Address := A'Address;
+begin
+  null;
+end;
diff --git a/gcc/testsuite/gnat.dg/incomplete4_pkg.ads b/gcc/testsuite/gnat.dg/incomplete4_pkg.ads
new file mode 100644 (file)
index 0000000..992986e
--- /dev/null
@@ -0,0 +1,9 @@
+package Incomplete4_Pkg is
+
+   type Circular_Type;
+   type Ptr is access Circular_Type;
+   type Circular_Type is array (1..100) of Ptr;
+
+   A : Circular_Type;
+
+end Incomplete4_Pkg;