Daily bump.
[official-gcc.git] / gcc / ada / accessibility.adb
blob298103377a7bcc9f15ce0dc2bc49b87b4253a256
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- A C C E S S I B I L I T Y --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2022-2024, Free Software Foundation, Inc. --
10 -- --
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. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with Atree; use Atree;
27 with Checks; use Checks;
28 with Debug; use Debug;
29 with Einfo; use Einfo;
30 with Einfo.Entities; use Einfo.Entities;
31 with Elists; use Elists;
32 with Errout; use Errout;
33 with Einfo.Utils; use Einfo.Utils;
34 with Exp_Atag; use Exp_Atag;
35 with Exp_Ch7; use Exp_Ch7;
36 with Exp_Tss; use Exp_Tss;
37 with Exp_Util; use Exp_Util;
38 with Namet; use Namet;
39 with Nlists; use Nlists;
40 with Nmake; use Nmake;
41 with Opt; use Opt;
42 with Restrict; use Restrict;
43 with Rtsfind; use Rtsfind;
44 with Sem; use Sem;
45 with Sem_Aux; use Sem_Aux;
46 with Sem_Ch8; use Sem_Ch8;
47 with Sem_Res; use Sem_Res;
48 with Sem_Util; use Sem_Util;
49 with Sinfo; use Sinfo;
50 with Sinfo.Nodes; use Sinfo.Nodes;
51 with Sinfo.Utils; use Sinfo.Utils;
52 with Snames; use Snames;
53 with Stand; use Stand;
54 with Tbuild; use Tbuild;
56 package body Accessibility is
58 ---------------------------
59 -- Accessibility_Message --
60 ---------------------------
62 procedure Accessibility_Message (N : Node_Id; Typ : Entity_Id) is
63 Loc : constant Source_Ptr := Sloc (N);
64 P : constant Node_Id := Prefix (N);
65 Indic : Node_Id := Parent (Parent (N));
67 begin
68 -- In an instance, this is a runtime check, but one we know will fail,
69 -- so generate an appropriate warning.
71 if In_Instance_Body then
72 Error_Msg_Warn := SPARK_Mode /= On;
73 Error_Msg_F
74 ("non-local pointer cannot point to local object<<", P);
75 Error_Msg_F ("\Program_Error [<<", P);
76 Rewrite (N,
77 Make_Raise_Program_Error (Loc,
78 Reason => PE_Accessibility_Check_Failed));
79 Set_Etype (N, Typ);
80 return;
82 else
83 Error_Msg_F ("non-local pointer cannot point to local object", P);
85 -- Check for case where we have a missing access definition
87 if Is_Record_Type (Current_Scope)
88 and then
89 Nkind (Parent (N)) in N_Discriminant_Association
90 | N_Index_Or_Discriminant_Constraint
91 then
92 Indic := Parent (Parent (N));
93 while Present (Indic)
94 and then Nkind (Indic) /= N_Subtype_Indication
95 loop
96 Indic := Parent (Indic);
97 end loop;
99 if Present (Indic) then
100 Error_Msg_NE
101 ("\use an access definition for" &
102 " the access discriminant of&",
103 N, Entity (Subtype_Mark (Indic)));
104 end if;
105 end if;
106 end if;
107 end Accessibility_Message;
109 -------------------------
110 -- Accessibility_Level --
111 -------------------------
113 function Accessibility_Level
114 (Expr : Node_Id;
115 Level : Accessibility_Level_Kind;
116 In_Return_Context : Boolean := False;
117 Allow_Alt_Model : Boolean := True) return Node_Id
119 Loc : constant Source_Ptr := Sloc (Expr);
121 function Accessibility_Level (Expr : Node_Id) return Node_Id is
122 (Accessibility_Level
123 (Expr, Level, In_Return_Context, Allow_Alt_Model));
124 -- Renaming of the enclosing function to facilitate recursive calls
126 function Make_Level_Literal (Level : Uint) return Node_Id;
127 -- Construct an integer literal representing an accessibility level with
128 -- its type set to Natural.
130 function Innermost_Master_Scope_Depth (N : Node_Id) return Uint;
131 -- Returns the scope depth of the given node's innermost enclosing scope
132 -- (effectively the accessibility level of the innermost enclosing
133 -- master).
135 function Function_Call_Or_Allocator_Level (N : Node_Id) return Node_Id;
136 -- Centralized processing of subprogram calls which may appear in prefix
137 -- notation.
139 function Typ_Access_Level (Typ : Entity_Id) return Uint
140 is (Type_Access_Level (Typ, Allow_Alt_Model));
141 -- Renaming of Type_Access_Level with Allow_Alt_Model specified to avoid
142 -- passing the parameter specifically in every call.
144 ----------------------------------
145 -- Innermost_Master_Scope_Depth --
146 ----------------------------------
148 function Innermost_Master_Scope_Depth (N : Node_Id) return Uint is
149 Encl_Scop : Entity_Id;
150 Ent : Entity_Id;
151 Node_Par : Node_Id := Parent (N);
152 Master_Lvl_Modifier : Int := 0;
154 begin
155 -- Locate the nearest enclosing node (by traversing Parents)
156 -- that Defining_Entity can be applied to, and return the
157 -- depth of that entity's nearest enclosing scope.
159 -- The RM 7.6.1(3) definition of "master" includes statements
160 -- and conditions for loops among other things. Are these cases
161 -- detected properly ???
163 while Present (Node_Par) loop
164 Ent := Defining_Entity_Or_Empty (Node_Par);
166 if Present (Ent) then
167 -- X'Old is nested within the current subprogram, so we do not
168 -- want Find_Enclosing_Scope of that subprogram. If this is an
169 -- allocator, then we're looking for the innermost master of
170 -- the call, so again we do not want Find_Enclosing_Scope.
172 if (Nkind (N) = N_Attribute_Reference
173 and then Attribute_Name (N) = Name_Old)
174 or else Nkind (N) = N_Allocator
175 then
176 Encl_Scop := Ent;
177 else
178 Encl_Scop := Find_Enclosing_Scope (Ent);
179 end if;
181 -- Ignore transient scopes made during expansion while also
182 -- taking into account certain expansions - like iterators
183 -- which get expanded into renamings and thus not marked
184 -- as coming from source.
186 if Comes_From_Source (Node_Par)
187 or else (Nkind (Node_Par) = N_Object_Renaming_Declaration
188 and then Comes_From_Iterator (Node_Par))
189 then
190 -- Note that in some rare cases the scope depth may not be
191 -- set, for example, when we are in the middle of analyzing
192 -- a type and the enclosing scope is said type. In that case
193 -- simply return zero for the outermost scope.
195 if Scope_Depth_Set (Encl_Scop) then
196 return Scope_Depth (Encl_Scop) + Master_Lvl_Modifier;
197 else
198 return Uint_0;
199 end if;
200 end if;
202 -- For a return statement within a function, return
203 -- the depth of the function itself. This is not just
204 -- a small optimization, but matters when analyzing
205 -- the expression in an expression function before
206 -- the body is created.
208 elsif Nkind (Node_Par) in N_Extended_Return_Statement
209 | N_Simple_Return_Statement
210 then
211 return Scope_Depth (Enclosing_Subprogram (Node_Par));
213 -- Statements are counted as masters
215 elsif Is_Master (Node_Par) then
216 Master_Lvl_Modifier := Master_Lvl_Modifier + 1;
218 end if;
220 Node_Par := Parent (Node_Par);
221 end loop;
223 -- Should never reach the following return
225 pragma Assert (False);
227 return Scope_Depth (Current_Scope) + 1;
228 end Innermost_Master_Scope_Depth;
230 ------------------------
231 -- Make_Level_Literal --
232 ------------------------
234 function Make_Level_Literal (Level : Uint) return Node_Id is
235 Result : constant Node_Id := Make_Integer_Literal (Loc, Level);
237 begin
238 Set_Etype (Result, Standard_Natural);
239 return Result;
240 end Make_Level_Literal;
242 --------------------------------------
243 -- Function_Call_Or_Allocator_Level --
244 --------------------------------------
246 function Function_Call_Or_Allocator_Level (N : Node_Id) return Node_Id is
247 Par : Node_Id;
248 Prev_Par : Node_Id;
249 begin
250 -- Results of functions are objects, so we either get the
251 -- accessibility of the function or, in case of a call which is
252 -- indirect, the level of the access-to-subprogram type.
254 -- This code looks wrong ???
256 if Nkind (N) = N_Function_Call
257 and then Ada_Version < Ada_2005
258 then
259 if Is_Entity_Name (Name (N)) then
260 return Make_Level_Literal
261 (Subprogram_Access_Level (Entity (Name (N))));
262 else
263 return Make_Level_Literal
264 (Typ_Access_Level (Etype (Prefix (Name (N)))));
265 end if;
267 -- We ignore coextensions as they cannot be implemented under the
268 -- "small-integer" model.
270 elsif Nkind (N) = N_Allocator
271 and then (Is_Static_Coextension (N)
272 or else Is_Dynamic_Coextension (N))
273 then
274 return Make_Level_Literal (Scope_Depth (Standard_Standard));
275 end if;
277 -- Named access types have a designated level
279 if Is_Named_Access_Type (Etype (N)) then
280 return Make_Level_Literal (Typ_Access_Level (Etype (N)));
282 -- Otherwise, the level is dictated by RM 3.10.2 (10.7/3)
284 else
285 -- Check No_Dynamic_Accessibility_Checks restriction override for
286 -- alternative accessibility model.
288 if Allow_Alt_Model
289 and then No_Dynamic_Accessibility_Checks_Enabled (N)
290 and then Is_Anonymous_Access_Type (Etype (N))
291 then
292 -- In the alternative model the level is that of the
293 -- designated type.
295 if Debug_Flag_Underscore_B then
296 return Make_Level_Literal (Typ_Access_Level (Etype (N)));
298 -- For function calls the level is that of the innermost
299 -- master, otherwise (for allocators etc.) we get the level
300 -- of the corresponding anonymous access type, which is
301 -- calculated through the normal path of execution.
303 elsif Nkind (N) = N_Function_Call then
304 return Make_Level_Literal
305 (Innermost_Master_Scope_Depth (Expr));
306 end if;
307 end if;
309 if Nkind (N) = N_Function_Call then
310 -- Dynamic checks are generated when we are within a return
311 -- value or we are in a function call within an anonymous
312 -- access discriminant constraint of a return object (signified
313 -- by In_Return_Context) on the side of the callee.
315 -- So, in this case, return accessibility level of the
316 -- enclosing subprogram.
318 if In_Return_Value (N)
319 or else In_Return_Context
320 then
321 return Make_Level_Literal
322 (Subprogram_Access_Level (Current_Subprogram));
323 end if;
324 end if;
326 -- When the call is being dereferenced the level is that of the
327 -- enclosing master of the dereferenced call.
329 if Nkind (Parent (N)) in N_Explicit_Dereference
330 | N_Indexed_Component
331 | N_Selected_Component
332 then
333 return Make_Level_Literal
334 (Innermost_Master_Scope_Depth (Expr));
335 end if;
337 -- Find any relevant enclosing parent nodes that designate an
338 -- object being initialized.
340 -- Note: The above is only relevant if the result is used "in its
341 -- entirety" as RM 3.10.2 (10.2/3) states. However, this is
342 -- accounted for in the case statement in the main body of
343 -- Accessibility_Level for N_Selected_Component.
345 Par := Parent (Expr);
346 Prev_Par := Empty;
347 while Present (Par) loop
348 -- Detect an expanded implicit conversion, typically this
349 -- occurs on implicitly converted actuals in calls.
351 -- Does this catch all implicit conversions ???
353 if Nkind (Par) = N_Type_Conversion
354 and then Is_Named_Access_Type (Etype (Par))
355 then
356 return Make_Level_Literal
357 (Typ_Access_Level (Etype (Par)));
358 end if;
360 -- Jump out when we hit an object declaration or the right-hand
361 -- side of an assignment, or a construct such as an aggregate
362 -- subtype indication which would be the result is not used
363 -- "in its entirety."
365 exit when Nkind (Par) in N_Object_Declaration
366 or else (Nkind (Par) = N_Assignment_Statement
367 and then Name (Par) /= Prev_Par);
369 Prev_Par := Par;
370 Par := Parent (Par);
371 end loop;
373 -- Assignment statements are handled in a similar way in
374 -- accordance to the left-hand part. However, strictly speaking,
375 -- this is illegal according to the RM, but this change is needed
376 -- to pass an ACATS C-test and is useful in general ???
378 case Nkind (Par) is
379 when N_Object_Declaration =>
380 return Make_Level_Literal
381 (Scope_Depth
382 (Scope (Defining_Identifier (Par))));
384 when N_Assignment_Statement =>
385 -- Return the accessibility level of the left-hand part
387 return Accessibility_Level
388 (Expr => Name (Par),
389 Level => Object_Decl_Level,
390 In_Return_Context => In_Return_Context);
392 when others =>
393 return Make_Level_Literal
394 (Innermost_Master_Scope_Depth (Expr));
395 end case;
396 end if;
397 end Function_Call_Or_Allocator_Level;
399 -- Local variables
401 E : Node_Id;
402 Pre : Node_Id;
404 -- Start of processing for Accessibility_Level
406 begin
407 -- We could be looking at a reference to a formal due to the expansion
408 -- of entries and other cases, so obtain the renaming if necessary.
410 if Present (Param_Entity (Expr)) then
411 E := Param_Entity (Expr);
413 -- Use the original node unless it is an unanalyzed identifier, as we
414 -- don't want to reason on unanalyzed expressions from predicates.
416 elsif Nkind (Original_Node (Expr)) /= N_Identifier
417 or else Analyzed (Original_Node (Expr))
418 then
419 E := Original_Node (Expr);
421 else
422 E := Expr;
423 end if;
425 -- Extract the entity
427 if Nkind (E) in N_Has_Entity and then Present (Entity (E)) then
428 E := Entity (E);
430 -- Deal with a possible renaming of a private protected component
432 if Ekind (E) in E_Constant | E_Variable and then Is_Prival (E) then
433 E := Prival_Link (E);
434 end if;
435 end if;
437 -- Perform the processing on the expression
439 case Nkind (E) is
440 -- The level of an aggregate is that of the innermost master that
441 -- evaluates it as defined in RM 3.10.2 (10/4).
443 when N_Aggregate =>
444 return Make_Level_Literal (Innermost_Master_Scope_Depth (Expr));
446 -- The accessibility level is that of the access type, except for
447 -- anonymous allocators which have special rules defined in RM 3.10.2
448 -- (14/3).
450 when N_Allocator =>
451 return Function_Call_Or_Allocator_Level (E);
453 -- We could reach this point for two reasons. Either the expression
454 -- applies to a special attribute ('Loop_Entry, 'Result, or 'Old), or
455 -- we are looking at the access attributes directly ('Access,
456 -- 'Address, or 'Unchecked_Access).
458 when N_Attribute_Reference =>
459 Pre := Original_Node (Prefix (E));
461 -- Regular 'Access attribute presence means we have to look at the
462 -- prefix.
464 if Attribute_Name (E) = Name_Access then
465 return Accessibility_Level (Prefix (E));
467 -- Unchecked or unrestricted attributes have unlimited depth
469 elsif Attribute_Name (E) in Name_Address
470 | Name_Unchecked_Access
471 | Name_Unrestricted_Access
472 then
473 return Make_Level_Literal (Scope_Depth (Standard_Standard));
475 -- 'Access can be taken further against other special attributes,
476 -- so handle these cases explicitly.
478 elsif Attribute_Name (E)
479 in Name_Old |
480 Name_Loop_Entry |
481 Name_Result |
482 Name_Super |
483 Name_Tag |
484 Name_Safe_First |
485 Name_Safe_Last |
486 Name_First |
487 Name_Last
488 then
489 -- Named access types
491 if Is_Named_Access_Type (Etype (Pre)) then
492 return Make_Level_Literal
493 (Typ_Access_Level (Etype (Pre)));
495 -- Anonymous access types
497 elsif Nkind (Pre) in N_Has_Entity
498 and then Ekind (Entity (Pre)) not in Subprogram_Kind
499 and then Present (Get_Dynamic_Accessibility (Entity (Pre)))
500 and then Level = Dynamic_Level
501 then
502 pragma Assert (Is_Anonymous_Access_Type (Etype (Pre)));
503 return New_Occurrence_Of
504 (Get_Dynamic_Accessibility (Entity (Pre)), Loc);
506 -- Otherwise the level is treated in a similar way as
507 -- aggregates according to RM 6.1.1 (35.1/4) which concerns
508 -- an implicit constant declaration - in turn defining the
509 -- accessibility level to be that of the implicit constant
510 -- declaration.
512 else
513 return Make_Level_Literal
514 (Innermost_Master_Scope_Depth (Expr));
515 end if;
517 else
518 raise Program_Error;
519 end if;
521 -- This is the "base case" for accessibility level calculations which
522 -- means we are near the end of our recursive traversal.
524 when N_Defining_Identifier =>
525 -- A dynamic check is performed on the side of the callee when we
526 -- are within a return statement, so return a library-level
527 -- accessibility level to null out checks on the side of the
528 -- caller.
530 if Is_Explicitly_Aliased (E)
531 and then (In_Return_Context
532 or else (Level /= Dynamic_Level
533 and then In_Return_Value (Expr)))
534 then
535 return Make_Level_Literal (Scope_Depth (Standard_Standard));
537 -- Something went wrong and an extra accessibility formal has not
538 -- been generated when one should have ???
540 elsif Is_Formal (E)
541 and then No (Get_Dynamic_Accessibility (E))
542 and then Ekind (Etype (E)) = E_Anonymous_Access_Type
543 then
544 return Make_Level_Literal (Scope_Depth (Standard_Standard));
546 -- Stand-alone object of an anonymous access type "SAOAAT"
548 elsif (Is_Formal (E)
549 or else Ekind (E) in E_Variable
550 | E_Constant)
551 and then Present (Get_Dynamic_Accessibility (E))
552 and then (Level = Dynamic_Level
553 or else Level = Zero_On_Dynamic_Level)
554 then
555 if Level = Zero_On_Dynamic_Level then
556 return Make_Level_Literal
557 (Scope_Depth (Standard_Standard));
558 end if;
560 -- No_Dynamic_Accessibility_Checks restriction override for
561 -- alternative accessibility model.
563 if Allow_Alt_Model
564 and then No_Dynamic_Accessibility_Checks_Enabled (E)
565 then
566 -- In the alternative model the level is that of the
567 -- designated type entity's context.
569 if Debug_Flag_Underscore_B then
570 return Make_Level_Literal (Typ_Access_Level (Etype (E)));
572 -- Otherwise the level depends on the entity's context
574 elsif Is_Formal (E) then
575 return Make_Level_Literal
576 (Subprogram_Access_Level
577 (Enclosing_Subprogram (E)));
578 else
579 return Make_Level_Literal
580 (Scope_Depth (Enclosing_Dynamic_Scope (E)));
581 end if;
582 end if;
584 -- Return the dynamic level in the normal case
586 return New_Occurrence_Of
587 (Get_Dynamic_Accessibility (E), Loc);
589 -- Initialization procedures have a special extra accessibility
590 -- parameter associated with the level at which the object
591 -- being initialized exists
593 elsif Ekind (E) = E_Record_Type
594 and then Is_Limited_Record (E)
595 and then Current_Scope = Init_Proc (E)
596 and then Present (Init_Proc_Level_Formal (Current_Scope))
597 then
598 return New_Occurrence_Of
599 (Init_Proc_Level_Formal (Current_Scope), Loc);
601 -- Current instance of the type is deeper than that of the type
602 -- according to RM 3.10.2 (21).
604 elsif Is_Type (E) then
605 -- When restriction No_Dynamic_Accessibility_Checks is active
606 -- along with -gnatd_b.
608 if Allow_Alt_Model
609 and then No_Dynamic_Accessibility_Checks_Enabled (E)
610 and then Debug_Flag_Underscore_B
611 then
612 return Make_Level_Literal (Typ_Access_Level (E));
613 end if;
615 -- Normal path
617 return Make_Level_Literal (Typ_Access_Level (E) + 1);
619 -- Move up the renamed entity or object if it came from source
620 -- since expansion may have created a dummy renaming under
621 -- certain circumstances.
623 -- Note: We check if the original node of the renaming comes
624 -- from source because the node may have been rewritten.
626 elsif Present (Renamed_Entity_Or_Object (E))
627 and then Comes_From_Source
628 (Original_Node (Renamed_Entity_Or_Object (E)))
629 then
630 return Accessibility_Level (Renamed_Entity_Or_Object (E));
632 -- Named access types get their level from their associated type
634 elsif Is_Named_Access_Type (Etype (E)) then
635 return Make_Level_Literal
636 (Typ_Access_Level (Etype (E)));
638 -- Check if E is an expansion-generated renaming of an iterator
639 -- by examining Related_Expression. If so, determine the
640 -- accessibility level based on the original expression.
642 elsif Ekind (E) in E_Constant | E_Variable
643 and then Present (Related_Expression (E))
644 then
645 return Accessibility_Level (Related_Expression (E));
647 elsif Level = Dynamic_Level
648 and then Ekind (E) in E_In_Parameter | E_In_Out_Parameter
649 and then Present (Init_Proc_Level_Formal (Scope (E)))
650 then
651 return New_Occurrence_Of
652 (Init_Proc_Level_Formal (Scope (E)), Loc);
654 -- Normal object - get the level of the enclosing scope
656 else
657 return Make_Level_Literal
658 (Scope_Depth (Enclosing_Dynamic_Scope (E)));
659 end if;
661 -- Handle indexed and selected components including the special cases
662 -- whereby there is an implicit dereference, a component of a
663 -- composite type, or a function call in prefix notation.
665 -- We don't handle function calls in prefix notation correctly ???
667 when N_Indexed_Component | N_Selected_Component | N_Slice =>
668 Pre := Prefix (E);
670 -- Fetch the original node when the prefix comes from the result
671 -- of expanding a function call since we want to find the level
672 -- of the original source call.
674 if not Comes_From_Source (Pre)
675 and then Nkind (Original_Node (Pre)) = N_Function_Call
676 then
677 Pre := Original_Node (Pre);
678 end if;
680 -- When E is an indexed component or selected component and
681 -- the current Expr is a function call, we know that we are
682 -- looking at an expanded call in prefix notation.
684 if Nkind (Expr) = N_Function_Call then
685 return Function_Call_Or_Allocator_Level (Expr);
687 -- If the prefix is a named access type, then we are dealing
688 -- with an implicit deferences. In that case the level is that
689 -- of the named access type in the prefix.
691 elsif Is_Named_Access_Type (Etype (Pre)) then
692 return Make_Level_Literal
693 (Typ_Access_Level (Etype (Pre)));
695 -- The current expression is a named access type, so there is no
696 -- reason to look at the prefix. Instead obtain the level of E's
697 -- named access type.
699 elsif Is_Named_Access_Type (Etype (E)) then
700 return Make_Level_Literal
701 (Typ_Access_Level (Etype (E)));
703 -- A nondiscriminant selected component where the component
704 -- is an anonymous access type means that its associated
705 -- level is that of the containing type - see RM 3.10.2 (16).
707 -- Note that when restriction No_Dynamic_Accessibility_Checks is
708 -- in effect we treat discriminant components as regular
709 -- components.
711 elsif
712 (Nkind (E) = N_Selected_Component
713 and then Ekind (Etype (E)) = E_Anonymous_Access_Type
714 and then Ekind (Etype (Pre)) /= E_Anonymous_Access_Type
715 and then (not (Nkind (Selector_Name (E)) in N_Has_Entity
716 and then Ekind (Entity (Selector_Name (E)))
717 = E_Discriminant)
719 -- The alternative accessibility models both treat
720 -- discriminants as regular components.
722 or else (No_Dynamic_Accessibility_Checks_Enabled (E)
723 and then Allow_Alt_Model)))
725 -- Arrays featuring components of anonymous access components
726 -- get their corresponding level from their containing type's
727 -- declaration.
729 or else
730 (Nkind (E) = N_Indexed_Component
731 and then Ekind (Etype (E)) = E_Anonymous_Access_Type
732 and then Ekind (Etype (Pre)) in Array_Kind
733 and then Ekind (Component_Type (Base_Type (Etype (Pre))))
734 = E_Anonymous_Access_Type)
735 then
736 -- When restriction No_Dynamic_Accessibility_Checks is active
737 -- and -gnatd_b set, the level is that of the designated type.
739 if Allow_Alt_Model
740 and then No_Dynamic_Accessibility_Checks_Enabled (E)
741 and then Debug_Flag_Underscore_B
742 then
743 return Make_Level_Literal
744 (Typ_Access_Level (Etype (E)));
745 end if;
747 -- Otherwise proceed normally
749 return Make_Level_Literal
750 (Typ_Access_Level (Etype (Prefix (E))));
752 -- The accessibility calculation routine that handles function
753 -- calls (Function_Call_Level) assumes, in the case the
754 -- result is of an anonymous access type, that the result will be
755 -- used "in its entirety" when the call is present within an
756 -- assignment or object declaration.
758 -- To properly handle cases where the result is not used in its
759 -- entirety, we test if the prefix of the component in question is
760 -- a function call, which tells us that one of its components has
761 -- been identified and is being accessed. Therefore we can
762 -- conclude that the result is not used "in its entirety"
763 -- according to RM 3.10.2 (10.2/3).
765 elsif Nkind (Pre) = N_Function_Call
766 and then not Is_Named_Access_Type (Etype (Pre))
767 then
768 -- Dynamic checks are generated when we are within a return
769 -- value or we are in a function call within an anonymous
770 -- access discriminant constraint of a return object (signified
771 -- by In_Return_Context) on the side of the callee.
773 -- So, in this case, return a library accessibility level to
774 -- null out the check on the side of the caller.
776 if (In_Return_Value (E)
777 or else In_Return_Context)
778 and then Level /= Dynamic_Level
779 then
780 return Make_Level_Literal
781 (Scope_Depth (Standard_Standard));
782 end if;
784 return Make_Level_Literal
785 (Innermost_Master_Scope_Depth (Expr));
787 -- Otherwise, continue recursing over the expression prefixes
789 else
790 return Accessibility_Level (Prefix (E));
791 end if;
793 -- Qualified expressions
795 when N_Qualified_Expression =>
796 if Is_Named_Access_Type (Etype (E)) then
797 return Make_Level_Literal
798 (Typ_Access_Level (Etype (E)));
799 else
800 return Accessibility_Level (Expression (E));
801 end if;
803 -- Handle function calls
805 when N_Function_Call =>
806 return Function_Call_Or_Allocator_Level (E);
808 -- Explicit dereference accessibility level calculation
810 when N_Explicit_Dereference =>
811 Pre := Original_Node (Prefix (E));
813 -- The prefix is a named access type so the level is taken from
814 -- its type.
816 if Is_Named_Access_Type (Etype (Pre)) then
817 return Make_Level_Literal (Typ_Access_Level (Etype (Pre)));
819 -- Otherwise, recurse deeper
821 else
822 return Accessibility_Level (Prefix (E));
823 end if;
825 -- Type conversions
827 when N_Type_Conversion | N_Unchecked_Type_Conversion =>
828 -- View conversions are special in that they require use to
829 -- inspect the expression of the type conversion.
831 -- Allocators of anonymous access types are internally generated,
832 -- so recurse deeper in that case as well.
834 if Is_View_Conversion (E)
835 or else Ekind (Etype (E)) = E_Anonymous_Access_Type
836 then
837 return Accessibility_Level (Expression (E));
839 -- We don't care about the master if we are looking at a named
840 -- access type.
842 elsif Is_Named_Access_Type (Etype (E)) then
843 return Make_Level_Literal
844 (Typ_Access_Level (Etype (E)));
846 -- In section RM 3.10.2 (10/4) the accessibility rules for
847 -- aggregates and value conversions are outlined. Are these
848 -- followed in the case of initialization of an object ???
850 -- Should use Innermost_Master_Scope_Depth ???
852 else
853 return Accessibility_Level (Current_Scope);
854 end if;
856 -- Default to the type accessibility level for the type of the
857 -- expression's entity.
859 when others =>
860 return Make_Level_Literal (Typ_Access_Level (Etype (E)));
861 end case;
862 end Accessibility_Level;
864 -------------------------------
865 -- Apply_Accessibility_Check --
866 -------------------------------
868 procedure Apply_Accessibility_Check
869 (N : Node_Id;
870 Typ : Entity_Id;
871 Insert_Node : Node_Id)
873 Loc : constant Source_Ptr := Sloc (N);
875 Check_Cond : Node_Id;
876 Param_Ent : Entity_Id := Param_Entity (N);
877 Param_Level : Node_Id;
878 Type_Level : Node_Id;
880 begin
881 -- Verify we haven't tried to add a dynamic accessibility check when we
882 -- shouldn't.
884 pragma Assert (not No_Dynamic_Accessibility_Checks_Enabled (N));
886 if Ada_Version >= Ada_2012
887 and then No (Param_Ent)
888 and then Is_Entity_Name (N)
889 and then Ekind (Entity (N)) in E_Constant | E_Variable
890 and then Present (Effective_Extra_Accessibility (Entity (N)))
891 then
892 Param_Ent := Entity (N);
893 while Present (Renamed_Object (Param_Ent)) loop
894 -- Renamed_Object must return an Entity_Name here
895 -- because of preceding "Present (E_E_A (...))" test.
897 Param_Ent := Entity (Renamed_Object (Param_Ent));
898 end loop;
899 end if;
901 if Inside_A_Generic then
902 return;
904 -- Only apply the run-time check if the access parameter has an
905 -- associated extra access level parameter and when accessibility checks
906 -- are enabled.
908 elsif Present (Param_Ent)
909 and then Present (Get_Dynamic_Accessibility (Param_Ent))
910 and then not Accessibility_Checks_Suppressed (Param_Ent)
911 and then not Accessibility_Checks_Suppressed (Typ)
912 then
913 -- Obtain the parameter's accessibility level
915 Param_Level :=
916 New_Occurrence_Of (Get_Dynamic_Accessibility (Param_Ent), Loc);
918 -- Use the dynamic accessibility parameter for the function's result
919 -- when one has been created instead of statically referring to the
920 -- deepest type level so as to appropriatly handle the rules for
921 -- RM 3.10.2 (10.1/3).
923 if Ekind (Scope (Param_Ent)) = E_Function
924 and then In_Return_Value (N)
925 and then Ekind (Typ) = E_Anonymous_Access_Type
926 then
927 -- Associate the level of the result type to the extra result
928 -- accessibility parameter belonging to the current function.
930 if Present (Extra_Accessibility_Of_Result (Scope (Param_Ent))) then
931 Type_Level :=
932 New_Occurrence_Of
933 (Extra_Accessibility_Of_Result (Scope (Param_Ent)), Loc);
935 -- In Ada 2005 and earlier modes, a result extra accessibility
936 -- parameter is not generated and no dynamic check is performed.
938 else
939 return;
940 end if;
942 -- Otherwise get the type's accessibility level normally
944 else
945 Type_Level :=
946 Make_Integer_Literal (Loc, Deepest_Type_Access_Level (Typ));
947 end if;
949 -- Raise Program_Error if the accessibility level of the access
950 -- parameter is deeper than the level of the target access type.
952 Check_Cond :=
953 Make_Op_Gt (Loc,
954 Left_Opnd => Param_Level,
955 Right_Opnd => Type_Level);
957 Insert_Action (Insert_Node,
958 Make_Raise_Program_Error (Loc,
959 Condition => Check_Cond,
960 Reason => PE_Accessibility_Check_Failed));
962 Analyze_And_Resolve (N);
964 -- If constant folding has happened on the condition for the
965 -- generated error, then warn about it being unconditional.
967 if Nkind (Check_Cond) = N_Identifier
968 and then Entity (Check_Cond) = Standard_True
969 then
970 Error_Msg_Warn := SPARK_Mode /= On;
971 Error_Msg_N ("accessibility check fails<<", N);
972 Error_Msg_N ("\Program_Error [<<", N);
973 end if;
974 end if;
975 end Apply_Accessibility_Check;
977 ---------------------------------------------
978 -- Apply_Accessibility_Check_For_Allocator --
979 ---------------------------------------------
981 procedure Apply_Accessibility_Check_For_Allocator
982 (N : Node_Id;
983 Exp : Node_Id;
984 Ref : Node_Id;
985 Built_In_Place : Boolean := False)
987 Loc : constant Source_Ptr := Sloc (N);
988 PtrT : constant Entity_Id := Etype (N);
989 DesigT : constant Entity_Id := Designated_Type (PtrT);
990 Pool_Id : constant Entity_Id := Associated_Storage_Pool (PtrT);
991 Cond : Node_Id;
992 Fin_Call : Node_Id;
993 Free_Stmt : Node_Id;
994 Obj_Ref : Node_Id;
995 Stmts : List_Id;
997 begin
998 if Ada_Version >= Ada_2005
999 and then Is_Class_Wide_Type (DesigT)
1000 and then Tagged_Type_Expansion
1001 and then not Scope_Suppress.Suppress (Accessibility_Check)
1002 and then not No_Dynamic_Accessibility_Checks_Enabled (Ref)
1003 and then
1004 (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
1005 or else
1006 (Is_Class_Wide_Type (Etype (Exp))
1007 and then Scope (PtrT) /= Current_Scope))
1008 then
1009 -- If the allocator was built in place, Ref is already a reference
1010 -- to the access object initialized to the result of the allocator
1011 -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). We call
1012 -- Remove_Side_Effects for cases where the build-in-place call may
1013 -- still be the prefix of the reference (to avoid generating
1014 -- duplicate calls). Otherwise, it is the entity associated with
1015 -- the object containing the address of the allocated object.
1017 if Built_In_Place then
1018 Remove_Side_Effects (Ref);
1019 Obj_Ref := New_Copy_Tree (Ref);
1020 else
1021 Obj_Ref := New_Occurrence_Of (Ref, Loc);
1022 end if;
1024 -- For access to interface types we must generate code to displace
1025 -- the pointer to the base of the object since the subsequent code
1026 -- references components located in the TSD of the object (which
1027 -- is associated with the primary dispatch table --see a-tags.ads)
1028 -- and also generates code invoking Free, which requires also a
1029 -- reference to the base of the unallocated object.
1031 if Is_Interface (DesigT) and then Tagged_Type_Expansion then
1032 Obj_Ref :=
1033 Unchecked_Convert_To (Etype (Obj_Ref),
1034 Make_Function_Call (Loc,
1035 Name =>
1036 New_Occurrence_Of (RTE (RE_Base_Address), Loc),
1037 Parameter_Associations => New_List (
1038 Unchecked_Convert_To (RTE (RE_Address),
1039 New_Copy_Tree (Obj_Ref)))));
1040 end if;
1042 -- Step 1: Create the object clean up code
1044 Stmts := New_List;
1046 -- Deallocate the object if the accessibility check fails. This is
1047 -- done only on targets or profiles that support deallocation.
1049 -- Free (Obj_Ref);
1051 if RTE_Available (RE_Free) then
1052 Free_Stmt := Make_Free_Statement (Loc, New_Copy_Tree (Obj_Ref));
1053 Set_Storage_Pool (Free_Stmt, Pool_Id);
1055 Append_To (Stmts, Free_Stmt);
1057 -- The target or profile cannot deallocate objects
1059 else
1060 Free_Stmt := Empty;
1061 end if;
1063 -- Finalize the object if applicable. Generate:
1065 -- [Deep_]Finalize (Obj_Ref.all);
1067 if Needs_Finalization (DesigT)
1068 and then not No_Heap_Finalization (PtrT)
1069 then
1070 Fin_Call :=
1071 Make_Final_Call
1072 (Obj_Ref =>
1073 Make_Explicit_Dereference (Loc, New_Copy (Obj_Ref)),
1074 Typ => DesigT);
1076 -- Guard against a missing [Deep_]Finalize when the designated
1077 -- type was not properly frozen.
1079 if No (Fin_Call) then
1080 Fin_Call := Make_Null_Statement (Loc);
1081 end if;
1083 -- When the target or profile supports deallocation, wrap the
1084 -- finalization call in a block to ensure proper deallocation even
1085 -- if finalization fails. Generate:
1087 -- begin
1088 -- <Fin_Call>
1089 -- exception
1090 -- when others =>
1091 -- <Free_Stmt>
1092 -- raise;
1093 -- end;
1095 if Present (Free_Stmt) then
1096 Fin_Call :=
1097 Make_Block_Statement (Loc,
1098 Handled_Statement_Sequence =>
1099 Make_Handled_Sequence_Of_Statements (Loc,
1100 Statements => New_List (Fin_Call),
1102 Exception_Handlers => New_List (
1103 Make_Exception_Handler (Loc,
1104 Exception_Choices => New_List (
1105 Make_Others_Choice (Loc)),
1106 Statements => New_List (
1107 New_Copy_Tree (Free_Stmt),
1108 Make_Raise_Statement (Loc))))));
1109 end if;
1111 Prepend_To (Stmts, Fin_Call);
1112 end if;
1114 -- Signal the accessibility failure through a Program_Error
1116 Append_To (Stmts,
1117 Make_Raise_Program_Error (Loc,
1118 Reason => PE_Accessibility_Check_Failed));
1120 -- Step 2: Create the accessibility comparison
1122 -- Generate:
1123 -- Ref'Tag
1125 Obj_Ref :=
1126 Make_Attribute_Reference (Loc,
1127 Prefix => Obj_Ref,
1128 Attribute_Name => Name_Tag);
1130 -- For tagged types, determine the accessibility level by looking at
1131 -- the type specific data of the dispatch table. Generate:
1133 -- Type_Specific_Data (Address (Ref'Tag)).Access_Level
1135 if Tagged_Type_Expansion then
1136 Cond := Build_Get_Access_Level (Loc, Obj_Ref);
1138 -- Use a runtime call to determine the accessibility level when
1139 -- compiling on virtual machine targets. Generate:
1141 -- Get_Access_Level (Ref'Tag)
1143 else
1144 Cond :=
1145 Make_Function_Call (Loc,
1146 Name =>
1147 New_Occurrence_Of (RTE (RE_Get_Access_Level), Loc),
1148 Parameter_Associations => New_List (Obj_Ref));
1149 end if;
1151 Cond :=
1152 Make_Op_Gt (Loc,
1153 Left_Opnd => Cond,
1154 Right_Opnd => Accessibility_Level (N, Dynamic_Level));
1156 -- Due to the complexity and side effects of the check, utilize an if
1157 -- statement instead of the regular Program_Error circuitry.
1159 Insert_Action (N,
1160 Make_Implicit_If_Statement (N,
1161 Condition => Cond,
1162 Then_Statements => Stmts));
1163 end if;
1164 end Apply_Accessibility_Check_For_Allocator;
1166 ------------------------------------------
1167 -- Check_Return_Construct_Accessibility --
1168 ------------------------------------------
1170 procedure Check_Return_Construct_Accessibility
1171 (Return_Stmt : Node_Id;
1172 Stm_Entity : Entity_Id)
1174 Loc : constant Source_Ptr := Sloc (Return_Stmt);
1175 Scope_Id : constant Entity_Id := Return_Applies_To (Stm_Entity);
1177 R_Type : constant Entity_Id := Etype (Scope_Id);
1178 -- Function result subtype
1180 function First_Selector (Assoc : Node_Id) return Node_Id;
1181 -- Obtain the first selector or choice from a given association
1183 function Is_Formal_Of_Current_Function
1184 (Assoc_Expr : Node_Id) return Boolean;
1185 -- Predicate to test if a given expression associated with a
1186 -- discriminant is a formal parameter to the function in which the
1187 -- return construct we checking applies to.
1189 --------------------
1190 -- First_Selector --
1191 --------------------
1193 function First_Selector (Assoc : Node_Id) return Node_Id is
1194 begin
1195 if Nkind (Assoc) = N_Component_Association then
1196 return First (Choices (Assoc));
1198 elsif Nkind (Assoc) = N_Discriminant_Association then
1199 return (First (Selector_Names (Assoc)));
1201 else
1202 raise Program_Error;
1203 end if;
1204 end First_Selector;
1206 -----------------------------------
1207 -- Is_Formal_Of_Current_Function --
1208 -----------------------------------
1210 function Is_Formal_Of_Current_Function
1211 (Assoc_Expr : Node_Id) return Boolean is
1212 begin
1213 return Is_Entity_Name (Assoc_Expr)
1214 and then Enclosing_Subprogram
1215 (Entity (Assoc_Expr)) = Scope_Id
1216 and then Is_Formal (Entity (Assoc_Expr));
1217 end Is_Formal_Of_Current_Function;
1219 -- Local declarations
1221 Assoc : Node_Id := Empty;
1222 -- Assoc should perhaps be renamed and declared as a
1223 -- Node_Or_Entity_Id since it encompasses not only component and
1224 -- discriminant associations, but also discriminant components within
1225 -- a type declaration or subtype indication ???
1227 Assoc_Expr : Node_Id;
1228 Assoc_Present : Boolean := False;
1230 Check_Cond : Node_Id;
1231 Unseen_Disc_Count : Nat := 0;
1232 Seen_Discs : Elist_Id;
1233 Disc : Entity_Id;
1234 First_Disc : Entity_Id;
1236 Obj_Decl : Node_Id;
1237 Return_Con : Node_Id;
1238 Unqual : Node_Id;
1240 -- Start of processing for Check_Return_Construct_Accessibility
1242 begin
1243 -- Only perform checks on record types with access discriminants and
1244 -- non-internally generated functions.
1246 if not Is_Record_Type (R_Type)
1247 or else not Has_Anonymous_Access_Discriminant (R_Type)
1248 or else not Comes_From_Source (Return_Stmt)
1249 then
1250 return;
1251 end if;
1253 -- We are only interested in return statements
1255 if Nkind (Return_Stmt) not in
1256 N_Extended_Return_Statement | N_Simple_Return_Statement
1257 then
1258 return;
1259 end if;
1261 -- Fetch the object from the return statement, in the case of a
1262 -- simple return statement the expression is part of the node.
1264 if Nkind (Return_Stmt) = N_Extended_Return_Statement then
1265 -- Obtain the object definition from the expanded extended return
1267 Return_Con := First (Return_Object_Declarations (Return_Stmt));
1268 while Present (Return_Con) loop
1269 -- Inspect the original node to avoid object declarations
1270 -- expanded into renamings.
1272 if Nkind (Original_Node (Return_Con)) = N_Object_Declaration
1273 and then Comes_From_Source (Original_Node (Return_Con))
1274 then
1275 exit;
1276 end if;
1278 Nlists.Next (Return_Con);
1279 end loop;
1281 pragma Assert (Present (Return_Con));
1283 -- Could be dealing with a renaming
1285 Return_Con := Original_Node (Return_Con);
1286 else
1287 Return_Con := Expression (Return_Stmt);
1288 end if;
1290 -- Obtain the accessibility levels of the expressions associated
1291 -- with all anonymous access discriminants, then generate a
1292 -- dynamic check or static error when relevant.
1294 -- Note the repeated use of Original_Node to avoid checking
1295 -- expanded code.
1297 Unqual := Original_Node (Unqualify (Original_Node (Return_Con)));
1299 -- Get the corresponding declaration based on the return object's
1300 -- identifier.
1302 if Nkind (Unqual) = N_Identifier
1303 and then Nkind (Parent (Entity (Unqual)))
1304 in N_Object_Declaration
1305 | N_Object_Renaming_Declaration
1306 then
1307 Obj_Decl := Original_Node (Parent (Entity (Unqual)));
1309 -- We were passed the object declaration directly, so use it
1311 elsif Nkind (Unqual) in N_Object_Declaration
1312 | N_Object_Renaming_Declaration
1313 then
1314 Obj_Decl := Unqual;
1316 -- Otherwise, we are looking at something else
1318 else
1319 Obj_Decl := Empty;
1321 end if;
1323 -- Hop up object renamings when present
1325 if Present (Obj_Decl)
1326 and then Nkind (Obj_Decl) = N_Object_Renaming_Declaration
1327 then
1328 while Nkind (Obj_Decl) = N_Object_Renaming_Declaration loop
1330 if Nkind (Name (Obj_Decl)) not in N_Entity then
1331 -- We may be looking at the expansion of iterators or
1332 -- some other internally generated construct, so it is safe
1333 -- to ignore checks ???
1335 if not Comes_From_Source (Obj_Decl) then
1336 return;
1337 end if;
1339 Obj_Decl := Original_Node
1340 (Declaration_Node
1341 (Ultimate_Prefix (Name (Obj_Decl))));
1343 -- Move up to the next declaration based on the object's name
1345 else
1346 Obj_Decl := Original_Node
1347 (Declaration_Node (Name (Obj_Decl)));
1348 end if;
1349 end loop;
1350 end if;
1352 -- Obtain the discriminant values from the return aggregate
1354 -- Do we cover extension aggregates correctly ???
1356 if Nkind (Unqual) = N_Aggregate then
1357 if Present (Expressions (Unqual)) then
1358 Assoc := First (Expressions (Unqual));
1359 else
1360 Assoc := First (Component_Associations (Unqual));
1361 end if;
1363 -- There is an object declaration for the return object
1365 elsif Present (Obj_Decl) then
1366 -- When a subtype indication is present in an object declaration
1367 -- it must contain the object's discriminants.
1369 if Nkind (Object_Definition (Obj_Decl)) = N_Subtype_Indication then
1370 Assoc := First
1371 (Constraints
1372 (Constraint
1373 (Object_Definition (Obj_Decl))));
1375 -- The object declaration contains an aggregate
1377 elsif Present (Expression (Obj_Decl)) then
1379 if Nkind (Unqualify (Expression (Obj_Decl))) = N_Aggregate then
1380 -- Grab the first associated discriminant expresion
1382 if Present
1383 (Expressions (Unqualify (Expression (Obj_Decl))))
1384 then
1385 Assoc := First
1386 (Expressions
1387 (Unqualify (Expression (Obj_Decl))));
1388 else
1389 Assoc := First
1390 (Component_Associations
1391 (Unqualify (Expression (Obj_Decl))));
1392 end if;
1394 -- Otherwise, this is something else
1396 else
1397 return;
1398 end if;
1400 -- There are no supplied discriminants in the object declaration,
1401 -- so get them from the type definition since they must be default
1402 -- initialized.
1404 -- Do we handle constrained subtypes correctly ???
1406 elsif Nkind (Unqual) = N_Object_Declaration then
1407 Assoc := First_Discriminant
1408 (Etype (Object_Definition (Obj_Decl)));
1410 else
1411 Assoc := First_Discriminant (Etype (Unqual));
1412 end if;
1414 -- When we are not looking at an aggregate or an identifier, return
1415 -- since any other construct (like a function call) is not
1416 -- applicable since checks will be performed on the side of the
1417 -- callee.
1419 else
1420 return;
1421 end if;
1423 -- Obtain the discriminants so we know the actual type in case the
1424 -- value of their associated expression gets implicitly converted.
1426 if No (Obj_Decl) then
1427 pragma Assert (Nkind (Unqual) = N_Aggregate);
1429 Disc := First_Discriminant (Etype (Unqual));
1431 else
1432 Disc := First_Discriminant
1433 (Etype (Defining_Identifier (Obj_Decl)));
1434 end if;
1436 -- Preserve the first discriminant for checking named associations
1438 First_Disc := Disc;
1440 -- Count the number of discriminants for processing an aggregate
1441 -- which includes an others.
1443 Disc := First_Disc;
1444 while Present (Disc) loop
1445 Unseen_Disc_Count := Unseen_Disc_Count + 1;
1447 Next_Discriminant (Disc);
1448 end loop;
1450 Seen_Discs := New_Elmt_List;
1452 -- Loop through each of the discriminants and check each expression
1453 -- associated with an anonymous access discriminant.
1455 -- When named associations occur in the return aggregate then
1456 -- discriminants can be in any order, so we need to ensure we do
1457 -- not continue to loop when all discriminants have been seen.
1459 Disc := First_Disc;
1460 while Present (Assoc)
1461 and then (Present (Disc) or else Assoc_Present)
1462 and then Unseen_Disc_Count > 0
1463 loop
1464 -- Handle named associations by searching through the names of
1465 -- the relevant discriminant components.
1467 if Nkind (Assoc)
1468 in N_Component_Association | N_Discriminant_Association
1469 then
1470 Assoc_Expr := Expression (Assoc);
1471 Assoc_Present := True;
1473 -- We currently don't handle box initialized discriminants,
1474 -- however, since default initialized anonymous access
1475 -- discriminants are a corner case, this is ok for now ???
1477 if Nkind (Assoc) = N_Component_Association
1478 and then Box_Present (Assoc)
1479 then
1480 if Nkind (First_Selector (Assoc)) = N_Others_Choice then
1481 Unseen_Disc_Count := 0;
1482 end if;
1484 -- When others is present we must identify a discriminant we
1485 -- haven't already seen so as to get the appropriate type for
1486 -- the static accessibility check.
1488 -- This works because all components within an others clause
1489 -- must have the same type.
1491 elsif Nkind (First_Selector (Assoc)) = N_Others_Choice then
1493 Disc := First_Disc;
1494 Outer : while Present (Disc) loop
1495 declare
1496 Current_Seen_Disc : Elmt_Id;
1497 begin
1498 -- Move through the list of identified discriminants
1500 Current_Seen_Disc := First_Elmt (Seen_Discs);
1501 while Present (Current_Seen_Disc) loop
1502 -- Exit the loop when we found a match
1504 exit when
1505 Chars (Node (Current_Seen_Disc)) = Chars (Disc);
1507 Next_Elmt (Current_Seen_Disc);
1508 end loop;
1510 -- When we have exited the above loop without finding
1511 -- a match then we know that Disc has not been seen.
1513 exit Outer when No (Current_Seen_Disc);
1514 end;
1516 Next_Discriminant (Disc);
1517 end loop Outer;
1519 -- If we got to an others clause with a non-zero
1520 -- discriminant count there must be a discriminant left to
1521 -- check.
1523 pragma Assert (Present (Disc));
1525 -- Set the unseen discriminant count to zero because we know
1526 -- an others clause sets all remaining components of an
1527 -- aggregate.
1529 Unseen_Disc_Count := 0;
1531 -- Move through each of the selectors in the named association
1532 -- and obtain a discriminant for accessibility checking if one
1533 -- is referenced in the list. Also track which discriminants
1534 -- are referenced for the purpose of handling an others clause.
1536 else
1537 declare
1538 Assoc_Choice : Node_Id;
1539 Curr_Disc : Node_Id;
1540 begin
1542 Disc := Empty;
1543 Curr_Disc := First_Disc;
1544 while Present (Curr_Disc) loop
1545 -- Check each of the choices in the associations for a
1546 -- match to the name of the current discriminant.
1548 Assoc_Choice := First_Selector (Assoc);
1549 while Present (Assoc_Choice) loop
1550 -- When the name matches we track that we have seen
1551 -- the discriminant, but instead of exiting the
1552 -- loop we continue iterating to make sure all the
1553 -- discriminants within the named association get
1554 -- tracked.
1556 if Chars (Assoc_Choice) = Chars (Curr_Disc) then
1557 Append_Elmt (Curr_Disc, Seen_Discs);
1559 Disc := Curr_Disc;
1560 Unseen_Disc_Count := Unseen_Disc_Count - 1;
1561 end if;
1563 Next (Assoc_Choice);
1564 end loop;
1566 Next_Discriminant (Curr_Disc);
1567 end loop;
1568 end;
1569 end if;
1571 -- Unwrap the associated expression if we are looking at a default
1572 -- initialized type declaration. In this case Assoc is not really
1573 -- an association, but a component declaration. Should Assoc be
1574 -- renamed in some way to be more clear ???
1576 -- This occurs when the return object does not initialize
1577 -- discriminant and instead relies on the type declaration for
1578 -- their supplied values.
1580 elsif Nkind (Assoc) in N_Entity
1581 and then Ekind (Assoc) = E_Discriminant
1582 then
1583 Append_Elmt (Disc, Seen_Discs);
1585 Assoc_Expr := Discriminant_Default_Value (Assoc);
1586 Unseen_Disc_Count := Unseen_Disc_Count - 1;
1588 -- Otherwise, there is nothing to do because Assoc is an
1589 -- expression within the return aggregate itself.
1591 else
1592 Append_Elmt (Disc, Seen_Discs);
1594 Assoc_Expr := Assoc;
1595 Unseen_Disc_Count := Unseen_Disc_Count - 1;
1596 end if;
1598 -- Check the accessibility level of the expression when the
1599 -- discriminant is of an anonymous access type.
1601 if Present (Assoc_Expr)
1602 and then Present (Disc)
1603 and then Ekind (Etype (Disc)) = E_Anonymous_Access_Type
1605 -- We disable the check when we have a tagged return type and
1606 -- the associated expression for the discriminant is a formal
1607 -- parameter since the check would require us to compare the
1608 -- accessibility level of Assoc_Expr to the level of the
1609 -- Extra_Accessibility_Of_Result of the function - which is
1610 -- currently disabled for functions with tagged return types.
1611 -- This may change in the future ???
1613 -- See Needs_Result_Accessibility_Level for details.
1615 and then not
1616 (No (Extra_Accessibility_Of_Result (Scope_Id))
1617 and then Is_Formal_Of_Current_Function (Assoc_Expr)
1618 and then Is_Tagged_Type (Etype (Scope_Id)))
1619 then
1620 -- Generate a dynamic check based on the extra accessibility of
1621 -- the result or the scope of the current function.
1623 Check_Cond :=
1624 Make_Op_Gt (Loc,
1625 Left_Opnd => Accessibility_Level
1626 (Expr => Assoc_Expr,
1627 Level => Dynamic_Level,
1628 In_Return_Context => True),
1629 Right_Opnd =>
1630 (if Present (Extra_Accessibility_Of_Result (Scope_Id))
1632 -- When Assoc_Expr is a formal we have to look at the
1633 -- extra accessibility-level formal associated with
1634 -- the result.
1636 and then Is_Formal_Of_Current_Function (Assoc_Expr)
1637 then
1638 New_Occurrence_Of
1639 (Extra_Accessibility_Of_Result (Scope_Id), Loc)
1641 -- Otherwise, we compare the level of Assoc_Expr to the
1642 -- scope of the current function.
1644 else
1645 Make_Integer_Literal
1646 (Loc, Scope_Depth (Scope (Scope_Id)))));
1648 Insert_Before_And_Analyze (Return_Stmt,
1649 Make_Raise_Program_Error (Loc,
1650 Condition => Check_Cond,
1651 Reason => PE_Accessibility_Check_Failed));
1653 -- If constant folding has happened on the condition for the
1654 -- generated error, then warn about it being unconditional when
1655 -- we know an error will be raised.
1657 if Nkind (Check_Cond) = N_Identifier
1658 and then Entity (Check_Cond) = Standard_True
1659 then
1660 Error_Msg_N
1661 ("access discriminant in return object would be a dangling"
1662 & " reference", Return_Stmt);
1663 end if;
1664 end if;
1666 -- Iterate over the discriminants, except when we have encountered
1667 -- a named association since the discriminant order becomes
1668 -- irrelevant in that case.
1670 if not Assoc_Present then
1671 Next_Discriminant (Disc);
1672 end if;
1674 -- Iterate over associations
1676 if not Is_List_Member (Assoc) then
1677 exit;
1678 else
1679 Nlists.Next (Assoc);
1680 end if;
1681 end loop;
1682 end Check_Return_Construct_Accessibility;
1684 -------------------------------
1685 -- Deepest_Type_Access_Level --
1686 -------------------------------
1688 function Deepest_Type_Access_Level
1689 (Typ : Entity_Id;
1690 Allow_Alt_Model : Boolean := True) return Uint
1692 begin
1693 if Ekind (Typ) = E_Anonymous_Access_Type
1694 and then not Is_Local_Anonymous_Access (Typ)
1695 and then Nkind (Associated_Node_For_Itype (Typ)) = N_Object_Declaration
1696 then
1697 -- No_Dynamic_Accessibility_Checks override for alternative
1698 -- accessibility model.
1700 if Allow_Alt_Model
1701 and then No_Dynamic_Accessibility_Checks_Enabled (Typ)
1702 then
1703 return Type_Access_Level (Typ, Allow_Alt_Model);
1704 end if;
1706 -- Typ is the type of an Ada 2012 stand-alone object of an anonymous
1707 -- access type.
1709 return
1710 Scope_Depth (Enclosing_Dynamic_Scope
1711 (Defining_Identifier
1712 (Associated_Node_For_Itype (Typ))));
1714 -- For generic formal type, return Int'Last (infinite).
1715 -- See comment preceding Is_Generic_Type call in Type_Access_Level.
1717 elsif Is_Generic_Type (Root_Type (Typ)) then
1718 return UI_From_Int (Int'Last);
1720 else
1721 return Type_Access_Level (Typ, Allow_Alt_Model);
1722 end if;
1723 end Deepest_Type_Access_Level;
1725 -----------------------------------
1726 -- Effective_Extra_Accessibility --
1727 -----------------------------------
1729 function Effective_Extra_Accessibility (Id : Entity_Id) return Entity_Id is
1730 begin
1731 if Present (Renamed_Object (Id))
1732 and then Is_Entity_Name (Renamed_Object (Id))
1733 then
1734 return Effective_Extra_Accessibility (Entity (Renamed_Object (Id)));
1735 else
1736 return Extra_Accessibility (Id);
1737 end if;
1738 end Effective_Extra_Accessibility;
1740 -------------------------------
1741 -- Get_Dynamic_Accessibility --
1742 -------------------------------
1744 function Get_Dynamic_Accessibility (E : Entity_Id) return Entity_Id is
1745 begin
1746 -- When minimum accessibility is set for E then we utilize it - except
1747 -- in a few edge cases like the expansion of select statements where
1748 -- generated subprogram may attempt to unnecessarily use a minimum
1749 -- accessibility object declared outside of scope.
1751 -- To avoid these situations where expansion may get complex we verify
1752 -- that the minimum accessibility object is within scope.
1754 if Is_Formal (E)
1755 and then Present (Minimum_Accessibility (E))
1756 and then In_Open_Scopes (Scope (Minimum_Accessibility (E)))
1757 then
1758 return Minimum_Accessibility (E);
1759 end if;
1761 return Extra_Accessibility (E);
1762 end Get_Dynamic_Accessibility;
1764 -----------------------
1765 -- Has_Access_Values --
1766 -----------------------
1768 function Has_Access_Values (T : Entity_Id) return Boolean
1770 Typ : constant Entity_Id := Underlying_Type (T);
1772 begin
1773 -- Case of a private type which is not completed yet. This can only
1774 -- happen in the case of a generic formal type appearing directly, or
1775 -- as a component of the type to which this function is being applied
1776 -- at the top level. Return False in this case, since we certainly do
1777 -- not know that the type contains access types.
1779 if No (Typ) then
1780 return False;
1782 elsif Is_Access_Type (Typ) then
1783 return True;
1785 elsif Is_Array_Type (Typ) then
1786 return Has_Access_Values (Component_Type (Typ));
1788 elsif Is_Record_Type (Typ) then
1789 declare
1790 Comp : Entity_Id;
1792 begin
1793 -- Loop to check components
1795 Comp := First_Component_Or_Discriminant (Typ);
1796 while Present (Comp) loop
1798 -- Check for access component, tag field does not count, even
1799 -- though it is implemented internally using an access type.
1801 if Has_Access_Values (Etype (Comp))
1802 and then Chars (Comp) /= Name_uTag
1803 then
1804 return True;
1805 end if;
1807 Next_Component_Or_Discriminant (Comp);
1808 end loop;
1809 end;
1811 return False;
1813 else
1814 return False;
1815 end if;
1816 end Has_Access_Values;
1818 ---------------------------------------
1819 -- Has_Anonymous_Access_Discriminant --
1820 ---------------------------------------
1822 function Has_Anonymous_Access_Discriminant (Typ : Entity_Id) return Boolean
1824 Disc : Node_Id;
1826 begin
1827 if not Has_Discriminants (Typ) then
1828 return False;
1829 end if;
1831 Disc := First_Discriminant (Typ);
1832 while Present (Disc) loop
1833 if Ekind (Etype (Disc)) = E_Anonymous_Access_Type then
1834 return True;
1835 end if;
1837 Next_Discriminant (Disc);
1838 end loop;
1840 return False;
1841 end Has_Anonymous_Access_Discriminant;
1843 --------------------------------------------
1844 -- Has_Unconstrained_Access_Discriminants --
1845 --------------------------------------------
1847 function Has_Unconstrained_Access_Discriminants
1848 (Subtyp : Entity_Id) return Boolean
1850 Discr : Entity_Id;
1852 begin
1853 if Has_Discriminants (Subtyp)
1854 and then not Is_Constrained (Subtyp)
1855 then
1856 Discr := First_Discriminant (Subtyp);
1857 while Present (Discr) loop
1858 if Ekind (Etype (Discr)) = E_Anonymous_Access_Type then
1859 return True;
1860 end if;
1862 Next_Discriminant (Discr);
1863 end loop;
1864 end if;
1866 return False;
1867 end Has_Unconstrained_Access_Discriminants;
1869 --------------------------------
1870 -- Is_Anonymous_Access_Actual --
1871 --------------------------------
1873 function Is_Anonymous_Access_Actual (N : Node_Id) return Boolean is
1874 Par : Node_Id;
1875 begin
1876 if Ekind (Etype (N)) /= E_Anonymous_Access_Type then
1877 return False;
1878 end if;
1880 Par := Parent (N);
1881 while Present (Par)
1882 and then Nkind (Par) in N_Case_Expression
1883 | N_If_Expression
1884 | N_Parameter_Association
1885 loop
1886 Par := Parent (Par);
1887 end loop;
1888 return Nkind (Par) in N_Subprogram_Call;
1889 end Is_Anonymous_Access_Actual;
1891 --------------------------------------
1892 -- Is_Special_Aliased_Formal_Access --
1893 --------------------------------------
1895 function Is_Special_Aliased_Formal_Access
1896 (Exp : Node_Id;
1897 In_Return_Context : Boolean := False) return Boolean
1899 Scop : constant Entity_Id := Current_Subprogram;
1900 begin
1901 -- Verify the expression is an access reference to 'Access within a
1902 -- return statement as this is the only time an explicitly aliased
1903 -- formal has different semantics.
1905 if Nkind (Exp) /= N_Attribute_Reference
1906 or else Get_Attribute_Id (Attribute_Name (Exp)) /= Attribute_Access
1907 or else not (In_Return_Value (Exp)
1908 or else In_Return_Context)
1909 or else not Needs_Result_Accessibility_Level (Scop)
1910 then
1911 return False;
1912 end if;
1914 -- Check if the prefix of the reference is indeed an explicitly aliased
1915 -- formal parameter for the function Scop. Additionally, we must check
1916 -- that Scop returns an anonymous access type, otherwise the special
1917 -- rules dictating a need for a dynamic check are not in effect.
1919 return Is_Entity_Name (Prefix (Exp))
1920 and then Is_Explicitly_Aliased (Entity (Prefix (Exp)));
1921 end Is_Special_Aliased_Formal_Access;
1923 --------------------------------------
1924 -- Needs_Result_Accessibility_Level --
1925 --------------------------------------
1927 function Needs_Result_Accessibility_Level
1928 (Func_Id : Entity_Id) return Boolean
1930 Func_Typ : constant Entity_Id := Underlying_Type (Etype (Func_Id));
1932 function Has_Unconstrained_Access_Discriminant_Component
1933 (Comp_Typ : Entity_Id) return Boolean;
1934 -- Returns True if any component of the type has an unconstrained access
1935 -- discriminant.
1937 -----------------------------------------------------
1938 -- Has_Unconstrained_Access_Discriminant_Component --
1939 -----------------------------------------------------
1941 function Has_Unconstrained_Access_Discriminant_Component
1942 (Comp_Typ : Entity_Id) return Boolean
1944 begin
1945 if not Is_Limited_Type (Comp_Typ) then
1946 return False;
1948 -- Only limited types can have access discriminants with
1949 -- defaults.
1951 elsif Has_Unconstrained_Access_Discriminants (Comp_Typ) then
1952 return True;
1954 elsif Is_Array_Type (Comp_Typ) then
1955 return Has_Unconstrained_Access_Discriminant_Component
1956 (Underlying_Type (Component_Type (Comp_Typ)));
1958 elsif Is_Record_Type (Comp_Typ) then
1959 declare
1960 Comp : Entity_Id;
1962 begin
1963 Comp := First_Component (Comp_Typ);
1964 while Present (Comp) loop
1965 if Has_Unconstrained_Access_Discriminant_Component
1966 (Underlying_Type (Etype (Comp)))
1967 then
1968 return True;
1969 end if;
1971 Next_Component (Comp);
1972 end loop;
1973 end;
1974 end if;
1976 return False;
1977 end Has_Unconstrained_Access_Discriminant_Component;
1979 Disable_Tagged_Cases : constant Boolean := True;
1980 -- Flag used to temporarily disable a "True" result for tagged types.
1981 -- See comments further below for details.
1983 -- Start of processing for Needs_Result_Accessibility_Level
1985 begin
1986 -- False if completion unavailable, which can happen when we are
1987 -- analyzing an abstract subprogram or if the subprogram has
1988 -- delayed freezing.
1990 if No (Func_Typ) then
1991 return False;
1993 -- False if not a function, also handle enum-lit renames case
1995 elsif Func_Typ = Standard_Void_Type
1996 or else Is_Scalar_Type (Func_Typ)
1997 then
1998 return False;
2000 -- Handle a corner case, a cross-dialect subp renaming. For example,
2001 -- an Ada 2012 renaming of an Ada 2005 subprogram. This can occur when
2002 -- an Ada 2005 (or earlier) unit references predefined run-time units.
2004 elsif Present (Alias (Func_Id)) then
2006 -- Unimplemented: a cross-dialect subp renaming which does not set
2007 -- the Alias attribute (e.g., a rename of a dereference of an access
2008 -- to subprogram value). ???
2010 return Present (Extra_Accessibility_Of_Result (Alias (Func_Id)));
2012 -- Remaining cases require Ada 2012 mode, unless they are dispatching
2013 -- operations, since they may be overridden by Ada_2012 primitives.
2015 elsif Ada_Version < Ada_2012
2016 and then not Is_Dispatching_Operation (Func_Id)
2017 then
2018 return False;
2020 -- Handle the situation where a result is an anonymous access type
2021 -- RM 3.10.2 (10.3/3).
2023 elsif Ekind (Func_Typ) = E_Anonymous_Access_Type then
2024 return True;
2026 -- In the case of, say, a null tagged record result type, the need for
2027 -- this extra parameter might not be obvious so this function returns
2028 -- True for all tagged types for compatibility reasons.
2030 -- A function with, say, a tagged null controlling result type might
2031 -- be overridden by a primitive of an extension having an access
2032 -- discriminant and the overrider and overridden must have compatible
2033 -- calling conventions (including implicitly declared parameters).
2035 -- Similarly, values of one access-to-subprogram type might designate
2036 -- both a primitive subprogram of a given type and a function which is,
2037 -- for example, not a primitive subprogram of any type. Again, this
2038 -- requires calling convention compatibility. It might be possible to
2039 -- solve these issues by introducing wrappers, but that is not the
2040 -- approach that was chosen.
2042 -- Note: Despite the reasoning noted above, the extra accessibility
2043 -- parameter for tagged types is disabled for performance reasons.
2045 elsif Is_Tagged_Type (Func_Typ) then
2046 return not Disable_Tagged_Cases;
2048 elsif Has_Unconstrained_Access_Discriminants (Func_Typ) then
2049 return True;
2051 elsif Has_Unconstrained_Access_Discriminant_Component (Func_Typ) then
2052 return True;
2054 -- False for all other cases
2056 else
2057 return False;
2058 end if;
2059 end Needs_Result_Accessibility_Level;
2061 ------------------------------------------
2062 -- Prefix_With_Safe_Accessibility_Level --
2063 ------------------------------------------
2065 function Prefix_With_Safe_Accessibility_Level
2066 (N : Node_Id;
2067 Typ : Entity_Id) return Boolean
2069 P : constant Node_Id := Prefix (N);
2070 Aname : constant Name_Id := Attribute_Name (N);
2071 Attr_Id : constant Attribute_Id := Get_Attribute_Id (Aname);
2072 Btyp : constant Entity_Id := Base_Type (Typ);
2074 function Safe_Value_Conversions return Boolean;
2075 -- Return False if the prefix has a value conversion of an array type
2077 ----------------------------
2078 -- Safe_Value_Conversions --
2079 ----------------------------
2081 function Safe_Value_Conversions return Boolean is
2082 PP : Node_Id := P;
2084 begin
2085 loop
2086 if Nkind (PP) in N_Selected_Component | N_Indexed_Component then
2087 PP := Prefix (PP);
2089 elsif Comes_From_Source (PP)
2090 and then Nkind (PP) in N_Type_Conversion
2091 | N_Unchecked_Type_Conversion
2092 and then Is_Array_Type (Etype (PP))
2093 then
2094 return False;
2096 elsif Comes_From_Source (PP)
2097 and then Nkind (PP) = N_Qualified_Expression
2098 and then Is_Array_Type (Etype (PP))
2099 and then Nkind (Original_Node (Expression (PP))) in
2100 N_Aggregate | N_Extension_Aggregate
2101 then
2102 return False;
2104 else
2105 exit;
2106 end if;
2107 end loop;
2109 return True;
2110 end Safe_Value_Conversions;
2112 -- Start of processing for Prefix_With_Safe_Accessibility_Level
2114 begin
2115 -- No check required for unchecked and unrestricted access
2117 if Attr_Id = Attribute_Unchecked_Access
2118 or else Attr_Id = Attribute_Unrestricted_Access
2119 then
2120 return True;
2122 -- Check value conversions
2124 elsif Ekind (Btyp) = E_General_Access_Type
2125 and then not Safe_Value_Conversions
2126 then
2127 return False;
2128 end if;
2130 return True;
2131 end Prefix_With_Safe_Accessibility_Level;
2133 -----------------------------
2134 -- Subprogram_Access_Level --
2135 -----------------------------
2137 function Subprogram_Access_Level (Subp : Entity_Id) return Uint is
2138 begin
2139 if Present (Alias (Subp)) then
2140 return Subprogram_Access_Level (Alias (Subp));
2141 else
2142 return Scope_Depth (Enclosing_Dynamic_Scope (Subp));
2143 end if;
2144 end Subprogram_Access_Level;
2146 --------------------------------
2147 -- Static_Accessibility_Level --
2148 --------------------------------
2150 function Static_Accessibility_Level
2151 (Expr : Node_Id;
2152 Level : Static_Accessibility_Level_Kind;
2153 In_Return_Context : Boolean := False) return Uint
2155 begin
2156 return Intval
2157 (Accessibility_Level (Expr, Level, In_Return_Context));
2158 end Static_Accessibility_Level;
2160 -----------------------
2161 -- Type_Access_Level --
2162 -----------------------
2164 function Type_Access_Level
2165 (Typ : Entity_Id;
2166 Allow_Alt_Model : Boolean := True;
2167 Assoc_Ent : Entity_Id := Empty) return Uint
2169 Btyp : Entity_Id := Base_Type (Typ);
2170 Def_Ent : Entity_Id;
2172 begin
2173 -- Ada 2005 (AI-230): For most cases of anonymous access types, we
2174 -- simply use the level where the type is declared. This is true for
2175 -- stand-alone object declarations, and for anonymous access types
2176 -- associated with components the level is the same as that of the
2177 -- enclosing composite type. However, special treatment is needed for
2178 -- the cases of access parameters, return objects of an anonymous access
2179 -- type, and, in Ada 95, access discriminants of limited types.
2181 if Is_Access_Type (Btyp) then
2182 if Ekind (Btyp) = E_Anonymous_Access_Type then
2183 -- No_Dynamic_Accessibility_Checks restriction override for
2184 -- alternative accessibility model.
2186 if Allow_Alt_Model
2187 and then No_Dynamic_Accessibility_Checks_Enabled (Btyp)
2188 then
2189 -- In the -gnatd_b model, the level of an anonymous access
2190 -- type is always that of the designated type.
2192 if Debug_Flag_Underscore_B then
2193 return Type_Access_Level
2194 (Designated_Type (Btyp), Allow_Alt_Model);
2195 end if;
2197 -- When an anonymous access type's Assoc_Ent is specified,
2198 -- calculate the result based on the general accessibility
2199 -- level routine.
2201 -- We would like to use Associated_Node_For_Itype here instead,
2202 -- but in some cases it is not fine grained enough ???
2204 if Present (Assoc_Ent) then
2205 return Static_Accessibility_Level
2206 (Assoc_Ent, Object_Decl_Level);
2207 end if;
2209 -- Otherwise take the context of the anonymous access type into
2210 -- account.
2212 -- Obtain the defining entity for the internally generated
2213 -- anonymous access type.
2215 Def_Ent := Defining_Entity_Or_Empty
2216 (Associated_Node_For_Itype (Typ));
2218 if Present (Def_Ent) then
2219 -- When the defining entity is a subprogram then we know the
2220 -- anonymous access type Typ has been generated to either
2221 -- describe an anonymous access type formal or an anonymous
2222 -- access result type.
2224 -- Since we are only interested in the formal case, avoid
2225 -- the anonymous access result type.
2227 if Is_Subprogram (Def_Ent)
2228 and then not (Ekind (Def_Ent) = E_Function
2229 and then Etype (Def_Ent) = Typ)
2230 then
2231 -- When the type comes from an anonymous access
2232 -- parameter, the level is that of the subprogram
2233 -- declaration.
2235 return Scope_Depth (Def_Ent);
2237 -- When the type is an access discriminant, the level is
2238 -- that of the type.
2240 elsif Ekind (Def_Ent) = E_Discriminant then
2241 return Scope_Depth
2242 (if Present (Full_View (Scope (Def_Ent))) then
2243 Full_View (Scope (Def_Ent))
2244 else
2245 Scope (Def_Ent));
2246 end if;
2247 end if;
2249 -- If the type is a nonlocal anonymous access type (such as for
2250 -- an access parameter) we treat it as being declared at the
2251 -- library level to ensure that names such as X.all'access don't
2252 -- fail static accessibility checks.
2254 elsif not Is_Local_Anonymous_Access (Typ) then
2255 return Scope_Depth (Standard_Standard);
2257 -- If this is a return object, the accessibility level is that of
2258 -- the result subtype of the enclosing function. The test here is
2259 -- little complicated, because we have to account for extended
2260 -- return statements that have been rewritten as blocks, in which
2261 -- case we have to find and the Is_Return_Object attribute of the
2262 -- itype's associated object. It would be nice to find a way to
2263 -- simplify this test, but it doesn't seem worthwhile to add a new
2264 -- flag just for purposes of this test. ???
2266 elsif Ekind (Scope (Btyp)) = E_Return_Statement
2267 or else
2268 (Is_Itype (Btyp)
2269 and then Nkind (Associated_Node_For_Itype (Btyp)) =
2270 N_Object_Declaration
2271 and then Is_Return_Object
2272 (Defining_Identifier
2273 (Associated_Node_For_Itype (Btyp))))
2274 then
2275 declare
2276 Scop : Entity_Id;
2278 begin
2279 Scop := Scope (Scope (Btyp));
2280 while Present (Scop) loop
2281 exit when Ekind (Scop) = E_Function;
2282 Scop := Scope (Scop);
2283 end loop;
2285 -- Treat the return object's type as having the level of the
2286 -- function's result subtype (as per RM05-6.5(5.3/2)).
2288 return Type_Access_Level (Etype (Scop), Allow_Alt_Model);
2289 end;
2290 end if;
2291 end if;
2293 Btyp := Root_Type (Btyp);
2295 -- The accessibility level of anonymous access types associated with
2296 -- discriminants is that of the current instance of the type, and
2297 -- that's deeper than the type itself (AARM 3.10.2 (12.3.21)).
2299 -- AI-402: access discriminants have accessibility based on the
2300 -- object rather than the type in Ada 2005, so the above paragraph
2301 -- doesn't apply.
2303 -- ??? Needs completion with rules from AI-416
2305 if Ada_Version <= Ada_95
2306 and then Ekind (Typ) = E_Anonymous_Access_Type
2307 and then Present (Associated_Node_For_Itype (Typ))
2308 and then Nkind (Associated_Node_For_Itype (Typ)) =
2309 N_Discriminant_Specification
2310 then
2311 return Scope_Depth (Enclosing_Dynamic_Scope (Btyp)) + 1;
2312 end if;
2313 end if;
2315 -- Return library level for a generic formal type. This is done because
2316 -- RM(10.3.2) says that "The statically deeper relationship does not
2317 -- apply to ... a descendant of a generic formal type". Rather than
2318 -- checking at each point where a static accessibility check is
2319 -- performed to see if we are dealing with a formal type, this rule is
2320 -- implemented by having Type_Access_Level and Deepest_Type_Access_Level
2321 -- return extreme values for a formal type; Deepest_Type_Access_Level
2322 -- returns Int'Last. By calling the appropriate function from among the
2323 -- two, we ensure that the static accessibility check will pass if we
2324 -- happen to run into a formal type. More specifically, we should call
2325 -- Deepest_Type_Access_Level instead of Type_Access_Level whenever the
2326 -- call occurs as part of a static accessibility check and the error
2327 -- case is the case where the type's level is too shallow (as opposed
2328 -- to too deep).
2330 if Is_Generic_Type (Root_Type (Btyp)) then
2331 return Scope_Depth (Standard_Standard);
2332 end if;
2334 return Scope_Depth (Enclosing_Dynamic_Scope (Btyp));
2335 end Type_Access_Level;
2337 end Accessibility;