From: Eric Botcazou <[email protected]>

The problem is that, unlike in the nongeneric case, the analysis of the
access result definition in the generic function specification does not
cause Is_Local_Anonymous_Access to be set on the anonymous access type
created for the result.

The fix exposes a loophole in the calculation of the accessibility level
for formal objects of generic subprograms, as well as two illegal cases
in the GNAT.CPP_Exceptions unit of the run-time library.

gcc/ada/ChangeLog:

        * accessibility.ads: Alphabetize declarations.
        (Subprogram_Access_Level): Beef up description.
        * accessibility.adb (Accessibility_Level): Deal with formal objects
        of generic subprograms.
        * sem_ch12.adb (Analyze_Generic_Subprogram_Declaration): Set the
        Is_Local_Anonymous_Access flag on the access result type, if any.
        * libgnat/g-cppexc.ads (Get_Access_To_Tagged_Object): Do not declare
        the formal type parameter as abstract.
        * libgnat/g-cppexc.adb (Get_Access_To_Object): Fix illegal code.
        (Get_Access_To_Tagged_Object): Likewise.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/accessibility.adb    | 11 ++++++---
 gcc/ada/accessibility.ads    | 46 ++++++++++++++++++++----------------
 gcc/ada/libgnat/g-cppexc.adb | 22 +++++++----------
 gcc/ada/libgnat/g-cppexc.ads |  2 +-
 gcc/ada/sem_ch12.adb         |  2 ++
 5 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/gcc/ada/accessibility.adb b/gcc/ada/accessibility.adb
index 52d4810987f..f29e846a98e 100644
--- a/gcc/ada/accessibility.adb
+++ b/gcc/ada/accessibility.adb
@@ -715,8 +715,7 @@ package body Accessibility is
 
                --  Return the dynamic level in the normal case
 
-               return New_Occurrence_Of
-                        (Get_Dynamic_Accessibility (E), Loc);
+               return New_Occurrence_Of (Get_Dynamic_Accessibility (E), Loc);
 
             --  Initialization procedures have a special extra accessibility
             --  parameter associated with the level at which the object
@@ -782,7 +781,13 @@ package body Accessibility is
                return New_Occurrence_Of
                         (Init_Proc_Level_Formal (Scope (E)), Loc);
 
-            --  Normal object - get the level of the enclosing scope
+            --  Formal object of generic subprogram - get the level of the
+            --  subprogram
+
+            elsif Is_Formal_Object (E) and then Is_Subprogram (Scope (E)) then
+               return Make_Level_Literal (Subprogram_Access_Level (Scope (E)));
+
+            --  Normal object - get the depth of the enclosing dynamic scope
 
             else
                return Make_Level_Literal
diff --git a/gcc/ada/accessibility.ads b/gcc/ada/accessibility.ads
index d339caf3ea8..552074e085d 100644
--- a/gcc/ada/accessibility.ads
+++ b/gcc/ada/accessibility.ads
@@ -154,6 +154,26 @@ package Accessibility is
    function Has_Anonymous_Access_Discriminant (Typ : Entity_Id) return Boolean;
    --  Returns True if Typ has one or more anonymous access discriminants
 
+   function Has_Unconstrained_Access_Discriminants
+     (Subtyp : Entity_Id) return Boolean;
+   --  Returns True if the given subtype is unconstrained and has one or more
+   --  access discriminants.
+
+   function Needs_Accessibility_Level_Temp_Or_Check
+     (Conditional_Expr : Node_Id) return Boolean;
+   --  Determine whether a conditional expression occurs in a context that
+   --  requires either an associated accessibility-level-valued temp (which
+   --  is assigned to in each arm of the conditional expression) or an
+   --  accessibility level check (which is pushed down into each arm of the
+   --  conditional expression).
+
+   function Needs_Result_Accessibility_Level
+     (Func_Id : Entity_Id) return Boolean;
+   --  Ada 2012 (AI05-0234): Return True if the function needs an implicit
+   --  parameter to identify the accessibility level of the function result
+   --  "determined by the point of call". Return False if the type of the
+   --  function result is a private type and its completion is unavailable.
+
    function Prefix_With_Safe_Accessibility_Level
      (N   : Node_Id;
       Typ : Entity_Id) return Boolean;
@@ -177,28 +197,12 @@ package Accessibility is
    --  integer for use in compile-time checking. Note: Level is restricted to
    --  be non-dynamic.
 
