[Ada] Fix for internal error on semi-circular record aggregate
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 10 Feb 2022 11:37:56 +0000 (12:37 +0100)
committerPierre-Marie de Rodat <derodat@adacore.com>
Thu, 19 May 2022 14:05:32 +0000 (14:05 +0000)
This creates a couple of record subtypes pointing to each other through
access subtypes, and we break the circularity at the latter subtypes.

gcc/ada/

* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Record_Subtype>: If
it is a special subtype designated by an access subtype, then defer
the completion of incomplete types.

gcc/ada/gcc-interface/decl.cc

index c096b0d..075a7eb 100644 (file)
@@ -2134,6 +2134,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
           suppress expanding incomplete types.  */
        gnu_type = make_node (UNCONSTRAINED_ARRAY_TYPE);
 
+       /* The component may refer to this type, so defer completion of any
+          incomplete types.  */
        if (!definition)
          {
            defer_incomplete_level++;
@@ -3066,7 +3068,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 
        process_attributes (&gnu_type, &attr_list, true, gnat_entity);
 
-       /* If we are not defining it, suppress expanding incomplete types.  */
+       /* Some component may refer to this type, so defer completion of any
+          incomplete types.  */
        if (!definition)
          {
            defer_incomplete_level++;
@@ -3439,7 +3442,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
        {
          Entity_Id gnat_base_type = Implementation_Base_Type (gnat_entity);
 
-         if (!definition)
+         /* Some component may refer to this type, so defer completion of any
+            incomplete types.  We also need to do it for the special subtypes
+            designated by access subtypes in case they are recursive, see the
+            E_Access_Subtype case below.  */
+         if (!definition
+             || (Is_Itype (gnat_entity)
+                 && Is_Frozen (gnat_entity)
+                 && No (Freeze_Node (gnat_entity))))
            {
              defer_incomplete_level++;
              this_deferred = true;