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