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