This is the second go at this patch, and now with a testcase!

In summary:

If the type is derived in the current compilation unit, and Allocate is not
overridden on derivation (as is typically the case with
Root_Storage_Pool_With_Subpools), the entity for Allocate for the derived
type is then an alias to System.Storage_Pools.Subpools.Allocate. When the
allocator is built, gnat_to_gnu_entity is called with definition == false
for the derived storage pool's allocate operation. An assertion is
gnat_to_gnu_entity fails in this case, since it is not a definition, and
Is_Public is false (since the entity is nested in the same compilation
unit).

This patch adds an extra check in the assertion (decl.c: gnat_to_gnu_entity)
that the entity has the Aliased property, and that the Alias is also Public.


Added a regression test for the declaration and allocation from a
Root_Pool_With_Subpools type derrived within the same compilation unit (a
package nested in a subprogram in this testcase).

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 871a309ab7d..ae49c2625f8 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -447,6 +447,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree
gnu_expr, bool definition)
   /* If we get here, it means we have not yet done anything with this
entity.
      If we are not defining it, it must be a type or an entity that is
defined
      elsewhere or externally, otherwise we should have defined it already.
*/
+
+  /* One exception relates to an entity, typically an inherited operation,
+     which has an alias pointing to the parent's operation. Often such an
+     aliased entity will also carry with it the Is_Public property if it
was
+     declared in a separate compilation unit, but when a type is extended
+     within the current unit, the aliased entity will not pass this
+     assertion. It is neither defined (since it is an inherited operation,
+     and is not Public, since it is within the current compilation unit.
+
+        For this case we look for an Alias that is also Public */
+  
   gcc_assert (definition
              || is_type
              || kind == E_Discriminant
@@ -454,6 +465,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree
gnu_expr, bool definition)
              || kind == E_Label
              || (kind == E_Constant && Present (Full_View (gnat_entity)))
              || Is_Public (gnat_entity)
+          || (Present (Alias (gnat_entity)) && Is_Public (Alias
(gnat_entity)))
              || type_annotate_only);
 
   /* Get the name of the entity and set up the line number and filename of
diff --git a/gcc/testsuite/gnat.dg/subpools1.adb
b/gcc/testsuite/gnat.dg/subpools1.adb
new file mode 100644
index 00000000000..87b9e53baca
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/subpools1.adb
@@ -0,0 +1,99 @@
+-- { dg-do compile }
+
+with System.Storage_Elements;
+with System.Storage_Pools.Subpools;
+
+procedure Subpools1 is
+
+   use System.Storage_Pools.Subpools;
+   
+   package Local_Pools is
+      
+      use System.Storage_Elements;
+      
+      subtype Address is System.Address;
+      use type Address;
+      
+      type Local_Pool is new Root_Storage_Pool_With_Subpools 
+        with null record;
+      
+      overriding
+      function Create_Subpool (Pool: in out Local_Pool)
+                              return not null Subpool_Handle;
+      
+      overriding
+      procedure Allocate_From_Subpool
+        (Pool                    : in out Local_Pool;
+         Storage_Address         :    out Address;
+         Size_In_Storage_Elements: in     Storage_Count;
+         Alignment               : in     Storage_Count;
+         Subpool                 : in     not null Subpool_Handle);
+      
+      overriding
+      procedure Deallocate_Subpool
+        (Pool   : in out Local_Pool;
+         Subpool: in out Subpool_Handle) is null;
+      
+      overriding
+      function Default_Subpool_For_Pool (Pool: in out Local_Pool)
+                                        return not null Subpool_Handle;
+      
+   end Local_Pools;
+   
+   package body Local_Pools is
+      
+      type Local_Subpool is new Root_Subpool with null record;
+      
+      Dummy_Subpool: aliased Local_Subpool;
+      
+      overriding
+      function Create_Subpool (Pool: in out Local_Pool)
+                              return not null Subpool_Handle 
+      is 
+      begin 
+         return Result: not null Subpool_Handle 
+           := Dummy_Subpool'Unchecked_Access
+         do
+            Set_Pool_Of_Subpool (Result, Pool);
+         end return;
+      end Create_Subpool;
+      
+      
+      overriding
+      procedure Allocate_From_Subpool
+        (Pool                    : in out Local_Pool;
+         Storage_Address         :    out Address;
+         Size_In_Storage_Elements: in     Storage_Count;
+         Alignment               : in     Storage_Count;
+         Subpool                 : in     not null Subpool_Handle)
+      is
+         type Storage_Array_Access is access Storage_Array;
+         
+         New_Alloc: Storage_Array_Access
+           := new Storage_Array (1 .. Size_In_Storage_Elements +
Alignment);
+      begin
+         for SE of New_Alloc.all loop
+            Storage_Address := SE'Address;
+            exit when Storage_Address mod Alignment = 0;
+         end loop;
+      end Allocate_From_Subpool;
+      
+      overriding
+      function Default_Subpool_For_Pool (Pool: in out Local_Pool)
+                                        return not null Subpool_Handle
+        is (Dummy_Subpool'Unchecked_Access);
+      
+   end Local_Pools;
+   
+   
+   A_Pool: Local_Pools.Local_Pool;
+   A_Subpool: Subpool_Handle := A_Pool.Create_Subpool;
+   
+   type Integer_Access is access Integer with
+     Storage_Pool => A_Pool;
+   
+   X: Integer_Access := new Integer; 
+   
+begin
+   null;
+end Subpools1;

Bootstrapped and tested from trunk on x86_64-unknown-freebsd12.1. 

Cheers,

Richard Wai
ANNEXI-STRAYLINE

> -----Original Message-----
> From: Eric Botcazou <ebotca...@adacore.com>
> Sent: March 7, 2020 5:48 AM
> To: Richard Wai <rich...@annexi-strayline.com>
> Cc: gcc-patches@gcc.gnu.org
> Subject: Re: [PATCH] Ada: gcc-interface: fixed assertion for aliased
entities
> 
> > Please excuse my ignorance as this is my first (and hopefully not
> > last) patch submission.. But I don't see any testcases in the Ada
> > testsuite except for the (outdated) ACATS tests, which doesn't cover
> > this assertion. So I'm honestly not sure how I should go about that..
> 
> See testsuite/gnat.dg, there are around 3000 regressions tests.
> 
> > Shall I add the Is_Public check to the Alias and resubmit the patch?
> 
> Yes, please, but it can only be approved with an associated testcase.
> 
> --
> Eric Botcazou

Reply via email to