| ------------------------------------------------------------------------------ |
| -- -- |
| -- GNAT COMPILER COMPONENTS -- |
| -- -- |
| -- A C C E S S I B I L I T Y -- |
| -- -- |
| -- S p e c -- |
| -- -- |
| -- Copyright (C) 2022-2025, 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; |