------------------------------------------------------------------------------ -- -- -- 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;