blob: fb29be3814da93d171a7c4236fd97c965cafe0c8 [file] [log] [blame]
------------------------------------------------------------------------------
-- --
-- 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;