1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
  
     | 
    
      ------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                        A C C E S S I B I L I T Y                         --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--          Copyright (C) 2022-2024, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------
--  Accessibility level and check generation routines
with Types; use Types;
with Uintp; use Uintp;
package Accessibility is
   procedure Accessibility_Message (N : Node_Id; Typ : Entity_Id);
   --  Error, or warning within an instance, if the static accessibility
   --  rules of 3.10.2 are violated.
   type Accessibility_Level_Kind is
     (Dynamic_Level,
      Object_Decl_Level,
      Zero_On_Dynamic_Level);
   --  Accessibility_Level_Kind is an enumerated type which captures the
   --  different modes in which an accessibility level could be obtained for
   --  a given expression.
   --  When in the context of the function Accessibility_Level,
   --  Accessibility_Level_Kind signals what type of accessibility level to
   --  obtain. For example, when Level is Dynamic_Level, a defining identifier
   --  associated with a SAOOAAT may be returned or an N_Integer_Literal node.
   --  When the level is Object_Decl_Level, an N_Integer_Literal node is
   --  returned containing the level of the declaration of the object if
   --  relevant (be it a SAOOAAT or otherwise). Finally, Zero_On_Dynamic_Level
   --  returns library level for all cases where the accessibility level is
   --  dynamic (used to bypass static accessibility checks in dynamic cases).
   function Accessibility_Level
     (Expr              : Node_Id;
      Level             : Accessibility_Level_Kind;
      In_Return_Context : Boolean := False;
      Allow_Alt_Model   : Boolean := True) return Node_Id;
   --  Centralized accessibility level calculation routine for finding the
   --  accessibility level of a given expression Expr.
   --  In_Return_Context forces the Accessibility_Level calculations to be
   --  carried out "as if" Expr existed in a return value. This is useful for
   --  calculating the accessibility levels for discriminant associations
   --  and return aggregates.
   --  The Allow_Alt_Model parameter allows the alternative level calculation
   --  under the restriction No_Dynamic_Accessibility_Checks to be performed.
   procedure Apply_Accessibility_Check
     (N           : Node_Id;
      Typ         : Entity_Id;
      Insert_Node : Node_Id);
   --  Given a name N denoting an access parameter, emits a run-time
   --  accessibility check (if necessary), checking that the level of
   --  the object denoted by the access parameter is not deeper than the
   --  level of the type Typ. Program_Error is raised if the check fails.
   --  Insert_Node indicates the node where the check should be inserted.
   procedure Apply_Accessibility_Check_For_Allocator
     (N              : Node_Id;
      Exp            : Node_Id;
      Ref            : Node_Id;
      Built_In_Place : Boolean := False);
   --  Ada 2005 (AI-344): For an allocator with a class-wide designated
   --  type, generate an accessibility check to verify that the level of the
   --  type of the created object is not deeper than the level of the access
   --  type. If the type of the qualified expression is class-wide, then
   --  always generate the check (except in the case where it is known to be
   --  unnecessary, see comment below). Otherwise, only generate the check
   --  if the level of the qualified expression type is statically deeper
   --  than the access type.
   --
   --  Although the static accessibility will generally have been performed
   --  as a legality check, it won't have been done in cases where the
   --  allocator appears in generic body, so a run-time check is needed in
   --  general. One special case is when the access type is declared in the
   --  same scope as the class-wide allocator, in which case the check can
   --  never fail, so it need not be generated.
   --
   --  As an open issue, there seem to be cases where the static level
   --  associated with the class-wide object's underlying type is not
   --  sufficient to perform the proper accessibility check, such as for
   --  allocators in nested subprograms or accept statements initialized by
   --  class-wide formals when the actual originates outside at a deeper
   --  static level. The nested subprogram case might require passing
   --  accessibility levels along with class-wide parameters, and the task
   --  case seems to be an actual gap in the language rules that needs to
   --  be fixed by the ARG. ???
   procedure Check_Return_Construct_Accessibility
     (Return_Stmt : Node_Id;
      Stm_Entity  : Entity_Id);
   --  Apply legality rule of 6.5 (5.9) to the access discriminants of an
   --  aggregate in a return statement.
   function Deepest_Type_Access_Level
     (Typ             : Entity_Id;
      Allow_Alt_Model : Boolean := True) return Uint;
   --  Same as Type_Access_Level, except that if the type is the type of an Ada
   --  2012 stand-alone object of an anonymous access type, then return the
   --  static accessibility level of the object. In that case, the dynamic
   --  accessibility level of the object may take on values in a range. The low
   --  bound of that range is returned by Type_Access_Level; this function
   --  yields the high bound of that range. Also differs from Type_Access_Level
   --  in the case of a descendant of a generic formal type (returns Int'Last
   --  instead of 0).
   --  The Allow_Alt_Model parameter allows the alternative level calculation
   --  under the restriction No_Dynamic_Accessibility_Checks to be performed.
   function Effective_Extra_Accessibility (Id : Entity_Id) return Entity_Id;
   --  Same as Einfo.Extra_Accessibility except thtat object renames
   --  are looked through.
   function Get_Dynamic_Accessibility (E : Entity_Id) return Entity_Id;
   --  Obtain the accessibility level for a given entity formal taking into
   --  account both extra and minimum accessibility.
   function Has_Access_Values (T : Entity_Id) return Boolean;
   --  Returns true if the underlying type of T is an access type, or has a
   --  component (at any recursive level) that is an access type. This is a
   --  conservative predicate, if it is not known whether or not T contains
   --  access values (happens for generic formals in some cases), then False is
   --  returned.  Note that tagged types return False. Even though the tag is
   --  implemented as an access type internally, this function tests only for
   --  access types known to the programmer. See also Has_Tagged_Component.
   function Has_Anonymous_Access_Discriminant (Typ : Entity_Id) return Boolean;
   --  Returns True if Typ has one or more anonymous access discriminants
   function Prefix_With_Safe_Accessibility_Level
     (N   : Node_Id;
      Typ : Entity_Id) return Boolean;
   --  Return True if the prefix does not have a value conversion of an
   --  array because a value conversion is like an aggregate with respect
   --  to determining accessibility level (RM 3.10.2); even if evaluation
   --  of a value conversion is guaranteed to not create a new object,
   --  accessibility rules are defined as if it might.
   subtype Static_Accessibility_Level_Kind
     is Accessibility_Level_Kind range Object_Decl_Level
                                         .. Zero_On_Dynamic_Level;
   --  Restrict the reange of Accessibility_Level_Kind to be non-dynamic for
   --  use in the static version of Accessibility_Level below.
   function Static_Accessibility_Level
     (Expr              : Node_Id;
      Level             : Static_Accessibility_Level_Kind;
      In_Return_Context : Boolean := False) return Uint;
   --  Overloaded version of Accessibility_Level which returns a universal
   --  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 Is_Anonymous_Access_Actual (N : Node_Id) return Boolean;
   --  Determine if N is used as an actual for a call whose corresponding
   --  formal is of an anonymous access type.
   function Is_Special_Aliased_Formal_Access
     (Exp               : Node_Id;
      In_Return_Context : Boolean := False) return Boolean;
   --  Determines whether a dynamic check must be generated for explicitly
   --  aliased formals within a function Scop for the expression Exp.
   --  In_Return_Context forces Is_Special_Aliased_Formal_Access to assume
   --  that Exp is within a return value which is useful for checking
   --  expressions within discriminant associations of return objects.
   --  More specially, Is_Special_Aliased_Formal_Access checks that Exp is a
   --  'Access attribute reference within a return statement where the ultimate
   --  prefix is an aliased formal of Scop and that Scop returns an anonymous
   --  access type. See RM 3.10.2 for more details.
   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
   function Type_Access_Level
     (Typ             : Entity_Id;
      Allow_Alt_Model : Boolean   := True;
      Assoc_Ent       : Entity_Id := Empty) return Uint;
   --  Return the accessibility level of Typ
   --  The Allow_Alt_Model parameter allows the alternative level calculation
   --  under the restriction No_Dynamic_Accessibility_Checks to be performed.
   --  Assoc_Ent allows for the optional specification of the entity associated
   --  with Typ. This gets utilized mostly for anonymous access type
   --  processing, where context matters in interpreting Typ's level.
end Accessibility;
 
     |