-   function Has_Unconstrained_Access_Discriminants
-     (Subtyp : Entity_Id) return Boolean;
-   --  Returns True if the given subtype is unconstrained and has one or more
-   --  access discriminants.
-
-   function Needs_Accessibility_Level_Temp_Or_Check
-     (Conditional_Expr : Node_Id) return Boolean;
-   --  Determine whether a conditional expression occurs in a context that
-   --  requires either an associated accessibility-level-valued temp (which
-   --  is assigned to in each arm of the conditional expression) or an
-   --  accessibility level check (which is pushed down into each arm of the
-   --  conditional expression).
-
-   function Needs_Result_Accessibility_Level
-     (Func_Id : Entity_Id) return Boolean;
-   --  Ada 2012 (AI05-0234): Return True if the function needs an implicit
-   --  parameter to identify the accessibility level of the function result
-   --  "determined by the point of call". Return False if the type of the
-   --  function result is a private type and its completion is unavailable.
-
    function Subprogram_Access_Level (Subp : Entity_Id) return Uint;
-   --  Return the accessibility level of the view denoted by Subp
+   --  Return the accessibility level of Subp. Note that this is the level of
+   --  the innermost master of the declaration of Subp (modulo renaming) and,
+   --  in particular, is *not* the level of the entities declared within Subp.
+   --  It is used to enforce the accessibility rules for access-to-subprogram
+   --  types, results of function calls, and formal objects of generic units.
 
    function Type_Access_Level
      (Typ             : Entity_Id;
diff --git a/gcc/ada/libgnat/g-cppexc.adb b/gcc/ada/libgnat/g-cppexc.adb
index 1522cde6ffa..20ec8df0a28 100644
--- a/gcc/ada/libgnat/g-cppexc.adb
+++ b/gcc/ada/libgnat/g-cppexc.adb
@@ -176,15 +176,12 @@ package body GNAT.CPP_Exceptions is
       Object_Addr : constant System.Address := Get_Object_Address (X);
       --  Address of the raised object
 
-      type T_Acc is access T;
-
-      function To_T_Acc is
-         new Ada.Unchecked_Conversion (System.Address, T_Acc);
-
       --  Import the object from the occurrence
-      Result : constant T_Acc := To_T_Acc (Object_Addr);
+      Result : aliased T;
+      pragma Import (Ada, Result);
+      for Result'Address use Object_Addr;
    begin
-      return Result;
+      return Result'Unchecked_Access;
    end Get_Access_To_Object;
 
    ---------------------------------
@@ -197,15 +194,12 @@ package body GNAT.CPP_Exceptions is
       Object_Addr : constant System.Address := Get_Object_Address (X);
       --  Address of the raised object
 
-      type T_Acc is access T'Class;
-
-      function To_T_Acc is
-         new Ada.Unchecked_Conversion (System.Address, T_Acc);
-
       --  Import the object from the occurrence
-      Result : constant T_Acc := To_T_Acc (Object_Addr);
+      Result : aliased T;
+      pragma Import (Ada, Result);
+      for Result'Address use Object_Addr;
    begin
-      return Result;
+      return Result'Unchecked_Access;
    end Get_Access_To_Tagged_Object;
 
    -------------------
diff --git a/gcc/ada/libgnat/g-cppexc.ads b/gcc/ada/libgnat/g-cppexc.ads
index 41048e2ef7c..b20f5eac117 100644
--- a/gcc/ada/libgnat/g-cppexc.ads
+++ b/gcc/ada/libgnat/g-cppexc.ads
@@ -69,7 +69,7 @@ package GNAT.CPP_Exceptions is
    --  explicitly expected by the handler.
 
    generic
-      type T is abstract tagged limited private;
+      type T is tagged limited private;
    function Get_Access_To_Tagged_Object (X : Exception_Occurrence)
                                         return access T'Class;
    --  Extract the object associated with X. The exception of the
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index ebdc9ba3670..600e3f055b1 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -4745,6 +4745,8 @@ package body Sem_Ch12 is
       if Nkind (Spec) = N_Function_Specification then
          if Nkind (Result_Definition (Spec)) = N_Access_Definition then
             Result_Type := Access_Definition (Spec, Result_Definition (Spec));
+            Set_Parent (Result_Type, Result_Definition (Spec));
+            Set_Is_Local_Anonymous_Access (Result_Type);
             Set_Etype (Id, Result_Type);
 
             --  Check restriction imposed by AI05-073: a generic function
-- 
2.53.0

Reply via email to