Disable tests for strdup/strndup on __hpux__
[official-gcc.git] / gcc / ada / exp_util.adb
blob1df63ed38c87ad7fc06d55498f36c2ed3d2ef86e
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ U T I L --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2023, 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 Aspects; use Aspects;
27 with Atree; use Atree;
28 with Casing; use Casing;
29 with Checks; use Checks;
30 with Debug; use Debug;
31 with Einfo; use Einfo;
32 with Einfo.Entities; use Einfo.Entities;
33 with Elists; use Elists;
34 with Errout; use Errout;
35 with Exp_Aggr; use Exp_Aggr;
36 with Exp_Ch6; use Exp_Ch6;
37 with Exp_Ch7; use Exp_Ch7;
38 with Exp_Ch11; use Exp_Ch11;
39 with Freeze; use Freeze;
40 with Ghost; use Ghost;
41 with Inline; use Inline;
42 with Itypes; use Itypes;
43 with Lib; use Lib;
44 with Nlists; use Nlists;
45 with Nmake; use Nmake;
46 with Opt; use Opt;
47 with Restrict; use Restrict;
48 with Rident; use Rident;
49 with Sem; use Sem;
50 with Sem_Aux; use Sem_Aux;
51 with Sem_Ch3; use Sem_Ch3;
52 with Sem_Ch6; use Sem_Ch6;
53 with Sem_Ch8; use Sem_Ch8;
54 with Sem_Ch12; use Sem_Ch12;
55 with Sem_Ch13; use Sem_Ch13;
56 with Sem_Disp; use Sem_Disp;
57 with Sem_Elab; use Sem_Elab;
58 with Sem_Eval; use Sem_Eval;
59 with Sem_Res; use Sem_Res;
60 with Sem_Type; use Sem_Type;
61 with Sem_Util; use Sem_Util;
62 with Sinfo.Utils; use Sinfo.Utils;
63 with Snames; use Snames;
64 with Stand; use Stand;
65 with Stringt; use Stringt;
66 with Tbuild; use Tbuild;
67 with Ttypes; use Ttypes;
68 with Validsw; use Validsw;
69 with Warnsw; use Warnsw;
71 with GNAT.HTable;
72 package body Exp_Util is
74 ---------------------------------------------------------
75 -- Handling of inherited class-wide pre/postconditions --
76 ---------------------------------------------------------
78 -- Following AI12-0113, the expression for a class-wide condition is
79 -- transformed for a subprogram that inherits it, by replacing calls
80 -- to primitive operations of the original controlling type into the
81 -- corresponding overriding operations of the derived type. The following
82 -- hash table manages this mapping, and is expanded on demand whenever
83 -- such inherited expression needs to be constructed.
85 -- The mapping is also used to check whether an inherited operation has
86 -- a condition that depends on overridden operations. For such an
87 -- operation we must create a wrapper that is then treated as a normal
88 -- overriding. In SPARK mode such operations are illegal.
90 -- For a given root type there may be several type extensions with their
91 -- own overriding operations, so at various times a given operation of
92 -- the root will be mapped into different overridings. The root type is
93 -- also mapped into the current type extension to indicate that its
94 -- operations are mapped into the overriding operations of that current
95 -- type extension.
97 -- The contents of the map are as follows:
99 -- Key Value
101 -- Discriminant (Entity_Id) Discriminant (Entity_Id)
102 -- Discriminant (Entity_Id) Non-discriminant name (Entity_Id)
103 -- Discriminant (Entity_Id) Expression (Node_Id)
104 -- Primitive subprogram (Entity_Id) Primitive subprogram (Entity_Id)
105 -- Type (Entity_Id) Type (Entity_Id)
107 Type_Map_Size : constant := 511;
109 subtype Type_Map_Header is Integer range 0 .. Type_Map_Size - 1;
110 function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header;
112 package Type_Map is new GNAT.HTable.Simple_HTable
113 (Header_Num => Type_Map_Header,
114 Key => Entity_Id,
115 Element => Node_Or_Entity_Id,
116 No_Element => Empty,
117 Hash => Type_Map_Hash,
118 Equal => "=");
120 -----------------------
121 -- Local Subprograms --
122 -----------------------
124 function Build_Task_Array_Image
125 (Loc : Source_Ptr;
126 Id_Ref : Node_Id;
127 A_Type : Entity_Id;
128 Dyn : Boolean := False) return Node_Id;
129 -- Build function to generate the image string for a task that is an array
130 -- component, concatenating the images of each index. To avoid storage
131 -- leaks, the string is built with successive slice assignments. The flag
132 -- Dyn indicates whether this is called for the initialization procedure of
133 -- an array of tasks, or for the name of a dynamically created task that is
134 -- assigned to an indexed component.
136 function Build_Task_Image_Function
137 (Loc : Source_Ptr;
138 Decls : List_Id;
139 Stats : List_Id;
140 Res : Entity_Id) return Node_Id;
141 -- Common processing for Task_Array_Image and Task_Record_Image. Build
142 -- function body that computes image.
144 procedure Build_Task_Image_Prefix
145 (Loc : Source_Ptr;
146 Len : out Entity_Id;
147 Res : out Entity_Id;
148 Pos : out Entity_Id;
149 Prefix : Entity_Id;
150 Sum : Node_Id;
151 Decls : List_Id;
152 Stats : List_Id);
153 -- Common processing for Task_Array_Image and Task_Record_Image. Create
154 -- local variables and assign prefix of name to result string.
156 function Build_Task_Record_Image
157 (Loc : Source_Ptr;
158 Id_Ref : Node_Id;
159 Dyn : Boolean := False) return Node_Id;
160 -- Build function to generate the image string for a task that is a record
161 -- component. Concatenate name of variable with that of selector. The flag
162 -- Dyn indicates whether this is called for the initialization procedure of
163 -- record with task components, or for a dynamically created task that is
164 -- assigned to a selected component.
166 procedure Evaluate_Slice_Bounds (Slice : Node_Id);
167 -- Force evaluation of bounds of a slice, which may be given by a range
168 -- or by a subtype indication with or without a constraint.
170 function Is_Uninitialized_Aggregate
171 (Exp : Node_Id;
172 T : Entity_Id) return Boolean;
173 -- Determine whether an array aggregate used in an object declaration
174 -- is uninitialized, when the aggregate is declared with a box and
175 -- the component type has no default value. Such an aggregate can be
176 -- optimized away to prevent the copying of uninitialized data, and
177 -- the bounds of the aggregate can be propagated directly to the
178 -- object declaration.
180 function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean;
181 -- Determine whether pragma Default_Initial_Condition denoted by Prag has
182 -- an assertion expression that should be verified at run time.
184 function Make_CW_Equivalent_Type
185 (T : Entity_Id;
186 E : Node_Id) return Entity_Id;
187 -- T is a class-wide type entity, E is the initial expression node that
188 -- constrains T in case such as: " X: T := E" or "new T'(E)". This function
189 -- returns the entity of the Equivalent type and inserts on the fly the
190 -- necessary declaration such as:
192 -- type anon is record
193 -- _parent : Root_Type (T); constrained with E discriminants (if any)
194 -- Extension : String (1 .. expr to match size of E);
195 -- end record;
197 -- This record is compatible with any object of the class of T thanks to
198 -- the first field and has the same size as E thanks to the second.
200 function Make_Literal_Range
201 (Loc : Source_Ptr;
202 Literal_Typ : Entity_Id) return Node_Id;
203 -- Produce a Range node whose bounds are:
204 -- Low_Bound (Literal_Type) ..
205 -- Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1)
206 -- this is used for expanding declarations like X : String := "sdfgdfg";
208 -- If the index type of the target array is not integer, we generate:
209 -- Low_Bound (Literal_Type) ..
210 -- Literal_Type'Val
211 -- (Literal_Type'Pos (Low_Bound (Literal_Type))
212 -- + (Length (Literal_Typ) -1))
214 function Make_Non_Empty_Check
215 (Loc : Source_Ptr;
216 N : Node_Id) return Node_Id;
217 -- Produce a boolean expression checking that the unidimensional array
218 -- node N is not empty.
220 function New_Class_Wide_Subtype
221 (CW_Typ : Entity_Id;
222 N : Node_Id) return Entity_Id;
223 -- Create an implicit subtype of CW_Typ attached to node N
225 function Requires_Cleanup_Actions
226 (L : List_Id;
227 Lib_Level : Boolean;
228 Nested_Constructs : Boolean) return Boolean;
229 -- Given a list L, determine whether it contains one of the following:
231 -- 1) controlled objects
232 -- 2) library-level tagged types
234 -- Lib_Level is True when the list comes from a construct at the library
235 -- level, and False otherwise. Nested_Constructs is True when any nested
236 -- packages declared in L must be processed, and False otherwise.
238 function Side_Effect_Free_Attribute (Name : Name_Id) return Boolean;
239 -- Return True if the evaluation of the given attribute is considered
240 -- side-effect-free, independently of its prefix and expressions.
242 -------------------------------------
243 -- Activate_Atomic_Synchronization --
244 -------------------------------------
246 procedure Activate_Atomic_Synchronization (N : Node_Id) is
247 Msg_Node : Node_Id;
249 begin
250 case Nkind (Parent (N)) is
252 -- Check for cases of appearing in the prefix of a construct where we
253 -- don't need atomic synchronization for this kind of usage.
255 when
256 -- Nothing to do if we are the prefix of an attribute, since we
257 -- do not want an atomic sync operation for things like 'Size.
259 N_Attribute_Reference
261 -- The N_Reference node is like an attribute
263 | N_Reference
265 -- Nothing to do for a reference to a component (or components)
266 -- of a composite object. Only reads and updates of the object
267 -- as a whole require atomic synchronization (RM C.6 (15)).
269 | N_Indexed_Component
270 | N_Selected_Component
271 | N_Slice
273 -- For all the above cases, nothing to do if we are the prefix
275 if Prefix (Parent (N)) = N then
276 return;
277 end if;
279 when others =>
280 null;
281 end case;
283 -- Nothing to do for the identifier in an object renaming declaration,
284 -- the renaming itself does not need atomic synchronization.
286 if Nkind (Parent (N)) = N_Object_Renaming_Declaration then
287 return;
288 end if;
290 -- Go ahead and set the flag
292 Set_Atomic_Sync_Required (N);
294 -- Generate info message if requested
296 if Warn_On_Atomic_Synchronization then
297 case Nkind (N) is
298 when N_Identifier =>
299 Msg_Node := N;
301 when N_Expanded_Name
302 | N_Selected_Component
304 Msg_Node := Selector_Name (N);
306 when N_Explicit_Dereference
307 | N_Indexed_Component
309 Msg_Node := Empty;
311 when others =>
312 pragma Assert (False);
313 return;
314 end case;
316 if Present (Msg_Node) then
317 Error_Msg_N
318 ("info: atomic synchronization set for &?.n?", Msg_Node);
319 else
320 Error_Msg_N
321 ("info: atomic synchronization set?.n?", N);
322 end if;
323 end if;
324 end Activate_Atomic_Synchronization;
326 ----------------------
327 -- Adjust_Condition --
328 ----------------------
330 procedure Adjust_Condition (N : Node_Id) is
332 function Is_Hardbool_Type (T : Entity_Id) return Boolean;
333 -- Return True iff T is a type annotated with the
334 -- Machine_Attribute pragma "hardbool".
336 ----------------------
337 -- Is_Hardbool_Type --
338 ----------------------
340 function Is_Hardbool_Type (T : Entity_Id) return Boolean is
342 function Find_Hardbool_Pragma
343 (Id : Entity_Id) return Node_Id;
344 -- Return a Rep_Item associated with entity Id that
345 -- corresponds to the Hardbool Machine_Attribute pragma, if
346 -- any, or Empty otherwise.
348 function Pragma_Arg_To_String (Item : Node_Id) return String is
349 (To_String (Strval (Expr_Value_S (Item))));
350 -- Return the pragma argument Item as a String
352 function Hardbool_Pragma_P (Item : Node_Id) return Boolean is
353 (Nkind (Item) = N_Pragma
354 and then
355 Pragma_Name (Item) = Name_Machine_Attribute
356 and then
357 Pragma_Arg_To_String
358 (Get_Pragma_Arg
359 (Next (First (Pragma_Argument_Associations (Item)))))
360 = "hardbool");
361 -- Return True iff representation Item is a "hardbool"
362 -- Machine_Attribute pragma.
364 --------------------------
365 -- Find_Hardbool_Pragma --
366 --------------------------
368 function Find_Hardbool_Pragma
369 (Id : Entity_Id) return Node_Id
371 Item : Node_Id;
373 begin
374 if not Has_Gigi_Rep_Item (Id) then
375 return Empty;
376 end if;
378 Item := First_Rep_Item (Id);
379 while Present (Item) loop
380 if Hardbool_Pragma_P (Item) then
381 return Item;
382 end if;
383 Item := Next_Rep_Item (Item);
384 end loop;
386 return Empty;
387 end Find_Hardbool_Pragma;
389 -- Start of processing for Is_Hardbool_Type
391 begin
392 return Present (Find_Hardbool_Pragma (T));
393 end Is_Hardbool_Type;
395 -- Start of processing for Adjust_Condition
397 begin
398 if No (N) then
399 return;
400 end if;
402 declare
403 Loc : constant Source_Ptr := Sloc (N);
404 T : constant Entity_Id := Etype (N);
406 begin
407 -- Defend against a call where the argument has no type, or has a
408 -- type that is not Boolean. This can occur because of prior errors.
410 if No (T) or else not Is_Boolean_Type (T) then
411 return;
412 end if;
414 -- Apply validity checking if needed
416 if Validity_Checks_On
417 and then
418 (Validity_Check_Tests or else Is_Hardbool_Type (T))
419 then
420 Ensure_Valid (N);
421 end if;
423 -- Immediate return if standard boolean, the most common case,
424 -- where nothing needs to be done.
426 if Base_Type (T) = Standard_Boolean then
427 return;
428 end if;
430 -- Case of zero/nonzero semantics or nonstandard enumeration
431 -- representation. In each case, we rewrite the node as:
433 -- ityp!(N) /= False'Enum_Rep
435 -- where ityp is an integer type with large enough size to hold any
436 -- value of type T.
438 if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
439 Rewrite (N,
440 Make_Op_Ne (Loc,
441 Left_Opnd =>
442 Unchecked_Convert_To
443 (Integer_Type_For (Esize (T), Uns => False), N),
444 Right_Opnd =>
445 Make_Attribute_Reference (Loc,
446 Attribute_Name => Name_Enum_Rep,
447 Prefix =>
448 New_Occurrence_Of (First_Literal (T), Loc))));
449 Analyze_And_Resolve (N, Standard_Boolean);
451 else
452 Rewrite (N, Convert_To (Standard_Boolean, N));
453 Analyze_And_Resolve (N, Standard_Boolean);
454 end if;
455 end;
456 end Adjust_Condition;
458 ------------------------
459 -- Adjust_Result_Type --
460 ------------------------
462 procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
463 begin
464 -- Ignore call if current type is not Standard.Boolean
466 if Etype (N) /= Standard_Boolean then
467 return;
468 end if;
470 -- If result is already of correct type, nothing to do. Note that
471 -- this will get the most common case where everything has a type
472 -- of Standard.Boolean.
474 if Base_Type (T) = Standard_Boolean then
475 return;
477 else
478 declare
479 KP : constant Node_Kind := Nkind (Parent (N));
481 begin
482 -- If result is to be used as a Condition in the syntax, no need
483 -- to convert it back, since if it was changed to Standard.Boolean
484 -- using Adjust_Condition, that is just fine for this usage.
486 if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
487 return;
489 -- If result is an operand of another logical operation, no need
490 -- to reset its type, since Standard.Boolean is just fine, and
491 -- such operations always do Adjust_Condition on their operands.
493 elsif KP in N_Op_Boolean
494 or else KP in N_Short_Circuit
495 or else KP = N_Op_Not
496 or else (KP in N_Type_Conversion
497 | N_Unchecked_Type_Conversion
498 and then Is_Boolean_Type (Etype (Parent (N))))
499 then
500 return;
502 -- Otherwise we perform a conversion from the current type, which
503 -- must be Standard.Boolean, to the desired type. Use the base
504 -- type to prevent spurious constraint checks that are extraneous
505 -- to the transformation. The type and its base have the same
506 -- representation, standard or otherwise.
508 else
509 Set_Analyzed (N);
510 Rewrite (N, Convert_To (Base_Type (T), N));
511 Analyze_And_Resolve (N, Base_Type (T));
512 end if;
513 end;
514 end if;
515 end Adjust_Result_Type;
517 --------------------------
518 -- Append_Freeze_Action --
519 --------------------------
521 procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
522 Fnode : Node_Id;
524 begin
525 Ensure_Freeze_Node (T);
526 Fnode := Freeze_Node (T);
528 if No (Actions (Fnode)) then
529 Set_Actions (Fnode, New_List (N));
530 else
531 Append (N, Actions (Fnode));
532 end if;
533 end Append_Freeze_Action;
535 ---------------------------
536 -- Append_Freeze_Actions --
537 ---------------------------
539 procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
540 Fnode : Node_Id;
542 begin
543 if No (L) then
544 return;
545 end if;
547 Ensure_Freeze_Node (T);
548 Fnode := Freeze_Node (T);
550 if No (Actions (Fnode)) then
551 Set_Actions (Fnode, L);
552 else
553 Append_List (L, Actions (Fnode));
554 end if;
555 end Append_Freeze_Actions;
557 ----------------------------------------
558 -- Attribute_Constrained_Static_Value --
559 ----------------------------------------
561 function Attribute_Constrained_Static_Value (Pref : Node_Id) return Boolean
563 Ptyp : constant Entity_Id := Etype (Pref);
564 Formal_Ent : constant Entity_Id := Param_Entity (Pref);
566 function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean;
567 -- Ada 2005 (AI-363): Returns True if the object name Obj denotes a
568 -- view of an aliased object whose subtype is constrained.
570 ---------------------------------
571 -- Is_Constrained_Aliased_View --
572 ---------------------------------
574 function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean is
575 E : Entity_Id;
577 begin
578 if Is_Entity_Name (Obj) then
579 E := Entity (Obj);
581 if Present (Renamed_Object (E)) then
582 return Is_Constrained_Aliased_View (Renamed_Object (E));
583 else
584 return Is_Aliased (E) and then Is_Constrained (Etype (E));
585 end if;
587 else
588 return Is_Aliased_View (Obj)
589 and then
590 (Is_Constrained (Etype (Obj))
591 or else
592 (Nkind (Obj) = N_Explicit_Dereference
593 and then
594 not Object_Type_Has_Constrained_Partial_View
595 (Typ => Base_Type (Etype (Obj)),
596 Scop => Current_Scope)));
597 end if;
598 end Is_Constrained_Aliased_View;
600 -- Start of processing for Attribute_Constrained_Static_Value
602 begin
603 -- We are in a case where the attribute is known statically, and
604 -- implicit dereferences have been rewritten.
606 pragma Assert
607 (not (Present (Formal_Ent)
608 and then Ekind (Formal_Ent) /= E_Constant
609 and then Present (Extra_Constrained (Formal_Ent)))
610 and then
611 not (Is_Access_Type (Etype (Pref))
612 and then (not Is_Entity_Name (Pref)
613 or else Is_Object (Entity (Pref))))
614 and then
615 not (Nkind (Pref) = N_Identifier
616 and then Ekind (Entity (Pref)) = E_Variable
617 and then Present (Extra_Constrained (Entity (Pref)))));
619 if Is_Entity_Name (Pref) then
620 declare
621 Ent : constant Entity_Id := Entity (Pref);
622 Res : Boolean;
624 begin
625 -- (RM J.4) obsolescent cases
627 if Is_Type (Ent) then
629 -- Private type
631 if Is_Private_Type (Ent) then
632 Res := not Has_Discriminants (Ent)
633 or else Is_Constrained (Ent);
635 -- It not a private type, must be a generic actual type
636 -- that corresponded to a private type. We know that this
637 -- correspondence holds, since otherwise the reference
638 -- within the generic template would have been illegal.
640 else
641 if Is_Composite_Type (Underlying_Type (Ent)) then
642 Res := Is_Constrained (Ent);
643 else
644 Res := True;
645 end if;
646 end if;
648 else
650 -- If the prefix is not a variable or is aliased, then
651 -- definitely true; if it's a formal parameter without an
652 -- associated extra formal, then treat it as constrained.
654 -- Ada 2005 (AI-363): An aliased prefix must be known to be
655 -- constrained in order to set the attribute to True.
657 if not Is_Variable (Pref)
658 or else Present (Formal_Ent)
659 or else (Ada_Version < Ada_2005
660 and then Is_Aliased_View (Pref))
661 or else (Ada_Version >= Ada_2005
662 and then Is_Constrained_Aliased_View (Pref))
663 then
664 Res := True;
666 -- Variable case, look at type to see if it is constrained.
667 -- Note that the one case where this is not accurate (the
668 -- procedure formal case), has been handled above.
670 -- We use the Underlying_Type here (and below) in case the
671 -- type is private without discriminants, but the full type
672 -- has discriminants. This case is illegal, but we generate
673 -- it internally for passing to the Extra_Constrained
674 -- parameter.
676 else
677 -- In Ada 2012, test for case of a limited tagged type,
678 -- in which case the attribute is always required to
679 -- return True. The underlying type is tested, to make
680 -- sure we also return True for cases where there is an
681 -- unconstrained object with an untagged limited partial
682 -- view which has defaulted discriminants (such objects
683 -- always produce a False in earlier versions of
684 -- Ada). (Ada 2012: AI05-0214)
686 Res :=
687 Is_Constrained (Underlying_Type (Etype (Ent)))
688 or else
689 (Ada_Version >= Ada_2012
690 and then Is_Tagged_Type (Underlying_Type (Ptyp))
691 and then Is_Limited_Type (Ptyp));
692 end if;
693 end if;
695 return Res;
696 end;
698 -- Prefix is not an entity name. These are also cases where we can
699 -- always tell at compile time by looking at the form and type of the
700 -- prefix. If an explicit dereference of an object with constrained
701 -- partial view, this is unconstrained (Ada 2005: AI95-0363). If the
702 -- underlying type is a limited tagged type, then Constrained is
703 -- required to always return True (Ada 2012: AI05-0214).
705 else
706 return not Is_Variable (Pref)
707 or else
708 (Nkind (Pref) = N_Explicit_Dereference
709 and then
710 not Object_Type_Has_Constrained_Partial_View
711 (Typ => Base_Type (Ptyp),
712 Scop => Current_Scope))
713 or else Is_Constrained (Underlying_Type (Ptyp))
714 or else (Ada_Version >= Ada_2012
715 and then Is_Tagged_Type (Underlying_Type (Ptyp))
716 and then Is_Limited_Type (Ptyp));
717 end if;
718 end Attribute_Constrained_Static_Value;
720 ------------------------------------
721 -- Build_Allocate_Deallocate_Proc --
722 ------------------------------------
724 procedure Build_Allocate_Deallocate_Proc
725 (N : Node_Id;
726 Is_Allocate : Boolean)
728 function Find_Object (E : Node_Id) return Node_Id;
729 -- Given an arbitrary expression of an allocator, try to find an object
730 -- reference in it, otherwise return the original expression.
732 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean;
733 -- Determine whether subprogram Subp denotes a custom allocate or
734 -- deallocate.
736 -----------------
737 -- Find_Object --
738 -----------------
740 function Find_Object (E : Node_Id) return Node_Id is
741 Expr : Node_Id;
743 begin
744 pragma Assert (Is_Allocate);
746 Expr := E;
747 loop
748 if Nkind (Expr) = N_Explicit_Dereference then
749 Expr := Prefix (Expr);
751 elsif Nkind (Expr) = N_Qualified_Expression then
752 Expr := Expression (Expr);
754 elsif Nkind (Expr) = N_Unchecked_Type_Conversion then
756 -- When interface class-wide types are involved in allocation,
757 -- the expander introduces several levels of address arithmetic
758 -- to perform dispatch table displacement. In this scenario the
759 -- object appears as:
761 -- Tag_Ptr (Base_Address (<object>'Address))
763 -- Detect this case and utilize the whole expression as the
764 -- "object" since it now points to the proper dispatch table.
766 if Is_RTE (Etype (Expr), RE_Tag_Ptr) then
767 exit;
769 -- Continue to strip the object
771 else
772 Expr := Expression (Expr);
773 end if;
775 else
776 exit;
777 end if;
778 end loop;
780 return Expr;
781 end Find_Object;
783 ---------------------------------
784 -- Is_Allocate_Deallocate_Proc --
785 ---------------------------------
787 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is
788 begin
789 -- Look for a subprogram body with only one statement which is a
790 -- call to Allocate_Any_Controlled / Deallocate_Any_Controlled.
792 if Ekind (Subp) = E_Procedure
793 and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body
794 then
795 declare
796 HSS : constant Node_Id :=
797 Handled_Statement_Sequence (Parent (Parent (Subp)));
798 Proc : Entity_Id;
800 begin
801 if Present (Statements (HSS))
802 and then Nkind (First (Statements (HSS))) =
803 N_Procedure_Call_Statement
804 then
805 Proc := Entity (Name (First (Statements (HSS))));
807 return
808 Is_RTE (Proc, RE_Allocate_Any_Controlled)
809 or else Is_RTE (Proc, RE_Deallocate_Any_Controlled);
810 end if;
811 end;
812 end if;
814 return False;
815 end Is_Allocate_Deallocate_Proc;
817 -- Local variables
819 Desig_Typ : Entity_Id;
820 Expr : Node_Id;
821 Needs_Fin : Boolean;
822 Pool_Id : Entity_Id;
823 Proc_To_Call : Node_Id := Empty;
824 Ptr_Typ : Entity_Id;
825 Use_Secondary_Stack_Pool : Boolean;
827 -- Start of processing for Build_Allocate_Deallocate_Proc
829 begin
830 -- Obtain the attributes of the allocation / deallocation
832 if Nkind (N) = N_Free_Statement then
833 Expr := Expression (N);
834 Ptr_Typ := Base_Type (Etype (Expr));
835 Proc_To_Call := Procedure_To_Call (N);
837 else
838 if Nkind (N) = N_Object_Declaration then
839 Expr := Expression (N);
840 else
841 Expr := N;
842 end if;
844 -- In certain cases an allocator with a qualified expression may
845 -- be relocated and used as the initialization expression of a
846 -- temporary:
848 -- before:
849 -- Obj : Ptr_Typ := new Desig_Typ'(...);
851 -- after:
852 -- Tmp : Ptr_Typ := new Desig_Typ'(...);
853 -- Obj : Ptr_Typ := Tmp;
855 -- Since the allocator is always marked as analyzed to avoid infinite
856 -- expansion, it will never be processed by this routine given that
857 -- the designated type needs finalization actions. Detect this case
858 -- and complete the expansion of the allocator.
860 if Nkind (Expr) = N_Identifier
861 and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration
862 and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator
863 then
864 Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True);
865 return;
866 end if;
868 -- The allocator may have been rewritten into something else in which
869 -- case the expansion performed by this routine does not apply.
871 if Nkind (Expr) /= N_Allocator then
872 return;
873 end if;
875 Ptr_Typ := Base_Type (Etype (Expr));
876 Proc_To_Call := Procedure_To_Call (Expr);
877 end if;
879 Pool_Id := Associated_Storage_Pool (Ptr_Typ);
880 Desig_Typ := Available_View (Designated_Type (Ptr_Typ));
882 -- Handle concurrent types
884 if Is_Concurrent_Type (Desig_Typ)
885 and then Present (Corresponding_Record_Type (Desig_Typ))
886 then
887 Desig_Typ := Corresponding_Record_Type (Desig_Typ);
888 end if;
890 Use_Secondary_Stack_Pool :=
891 Is_RTE (Pool_Id, RE_SS_Pool)
892 or else (Nkind (Expr) = N_Allocator
893 and then Is_RTE (Storage_Pool (Expr), RE_SS_Pool));
895 -- Do not process allocations / deallocations without a pool
897 if No (Pool_Id) then
898 return;
900 -- Do not process allocations from the return stack
902 elsif Is_RTE (Pool_Id, RE_RS_Pool) then
903 return;
905 -- Do not process allocations on / deallocations from the secondary
906 -- stack, except for access types used to implement indirect temps.
908 elsif Use_Secondary_Stack_Pool
909 and then not Old_Attr_Util.Indirect_Temps
910 .Is_Access_Type_For_Indirect_Temp (Ptr_Typ)
911 then
912 return;
914 -- Optimize the case where we are using the default Global_Pool_Object,
915 -- and we don't need the heavy finalization machinery.
917 elsif Is_RTE (Pool_Id, RE_Global_Pool_Object)
918 and then not Needs_Finalization (Desig_Typ)
919 then
920 return;
922 -- Do not replicate the machinery if the allocator / free has already
923 -- been expanded and has a custom Allocate / Deallocate.
925 elsif Present (Proc_To_Call)
926 and then Is_Allocate_Deallocate_Proc (Proc_To_Call)
927 then
928 return;
929 end if;
931 -- Finalization actions are required when the object to be allocated or
932 -- deallocated needs these actions and the associated access type is not
933 -- subject to pragma No_Heap_Finalization.
935 Needs_Fin :=
936 Needs_Finalization (Desig_Typ)
937 and then not No_Heap_Finalization (Ptr_Typ);
939 if Needs_Fin then
941 -- Do nothing if the access type may never allocate / deallocate
942 -- objects.
944 if No_Pool_Assigned (Ptr_Typ) then
945 return;
946 end if;
948 -- The allocation / deallocation of a controlled object must be
949 -- chained on / detached from a finalization master.
951 pragma Assert (Present (Finalization_Master (Ptr_Typ)));
953 -- The only other kind of allocation / deallocation supported by this
954 -- routine is on / from a subpool.
956 elsif Nkind (Expr) = N_Allocator
957 and then No (Subpool_Handle_Name (Expr))
958 then
959 return;
960 end if;
962 declare
963 Loc : constant Source_Ptr := Sloc (N);
964 Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A');
965 Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L');
966 Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
967 Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
969 Actuals : List_Id;
970 Alloc_Nod : Node_Id := Empty;
971 Alloc_Expr : Node_Id := Empty;
972 Fin_Addr_Id : Entity_Id;
973 Fin_Mas_Act : Node_Id;
974 Fin_Mas_Id : Entity_Id;
975 Proc_To_Call : Entity_Id;
976 Subpool : Node_Id := Empty;
978 begin
979 -- When we are building an allocator procedure, extract the allocator
980 -- node for later processing and calculation of alignment.
982 if Is_Allocate then
984 if Nkind (Expr) = N_Allocator then
985 Alloc_Nod := Expr;
987 -- When Expr is an object declaration we have to examine its
988 -- expression.
990 elsif Nkind (Expr) = N_Object_Declaration
991 and then Nkind (Expression (Expr)) = N_Allocator
992 then
993 Alloc_Nod := Expression (Expr);
995 -- Otherwise, we raise an error because we should have found one
997 else
998 raise Program_Error;
999 end if;
1001 -- Extract the qualified expression if there is one from the
1002 -- allocator.
1004 if Nkind (Expression (Alloc_Nod)) = N_Qualified_Expression then
1005 Alloc_Expr := Expression (Alloc_Nod);
1006 end if;
1007 end if;
1009 -- Step 1: Construct all the actuals for the call to library routine
1010 -- Allocate_Any_Controlled / Deallocate_Any_Controlled.
1012 -- a) Storage pool
1014 Actuals := New_List (New_Occurrence_Of (Pool_Id, Loc));
1016 if Is_Allocate then
1018 -- b) Subpool
1020 if Nkind (Expr) = N_Allocator then
1021 Subpool := Subpool_Handle_Name (Expr);
1022 end if;
1024 -- If a subpool is present it can be an arbitrary name, so make
1025 -- the actual by copying the tree.
1027 if Present (Subpool) then
1028 Append_To (Actuals, New_Copy_Tree (Subpool, New_Sloc => Loc));
1029 else
1030 Append_To (Actuals, Make_Null (Loc));
1031 end if;
1033 -- c) Finalization master
1035 if Needs_Fin then
1036 Fin_Mas_Id := Finalization_Master (Ptr_Typ);
1037 Fin_Mas_Act := New_Occurrence_Of (Fin_Mas_Id, Loc);
1039 -- Handle the case where the master is actually a pointer to a
1040 -- master. This case arises in build-in-place functions.
1042 if Is_Access_Type (Etype (Fin_Mas_Id)) then
1043 Append_To (Actuals, Fin_Mas_Act);
1044 else
1045 Append_To (Actuals,
1046 Make_Attribute_Reference (Loc,
1047 Prefix => Fin_Mas_Act,
1048 Attribute_Name => Name_Unrestricted_Access));
1049 end if;
1050 else
1051 Append_To (Actuals, Make_Null (Loc));
1052 end if;
1054 -- d) Finalize_Address
1056 -- Primitive Finalize_Address is never generated in CodePeer mode
1057 -- since it contains an Unchecked_Conversion.
1059 if Needs_Fin and then not CodePeer_Mode then
1060 Fin_Addr_Id := Finalize_Address (Desig_Typ);
1061 pragma Assert (Present (Fin_Addr_Id));
1063 Append_To (Actuals,
1064 Make_Attribute_Reference (Loc,
1065 Prefix => New_Occurrence_Of (Fin_Addr_Id, Loc),
1066 Attribute_Name => Name_Unrestricted_Access));
1067 else
1068 Append_To (Actuals, Make_Null (Loc));
1069 end if;
1070 end if;
1072 -- e) Address
1073 -- f) Storage_Size
1074 -- g) Alignment
1076 Append_To (Actuals, New_Occurrence_Of (Addr_Id, Loc));
1077 Append_To (Actuals, New_Occurrence_Of (Size_Id, Loc));
1079 -- Class-wide allocations without expressions and non-class-wide
1080 -- allocations can be performed without getting the alignment from
1081 -- the type's Type Specific Record.
1083 if ((Is_Allocate and then No (Alloc_Expr))
1084 or else
1085 not Is_Class_Wide_Type (Desig_Typ))
1086 and then not Use_Secondary_Stack_Pool
1087 then
1088 Append_To (Actuals, New_Occurrence_Of (Alig_Id, Loc));
1090 -- For operations on class-wide types we obtain the value of
1091 -- alignment from the Type Specific Record of the relevant object.
1092 -- This is needed because the frontend expansion of class-wide types
1093 -- into equivalent types confuses the back end.
1095 else
1096 -- Generate:
1097 -- Obj.all'Alignment
1098 -- or
1099 -- Alloc_Expr'Alignment
1101 -- ... because 'Alignment applied to class-wide types is expanded
1102 -- into the code that reads the value of alignment from the TSD
1103 -- (see Expand_N_Attribute_Reference)
1105 -- In the Use_Secondary_Stack_Pool case, Alig_Id is not
1106 -- passed in and therefore must not be referenced.
1108 Append_To (Actuals,
1109 Unchecked_Convert_To (RTE (RE_Storage_Offset),
1110 Make_Attribute_Reference (Loc,
1111 Prefix =>
1112 (if No (Alloc_Expr) then
1113 Make_Explicit_Dereference (Loc, Relocate_Node (Expr))
1114 else
1115 Relocate_Node (Expression (Alloc_Expr))),
1116 Attribute_Name => Name_Alignment)));
1117 end if;
1119 -- h) Is_Controlled
1121 if Needs_Fin then
1122 Is_Controlled : declare
1123 Flag_Id : constant Entity_Id := Make_Temporary (Loc, 'F');
1124 Flag_Expr : Node_Id;
1125 Param : Node_Id;
1126 Pref : Node_Id;
1127 Temp : Node_Id;
1129 begin
1130 if Is_Allocate then
1131 Temp := Find_Object (Expression (Expr));
1132 else
1133 Temp := Expr;
1134 end if;
1136 -- Processing for allocations where the expression is a subtype
1137 -- indication.
1139 if Is_Allocate
1140 and then Is_Entity_Name (Temp)
1141 and then Is_Type (Entity (Temp))
1142 then
1143 Flag_Expr :=
1144 New_Occurrence_Of
1145 (Boolean_Literals
1146 (Needs_Finalization (Entity (Temp))), Loc);
1148 -- The allocation / deallocation of a class-wide object relies
1149 -- on a runtime check to determine whether the object is truly
1150 -- controlled or not. Depending on this check, the finalization
1151 -- machinery will request or reclaim extra storage reserved for
1152 -- a list header.
1154 elsif Is_Class_Wide_Type (Desig_Typ) then
1156 -- Detect a special case where interface class-wide types
1157 -- are involved as the object appears as:
1159 -- Tag_Ptr (Base_Address (<object>'Address))
1161 -- The expression already yields the proper tag, generate:
1163 -- Temp.all
1165 if Is_RTE (Etype (Temp), RE_Tag_Ptr) then
1166 Param :=
1167 Make_Explicit_Dereference (Loc,
1168 Prefix => Relocate_Node (Temp));
1170 -- In the default case, obtain the tag of the object about
1171 -- to be allocated / deallocated. Generate:
1173 -- Temp'Tag
1175 -- If the object is an unchecked conversion (typically to
1176 -- an access to class-wide type), we must preserve the
1177 -- conversion to ensure that the object is seen as tagged
1178 -- in the code that follows.
1180 else
1181 Pref := Temp;
1183 if Nkind (Parent (Pref)) = N_Unchecked_Type_Conversion
1184 then
1185 Pref := Parent (Pref);
1186 end if;
1188 Param :=
1189 Make_Attribute_Reference (Loc,
1190 Prefix => Relocate_Node (Pref),
1191 Attribute_Name => Name_Tag);
1192 end if;
1194 -- Generate:
1195 -- Needs_Finalization (<Param>)
1197 Flag_Expr :=
1198 Make_Function_Call (Loc,
1199 Name =>
1200 New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc),
1201 Parameter_Associations => New_List (Param));
1203 -- Processing for generic actuals
1205 elsif Is_Generic_Actual_Type (Desig_Typ) then
1206 Flag_Expr :=
1207 New_Occurrence_Of (Boolean_Literals
1208 (Needs_Finalization (Base_Type (Desig_Typ))), Loc);
1210 -- The object does not require any specialized checks, it is
1211 -- known to be controlled.
1213 else
1214 Flag_Expr := New_Occurrence_Of (Standard_True, Loc);
1215 end if;
1217 -- Create the temporary which represents the finalization state
1218 -- of the expression. Generate:
1220 -- F : constant Boolean := <Flag_Expr>;
1222 Insert_Action (N,
1223 Make_Object_Declaration (Loc,
1224 Defining_Identifier => Flag_Id,
1225 Constant_Present => True,
1226 Object_Definition =>
1227 New_Occurrence_Of (Standard_Boolean, Loc),
1228 Expression => Flag_Expr));
1230 Append_To (Actuals, New_Occurrence_Of (Flag_Id, Loc));
1231 end Is_Controlled;
1233 -- The object is not controlled
1235 else
1236 Append_To (Actuals, New_Occurrence_Of (Standard_False, Loc));
1237 end if;
1239 -- i) On_Subpool
1241 if Is_Allocate then
1242 Append_To (Actuals,
1243 New_Occurrence_Of (Boolean_Literals (Present (Subpool)), Loc));
1244 end if;
1246 -- Step 2: Build a wrapper Allocate / Deallocate which internally
1247 -- calls Allocate_Any_Controlled / Deallocate_Any_Controlled.
1249 -- Select the proper routine to call
1251 if Is_Allocate then
1252 Proc_To_Call := RTE (RE_Allocate_Any_Controlled);
1253 else
1254 Proc_To_Call := RTE (RE_Deallocate_Any_Controlled);
1255 end if;
1257 -- Create a custom Allocate / Deallocate routine which has identical
1258 -- profile to that of System.Storage_Pools.
1260 declare
1261 -- P : Root_Storage_Pool
1262 function Pool_Param return Node_Id is (
1263 Make_Parameter_Specification (Loc,
1264 Defining_Identifier => Make_Temporary (Loc, 'P'),
1265 Parameter_Type =>
1266 New_Occurrence_Of (RTE (RE_Root_Storage_Pool), Loc)));
1268 -- A : [out] Address
1269 function Address_Param return Node_Id is (
1270 Make_Parameter_Specification (Loc,
1271 Defining_Identifier => Addr_Id,
1272 Out_Present => Is_Allocate,
1273 Parameter_Type =>
1274 New_Occurrence_Of (RTE (RE_Address), Loc)));
1276 -- S : Storage_Count
1277 function Size_Param return Node_Id is (
1278 Make_Parameter_Specification (Loc,
1279 Defining_Identifier => Size_Id,
1280 Parameter_Type =>
1281 New_Occurrence_Of (RTE (RE_Storage_Count), Loc)));
1283 -- L : Storage_Count
1284 function Alignment_Param return Node_Id is (
1285 Make_Parameter_Specification (Loc,
1286 Defining_Identifier => Alig_Id,
1287 Parameter_Type =>
1288 New_Occurrence_Of (RTE (RE_Storage_Count), Loc)));
1290 Formal_Params : List_Id;
1291 begin
1292 if Use_Secondary_Stack_Pool then
1293 -- Gigi expects a different profile in the Secondary_Stack_Pool
1294 -- case. There must be no uses of the two missing formals
1295 -- (i.e., Pool_Param and Alignment_Param) in this case.
1296 Formal_Params := New_List
1297 (Address_Param, Size_Param, Alignment_Param);
1298 else
1299 Formal_Params := New_List (
1300 Pool_Param, Address_Param, Size_Param, Alignment_Param);
1301 end if;
1303 Insert_Action (N,
1304 Make_Subprogram_Body (Loc,
1305 Specification =>
1306 -- procedure Pnn
1307 Make_Procedure_Specification (Loc,
1308 Defining_Unit_Name => Proc_Id,
1309 Parameter_Specifications => Formal_Params),
1311 Declarations => No_List,
1313 Handled_Statement_Sequence =>
1314 Make_Handled_Sequence_Of_Statements (Loc,
1315 Statements => New_List (
1316 Make_Procedure_Call_Statement (Loc,
1317 Name =>
1318 New_Occurrence_Of (Proc_To_Call, Loc),
1319 Parameter_Associations => Actuals)))),
1320 Suppress => All_Checks);
1321 end;
1323 -- The newly generated Allocate / Deallocate becomes the default
1324 -- procedure to call when the back end processes the allocation /
1325 -- deallocation.
1327 if Is_Allocate then
1328 Set_Procedure_To_Call (Expr, Proc_Id);
1329 else
1330 Set_Procedure_To_Call (N, Proc_Id);
1331 end if;
1332 end;
1333 end Build_Allocate_Deallocate_Proc;
1335 -------------------------------
1336 -- Build_Abort_Undefer_Block --
1337 -------------------------------
1339 function Build_Abort_Undefer_Block
1340 (Loc : Source_Ptr;
1341 Stmts : List_Id;
1342 Context : Node_Id) return Node_Id
1344 Exceptions_OK : constant Boolean :=
1345 not Restriction_Active (No_Exception_Propagation);
1347 AUD : Entity_Id;
1348 Blk : Node_Id;
1349 Blk_Id : Entity_Id;
1350 HSS : Node_Id;
1352 begin
1353 -- The block should be generated only when undeferring abort in the
1354 -- context of a potential exception.
1356 pragma Assert (Abort_Allowed and Exceptions_OK);
1358 -- Generate:
1359 -- begin
1360 -- <Stmts>
1361 -- at end
1362 -- Abort_Undefer_Direct;
1363 -- end;
1365 AUD := RTE (RE_Abort_Undefer_Direct);
1367 HSS :=
1368 Make_Handled_Sequence_Of_Statements (Loc,
1369 Statements => Stmts,
1370 At_End_Proc => New_Occurrence_Of (AUD, Loc));
1372 Blk :=
1373 Make_Block_Statement (Loc,
1374 Handled_Statement_Sequence => HSS);
1375 Set_Is_Abort_Block (Blk);
1377 Add_Block_Identifier (Blk, Blk_Id);
1378 Expand_At_End_Handler (HSS, Blk_Id);
1380 -- Present the Abort_Undefer_Direct function to the back end to inline
1381 -- the call to the routine.
1383 Add_Inlined_Body (AUD, Context);
1385 return Blk;
1386 end Build_Abort_Undefer_Block;
1388 ---------------------------------
1389 -- Build_Class_Wide_Expression --
1390 ---------------------------------
1392 procedure Build_Class_Wide_Expression
1393 (Pragma_Or_Expr : Node_Id;
1394 Subp : Entity_Id;
1395 Par_Subp : Entity_Id;
1396 Adjust_Sloc : Boolean)
1398 function Replace_Entity (N : Node_Id) return Traverse_Result;
1399 -- Replace reference to formal of inherited operation or to primitive
1400 -- operation of root type, with corresponding entity for derived type,
1401 -- when constructing the class-wide condition of an overriding
1402 -- subprogram.
1404 --------------------
1405 -- Replace_Entity --
1406 --------------------
1408 function Replace_Entity (N : Node_Id) return Traverse_Result is
1409 New_E : Entity_Id;
1411 begin
1412 if Adjust_Sloc then
1413 Adjust_Inherited_Pragma_Sloc (N);
1414 end if;
1416 if Nkind (N) in N_Identifier | N_Expanded_Name | N_Operator_Symbol
1417 and then Present (Entity (N))
1418 and then
1419 (Is_Formal (Entity (N)) or else Is_Subprogram (Entity (N)))
1420 and then
1421 (Nkind (Parent (N)) /= N_Attribute_Reference
1422 or else Attribute_Name (Parent (N)) /= Name_Class)
1423 then
1424 -- The replacement does not apply to dispatching calls within the
1425 -- condition, but only to calls whose static tag is that of the
1426 -- parent type.
1428 if Is_Subprogram (Entity (N))
1429 and then Nkind (Parent (N)) = N_Function_Call
1430 and then Present (Controlling_Argument (Parent (N)))
1431 then
1432 return OK;
1433 end if;
1435 -- Determine whether entity has a renaming
1437 New_E := Type_Map.Get (Entity (N));
1439 if Present (New_E) then
1440 Rewrite (N, New_Occurrence_Of (New_E, Sloc (N)));
1441 end if;
1443 -- Update type of function call node, which should be the same as
1444 -- the function's return type.
1446 if Is_Subprogram (Entity (N))
1447 and then Nkind (Parent (N)) = N_Function_Call
1448 then
1449 Set_Etype (Parent (N), Etype (Entity (N)));
1450 end if;
1452 -- The whole expression will be reanalyzed
1454 elsif Nkind (N) in N_Has_Etype then
1455 Set_Analyzed (N, False);
1456 end if;
1458 return OK;
1459 end Replace_Entity;
1461 procedure Replace_Condition_Entities is
1462 new Traverse_Proc (Replace_Entity);
1464 -- Local variables
1466 Par_Typ : constant Entity_Id := Find_Dispatching_Type (Par_Subp);
1467 Subp_Typ : constant Entity_Id := Find_Dispatching_Type (Subp);
1469 -- Start of processing for Build_Class_Wide_Expression
1471 begin
1472 pragma Assert (Par_Typ /= Subp_Typ);
1474 Update_Primitives_Mapping (Par_Subp, Subp);
1475 Map_Formals (Par_Subp, Subp);
1476 Replace_Condition_Entities (Pragma_Or_Expr);
1477 end Build_Class_Wide_Expression;
1479 --------------------
1480 -- Build_DIC_Call --
1481 --------------------
1483 function Build_DIC_Call
1484 (Loc : Source_Ptr;
1485 Obj_Name : Node_Id;
1486 Typ : Entity_Id) return Node_Id
1488 Proc_Id : constant Entity_Id := DIC_Procedure (Typ);
1489 Formal_Typ : constant Entity_Id := Etype (First_Formal (Proc_Id));
1491 begin
1492 -- The DIC procedure has a null body if assertions are disabled or
1493 -- Assertion_Policy Ignore is in effect. In that case, it would be
1494 -- nice to generate a null statement instead of a call to the DIC
1495 -- procedure, but doing that seems to interfere with the determination
1496 -- of ECRs (early call regions) in SPARK. ???
1498 return
1499 Make_Procedure_Call_Statement (Loc,
1500 Name => New_Occurrence_Of (Proc_Id, Loc),
1501 Parameter_Associations => New_List (
1502 Unchecked_Convert_To (Formal_Typ, Obj_Name)));
1503 end Build_DIC_Call;
1505 ------------------------------
1506 -- Build_DIC_Procedure_Body --
1507 ------------------------------
1509 -- WARNING: This routine manages Ghost regions. Return statements must be
1510 -- replaced by gotos which jump to the end of the routine and restore the
1511 -- Ghost mode.
1513 procedure Build_DIC_Procedure_Body
1514 (Typ : Entity_Id;
1515 Partial_DIC : Boolean := False)
1517 Pragmas_Seen : Elist_Id := No_Elist;
1518 -- This list contains all DIC pragmas processed so far. The list is used
1519 -- to avoid redundant Default_Initial_Condition checks.
1521 procedure Add_DIC_Check
1522 (DIC_Prag : Node_Id;
1523 DIC_Expr : Node_Id;
1524 Stmts : in out List_Id);
1525 -- Subsidiary to all Add_xxx_DIC routines. Add a runtime check to verify
1526 -- assertion expression DIC_Expr of pragma DIC_Prag. All generated code
1527 -- is added to list Stmts.
1529 procedure Add_Inherited_DIC
1530 (DIC_Prag : Node_Id;
1531 Par_Typ : Entity_Id;
1532 Deriv_Typ : Entity_Id;
1533 Stmts : in out List_Id);
1534 -- Add a runtime check to verify the assertion expression of inherited
1535 -- pragma DIC_Prag. Par_Typ is parent type, which is also the owner of
1536 -- the DIC pragma. Deriv_Typ is the derived type inheriting the DIC
1537 -- pragma. All generated code is added to list Stmts.
1539 procedure Add_Inherited_Tagged_DIC
1540 (DIC_Prag : Node_Id;
1541 Expr : Node_Id;
1542 Stmts : in out List_Id);
1543 -- Add a runtime check to verify assertion expression DIC_Expr of
1544 -- inherited pragma DIC_Prag. This routine applies class-wide pre-
1545 -- and postcondition-like runtime semantics to the check. Expr is
1546 -- the assertion expression after substitution has been performed
1547 -- (via Replace_References). All generated code is added to list Stmts.
1549 procedure Add_Inherited_DICs
1550 (T : Entity_Id;
1551 Priv_Typ : Entity_Id;
1552 Full_Typ : Entity_Id;
1553 Obj_Id : Entity_Id;
1554 Checks : in out List_Id);
1555 -- Generate a DIC check for each inherited Default_Initial_Condition
1556 -- coming from all parent types of type T. Priv_Typ and Full_Typ denote
1557 -- the partial and full view of the parent type. Obj_Id denotes the
1558 -- entity of the _object formal parameter of the DIC procedure. All
1559 -- created checks are added to list Checks.
1561 procedure Add_Own_DIC
1562 (DIC_Prag : Node_Id;
1563 DIC_Typ : Entity_Id;
1564 Obj_Id : Entity_Id;
1565 Stmts : in out List_Id);
1566 -- Add a runtime check to verify the assertion expression of pragma
1567 -- DIC_Prag. DIC_Typ is the owner of the DIC pragma. Obj_Id is the
1568 -- object to substitute in the assertion expression for any references
1569 -- to the current instance of the type All generated code is added to
1570 -- list Stmts.
1572 procedure Add_Parent_DICs
1573 (T : Entity_Id;
1574 Obj_Id : Entity_Id;
1575 Checks : in out List_Id);
1576 -- Generate a Default_Initial_Condition check for each inherited DIC
1577 -- aspect coming from all parent types of type T. Obj_Id denotes the
1578 -- entity of the _object formal parameter of the DIC procedure. All
1579 -- created checks are added to list Checks.
1581 -------------------
1582 -- Add_DIC_Check --
1583 -------------------
1585 procedure Add_DIC_Check
1586 (DIC_Prag : Node_Id;
1587 DIC_Expr : Node_Id;
1588 Stmts : in out List_Id)
1590 Loc : constant Source_Ptr := Sloc (DIC_Prag);
1591 Nam : constant Name_Id := Original_Aspect_Pragma_Name (DIC_Prag);
1593 begin
1594 -- The DIC pragma is ignored, nothing left to do
1596 if Is_Ignored (DIC_Prag) then
1597 null;
1599 -- Otherwise the DIC expression must be checked at run time.
1600 -- Generate:
1602 -- pragma Check (<Nam>, <DIC_Expr>);
1604 else
1605 Append_New_To (Stmts,
1606 Make_Pragma (Loc,
1607 Pragma_Identifier =>
1608 Make_Identifier (Loc, Name_Check),
1610 Pragma_Argument_Associations => New_List (
1611 Make_Pragma_Argument_Association (Loc,
1612 Expression => Make_Identifier (Loc, Nam)),
1614 Make_Pragma_Argument_Association (Loc,
1615 Expression => DIC_Expr))));
1616 end if;
1618 -- Add the pragma to the list of processed pragmas
1620 Append_New_Elmt (DIC_Prag, Pragmas_Seen);
1621 end Add_DIC_Check;
1623 -----------------------
1624 -- Add_Inherited_DIC --
1625 -----------------------
1627 procedure Add_Inherited_DIC
1628 (DIC_Prag : Node_Id;
1629 Par_Typ : Entity_Id;
1630 Deriv_Typ : Entity_Id;
1631 Stmts : in out List_Id)
1633 Deriv_Proc : constant Entity_Id := DIC_Procedure (Deriv_Typ);
1634 Deriv_Obj : constant Entity_Id := First_Entity (Deriv_Proc);
1635 Par_Proc : constant Entity_Id := DIC_Procedure (Par_Typ);
1636 Par_Obj : constant Entity_Id := First_Entity (Par_Proc);
1637 Loc : constant Source_Ptr := Sloc (DIC_Prag);
1639 begin
1640 pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc));
1642 -- Verify the inherited DIC assertion expression by calling the DIC
1643 -- procedure of the parent type.
1645 -- Generate:
1646 -- <Par_Typ>DIC (Par_Typ (_object));
1648 Append_New_To (Stmts,
1649 Make_Procedure_Call_Statement (Loc,
1650 Name => New_Occurrence_Of (Par_Proc, Loc),
1651 Parameter_Associations => New_List (
1652 Convert_To
1653 (Typ => Etype (Par_Obj),
1654 Expr => New_Occurrence_Of (Deriv_Obj, Loc)))));
1655 end Add_Inherited_DIC;
1657 ------------------------------
1658 -- Add_Inherited_Tagged_DIC --
1659 ------------------------------
1661 procedure Add_Inherited_Tagged_DIC
1662 (DIC_Prag : Node_Id;
1663 Expr : Node_Id;
1664 Stmts : in out List_Id)
1666 begin
1667 -- Once the DIC assertion expression is fully processed, add a check
1668 -- to the statements of the DIC procedure.
1670 Add_DIC_Check
1671 (DIC_Prag => DIC_Prag,
1672 DIC_Expr => Expr,
1673 Stmts => Stmts);
1674 end Add_Inherited_Tagged_DIC;
1676 ------------------------
1677 -- Add_Inherited_DICs --
1678 ------------------------
1680 procedure Add_Inherited_DICs
1681 (T : Entity_Id;
1682 Priv_Typ : Entity_Id;
1683 Full_Typ : Entity_Id;
1684 Obj_Id : Entity_Id;
1685 Checks : in out List_Id)
1687 Deriv_Typ : Entity_Id;
1688 Expr : Node_Id;
1689 Prag : Node_Id;
1690 Prag_Expr : Node_Id;
1691 Prag_Expr_Arg : Node_Id;
1692 Prag_Typ : Node_Id;
1693 Prag_Typ_Arg : Node_Id;
1695 Par_Proc : Entity_Id;
1696 -- The "partial" invariant procedure of Par_Typ
1698 Par_Typ : Entity_Id;
1699 -- The suitable view of the parent type used in the substitution of
1700 -- type attributes.
1702 begin
1703 if No (Priv_Typ) and then No (Full_Typ) then
1704 return;
1705 end if;
1707 -- When the type inheriting the class-wide invariant is a concurrent
1708 -- type, use the corresponding record type because it contains all
1709 -- primitive operations of the concurrent type and allows for proper
1710 -- substitution.
1712 if Is_Concurrent_Type (T) then
1713 Deriv_Typ := Corresponding_Record_Type (T);
1714 else
1715 Deriv_Typ := T;
1716 end if;
1718 pragma Assert (Present (Deriv_Typ));
1720 -- Determine which rep item chain to use. Precedence is given to that
1721 -- of the parent type's partial view since it usually carries all the
1722 -- class-wide invariants.
1724 if Present (Priv_Typ) then
1725 Prag := First_Rep_Item (Priv_Typ);
1726 else
1727 Prag := First_Rep_Item (Full_Typ);
1728 end if;
1730 while Present (Prag) loop
1731 if Nkind (Prag) = N_Pragma
1732 and then Pragma_Name (Prag) = Name_Default_Initial_Condition
1733 then
1734 -- Nothing to do if the pragma was already processed
1736 if Contains (Pragmas_Seen, Prag) then
1737 return;
1738 end if;
1740 -- Extract arguments of the Default_Initial_Condition pragma
1742 Prag_Expr_Arg := First (Pragma_Argument_Associations (Prag));
1743 Prag_Expr := Expression_Copy (Prag_Expr_Arg);
1745 -- Pick up the implicit second argument of the pragma, which
1746 -- indicates the type that the pragma applies to.
1748 Prag_Typ_Arg := Next (Prag_Expr_Arg);
1749 if Present (Prag_Typ_Arg) then
1750 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg);
1751 else
1752 Prag_Typ := Empty;
1753 end if;
1755 -- The pragma applies to the partial view of the parent type
1757 if Present (Priv_Typ)
1758 and then Present (Prag_Typ)
1759 and then Entity (Prag_Typ) = Priv_Typ
1760 then
1761 Par_Typ := Priv_Typ;
1763 -- The pragma applies to the full view of the parent type
1765 elsif Present (Full_Typ)
1766 and then Present (Prag_Typ)
1767 and then Entity (Prag_Typ) = Full_Typ
1768 then
1769 Par_Typ := Full_Typ;
1771 -- Otherwise the pragma does not belong to the parent type and
1772 -- should not be considered.
1774 else
1775 return;
1776 end if;
1778 -- Substitute references in the DIC expression that are related
1779 -- to the partial type with corresponding references related to
1780 -- the derived type (call to Replace_References below).
1782 Expr := New_Copy_Tree (Prag_Expr);
1784 Par_Proc := Partial_DIC_Procedure (Par_Typ);
1786 -- If there's not a partial DIC procedure (such as when a
1787 -- full type doesn't have its own DIC, but is inherited from
1788 -- a type with DIC), get the full DIC procedure.
1790 if No (Par_Proc) then
1791 Par_Proc := DIC_Procedure (Par_Typ);
1792 end if;
1794 Replace_References
1795 (Expr => Expr,
1796 Par_Typ => Par_Typ,
1797 Deriv_Typ => Deriv_Typ,
1798 Par_Obj => First_Formal (Par_Proc),
1799 Deriv_Obj => Obj_Id);
1801 -- Why are there different actions depending on whether T is
1802 -- tagged? Can these be unified? ???
1804 if Is_Tagged_Type (T) then
1805 Add_Inherited_Tagged_DIC
1806 (DIC_Prag => Prag,
1807 Expr => Expr,
1808 Stmts => Checks);
1810 else
1811 Add_Inherited_DIC
1812 (DIC_Prag => Prag,
1813 Par_Typ => Par_Typ,
1814 Deriv_Typ => Deriv_Typ,
1815 Stmts => Checks);
1816 end if;
1818 -- Leave as soon as we get a DIC pragma, since we'll visit
1819 -- the pragmas of the parents, so will get to any "inherited"
1820 -- pragmas that way.
1822 return;
1823 end if;
1825 Next_Rep_Item (Prag);
1826 end loop;
1827 end Add_Inherited_DICs;
1829 -----------------
1830 -- Add_Own_DIC --
1831 -----------------
1833 procedure Add_Own_DIC
1834 (DIC_Prag : Node_Id;
1835 DIC_Typ : Entity_Id;
1836 Obj_Id : Entity_Id;
1837 Stmts : in out List_Id)
1839 DIC_Args : constant List_Id :=
1840 Pragma_Argument_Associations (DIC_Prag);
1841 DIC_Arg : constant Node_Id := First (DIC_Args);
1842 DIC_Asp : constant Node_Id := Corresponding_Aspect (DIC_Prag);
1843 DIC_Expr : constant Node_Id := Get_Pragma_Arg (DIC_Arg);
1845 -- Local variables
1847 Typ_Decl : constant Node_Id := Declaration_Node (DIC_Typ);
1849 Expr : Node_Id;
1851 -- Start of processing for Add_Own_DIC
1853 begin
1854 pragma Assert (Present (DIC_Expr));
1856 -- We need to preanalyze the expression itself inside a generic to
1857 -- be able to capture global references present in it.
1859 if Inside_A_Generic then
1860 Expr := DIC_Expr;
1861 else
1862 Expr := New_Copy_Tree (DIC_Expr);
1863 end if;
1865 -- Perform the following substitution:
1867 -- * Replace the current instance of DIC_Typ with a reference to
1868 -- the _object formal parameter of the DIC procedure.
1870 Replace_Type_References
1871 (Expr => Expr,
1872 Typ => DIC_Typ,
1873 Obj_Id => Obj_Id);
1875 -- Preanalyze the DIC expression to detect errors and at the same
1876 -- time capture the visibility of the proper package part.
1878 Set_Parent (Expr, Typ_Decl);
1879 Preanalyze_Assert_Expression (Expr, Any_Boolean);
1881 -- Save a copy of the expression with all replacements and analysis
1882 -- already taken place in case a derived type inherits the pragma.
1883 -- The copy will be used as the foundation of the derived type's own
1884 -- version of the DIC assertion expression.
1886 if Is_Tagged_Type (DIC_Typ) then
1887 Set_Expression_Copy (DIC_Arg, New_Copy_Tree (Expr));
1888 end if;
1890 -- If the pragma comes from an aspect specification, replace the
1891 -- saved expression because all type references must be substituted
1892 -- for the call to Preanalyze_Spec_Expression in Check_Aspect_At_xxx
1893 -- routines.
1895 if Present (DIC_Asp) then
1896 Set_Expression_Copy (DIC_Asp, New_Copy_Tree (Expr));
1897 end if;
1899 -- Once the DIC assertion expression is fully processed, add a check
1900 -- to the statements of the DIC procedure (unless the type is an
1901 -- abstract type, in which case we don't want the possibility of
1902 -- generating a call to an abstract function of the type; such DIC
1903 -- procedures can never be called in any case, so not generating the
1904 -- check at all is OK).
1906 if not Is_Abstract_Type (DIC_Typ) or else GNATprove_Mode then
1907 Add_DIC_Check
1908 (DIC_Prag => DIC_Prag,
1909 DIC_Expr => Expr,
1910 Stmts => Stmts);
1911 end if;
1912 end Add_Own_DIC;
1914 ---------------------
1915 -- Add_Parent_DICs --
1916 ---------------------
1918 procedure Add_Parent_DICs
1919 (T : Entity_Id;
1920 Obj_Id : Entity_Id;
1921 Checks : in out List_Id)
1923 Dummy_1 : Entity_Id;
1924 Dummy_2 : Entity_Id;
1926 Curr_Typ : Entity_Id;
1927 -- The entity of the current type being examined
1929 Full_Typ : Entity_Id;
1930 -- The full view of Par_Typ
1932 Par_Typ : Entity_Id;
1933 -- The entity of the parent type
1935 Priv_Typ : Entity_Id;
1936 -- The partial view of Par_Typ
1938 Op_Node : Elmt_Id;
1939 Par_Prim : Entity_Id;
1940 Prim : Entity_Id;
1942 begin
1943 -- Map the overridden primitive to the overriding one; required by
1944 -- Replace_References (called by Add_Inherited_DICs) to handle calls
1945 -- to parent primitives.
1947 Op_Node := First_Elmt (Primitive_Operations (T));
1948 while Present (Op_Node) loop
1949 Prim := Node (Op_Node);
1951 if Present (Overridden_Operation (Prim))
1952 and then Comes_From_Source (Prim)
1953 then
1954 Par_Prim := Overridden_Operation (Prim);
1956 -- Create a mapping of the form:
1957 -- parent type primitive -> derived type primitive
1959 Type_Map.Set (Par_Prim, Prim);
1960 end if;
1962 Next_Elmt (Op_Node);
1963 end loop;
1965 -- Climb the parent type chain
1967 Curr_Typ := T;
1968 loop
1969 -- Do not consider subtypes, as they inherit the DICs from their
1970 -- base types.
1972 Par_Typ := Base_Type (Etype (Base_Type (Curr_Typ)));
1974 -- Stop the climb once the root of the parent chain is
1975 -- reached.
1977 exit when Curr_Typ = Par_Typ;
1979 -- Process the DICs of the parent type
1981 Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2);
1983 -- Only try to inherit a DIC pragma from the parent type Par_Typ
1984 -- if it Has_Own_DIC pragma. The loop will proceed up the parent
1985 -- chain to find all types that have their own DIC.
1987 if Has_Own_DIC (Par_Typ) then
1988 Add_Inherited_DICs
1989 (T => T,
1990 Priv_Typ => Priv_Typ,
1991 Full_Typ => Full_Typ,
1992 Obj_Id => Obj_Id,
1993 Checks => Checks);
1994 end if;
1996 Curr_Typ := Par_Typ;
1997 end loop;
1998 end Add_Parent_DICs;
2000 -- Local variables
2002 Loc : constant Source_Ptr := Sloc (Typ);
2004 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
2005 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
2006 -- Save the Ghost-related attributes to restore on exit
2008 DIC_Prag : Node_Id;
2009 DIC_Typ : Entity_Id;
2010 Dummy_1 : Entity_Id;
2011 Dummy_2 : Entity_Id;
2012 Proc_Body : Node_Id;
2013 Proc_Body_Id : Entity_Id;
2014 Proc_Decl : Node_Id;
2015 Proc_Id : Entity_Id;
2016 Stmts : List_Id := No_List;
2018 CRec_Typ : Entity_Id := Empty;
2019 -- The corresponding record type of Full_Typ
2021 Full_Typ : Entity_Id := Empty;
2022 -- The full view of the working type
2024 Obj_Id : Entity_Id := Empty;
2025 -- The _object formal parameter of the invariant procedure
2027 Part_Proc : Entity_Id := Empty;
2028 -- The entity of the "partial" invariant procedure
2030 Priv_Typ : Entity_Id := Empty;
2031 -- The partial view of the working type
2033 Work_Typ : Entity_Id;
2034 -- The working type
2036 -- Start of processing for Build_DIC_Procedure_Body
2038 begin
2039 Work_Typ := Base_Type (Typ);
2041 -- Do not process class-wide types as these are Itypes, but lack a first
2042 -- subtype (see below).
2044 if Is_Class_Wide_Type (Work_Typ) then
2045 return;
2047 -- Do not process the underlying full view of a private type. There is
2048 -- no way to get back to the partial view, plus the body will be built
2049 -- by the full view or the base type.
2051 elsif Is_Underlying_Full_View (Work_Typ) then
2052 return;
2054 -- Use the first subtype when dealing with implicit base types
2056 elsif Is_Itype (Work_Typ) then
2057 Work_Typ := First_Subtype (Work_Typ);
2059 -- The input denotes the corresponding record type of a protected or a
2060 -- task type. Work with the concurrent type because the corresponding
2061 -- record type may not be visible to clients of the type.
2063 elsif Ekind (Work_Typ) = E_Record_Type
2064 and then Is_Concurrent_Record_Type (Work_Typ)
2065 then
2066 Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
2067 end if;
2069 -- The working type may be subject to pragma Ghost. Set the mode now to
2070 -- ensure that the DIC procedure is properly marked as Ghost.
2072 Set_Ghost_Mode (Work_Typ);
2074 -- The working type must be either define a DIC pragma of its own or
2075 -- inherit one from a parent type.
2077 pragma Assert (Has_DIC (Work_Typ));
2079 -- Recover the type which defines the DIC pragma. This is either the
2080 -- working type itself or a parent type when the pragma is inherited.
2082 DIC_Typ := Find_DIC_Type (Work_Typ);
2083 pragma Assert (Present (DIC_Typ));
2085 DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
2086 pragma Assert (Present (DIC_Prag));
2088 -- Nothing to do if pragma DIC appears without an argument or its sole
2089 -- argument is "null".
2091 if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
2092 goto Leave;
2093 end if;
2095 -- Obtain both views of the type
2097 Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy_1, CRec_Typ);
2099 -- The caller requests a body for the partial DIC procedure
2101 if Partial_DIC then
2102 Proc_Id := Partial_DIC_Procedure (Work_Typ);
2104 -- The "full" DIC procedure body was already created
2106 -- Create a declaration for the "partial" DIC procedure if it
2107 -- is not available.
2109 if No (Proc_Id) then
2110 Build_DIC_Procedure_Declaration
2111 (Typ => Work_Typ,
2112 Partial_DIC => True);
2114 Proc_Id := Partial_DIC_Procedure (Work_Typ);
2115 end if;
2117 -- The caller requests a body for the "full" DIC procedure
2119 else
2120 Proc_Id := DIC_Procedure (Work_Typ);
2121 Part_Proc := Partial_DIC_Procedure (Work_Typ);
2123 -- Create a declaration for the "full" DIC procedure if it is
2124 -- not available.
2126 if No (Proc_Id) then
2127 Build_DIC_Procedure_Declaration (Work_Typ);
2128 Proc_Id := DIC_Procedure (Work_Typ);
2129 end if;
2130 end if;
2132 -- At this point there should be a DIC procedure declaration
2134 pragma Assert (Present (Proc_Id));
2135 Proc_Decl := Unit_Declaration_Node (Proc_Id);
2137 -- Nothing to do if the DIC procedure already has a body
2139 if Present (Corresponding_Body (Proc_Decl)) then
2140 goto Leave;
2141 end if;
2143 -- Emulate the environment of the DIC procedure by installing its scope
2144 -- and formal parameters.
2146 Push_Scope (Proc_Id);
2147 Install_Formals (Proc_Id);
2149 Obj_Id := First_Formal (Proc_Id);
2150 pragma Assert (Present (Obj_Id));
2152 -- The "partial" DIC procedure verifies the DICs of the partial view
2153 -- only.
2155 if Partial_DIC then
2156 pragma Assert (Present (Priv_Typ));
2158 if Has_Own_DIC (Work_Typ) then -- If we're testing this then maybe
2159 Add_Own_DIC -- we shouldn't be calling Find_DIC_Typ above???
2160 (DIC_Prag => DIC_Prag,
2161 DIC_Typ => DIC_Typ, -- Should this just be Work_Typ???
2162 Obj_Id => Obj_Id,
2163 Stmts => Stmts);
2164 end if;
2166 -- Otherwise, the "full" DIC procedure verifies the DICs inherited from
2167 -- parent types, as well as indirectly verifying the DICs of the partial
2168 -- view by calling the "partial" DIC procedure.
2170 else
2171 -- Check the DIC of the partial view by calling the "partial" DIC
2172 -- procedure, unless the partial DIC body is empty. Generate:
2174 -- <Work_Typ>Partial_DIC (_object);
2176 if Present (Part_Proc) and then not Has_Null_Body (Part_Proc) then
2177 Append_New_To (Stmts,
2178 Make_Procedure_Call_Statement (Loc,
2179 Name => New_Occurrence_Of (Part_Proc, Loc),
2180 Parameter_Associations => New_List (
2181 New_Occurrence_Of (Obj_Id, Loc))));
2182 end if;
2184 -- Process inherited Default_Initial_Conditions for all parent types
2186 Add_Parent_DICs (Work_Typ, Obj_Id, Stmts);
2187 end if;
2189 End_Scope;
2191 -- Produce an empty completing body in the following cases:
2192 -- * Assertions are disabled
2193 -- * The DIC Assertion_Policy is Ignore
2195 if No (Stmts) then
2196 Stmts := New_List (Make_Null_Statement (Loc));
2197 end if;
2199 -- Generate:
2200 -- procedure <Work_Typ>DIC (_object : <Work_Typ>) is
2201 -- begin
2202 -- <Stmts>
2203 -- end <Work_Typ>DIC;
2205 Proc_Body :=
2206 Make_Subprogram_Body (Loc,
2207 Specification =>
2208 Copy_Subprogram_Spec (Parent (Proc_Id)),
2209 Declarations => Empty_List,
2210 Handled_Statement_Sequence =>
2211 Make_Handled_Sequence_Of_Statements (Loc,
2212 Statements => Stmts));
2213 Proc_Body_Id := Defining_Entity (Proc_Body);
2215 -- Perform minor decoration in case the body is not analyzed
2217 Mutate_Ekind (Proc_Body_Id, E_Subprogram_Body);
2218 Set_Etype (Proc_Body_Id, Standard_Void_Type);
2219 Set_Scope (Proc_Body_Id, Current_Scope);
2220 Set_SPARK_Pragma (Proc_Body_Id, SPARK_Pragma (Proc_Id));
2221 Set_SPARK_Pragma_Inherited
2222 (Proc_Body_Id, SPARK_Pragma_Inherited (Proc_Id));
2224 -- Link both spec and body to avoid generating duplicates
2226 Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
2227 Set_Corresponding_Spec (Proc_Body, Proc_Id);
2229 -- The body should not be inserted into the tree when the context
2230 -- is a generic unit because it is not part of the template.
2231 -- Note that the body must still be generated in order to resolve the
2232 -- DIC assertion expression.
2234 if Inside_A_Generic then
2235 null;
2237 -- Semi-insert the body into the tree for GNATprove by setting its
2238 -- Parent field. This allows for proper upstream tree traversals.
2240 elsif GNATprove_Mode then
2241 Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
2243 -- Otherwise the body is part of the freezing actions of the working
2244 -- type.
2246 else
2247 Append_Freeze_Action (Work_Typ, Proc_Body);
2248 end if;
2250 <<Leave>>
2251 Restore_Ghost_Region (Saved_GM, Saved_IGR);
2252 end Build_DIC_Procedure_Body;
2254 -------------------------------------
2255 -- Build_DIC_Procedure_Declaration --
2256 -------------------------------------
2258 -- WARNING: This routine manages Ghost regions. Return statements must be
2259 -- replaced by gotos which jump to the end of the routine and restore the
2260 -- Ghost mode.
2262 procedure Build_DIC_Procedure_Declaration
2263 (Typ : Entity_Id;
2264 Partial_DIC : Boolean := False)
2266 Loc : constant Source_Ptr := Sloc (Typ);
2268 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
2269 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
2270 -- Save the Ghost-related attributes to restore on exit
2272 DIC_Prag : Node_Id;
2273 DIC_Typ : Entity_Id;
2274 Proc_Decl : Node_Id;
2275 Proc_Id : Entity_Id;
2276 Proc_Nam : Name_Id;
2277 Typ_Decl : Node_Id;
2279 CRec_Typ : Entity_Id;
2280 -- The corresponding record type of Full_Typ
2282 Full_Typ : Entity_Id;
2283 -- The full view of working type
2285 Obj_Id : Entity_Id;
2286 -- The _object formal parameter of the DIC procedure
2288 Priv_Typ : Entity_Id;
2289 -- The partial view of working type
2291 UFull_Typ : Entity_Id;
2292 -- The underlying full view of Full_Typ
2294 Work_Typ : Entity_Id;
2295 -- The working type
2297 begin
2298 Work_Typ := Base_Type (Typ);
2300 -- Do not process class-wide types as these are Itypes, but lack a first
2301 -- subtype (see below).
2303 if Is_Class_Wide_Type (Work_Typ) then
2304 return;
2306 -- Do not process the underlying full view of a private type. There is
2307 -- no way to get back to the partial view, plus the body will be built
2308 -- by the full view or the base type.
2310 elsif Is_Underlying_Full_View (Work_Typ) then
2311 return;
2313 -- Use the first subtype when dealing with various base types
2315 elsif Is_Itype (Work_Typ) then
2316 Work_Typ := First_Subtype (Work_Typ);
2318 -- The input denotes the corresponding record type of a protected or a
2319 -- task type. Work with the concurrent type because the corresponding
2320 -- record type may not be visible to clients of the type.
2322 elsif Ekind (Work_Typ) = E_Record_Type
2323 and then Is_Concurrent_Record_Type (Work_Typ)
2324 then
2325 Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
2326 end if;
2328 -- The working type may be subject to pragma Ghost. Set the mode now to
2329 -- ensure that the DIC procedure is properly marked as Ghost.
2331 Set_Ghost_Mode (Work_Typ);
2333 -- The type must be either subject to a DIC pragma or inherit one from a
2334 -- parent type.
2336 pragma Assert (Has_DIC (Work_Typ));
2338 -- Recover the type which defines the DIC pragma. This is either the
2339 -- working type itself or a parent type when the pragma is inherited.
2341 DIC_Typ := Find_DIC_Type (Work_Typ);
2342 pragma Assert (Present (DIC_Typ));
2344 DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
2345 pragma Assert (Present (DIC_Prag));
2347 -- Nothing to do if pragma DIC appears without an argument or its sole
2348 -- argument is "null".
2350 if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
2351 goto Leave;
2352 end if;
2354 -- Nothing to do if the type already has a "partial" DIC procedure
2356 if Partial_DIC then
2357 if Present (Partial_DIC_Procedure (Work_Typ)) then
2358 goto Leave;
2359 end if;
2361 -- Nothing to do if the type already has a "full" DIC procedure
2363 elsif Present (DIC_Procedure (Work_Typ)) then
2364 goto Leave;
2365 end if;
2367 -- The caller requests the declaration of the "partial" DIC procedure
2369 if Partial_DIC then
2370 Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_DIC");
2372 -- Otherwise the caller requests the declaration of the "full" DIC
2373 -- procedure.
2375 else
2376 Proc_Nam := New_External_Name (Chars (Work_Typ), "DIC");
2377 end if;
2379 Proc_Id :=
2380 Make_Defining_Identifier (Loc, Chars => Proc_Nam);
2382 -- Perform minor decoration in case the declaration is not analyzed
2384 Mutate_Ekind (Proc_Id, E_Procedure);
2385 Set_Etype (Proc_Id, Standard_Void_Type);
2386 Set_Is_DIC_Procedure (Proc_Id);
2387 Set_Scope (Proc_Id, Current_Scope);
2388 Set_SPARK_Pragma (Proc_Id, SPARK_Mode_Pragma);
2389 Set_SPARK_Pragma_Inherited (Proc_Id);
2391 Set_DIC_Procedure (Work_Typ, Proc_Id);
2393 -- The DIC procedure requires debug info when the assertion expression
2394 -- is subject to Source Coverage Obligations.
2396 if Generate_SCO then
2397 Set_Debug_Info_Needed (Proc_Id);
2398 end if;
2400 -- Obtain all views of the input type
2402 Get_Views (Work_Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ);
2404 -- Associate the DIC procedure and various flags with all views
2406 Propagate_DIC_Attributes (Priv_Typ, From_Typ => Work_Typ);
2407 Propagate_DIC_Attributes (Full_Typ, From_Typ => Work_Typ);
2408 Propagate_DIC_Attributes (UFull_Typ, From_Typ => Work_Typ);
2409 Propagate_DIC_Attributes (CRec_Typ, From_Typ => Work_Typ);
2411 -- The declaration of the DIC procedure must be inserted after the
2412 -- declaration of the partial view as this allows for proper external
2413 -- visibility.
2415 if Present (Priv_Typ) then
2416 Typ_Decl := Declaration_Node (Priv_Typ);
2418 -- Derived types with the full view as parent do not have a partial
2419 -- view. Insert the DIC procedure after the derived type.
2421 else
2422 Typ_Decl := Declaration_Node (Full_Typ);
2423 end if;
2425 -- The type should have a declarative node
2427 pragma Assert (Present (Typ_Decl));
2429 -- Create the formal parameter which emulates the variable-like behavior
2430 -- of the type's current instance.
2432 Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject);
2434 -- Perform minor decoration in case the declaration is not analyzed
2436 Mutate_Ekind (Obj_Id, E_In_Parameter);
2437 Set_Etype (Obj_Id, Work_Typ);
2438 Set_Scope (Obj_Id, Proc_Id);
2440 Set_First_Entity (Proc_Id, Obj_Id);
2441 Set_Last_Entity (Proc_Id, Obj_Id);
2443 -- Generate:
2444 -- procedure <Work_Typ>DIC (_object : <Work_Typ>);
2446 Proc_Decl :=
2447 Make_Subprogram_Declaration (Loc,
2448 Specification =>
2449 Make_Procedure_Specification (Loc,
2450 Defining_Unit_Name => Proc_Id,
2451 Parameter_Specifications => New_List (
2452 Make_Parameter_Specification (Loc,
2453 Defining_Identifier => Obj_Id,
2454 Parameter_Type =>
2455 New_Occurrence_Of (Work_Typ, Loc)))));
2457 -- The declaration should not be inserted into the tree when the context
2458 -- is a generic unit because it is not part of the template.
2460 if Inside_A_Generic then
2461 null;
2463 -- Semi-insert the declaration into the tree for GNATprove by setting
2464 -- its Parent field. This allows for proper upstream tree traversals.
2466 elsif GNATprove_Mode then
2467 Set_Parent (Proc_Decl, Parent (Typ_Decl));
2469 -- Otherwise insert the declaration
2471 else
2472 Insert_After_And_Analyze (Typ_Decl, Proc_Decl);
2473 end if;
2475 <<Leave>>
2476 Restore_Ghost_Region (Saved_GM, Saved_IGR);
2477 end Build_DIC_Procedure_Declaration;
2479 ------------------------------------
2480 -- Build_Invariant_Procedure_Body --
2481 ------------------------------------
2483 -- WARNING: This routine manages Ghost regions. Return statements must be
2484 -- replaced by gotos which jump to the end of the routine and restore the
2485 -- Ghost mode.
2487 procedure Build_Invariant_Procedure_Body
2488 (Typ : Entity_Id;
2489 Partial_Invariant : Boolean := False)
2491 Loc : constant Source_Ptr := Sloc (Typ);
2493 Pragmas_Seen : Elist_Id := No_Elist;
2494 -- This list contains all invariant pragmas processed so far. The list
2495 -- is used to avoid generating redundant invariant checks.
2497 Produced_Check : Boolean := False;
2498 -- This flag tracks whether the type has produced at least one invariant
2499 -- check. The flag is used as a sanity check at the end of the routine.
2501 -- NOTE: most of the routines in Build_Invariant_Procedure_Body are
2502 -- intentionally unnested to avoid deep indentation of code.
2504 -- NOTE: all Add_xxx_Invariants routines are reactive. In other words
2505 -- they emit checks, loops (for arrays) and case statements (for record
2506 -- variant parts) only when there are invariants to verify. This keeps
2507 -- the body of the invariant procedure free of useless code.
2509 procedure Add_Array_Component_Invariants
2510 (T : Entity_Id;
2511 Obj_Id : Entity_Id;
2512 Checks : in out List_Id);
2513 -- Generate an invariant check for each component of array type T.
2514 -- Obj_Id denotes the entity of the _object formal parameter of the
2515 -- invariant procedure. All created checks are added to list Checks.
2517 procedure Add_Inherited_Invariants
2518 (T : Entity_Id;
2519 Priv_Typ : Entity_Id;
2520 Full_Typ : Entity_Id;
2521 Obj_Id : Entity_Id;
2522 Checks : in out List_Id);
2523 -- Generate an invariant check for each inherited class-wide invariant
2524 -- coming from all parent types of type T. Priv_Typ and Full_Typ denote
2525 -- the partial and full view of the parent type. Obj_Id denotes the
2526 -- entity of the _object formal parameter of the invariant procedure.
2527 -- All created checks are added to list Checks.
2529 procedure Add_Interface_Invariants
2530 (T : Entity_Id;
2531 Obj_Id : Entity_Id;
2532 Checks : in out List_Id);
2533 -- Generate an invariant check for each inherited class-wide invariant
2534 -- coming from all interfaces implemented by type T. Obj_Id denotes the
2535 -- entity of the _object formal parameter of the invariant procedure.
2536 -- All created checks are added to list Checks.
2538 procedure Add_Invariant_Check
2539 (Prag : Node_Id;
2540 Expr : Node_Id;
2541 Checks : in out List_Id;
2542 Inherited : Boolean := False);
2543 -- Subsidiary to all Add_xxx_Invariant routines. Add a runtime check to
2544 -- verify assertion expression Expr of pragma Prag. All generated code
2545 -- is added to list Checks. Flag Inherited should be set when the pragma
2546 -- is inherited from a parent or interface type.
2548 procedure Add_Own_Invariants
2549 (T : Entity_Id;
2550 Obj_Id : Entity_Id;
2551 Checks : in out List_Id;
2552 Priv_Item : Node_Id := Empty);
2553 -- Generate an invariant check for each invariant found for type T.
2554 -- Obj_Id denotes the entity of the _object formal parameter of the
2555 -- invariant procedure. All created checks are added to list Checks.
2556 -- Priv_Item denotes the first rep item of the private type.
2558 procedure Add_Parent_Invariants
2559 (T : Entity_Id;
2560 Obj_Id : Entity_Id;
2561 Checks : in out List_Id);
2562 -- Generate an invariant check for each inherited class-wide invariant
2563 -- coming from all parent types of type T. Obj_Id denotes the entity of
2564 -- the _object formal parameter of the invariant procedure. All created
2565 -- checks are added to list Checks.
2567 procedure Add_Record_Component_Invariants
2568 (T : Entity_Id;
2569 Obj_Id : Entity_Id;
2570 Checks : in out List_Id);
2571 -- Generate an invariant check for each component of record type T.
2572 -- Obj_Id denotes the entity of the _object formal parameter of the
2573 -- invariant procedure. All created checks are added to list Checks.
2575 ------------------------------------
2576 -- Add_Array_Component_Invariants --
2577 ------------------------------------
2579 procedure Add_Array_Component_Invariants
2580 (T : Entity_Id;
2581 Obj_Id : Entity_Id;
2582 Checks : in out List_Id)
2584 Comp_Typ : constant Entity_Id := Component_Type (T);
2585 Dims : constant Pos := Number_Dimensions (T);
2587 procedure Process_Array_Component
2588 (Indices : List_Id;
2589 Comp_Checks : in out List_Id);
2590 -- Generate an invariant check for an array component identified by
2591 -- the indices in list Indices. All created checks are added to list
2592 -- Comp_Checks.
2594 procedure Process_One_Dimension
2595 (Dim : Pos;
2596 Indices : List_Id;
2597 Dim_Checks : in out List_Id);
2598 -- Generate a loop over the Nth dimension Dim of an array type. List
2599 -- Indices contains all array indices for the dimension. All created
2600 -- checks are added to list Dim_Checks.
2602 -----------------------------
2603 -- Process_Array_Component --
2604 -----------------------------
2606 procedure Process_Array_Component
2607 (Indices : List_Id;
2608 Comp_Checks : in out List_Id)
2610 Proc_Id : Entity_Id;
2612 begin
2613 if Has_Invariants (Comp_Typ) then
2615 -- In GNATprove mode, the component invariants are checked by
2616 -- other means. They should not be added to the array type
2617 -- invariant procedure, so that the procedure can be used to
2618 -- check the array type invariants if any.
2620 if GNATprove_Mode then
2621 null;
2623 else
2624 Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ));
2626 -- The component type should have an invariant procedure
2627 -- if it has invariants of its own or inherits class-wide
2628 -- invariants from parent or interface types.
2630 pragma Assert (Present (Proc_Id));
2632 -- Generate:
2633 -- <Comp_Typ>Invariant (_object (<Indices>));
2635 -- The invariant procedure has a null body if assertions are
2636 -- disabled or Assertion_Policy Ignore is in effect.
2638 if not Has_Null_Body (Proc_Id) then
2639 Append_New_To (Comp_Checks,
2640 Make_Procedure_Call_Statement (Loc,
2641 Name =>
2642 New_Occurrence_Of (Proc_Id, Loc),
2643 Parameter_Associations => New_List (
2644 Make_Indexed_Component (Loc,
2645 Prefix => New_Occurrence_Of (Obj_Id, Loc),
2646 Expressions => New_Copy_List (Indices)))));
2647 end if;
2648 end if;
2650 Produced_Check := True;
2651 end if;
2652 end Process_Array_Component;
2654 ---------------------------
2655 -- Process_One_Dimension --
2656 ---------------------------
2658 procedure Process_One_Dimension
2659 (Dim : Pos;
2660 Indices : List_Id;
2661 Dim_Checks : in out List_Id)
2663 Comp_Checks : List_Id := No_List;
2664 Index : Entity_Id;
2666 begin
2667 -- Generate the invariant checks for the array component after all
2668 -- dimensions have produced their respective loops.
2670 if Dim > Dims then
2671 Process_Array_Component
2672 (Indices => Indices,
2673 Comp_Checks => Dim_Checks);
2675 -- Otherwise create a loop for the current dimension
2677 else
2678 -- Create a new loop variable for each dimension
2680 Index :=
2681 Make_Defining_Identifier (Loc,
2682 Chars => New_External_Name ('I', Dim));
2683 Append_To (Indices, New_Occurrence_Of (Index, Loc));
2685 Process_One_Dimension
2686 (Dim => Dim + 1,
2687 Indices => Indices,
2688 Dim_Checks => Comp_Checks);
2690 -- Generate:
2691 -- for I<Dim> in _object'Range (<Dim>) loop
2692 -- <Comp_Checks>
2693 -- end loop;
2695 -- Note that the invariant procedure may have a null body if
2696 -- assertions are disabled or Assertion_Policy Ignore is in
2697 -- effect.
2699 if Present (Comp_Checks) then
2700 Append_New_To (Dim_Checks,
2701 Make_Implicit_Loop_Statement (T,
2702 Identifier => Empty,
2703 Iteration_Scheme =>
2704 Make_Iteration_Scheme (Loc,
2705 Loop_Parameter_Specification =>
2706 Make_Loop_Parameter_Specification (Loc,
2707 Defining_Identifier => Index,
2708 Discrete_Subtype_Definition =>
2709 Make_Attribute_Reference (Loc,
2710 Prefix =>
2711 New_Occurrence_Of (Obj_Id, Loc),
2712 Attribute_Name => Name_Range,
2713 Expressions => New_List (
2714 Make_Integer_Literal (Loc, Dim))))),
2715 Statements => Comp_Checks));
2716 end if;
2717 end if;
2718 end Process_One_Dimension;
2720 -- Start of processing for Add_Array_Component_Invariants
2722 begin
2723 Process_One_Dimension
2724 (Dim => 1,
2725 Indices => New_List,
2726 Dim_Checks => Checks);
2727 end Add_Array_Component_Invariants;
2729 ------------------------------
2730 -- Add_Inherited_Invariants --
2731 ------------------------------
2733 procedure Add_Inherited_Invariants
2734 (T : Entity_Id;
2735 Priv_Typ : Entity_Id;
2736 Full_Typ : Entity_Id;
2737 Obj_Id : Entity_Id;
2738 Checks : in out List_Id)
2740 Deriv_Typ : Entity_Id;
2741 Expr : Node_Id;
2742 Prag : Node_Id;
2743 Prag_Expr : Node_Id;
2744 Prag_Expr_Arg : Node_Id;
2745 Prag_Typ : Node_Id;
2746 Prag_Typ_Arg : Node_Id;
2748 Par_Proc : Entity_Id;
2749 -- The "partial" invariant procedure of Par_Typ
2751 Par_Typ : Entity_Id;
2752 -- The suitable view of the parent type used in the substitution of
2753 -- type attributes.
2755 begin
2756 if No (Priv_Typ) and then No (Full_Typ) then
2757 return;
2758 end if;
2760 -- When the type inheriting the class-wide invariant is a concurrent
2761 -- type, use the corresponding record type because it contains all
2762 -- primitive operations of the concurrent type and allows for proper
2763 -- substitution.
2765 if Is_Concurrent_Type (T) then
2766 Deriv_Typ := Corresponding_Record_Type (T);
2767 else
2768 Deriv_Typ := T;
2769 end if;
2771 pragma Assert (Present (Deriv_Typ));
2773 -- Determine which rep item chain to use. Precedence is given to that
2774 -- of the parent type's partial view since it usually carries all the
2775 -- class-wide invariants.
2777 if Present (Priv_Typ) then
2778 Prag := First_Rep_Item (Priv_Typ);
2779 else
2780 Prag := First_Rep_Item (Full_Typ);
2781 end if;
2783 while Present (Prag) loop
2784 if Nkind (Prag) = N_Pragma
2785 and then Pragma_Name (Prag) = Name_Invariant
2786 then
2787 -- Nothing to do if the pragma was already processed
2789 if Contains (Pragmas_Seen, Prag) then
2790 return;
2792 -- Nothing to do when the caller requests the processing of all
2793 -- inherited class-wide invariants, but the pragma does not
2794 -- fall in this category.
2796 elsif not Class_Present (Prag) then
2797 return;
2798 end if;
2800 -- Extract the arguments of the invariant pragma
2802 Prag_Typ_Arg := First (Pragma_Argument_Associations (Prag));
2803 Prag_Expr_Arg := Next (Prag_Typ_Arg);
2804 Prag_Expr := Expression_Copy (Prag_Expr_Arg);
2805 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg);
2807 -- The pragma applies to the partial view of the parent type
2809 if Present (Priv_Typ)
2810 and then Entity (Prag_Typ) = Priv_Typ
2811 then
2812 Par_Typ := Priv_Typ;
2814 -- The pragma applies to the full view of the parent type
2816 elsif Present (Full_Typ)
2817 and then Entity (Prag_Typ) = Full_Typ
2818 then
2819 Par_Typ := Full_Typ;
2821 -- Otherwise the pragma does not belong to the parent type and
2822 -- should not be considered.
2824 else
2825 return;
2826 end if;
2828 -- Perform the following substitutions:
2830 -- * Replace a reference to the _object parameter of the
2831 -- parent type's partial invariant procedure with a
2832 -- reference to the _object parameter of the derived
2833 -- type's full invariant procedure.
2835 -- * Replace a reference to a discriminant of the parent type
2836 -- with a suitable value from the point of view of the
2837 -- derived type.
2839 -- * Replace a call to an overridden parent primitive with a
2840 -- call to the overriding derived type primitive.
2842 -- * Replace a call to an inherited parent primitive with a
2843 -- call to the internally-generated inherited derived type
2844 -- primitive.
2846 Expr := New_Copy_Tree (Prag_Expr);
2848 -- The parent type must have a "partial" invariant procedure
2849 -- because class-wide invariants are captured exclusively by
2850 -- it.
2852 Par_Proc := Partial_Invariant_Procedure (Par_Typ);
2853 pragma Assert (Present (Par_Proc));
2855 Replace_References
2856 (Expr => Expr,
2857 Par_Typ => Par_Typ,
2858 Deriv_Typ => Deriv_Typ,
2859 Par_Obj => First_Formal (Par_Proc),
2860 Deriv_Obj => Obj_Id);
2862 Add_Invariant_Check (Prag, Expr, Checks, Inherited => True);
2863 end if;
2865 Next_Rep_Item (Prag);
2866 end loop;
2867 end Add_Inherited_Invariants;
2869 ------------------------------
2870 -- Add_Interface_Invariants --
2871 ------------------------------
2873 procedure Add_Interface_Invariants
2874 (T : Entity_Id;
2875 Obj_Id : Entity_Id;
2876 Checks : in out List_Id)
2878 Iface_Elmt : Elmt_Id;
2879 Ifaces : Elist_Id;
2881 begin
2882 -- Generate an invariant check for each class-wide invariant coming
2883 -- from all interfaces implemented by type T.
2885 if Is_Tagged_Type (T) then
2886 Collect_Interfaces (T, Ifaces);
2888 -- Process the class-wide invariants of all implemented interfaces
2890 Iface_Elmt := First_Elmt (Ifaces);
2891 while Present (Iface_Elmt) loop
2893 -- The Full_Typ parameter is intentionally left Empty because
2894 -- interfaces are treated as the partial view of a private type
2895 -- in order to achieve uniformity with the general case.
2897 Add_Inherited_Invariants
2898 (T => T,
2899 Priv_Typ => Node (Iface_Elmt),
2900 Full_Typ => Empty,
2901 Obj_Id => Obj_Id,
2902 Checks => Checks);
2904 Next_Elmt (Iface_Elmt);
2905 end loop;
2906 end if;
2907 end Add_Interface_Invariants;
2909 -------------------------
2910 -- Add_Invariant_Check --
2911 -------------------------
2913 procedure Add_Invariant_Check
2914 (Prag : Node_Id;
2915 Expr : Node_Id;
2916 Checks : in out List_Id;
2917 Inherited : Boolean := False)
2919 Args : constant List_Id := Pragma_Argument_Associations (Prag);
2920 Nam : constant Name_Id := Original_Aspect_Pragma_Name (Prag);
2921 Ploc : constant Source_Ptr := Sloc (Prag);
2922 Str_Arg : constant Node_Id := Next (Next (First (Args)));
2924 Assoc : List_Id;
2925 Str : String_Id;
2927 begin
2928 -- The invariant is ignored, nothing left to do
2930 if Is_Ignored (Prag) then
2931 null;
2933 -- Otherwise the invariant is checked. Build a pragma Check to verify
2934 -- the expression at run time.
2936 else
2937 Assoc := New_List (
2938 Make_Pragma_Argument_Association (Ploc,
2939 Expression => Make_Identifier (Ploc, Nam)),
2940 Make_Pragma_Argument_Association (Ploc,
2941 Expression => Expr));
2943 -- Handle the String argument (if any)
2945 if Present (Str_Arg) then
2946 Str := Strval (Get_Pragma_Arg (Str_Arg));
2948 -- When inheriting an invariant, modify the message from
2949 -- "failed invariant" to "failed inherited invariant".
2951 if Inherited then
2952 String_To_Name_Buffer (Str);
2954 if Name_Buffer (1 .. 16) = "failed invariant" then
2955 Insert_Str_In_Name_Buffer ("inherited ", 8);
2956 Str := String_From_Name_Buffer;
2957 end if;
2958 end if;
2960 Append_To (Assoc,
2961 Make_Pragma_Argument_Association (Ploc,
2962 Expression => Make_String_Literal (Ploc, Str)));
2963 end if;
2965 -- Generate:
2966 -- pragma Check (<Nam>, <Expr>, <Str>);
2968 Append_New_To (Checks,
2969 Make_Pragma (Ploc,
2970 Chars => Name_Check,
2971 Pragma_Argument_Associations => Assoc));
2972 end if;
2974 -- Output an info message when inheriting an invariant and the
2975 -- listing option is enabled.
2977 if Inherited and List_Inherited_Aspects then
2978 Error_Msg_Sloc := Sloc (Prag);
2979 Error_Msg_N
2980 ("info: & inherits `Invariant''Class` aspect from #?.l?", Typ);
2981 end if;
2983 -- Add the pragma to the list of processed pragmas
2985 Append_New_Elmt (Prag, Pragmas_Seen);
2986 Produced_Check := True;
2987 end Add_Invariant_Check;
2989 ---------------------------
2990 -- Add_Parent_Invariants --
2991 ---------------------------
2993 procedure Add_Parent_Invariants
2994 (T : Entity_Id;
2995 Obj_Id : Entity_Id;
2996 Checks : in out List_Id)
2998 Dummy_1 : Entity_Id;
2999 Dummy_2 : Entity_Id;
3001 Curr_Typ : Entity_Id;
3002 -- The entity of the current type being examined
3004 Full_Typ : Entity_Id;
3005 -- The full view of Par_Typ
3007 Par_Typ : Entity_Id;
3008 -- The entity of the parent type
3010 Priv_Typ : Entity_Id;
3011 -- The partial view of Par_Typ
3013 begin
3014 -- Do not process array types because they cannot have true parent
3015 -- types. This also prevents the generation of a duplicate invariant
3016 -- check when the input type is an array base type because its Etype
3017 -- denotes the first subtype, both of which share the same component
3018 -- type.
3020 if Is_Array_Type (T) then
3021 return;
3022 end if;
3024 -- Climb the parent type chain
3026 Curr_Typ := T;
3027 loop
3028 -- Do not consider subtypes as they inherit the invariants
3029 -- from their base types.
3031 Par_Typ := Base_Type (Etype (Curr_Typ));
3033 -- Stop the climb once the root of the parent chain is
3034 -- reached.
3036 exit when Curr_Typ = Par_Typ;
3038 -- Process the class-wide invariants of the parent type
3040 Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2);
3042 -- Process the elements of an array type
3044 if Is_Array_Type (Full_Typ) then
3045 Add_Array_Component_Invariants (Full_Typ, Obj_Id, Checks);
3047 -- Process the components of a record type
3049 elsif Ekind (Full_Typ) = E_Record_Type then
3050 Add_Record_Component_Invariants (Full_Typ, Obj_Id, Checks);
3051 end if;
3053 Add_Inherited_Invariants
3054 (T => T,
3055 Priv_Typ => Priv_Typ,
3056 Full_Typ => Full_Typ,
3057 Obj_Id => Obj_Id,
3058 Checks => Checks);
3060 Curr_Typ := Par_Typ;
3061 end loop;
3062 end Add_Parent_Invariants;
3064 ------------------------
3065 -- Add_Own_Invariants --
3066 ------------------------
3068 procedure Add_Own_Invariants
3069 (T : Entity_Id;
3070 Obj_Id : Entity_Id;
3071 Checks : in out List_Id;
3072 Priv_Item : Node_Id := Empty)
3074 Expr : Node_Id;
3075 Prag : Node_Id;
3076 Prag_Asp : Node_Id;
3077 Prag_Expr : Node_Id;
3078 Prag_Expr_Arg : Node_Id;
3079 Prag_Typ : Node_Id;
3080 Prag_Typ_Arg : Node_Id;
3082 begin
3083 if No (T) then
3084 return;
3085 end if;
3087 Prag := First_Rep_Item (T);
3088 while Present (Prag) loop
3089 if Nkind (Prag) = N_Pragma
3090 and then Pragma_Name (Prag) = Name_Invariant
3091 then
3092 -- Stop the traversal of the rep item chain once a specific
3093 -- item is encountered.
3095 if Present (Priv_Item) and then Prag = Priv_Item then
3096 exit;
3097 end if;
3099 -- Nothing to do if the pragma was already processed
3101 if Contains (Pragmas_Seen, Prag) then
3102 return;
3103 end if;
3105 -- Extract the arguments of the invariant pragma
3107 Prag_Typ_Arg := First (Pragma_Argument_Associations (Prag));
3108 Prag_Expr_Arg := Next (Prag_Typ_Arg);
3109 Prag_Expr := Get_Pragma_Arg (Prag_Expr_Arg);
3110 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg);
3111 Prag_Asp := Corresponding_Aspect (Prag);
3113 -- Verify the pragma belongs to T, otherwise the pragma applies
3114 -- to a parent type in which case it will be processed later by
3115 -- Add_Parent_Invariants or Add_Interface_Invariants.
3117 if Entity (Prag_Typ) /= T then
3118 return;
3119 end if;
3121 -- We need to preanalyze the expression itself inside a generic
3122 -- to be able to capture global references present in it.
3124 if Inside_A_Generic then
3125 Expr := Prag_Expr;
3126 else
3127 Expr := New_Copy_Tree (Prag_Expr);
3128 end if;
3130 -- Substitute all references to type T with references to the
3131 -- _object formal parameter.
3133 Replace_Type_References (Expr, T, Obj_Id);
3135 -- Preanalyze the invariant expression to detect errors and at
3136 -- the same time capture the visibility of the proper package
3137 -- part.
3139 Set_Parent (Expr, Parent (Prag_Expr));
3140 Preanalyze_Assert_Expression (Expr, Any_Boolean);
3142 -- Save a copy of the expression when T is tagged to detect
3143 -- errors and capture the visibility of the proper package part
3144 -- for the generation of inherited type invariants.
3146 if Is_Tagged_Type (T) then
3147 Set_Expression_Copy (Prag_Expr_Arg, New_Copy_Tree (Expr));
3148 end if;
3150 -- If the pragma comes from an aspect specification, replace
3151 -- the saved expression because all type references must be
3152 -- substituted for the call to Preanalyze_Spec_Expression in
3153 -- Check_Aspect_At_xxx routines.
3155 if Present (Prag_Asp) then
3156 Set_Expression_Copy (Prag_Asp, New_Copy_Tree (Expr));
3157 end if;
3159 Add_Invariant_Check (Prag, Expr, Checks);
3160 end if;
3162 Next_Rep_Item (Prag);
3163 end loop;
3164 end Add_Own_Invariants;
3166 -------------------------------------
3167 -- Add_Record_Component_Invariants --
3168 -------------------------------------
3170 procedure Add_Record_Component_Invariants
3171 (T : Entity_Id;
3172 Obj_Id : Entity_Id;
3173 Checks : in out List_Id)
3175 procedure Process_Component_List
3176 (Comp_List : Node_Id;
3177 CL_Checks : in out List_Id);
3178 -- Generate invariant checks for all record components found in
3179 -- component list Comp_List, including variant parts. All created
3180 -- checks are added to list CL_Checks.
3182 procedure Process_Record_Component
3183 (Comp_Id : Entity_Id;
3184 Comp_Checks : in out List_Id);
3185 -- Generate an invariant check for a record component identified by
3186 -- Comp_Id. All created checks are added to list Comp_Checks.
3188 ----------------------------
3189 -- Process_Component_List --
3190 ----------------------------
3192 procedure Process_Component_List
3193 (Comp_List : Node_Id;
3194 CL_Checks : in out List_Id)
3196 Comp : Node_Id;
3197 Var : Node_Id;
3198 Var_Alts : List_Id := No_List;
3199 Var_Checks : List_Id := No_List;
3200 Var_Stmts : List_Id;
3202 Produced_Variant_Check : Boolean := False;
3203 -- This flag tracks whether the component has produced at least
3204 -- one invariant check.
3206 begin
3207 -- Traverse the component items
3209 Comp := First (Component_Items (Comp_List));
3210 while Present (Comp) loop
3211 if Nkind (Comp) = N_Component_Declaration then
3213 -- Generate the component invariant check
3215 Process_Record_Component
3216 (Comp_Id => Defining_Entity (Comp),
3217 Comp_Checks => CL_Checks);
3218 end if;
3220 Next (Comp);
3221 end loop;
3223 -- Traverse the variant part
3225 if Present (Variant_Part (Comp_List)) then
3226 Var := First (Variants (Variant_Part (Comp_List)));
3227 while Present (Var) loop
3228 Var_Checks := No_List;
3230 -- Generate invariant checks for all components and variant
3231 -- parts that qualify.
3233 Process_Component_List
3234 (Comp_List => Component_List (Var),
3235 CL_Checks => Var_Checks);
3237 -- The components of the current variant produced at least
3238 -- one invariant check.
3240 if Present (Var_Checks) then
3241 Var_Stmts := Var_Checks;
3242 Produced_Variant_Check := True;
3244 -- Otherwise there are either no components with invariants,
3245 -- assertions are disabled, or Assertion_Policy Ignore is in
3246 -- effect.
3248 else
3249 Var_Stmts := New_List (Make_Null_Statement (Loc));
3250 end if;
3252 Append_New_To (Var_Alts,
3253 Make_Case_Statement_Alternative (Loc,
3254 Discrete_Choices =>
3255 New_Copy_List (Discrete_Choices (Var)),
3256 Statements => Var_Stmts));
3258 Next (Var);
3259 end loop;
3261 -- Create a case statement which verifies the invariant checks
3262 -- of a particular component list depending on the discriminant
3263 -- values only when there is at least one real invariant check.
3265 if Produced_Variant_Check then
3266 Append_New_To (CL_Checks,
3267 Make_Case_Statement (Loc,
3268 Expression =>
3269 Make_Selected_Component (Loc,
3270 Prefix => New_Occurrence_Of (Obj_Id, Loc),
3271 Selector_Name =>
3272 New_Occurrence_Of
3273 (Entity (Name (Variant_Part (Comp_List))), Loc)),
3274 Alternatives => Var_Alts));
3275 end if;
3276 end if;
3277 end Process_Component_List;
3279 ------------------------------
3280 -- Process_Record_Component --
3281 ------------------------------
3283 procedure Process_Record_Component
3284 (Comp_Id : Entity_Id;
3285 Comp_Checks : in out List_Id)
3287 Comp_Typ : constant Entity_Id := Etype (Comp_Id);
3288 Proc_Id : Entity_Id;
3290 Produced_Component_Check : Boolean := False;
3291 -- This flag tracks whether the component has produced at least
3292 -- one invariant check.
3294 begin
3295 -- Nothing to do for internal component _parent. Note that it is
3296 -- not desirable to check whether the component comes from source
3297 -- because protected type components are relocated to an internal
3298 -- corresponding record, but still need processing.
3300 if Chars (Comp_Id) = Name_uParent then
3301 return;
3302 end if;
3304 -- Verify the invariant of the component. Note that an access
3305 -- type may have an invariant when it acts as the full view of a
3306 -- private type and the invariant appears on the partial view. In
3307 -- this case verify the access value itself.
3309 if Has_Invariants (Comp_Typ) then
3311 -- In GNATprove mode, the component invariants are checked by
3312 -- other means. They should not be added to the record type
3313 -- invariant procedure, so that the procedure can be used to
3314 -- check the record type invariants if any.
3316 if GNATprove_Mode then
3317 null;
3319 else
3320 Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ));
3322 -- The component type should have an invariant procedure
3323 -- if it has invariants of its own or inherits class-wide
3324 -- invariants from parent or interface types.
3326 -- However, given that the invariant procedure is built by
3327 -- the expander, it is not available compiling generic units
3328 -- or when the sources have errors, since expansion is then
3329 -- disabled.
3331 pragma Assert (Present (Proc_Id)
3332 or else not Expander_Active);
3334 -- Generate:
3335 -- <Comp_Typ>Invariant (T (_object).<Comp_Id>);
3337 -- Note that the invariant procedure may have a null body if
3338 -- assertions are disabled or Assertion_Policy Ignore is in
3339 -- effect.
3341 if Present (Proc_Id)
3342 and then not Has_Null_Body (Proc_Id)
3343 then
3344 Append_New_To (Comp_Checks,
3345 Make_Procedure_Call_Statement (Loc,
3346 Name =>
3347 New_Occurrence_Of (Proc_Id, Loc),
3348 Parameter_Associations => New_List (
3349 Make_Selected_Component (Loc,
3350 Prefix =>
3351 Unchecked_Convert_To
3352 (T, New_Occurrence_Of (Obj_Id, Loc)),
3353 Selector_Name =>
3354 New_Occurrence_Of (Comp_Id, Loc)))));
3355 end if;
3356 end if;
3358 Produced_Check := True;
3359 Produced_Component_Check := True;
3360 end if;
3362 if Produced_Component_Check and then Has_Unchecked_Union (T) then
3363 Error_Msg_NE
3364 ("invariants cannot be checked on components of "
3365 & "unchecked_union type &??", Comp_Id, T);
3366 end if;
3367 end Process_Record_Component;
3369 -- Local variables
3371 Comps : Node_Id;
3372 Def : Node_Id;
3374 -- Start of processing for Add_Record_Component_Invariants
3376 begin
3377 -- An untagged derived type inherits the components of its parent
3378 -- type. In order to avoid creating redundant invariant checks, do
3379 -- not process the components now. Instead wait until the ultimate
3380 -- parent of the untagged derivation chain is reached.
3382 if not Is_Untagged_Derivation (T) then
3383 Def := Type_Definition (Parent (T));
3385 if Nkind (Def) = N_Derived_Type_Definition then
3386 Def := Record_Extension_Part (Def);
3387 end if;
3389 pragma Assert (Nkind (Def) = N_Record_Definition);
3390 Comps := Component_List (Def);
3392 if Present (Comps) then
3393 Process_Component_List
3394 (Comp_List => Comps,
3395 CL_Checks => Checks);
3396 end if;
3397 end if;
3398 end Add_Record_Component_Invariants;
3400 -- Local variables
3402 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
3403 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
3404 -- Save the Ghost-related attributes to restore on exit
3406 Dummy : Entity_Id;
3407 Priv_Item : Node_Id;
3408 Proc_Body : Node_Id;
3409 Proc_Body_Id : Entity_Id;
3410 Proc_Decl : Node_Id;
3411 Proc_Id : Entity_Id;
3412 Stmts : List_Id := No_List;
3414 CRec_Typ : Entity_Id := Empty;
3415 -- The corresponding record type of Full_Typ
3417 Full_Proc : Entity_Id := Empty;
3418 -- The entity of the "full" invariant procedure
3420 Full_Typ : Entity_Id := Empty;
3421 -- The full view of the working type
3423 Obj_Id : Entity_Id := Empty;
3424 -- The _object formal parameter of the invariant procedure
3426 Part_Proc : Entity_Id := Empty;
3427 -- The entity of the "partial" invariant procedure
3429 Priv_Typ : Entity_Id := Empty;
3430 -- The partial view of the working type
3432 Work_Typ : Entity_Id := Empty;
3433 -- The working type
3435 -- Start of processing for Build_Invariant_Procedure_Body
3437 begin
3438 Work_Typ := Typ;
3440 -- Do not process the underlying full view of a private type. There is
3441 -- no way to get back to the partial view, plus the body will be built
3442 -- by the full view or the base type.
3444 if Is_Underlying_Full_View (Work_Typ) then
3445 return;
3447 -- The input type denotes the implementation base type of a constrained
3448 -- array type. Work with the first subtype as all invariant pragmas are
3449 -- on its rep item chain.
3451 elsif Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
3452 Work_Typ := First_Subtype (Work_Typ);
3454 -- The input type denotes the corresponding record type of a protected
3455 -- or task type. Work with the concurrent type because the corresponding
3456 -- record type may not be visible to clients of the type.
3458 elsif Ekind (Work_Typ) = E_Record_Type
3459 and then Is_Concurrent_Record_Type (Work_Typ)
3460 then
3461 Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
3462 end if;
3464 -- The working type may be subject to pragma Ghost. Set the mode now to
3465 -- ensure that the invariant procedure is properly marked as Ghost.
3467 Set_Ghost_Mode (Work_Typ);
3469 -- The type must either have invariants of its own, inherit class-wide
3470 -- invariants from parent types or interfaces, or be an array or record
3471 -- type whose components have invariants.
3473 pragma Assert (Has_Invariants (Work_Typ));
3475 -- Interfaces are treated as the partial view of a private type in order
3476 -- to achieve uniformity with the general case.
3478 if Is_Interface (Work_Typ) then
3479 Priv_Typ := Work_Typ;
3481 -- Otherwise obtain both views of the type
3483 else
3484 Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy, CRec_Typ);
3485 end if;
3487 -- The caller requests a body for the partial invariant procedure
3489 if Partial_Invariant then
3490 Full_Proc := Invariant_Procedure (Work_Typ);
3491 Proc_Id := Partial_Invariant_Procedure (Work_Typ);
3493 -- The "full" invariant procedure body was already created
3495 if Present (Full_Proc)
3496 and then Present
3497 (Corresponding_Body (Unit_Declaration_Node (Full_Proc)))
3498 then
3499 -- This scenario happens only when the type is an untagged
3500 -- derivation from a private parent and the underlying full
3501 -- view was processed before the partial view.
3503 pragma Assert
3504 (Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ));
3506 -- Nothing to do because the processing of the underlying full
3507 -- view already checked the invariants of the partial view.
3509 goto Leave;
3510 end if;
3512 -- Create a declaration for the "partial" invariant procedure if it
3513 -- is not available.
3515 if No (Proc_Id) then
3516 Build_Invariant_Procedure_Declaration
3517 (Typ => Work_Typ,
3518 Partial_Invariant => True);
3520 Proc_Id := Partial_Invariant_Procedure (Work_Typ);
3521 end if;
3523 -- The caller requests a body for the "full" invariant procedure
3525 else
3526 Proc_Id := Invariant_Procedure (Work_Typ);
3527 Part_Proc := Partial_Invariant_Procedure (Work_Typ);
3529 -- Create a declaration for the "full" invariant procedure if it is
3530 -- not available.
3532 if No (Proc_Id) then
3533 Build_Invariant_Procedure_Declaration (Work_Typ);
3534 Proc_Id := Invariant_Procedure (Work_Typ);
3535 end if;
3536 end if;
3538 -- At this point there should be an invariant procedure declaration
3540 pragma Assert (Present (Proc_Id));
3541 Proc_Decl := Unit_Declaration_Node (Proc_Id);
3543 -- Nothing to do if the invariant procedure already has a body
3545 if Present (Corresponding_Body (Proc_Decl)) then
3546 goto Leave;
3547 end if;
3549 -- Emulate the environment of the invariant procedure by installing its
3550 -- scope and formal parameters. Note that this is not needed, but having
3551 -- the scope installed helps with the detection of invariant-related
3552 -- errors.
3554 Push_Scope (Proc_Id);
3555 Install_Formals (Proc_Id);
3557 Obj_Id := First_Formal (Proc_Id);
3558 pragma Assert (Present (Obj_Id));
3560 -- The "partial" invariant procedure verifies the invariants of the
3561 -- partial view only.
3563 if Partial_Invariant then
3564 pragma Assert (Present (Priv_Typ));
3566 Add_Own_Invariants
3567 (T => Priv_Typ,
3568 Obj_Id => Obj_Id,
3569 Checks => Stmts);
3571 -- Otherwise the "full" invariant procedure verifies the invariants of
3572 -- the full view, all array or record components, as well as class-wide
3573 -- invariants inherited from parent types or interfaces. In addition, it
3574 -- indirectly verifies the invariants of the partial view by calling the
3575 -- "partial" invariant procedure.
3577 else
3578 pragma Assert (Present (Full_Typ));
3580 -- Check the invariants of the partial view by calling the "partial"
3581 -- invariant procedure. Generate:
3583 -- <Work_Typ>Partial_Invariant (_object);
3585 if Present (Part_Proc) then
3586 Append_New_To (Stmts,
3587 Make_Procedure_Call_Statement (Loc,
3588 Name => New_Occurrence_Of (Part_Proc, Loc),
3589 Parameter_Associations => New_List (
3590 New_Occurrence_Of (Obj_Id, Loc))));
3592 Produced_Check := True;
3593 end if;
3595 Priv_Item := Empty;
3597 -- Derived subtypes do not have a partial view
3599 if Present (Priv_Typ) then
3601 -- The processing of the "full" invariant procedure intentionally
3602 -- skips the partial view because a) this may result in changes of
3603 -- visibility and b) lead to duplicate checks. However, when the
3604 -- full view is the underlying full view of an untagged derived
3605 -- type whose parent type is private, partial invariants appear on
3606 -- the rep item chain of the partial view only.
3608 -- package Pack_1 is
3609 -- type Root ... is private;
3610 -- private
3611 -- <full view of Root>
3612 -- end Pack_1;
3614 -- with Pack_1;
3615 -- package Pack_2 is
3616 -- type Child is new Pack_1.Root with Type_Invariant => ...;
3617 -- <underlying full view of Child>
3618 -- end Pack_2;
3620 -- As a result, the processing of the full view must also consider
3621 -- all invariants of the partial view.
3623 if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then
3624 null;
3626 -- Otherwise the invariants of the partial view are ignored
3628 else
3629 -- Note that the rep item chain is shared between the partial
3630 -- and full views of a type. To avoid processing the invariants
3631 -- of the partial view, signal the logic to stop when the first
3632 -- rep item of the partial view has been reached.
3634 Priv_Item := First_Rep_Item (Priv_Typ);
3636 -- Ignore the invariants of the partial view by eliminating the
3637 -- view.
3639 Priv_Typ := Empty;
3640 end if;
3641 end if;
3643 -- Process the invariants of the full view and in certain cases those
3644 -- of the partial view. This also handles any invariants on array or
3645 -- record components.
3647 Add_Own_Invariants
3648 (T => Priv_Typ,
3649 Obj_Id => Obj_Id,
3650 Checks => Stmts,
3651 Priv_Item => Priv_Item);
3653 Add_Own_Invariants
3654 (T => Full_Typ,
3655 Obj_Id => Obj_Id,
3656 Checks => Stmts,
3657 Priv_Item => Priv_Item);
3659 -- Process the elements of an array type
3661 if Is_Array_Type (Full_Typ) then
3662 Add_Array_Component_Invariants (Full_Typ, Obj_Id, Stmts);
3664 -- Process the components of a record type
3666 elsif Ekind (Full_Typ) = E_Record_Type then
3667 Add_Record_Component_Invariants (Full_Typ, Obj_Id, Stmts);
3669 -- Process the components of a corresponding record
3671 elsif Present (CRec_Typ) then
3672 Add_Record_Component_Invariants (CRec_Typ, Obj_Id, Stmts);
3673 end if;
3675 -- Process the inherited class-wide invariants of all parent types.
3676 -- This also handles any invariants on record components.
3678 Add_Parent_Invariants (Full_Typ, Obj_Id, Stmts);
3680 -- Process the inherited class-wide invariants of all implemented
3681 -- interface types.
3683 Add_Interface_Invariants (Full_Typ, Obj_Id, Stmts);
3684 end if;
3686 End_Scope;
3688 -- At this point there should be at least one invariant check. If this
3689 -- is not the case, then the invariant-related flags were not properly
3690 -- set, or there is a missing invariant procedure on one of the array
3691 -- or record components.
3693 pragma Assert (Produced_Check);
3695 -- Account for the case where assertions are disabled or all invariant
3696 -- checks are subject to Assertion_Policy Ignore. Produce a completing
3697 -- empty body.
3699 if No (Stmts) then
3700 Stmts := New_List (Make_Null_Statement (Loc));
3701 end if;
3703 -- Generate:
3704 -- procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>) is
3705 -- begin
3706 -- <Stmts>
3707 -- end <Work_Typ>[Partial_]Invariant;
3709 Proc_Body :=
3710 Make_Subprogram_Body (Loc,
3711 Specification =>
3712 Copy_Subprogram_Spec (Parent (Proc_Id)),
3713 Declarations => Empty_List,
3714 Handled_Statement_Sequence =>
3715 Make_Handled_Sequence_Of_Statements (Loc,
3716 Statements => Stmts));
3717 Proc_Body_Id := Defining_Entity (Proc_Body);
3719 -- Perform minor decoration in case the body is not analyzed
3721 Mutate_Ekind (Proc_Body_Id, E_Subprogram_Body);
3722 Set_Etype (Proc_Body_Id, Standard_Void_Type);
3723 Set_Scope (Proc_Body_Id, Current_Scope);
3725 -- Link both spec and body to avoid generating duplicates
3727 Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
3728 Set_Corresponding_Spec (Proc_Body, Proc_Id);
3730 -- The body should not be inserted into the tree when the context is
3731 -- a generic unit because it is not part of the template. Note
3732 -- that the body must still be generated in order to resolve the
3733 -- invariants.
3735 if Inside_A_Generic then
3736 null;
3738 -- Semi-insert the body into the tree for GNATprove by setting its
3739 -- Parent field. This allows for proper upstream tree traversals.
3741 elsif GNATprove_Mode then
3742 Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
3744 -- Otherwise the body is part of the freezing actions of the type
3746 else
3747 Append_Freeze_Action (Work_Typ, Proc_Body);
3748 end if;
3750 <<Leave>>
3751 Restore_Ghost_Region (Saved_GM, Saved_IGR);
3752 end Build_Invariant_Procedure_Body;
3754 -------------------------------------------
3755 -- Build_Invariant_Procedure_Declaration --
3756 -------------------------------------------
3758 -- WARNING: This routine manages Ghost regions. Return statements must be
3759 -- replaced by gotos which jump to the end of the routine and restore the
3760 -- Ghost mode.
3762 procedure Build_Invariant_Procedure_Declaration
3763 (Typ : Entity_Id;
3764 Partial_Invariant : Boolean := False)
3766 Loc : constant Source_Ptr := Sloc (Typ);
3768 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
3769 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
3770 -- Save the Ghost-related attributes to restore on exit
3772 Proc_Decl : Node_Id;
3773 Proc_Id : Entity_Id;
3774 Proc_Nam : Name_Id;
3775 Typ_Decl : Node_Id;
3777 CRec_Typ : Entity_Id;
3778 -- The corresponding record type of Full_Typ
3780 Full_Typ : Entity_Id;
3781 -- The full view of working type
3783 Obj_Id : Entity_Id;
3784 -- The _object formal parameter of the invariant procedure
3786 Obj_Typ : Entity_Id;
3787 -- The type of the _object formal parameter
3789 Priv_Typ : Entity_Id;
3790 -- The partial view of working type
3792 UFull_Typ : Entity_Id;
3793 -- The underlying full view of Full_Typ
3795 Work_Typ : Entity_Id;
3796 -- The working type
3798 begin
3799 Work_Typ := Typ;
3801 -- The input type denotes the implementation base type of a constrained
3802 -- array type. Work with the first subtype as all invariant pragmas are
3803 -- on its rep item chain.
3805 if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
3806 Work_Typ := First_Subtype (Work_Typ);
3808 -- The input denotes the corresponding record type of a protected or a
3809 -- task type. Work with the concurrent type because the corresponding
3810 -- record type may not be visible to clients of the type.
3812 elsif Ekind (Work_Typ) = E_Record_Type
3813 and then Is_Concurrent_Record_Type (Work_Typ)
3814 then
3815 Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
3816 end if;
3818 -- The working type may be subject to pragma Ghost. Set the mode now to
3819 -- ensure that the invariant procedure is properly marked as Ghost.
3821 Set_Ghost_Mode (Work_Typ);
3823 -- The type must either have invariants of its own, inherit class-wide
3824 -- invariants from parent or interface types, or be an array or record
3825 -- type whose components have invariants.
3827 pragma Assert (Has_Invariants (Work_Typ));
3829 -- Nothing to do if the type already has a "partial" invariant procedure
3831 if Partial_Invariant then
3832 if Present (Partial_Invariant_Procedure (Work_Typ)) then
3833 goto Leave;
3834 end if;
3836 -- Nothing to do if the type already has a "full" invariant procedure
3838 elsif Present (Invariant_Procedure (Work_Typ)) then
3839 goto Leave;
3840 end if;
3842 -- The caller requests the declaration of the "partial" invariant
3843 -- procedure.
3845 if Partial_Invariant then
3846 Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_Invariant");
3848 -- Otherwise the caller requests the declaration of the "full" invariant
3849 -- procedure.
3851 else
3852 Proc_Nam := New_External_Name (Chars (Work_Typ), "Invariant");
3853 end if;
3855 Proc_Id := Make_Defining_Identifier (Loc, Chars => Proc_Nam);
3857 -- Perform minor decoration in case the declaration is not analyzed
3859 Mutate_Ekind (Proc_Id, E_Procedure);
3860 Set_Etype (Proc_Id, Standard_Void_Type);
3861 Set_Scope (Proc_Id, Current_Scope);
3863 if Partial_Invariant then
3864 Set_Is_Partial_Invariant_Procedure (Proc_Id);
3865 Set_Partial_Invariant_Procedure (Work_Typ, Proc_Id);
3866 else
3867 Set_Is_Invariant_Procedure (Proc_Id);
3868 Set_Invariant_Procedure (Work_Typ, Proc_Id);
3869 end if;
3871 -- The invariant procedure requires debug info when the invariants are
3872 -- subject to Source Coverage Obligations.
3874 if Generate_SCO then
3875 Set_Debug_Info_Needed (Proc_Id);
3876 end if;
3878 -- Obtain all views of the input type
3880 Get_Views (Work_Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ);
3882 -- Associate the invariant procedure and various flags with all views
3884 Propagate_Invariant_Attributes (Priv_Typ, From_Typ => Work_Typ);
3885 Propagate_Invariant_Attributes (Full_Typ, From_Typ => Work_Typ);
3886 Propagate_Invariant_Attributes (UFull_Typ, From_Typ => Work_Typ);
3887 Propagate_Invariant_Attributes (CRec_Typ, From_Typ => Work_Typ);
3889 -- The declaration of the invariant procedure is inserted after the
3890 -- declaration of the partial view as this allows for proper external
3891 -- visibility.
3893 if Present (Priv_Typ) then
3894 Typ_Decl := Declaration_Node (Priv_Typ);
3896 -- Anonymous arrays in object declarations have no explicit declaration
3897 -- so use the related object declaration as the insertion point.
3899 elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ) then
3900 Typ_Decl := Associated_Node_For_Itype (Work_Typ);
3902 -- Derived types with the full view as parent do not have a partial
3903 -- view. Insert the invariant procedure after the derived type.
3905 else
3906 Typ_Decl := Declaration_Node (Full_Typ);
3907 end if;
3909 -- The type should have a declarative node
3911 pragma Assert (Present (Typ_Decl));
3913 -- Create the formal parameter which emulates the variable-like behavior
3914 -- of the current type instance.
3916 Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject);
3918 -- When generating an invariant procedure declaration for an abstract
3919 -- type (including interfaces), use the class-wide type as the _object
3920 -- type. This has several desirable effects:
3922 -- * The invariant procedure does not become a primitive of the type.
3923 -- This eliminates the need to either special case the treatment of
3924 -- invariant procedures, or to make it a predefined primitive and
3925 -- force every derived type to potentially provide an empty body.
3927 -- * The invariant procedure does not need to be declared as abstract.
3928 -- This allows for a proper body, which in turn avoids redundant
3929 -- processing of the same invariants for types with multiple views.
3931 -- * The class-wide type allows for calls to abstract primitives
3932 -- within a nonabstract subprogram. The calls are treated as
3933 -- dispatching and require additional processing when they are
3934 -- remapped to call primitives of derived types. See routine
3935 -- Replace_References for details.
3937 if Is_Abstract_Type (Work_Typ) then
3938 Obj_Typ := Class_Wide_Type (Work_Typ);
3939 else
3940 Obj_Typ := Work_Typ;
3941 end if;
3943 -- Perform minor decoration in case the declaration is not analyzed
3945 Mutate_Ekind (Obj_Id, E_In_Parameter);
3946 Set_Etype (Obj_Id, Obj_Typ);
3947 Set_Scope (Obj_Id, Proc_Id);
3949 Set_First_Entity (Proc_Id, Obj_Id);
3950 Set_Last_Entity (Proc_Id, Obj_Id);
3952 -- Generate:
3953 -- procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>);
3955 Proc_Decl :=
3956 Make_Subprogram_Declaration (Loc,
3957 Specification =>
3958 Make_Procedure_Specification (Loc,
3959 Defining_Unit_Name => Proc_Id,
3960 Parameter_Specifications => New_List (
3961 Make_Parameter_Specification (Loc,
3962 Defining_Identifier => Obj_Id,
3963 Parameter_Type => New_Occurrence_Of (Obj_Typ, Loc)))));
3965 -- The declaration should not be inserted into the tree when the context
3966 -- is a generic unit because it is not part of the template.
3968 if Inside_A_Generic then
3969 null;
3971 -- Semi-insert the declaration into the tree for GNATprove by setting
3972 -- its Parent field. This allows for proper upstream tree traversals.
3974 elsif GNATprove_Mode then
3975 Set_Parent (Proc_Decl, Parent (Typ_Decl));
3977 -- Otherwise insert the declaration
3979 else
3980 pragma Assert (Present (Typ_Decl));
3981 Insert_After_And_Analyze (Typ_Decl, Proc_Decl);
3982 end if;
3984 <<Leave>>
3985 Restore_Ghost_Region (Saved_GM, Saved_IGR);
3986 end Build_Invariant_Procedure_Declaration;
3988 --------------------------
3989 -- Build_Procedure_Form --
3990 --------------------------
3992 procedure Build_Procedure_Form (N : Node_Id) is
3993 Loc : constant Source_Ptr := Sloc (N);
3994 Subp : constant Entity_Id := Defining_Entity (N);
3996 Func_Formal : Entity_Id;
3997 Proc_Formals : List_Id;
3998 Proc_Decl : Node_Id;
4000 begin
4001 -- No action needed if this transformation was already done, or in case
4002 -- of subprogram renaming declarations.
4004 if Nkind (Specification (N)) = N_Procedure_Specification
4005 or else Nkind (N) = N_Subprogram_Renaming_Declaration
4006 then
4007 return;
4008 end if;
4010 -- Ditto when dealing with an expression function, where both the
4011 -- original expression and the generated declaration end up being
4012 -- expanded here.
4014 if Rewritten_For_C (Subp) then
4015 return;
4016 end if;
4018 Proc_Formals := New_List;
4020 -- Create a list of formal parameters with the same types as the
4021 -- function.
4023 Func_Formal := First_Formal (Subp);
4024 while Present (Func_Formal) loop
4025 Append_To (Proc_Formals,
4026 Make_Parameter_Specification (Loc,
4027 Defining_Identifier =>
4028 Make_Defining_Identifier (Loc, Chars (Func_Formal)),
4029 Parameter_Type =>
4030 New_Occurrence_Of (Etype (Func_Formal), Loc)));
4032 Next_Formal (Func_Formal);
4033 end loop;
4035 -- Add an extra out parameter to carry the function result
4037 Append_To (Proc_Formals,
4038 Make_Parameter_Specification (Loc,
4039 Defining_Identifier =>
4040 Make_Defining_Identifier (Loc, Name_UP_RESULT),
4041 Out_Present => True,
4042 Parameter_Type => New_Occurrence_Of (Etype (Subp), Loc)));
4044 -- The new procedure declaration is inserted before the function
4045 -- declaration. The processing in Build_Procedure_Body_Form relies on
4046 -- this order. Note that we insert before because in the case of a
4047 -- function body with no separate spec, we do not want to insert the
4048 -- new spec after the body which will later get rewritten.
4050 Proc_Decl :=
4051 Make_Subprogram_Declaration (Loc,
4052 Specification =>
4053 Make_Procedure_Specification (Loc,
4054 Defining_Unit_Name =>
4055 Make_Defining_Identifier (Loc, Chars (Subp)),
4056 Parameter_Specifications => Proc_Formals));
4058 Insert_Before_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl);
4060 -- Entity of procedure must remain invisible so that it does not
4061 -- overload subsequent references to the original function.
4063 Set_Is_Immediately_Visible (Defining_Entity (Proc_Decl), False);
4065 -- Mark the function as having a procedure form and link the function
4066 -- and its internally built procedure.
4068 Set_Rewritten_For_C (Subp);
4069 Set_Corresponding_Procedure (Subp, Defining_Entity (Proc_Decl));
4070 Set_Corresponding_Function (Defining_Entity (Proc_Decl), Subp);
4071 end Build_Procedure_Form;
4073 ------------------------
4074 -- Build_Runtime_Call --
4075 ------------------------
4077 function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
4078 begin
4079 -- If entity is not available, we can skip making the call (this avoids
4080 -- junk duplicated error messages in a number of cases).
4082 if not RTE_Available (RE) then
4083 return Make_Null_Statement (Loc);
4084 else
4085 return
4086 Make_Procedure_Call_Statement (Loc,
4087 Name => New_Occurrence_Of (RTE (RE), Loc));
4088 end if;
4089 end Build_Runtime_Call;
4091 ------------------------
4092 -- Build_SS_Mark_Call --
4093 ------------------------
4095 function Build_SS_Mark_Call
4096 (Loc : Source_Ptr;
4097 Mark : Entity_Id) return Node_Id
4099 begin
4100 -- Generate:
4101 -- Mark : constant Mark_Id := SS_Mark;
4103 return
4104 Make_Object_Declaration (Loc,
4105 Defining_Identifier => Mark,
4106 Constant_Present => True,
4107 Object_Definition =>
4108 New_Occurrence_Of (RTE (RE_Mark_Id), Loc),
4109 Expression =>
4110 Make_Function_Call (Loc,
4111 Name => New_Occurrence_Of (RTE (RE_SS_Mark), Loc)));
4112 end Build_SS_Mark_Call;
4114 ---------------------------
4115 -- Build_SS_Release_Call --
4116 ---------------------------
4118 function Build_SS_Release_Call
4119 (Loc : Source_Ptr;
4120 Mark : Entity_Id) return Node_Id
4122 begin
4123 -- Generate:
4124 -- SS_Release (Mark);
4126 return
4127 Make_Procedure_Call_Statement (Loc,
4128 Name =>
4129 New_Occurrence_Of (RTE (RE_SS_Release), Loc),
4130 Parameter_Associations => New_List (
4131 New_Occurrence_Of (Mark, Loc)));
4132 end Build_SS_Release_Call;
4134 ----------------------------
4135 -- Build_Task_Array_Image --
4136 ----------------------------
4138 -- This function generates the body for a function that constructs the
4139 -- image string for a task that is an array component. The function is
4140 -- local to the init proc for the array type, and is called for each one
4141 -- of the components. The constructed image has the form of an indexed
4142 -- component, whose prefix is the outer variable of the array type.
4143 -- The n-dimensional array type has known indexes Index, Index2...
4145 -- Id_Ref is an indexed component form created by the enclosing init proc.
4146 -- Its successive indexes are Val1, Val2, ... which are the loop variables
4147 -- in the loops that call the individual task init proc on each component.
4149 -- The generated function has the following structure:
4151 -- function F return String is
4152 -- Pref : String renames Task_Name;
4153 -- T1 : constant String := Index1'Image (Val1);
4154 -- ...
4155 -- Tn : constant String := Indexn'Image (Valn);
4156 -- Len : constant Integer :=
4157 -- Pref'Length + T1'Length + ... + Tn'Length + n + 1;
4158 -- -- Len includes commas and the end parentheses
4160 -- Res : String (1 .. Len);
4161 -- Pos : Integer := Pref'Length;
4163 -- begin
4164 -- Res (1 .. Pos) := Pref;
4165 -- Pos := Pos + 1;
4166 -- Res (Pos) := '(';
4167 -- Pos := Pos + 1;
4168 -- Res (Pos .. Pos + T1'Length - 1) := T1;
4169 -- Pos := Pos + T1'Length;
4170 -- Res (Pos) := '.';
4171 -- Pos := Pos + 1;
4172 -- ...
4173 -- Res (Pos .. Pos + Tn'Length - 1) := Tn;
4174 -- Res (Len) := ')';
4176 -- return Res;
4177 -- end F;
4179 -- Needless to say, multidimensional arrays of tasks are rare enough that
4180 -- the bulkiness of this code is not really a concern.
4182 function Build_Task_Array_Image
4183 (Loc : Source_Ptr;
4184 Id_Ref : Node_Id;
4185 A_Type : Entity_Id;
4186 Dyn : Boolean := False) return Node_Id
4188 Dims : constant Nat := Number_Dimensions (A_Type);
4189 -- Number of dimensions for array of tasks
4191 Temps : array (1 .. Dims) of Entity_Id;
4192 -- Array of temporaries to hold string for each index
4194 Indx : Node_Id;
4195 -- Index expression
4197 Len : Entity_Id;
4198 -- Total length of generated name
4200 Pos : Entity_Id;
4201 -- Running index for substring assignments
4203 Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
4204 -- Name of enclosing variable, prefix of resulting name
4206 Res : Entity_Id;
4207 -- String to hold result
4209 Val : Node_Id;
4210 -- Value of successive indexes
4212 Sum : Node_Id;
4213 -- Expression to compute total size of string
4215 T : Entity_Id;
4216 -- Entity for name at one index position
4218 Decls : constant List_Id := New_List;
4219 Stats : constant List_Id := New_List;
4221 begin
4222 -- For a dynamic task, the name comes from the target variable. For a
4223 -- static one it is a formal of the enclosing init proc.
4225 if Dyn then
4226 Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
4227 Append_To (Decls,
4228 Make_Object_Declaration (Loc,
4229 Defining_Identifier => Pref,
4230 Constant_Present => True,
4231 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4232 Expression =>
4233 Make_String_Literal (Loc,
4234 Strval => String_From_Name_Buffer)));
4236 else
4237 Append_To (Decls,
4238 Make_Object_Renaming_Declaration (Loc,
4239 Defining_Identifier => Pref,
4240 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
4241 Name => Make_Identifier (Loc, Name_uTask_Name)));
4242 end if;
4244 Indx := First_Index (A_Type);
4245 Val := First (Expressions (Id_Ref));
4247 for J in 1 .. Dims loop
4248 T := Make_Temporary (Loc, 'T');
4249 Temps (J) := T;
4251 Append_To (Decls,
4252 Make_Object_Declaration (Loc,
4253 Defining_Identifier => T,
4254 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4255 Constant_Present => True,
4256 Expression =>
4257 Make_Attribute_Reference (Loc,
4258 Attribute_Name => Name_Image,
4259 Prefix => New_Occurrence_Of (Etype (Indx), Loc),
4260 Expressions => New_List (New_Copy_Tree (Val)))));
4262 Next_Index (Indx);
4263 Next (Val);
4264 end loop;
4266 Sum := Make_Integer_Literal (Loc, Dims + 1);
4268 Sum :=
4269 Make_Op_Add (Loc,
4270 Left_Opnd => Sum,
4271 Right_Opnd =>
4272 Make_Attribute_Reference (Loc,
4273 Attribute_Name => Name_Length,
4274 Prefix => New_Occurrence_Of (Pref, Loc),
4275 Expressions => New_List (Make_Integer_Literal (Loc, 1))));
4277 for J in 1 .. Dims loop
4278 Sum :=
4279 Make_Op_Add (Loc,
4280 Left_Opnd => Sum,
4281 Right_Opnd =>
4282 Make_Attribute_Reference (Loc,
4283 Attribute_Name => Name_Length,
4284 Prefix =>
4285 New_Occurrence_Of (Temps (J), Loc),
4286 Expressions => New_List (Make_Integer_Literal (Loc, 1))));
4287 end loop;
4289 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
4291 Set_Character_Literal_Name (Get_Char_Code ('('));
4293 Append_To (Stats,
4294 Make_Assignment_Statement (Loc,
4295 Name =>
4296 Make_Indexed_Component (Loc,
4297 Prefix => New_Occurrence_Of (Res, Loc),
4298 Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4299 Expression =>
4300 Make_Character_Literal (Loc,
4301 Chars => Name_Find,
4302 Char_Literal_Value => UI_From_CC (Get_Char_Code ('(')))));
4304 Append_To (Stats,
4305 Make_Assignment_Statement (Loc,
4306 Name => New_Occurrence_Of (Pos, Loc),
4307 Expression =>
4308 Make_Op_Add (Loc,
4309 Left_Opnd => New_Occurrence_Of (Pos, Loc),
4310 Right_Opnd => Make_Integer_Literal (Loc, 1))));
4312 for J in 1 .. Dims loop
4314 Append_To (Stats,
4315 Make_Assignment_Statement (Loc,
4316 Name =>
4317 Make_Slice (Loc,
4318 Prefix => New_Occurrence_Of (Res, Loc),
4319 Discrete_Range =>
4320 Make_Range (Loc,
4321 Low_Bound => New_Occurrence_Of (Pos, Loc),
4322 High_Bound =>
4323 Make_Op_Subtract (Loc,
4324 Left_Opnd =>
4325 Make_Op_Add (Loc,
4326 Left_Opnd => New_Occurrence_Of (Pos, Loc),
4327 Right_Opnd =>
4328 Make_Attribute_Reference (Loc,
4329 Attribute_Name => Name_Length,
4330 Prefix =>
4331 New_Occurrence_Of (Temps (J), Loc),
4332 Expressions =>
4333 New_List (Make_Integer_Literal (Loc, 1)))),
4334 Right_Opnd => Make_Integer_Literal (Loc, 1)))),
4336 Expression => New_Occurrence_Of (Temps (J), Loc)));
4338 if J < Dims then
4339 Append_To (Stats,
4340 Make_Assignment_Statement (Loc,
4341 Name => New_Occurrence_Of (Pos, Loc),
4342 Expression =>
4343 Make_Op_Add (Loc,
4344 Left_Opnd => New_Occurrence_Of (Pos, Loc),
4345 Right_Opnd =>
4346 Make_Attribute_Reference (Loc,
4347 Attribute_Name => Name_Length,
4348 Prefix => New_Occurrence_Of (Temps (J), Loc),
4349 Expressions =>
4350 New_List (Make_Integer_Literal (Loc, 1))))));
4352 Set_Character_Literal_Name (Get_Char_Code (','));
4354 Append_To (Stats,
4355 Make_Assignment_Statement (Loc,
4356 Name => Make_Indexed_Component (Loc,
4357 Prefix => New_Occurrence_Of (Res, Loc),
4358 Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4359 Expression =>
4360 Make_Character_Literal (Loc,
4361 Chars => Name_Find,
4362 Char_Literal_Value => UI_From_CC (Get_Char_Code (',')))));
4364 Append_To (Stats,
4365 Make_Assignment_Statement (Loc,
4366 Name => New_Occurrence_Of (Pos, Loc),
4367 Expression =>
4368 Make_Op_Add (Loc,
4369 Left_Opnd => New_Occurrence_Of (Pos, Loc),
4370 Right_Opnd => Make_Integer_Literal (Loc, 1))));
4371 end if;
4372 end loop;
4374 Set_Character_Literal_Name (Get_Char_Code (')'));
4376 Append_To (Stats,
4377 Make_Assignment_Statement (Loc,
4378 Name =>
4379 Make_Indexed_Component (Loc,
4380 Prefix => New_Occurrence_Of (Res, Loc),
4381 Expressions => New_List (New_Occurrence_Of (Len, Loc))),
4382 Expression =>
4383 Make_Character_Literal (Loc,
4384 Chars => Name_Find,
4385 Char_Literal_Value => UI_From_CC (Get_Char_Code (')')))));
4386 return Build_Task_Image_Function (Loc, Decls, Stats, Res);
4387 end Build_Task_Array_Image;
4389 ----------------------------
4390 -- Build_Task_Image_Decls --
4391 ----------------------------
4393 function Build_Task_Image_Decls
4394 (Loc : Source_Ptr;
4395 Id_Ref : Node_Id;
4396 A_Type : Entity_Id;
4397 In_Init_Proc : Boolean := False) return List_Id
4399 Decls : constant List_Id := New_List;
4400 T_Id : Entity_Id := Empty;
4401 Decl : Node_Id;
4402 Expr : Node_Id := Empty;
4403 Fun : Node_Id := Empty;
4404 Is_Dyn : constant Boolean :=
4405 Nkind (Parent (Id_Ref)) = N_Assignment_Statement
4406 and then
4407 Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
4409 Component_Suffix_Index : constant Int :=
4410 (if In_Init_Proc then -1 else 0);
4411 -- If an init proc calls Build_Task_Image_Decls twice for its
4412 -- _Parent component (to split early/late initialization), we don't
4413 -- want two decls with the same name. Hence, the -1 suffix.
4415 begin
4416 -- If Discard_Names or No_Implicit_Heap_Allocations are in effect,
4417 -- generate a dummy declaration only.
4419 if Restriction_Active (No_Implicit_Heap_Allocations)
4420 or else Global_Discard_Names
4421 then
4422 T_Id := Make_Temporary (Loc, 'J');
4423 Name_Len := 0;
4425 return
4426 New_List (
4427 Make_Object_Declaration (Loc,
4428 Defining_Identifier => T_Id,
4429 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4430 Expression =>
4431 Make_String_Literal (Loc,
4432 Strval => String_From_Name_Buffer)));
4434 else
4435 if Nkind (Id_Ref) = N_Identifier
4436 or else Nkind (Id_Ref) = N_Defining_Identifier
4437 then
4438 -- For a simple variable, the image of the task is built from
4439 -- the name of the variable. To avoid possible conflict with the
4440 -- anonymous type created for a single protected object, add a
4441 -- numeric suffix.
4443 T_Id :=
4444 Make_Defining_Identifier (Loc,
4445 New_External_Name (Chars (Id_Ref), 'T', 1));
4447 Get_Name_String (Chars (Id_Ref));
4449 Expr :=
4450 Make_String_Literal (Loc,
4451 Strval => String_From_Name_Buffer);
4453 elsif Nkind (Id_Ref) = N_Selected_Component then
4454 T_Id :=
4455 Make_Defining_Identifier (Loc,
4456 New_External_Name (Chars (Selector_Name (Id_Ref)), 'T',
4457 Suffix_Index => Component_Suffix_Index));
4458 Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
4460 elsif Nkind (Id_Ref) = N_Indexed_Component then
4461 T_Id :=
4462 Make_Defining_Identifier (Loc,
4463 New_External_Name (Chars (A_Type), 'N'));
4465 Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
4466 end if;
4467 end if;
4469 if Present (Fun) then
4470 Append (Fun, Decls);
4471 Expr := Make_Function_Call (Loc,
4472 Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
4474 if not In_Init_Proc then
4475 Set_Uses_Sec_Stack (Defining_Entity (Fun));
4476 end if;
4477 end if;
4479 Decl := Make_Object_Declaration (Loc,
4480 Defining_Identifier => T_Id,
4481 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4482 Constant_Present => True,
4483 Expression => Expr);
4485 Append (Decl, Decls);
4486 return Decls;
4487 end Build_Task_Image_Decls;
4489 -------------------------------
4490 -- Build_Task_Image_Function --
4491 -------------------------------
4493 function Build_Task_Image_Function
4494 (Loc : Source_Ptr;
4495 Decls : List_Id;
4496 Stats : List_Id;
4497 Res : Entity_Id) return Node_Id
4499 Spec : Node_Id;
4501 begin
4502 Append_To (Stats,
4503 Make_Simple_Return_Statement (Loc,
4504 Expression => New_Occurrence_Of (Res, Loc)));
4506 Spec := Make_Function_Specification (Loc,
4507 Defining_Unit_Name => Make_Temporary (Loc, 'F'),
4508 Result_Definition => New_Occurrence_Of (Standard_String, Loc));
4510 -- Calls to 'Image use the secondary stack, which must be cleaned up
4511 -- after the task name is built.
4513 return Make_Subprogram_Body (Loc,
4514 Specification => Spec,
4515 Declarations => Decls,
4516 Handled_Statement_Sequence =>
4517 Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats));
4518 end Build_Task_Image_Function;
4520 -----------------------------
4521 -- Build_Task_Image_Prefix --
4522 -----------------------------
4524 procedure Build_Task_Image_Prefix
4525 (Loc : Source_Ptr;
4526 Len : out Entity_Id;
4527 Res : out Entity_Id;
4528 Pos : out Entity_Id;
4529 Prefix : Entity_Id;
4530 Sum : Node_Id;
4531 Decls : List_Id;
4532 Stats : List_Id)
4534 begin
4535 Len := Make_Temporary (Loc, 'L', Sum);
4537 Append_To (Decls,
4538 Make_Object_Declaration (Loc,
4539 Defining_Identifier => Len,
4540 Constant_Present => True,
4541 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc),
4542 Expression => Sum));
4544 Res := Make_Temporary (Loc, 'R');
4546 Append_To (Decls,
4547 Make_Object_Declaration (Loc,
4548 Defining_Identifier => Res,
4549 Object_Definition =>
4550 Make_Subtype_Indication (Loc,
4551 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
4552 Constraint =>
4553 Make_Index_Or_Discriminant_Constraint (Loc,
4554 Constraints =>
4555 New_List (
4556 Make_Range (Loc,
4557 Low_Bound => Make_Integer_Literal (Loc, 1),
4558 High_Bound => New_Occurrence_Of (Len, Loc)))))));
4560 -- Indicate that the result is an internal temporary, so it does not
4561 -- receive a bogus initialization when declaration is expanded. This
4562 -- is both efficient, and prevents anomalies in the handling of
4563 -- dynamic objects on the secondary stack.
4565 Set_Is_Internal (Res);
4566 Pos := Make_Temporary (Loc, 'P');
4568 Append_To (Decls,
4569 Make_Object_Declaration (Loc,
4570 Defining_Identifier => Pos,
4571 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc)));
4573 -- Pos := Prefix'Length;
4575 Append_To (Stats,
4576 Make_Assignment_Statement (Loc,
4577 Name => New_Occurrence_Of (Pos, Loc),
4578 Expression =>
4579 Make_Attribute_Reference (Loc,
4580 Attribute_Name => Name_Length,
4581 Prefix => New_Occurrence_Of (Prefix, Loc),
4582 Expressions => New_List (Make_Integer_Literal (Loc, 1)))));
4584 -- Res (1 .. Pos) := Prefix;
4586 Append_To (Stats,
4587 Make_Assignment_Statement (Loc,
4588 Name =>
4589 Make_Slice (Loc,
4590 Prefix => New_Occurrence_Of (Res, Loc),
4591 Discrete_Range =>
4592 Make_Range (Loc,
4593 Low_Bound => Make_Integer_Literal (Loc, 1),
4594 High_Bound => New_Occurrence_Of (Pos, Loc))),
4596 Expression => New_Occurrence_Of (Prefix, Loc)));
4598 Append_To (Stats,
4599 Make_Assignment_Statement (Loc,
4600 Name => New_Occurrence_Of (Pos, Loc),
4601 Expression =>
4602 Make_Op_Add (Loc,
4603 Left_Opnd => New_Occurrence_Of (Pos, Loc),
4604 Right_Opnd => Make_Integer_Literal (Loc, 1))));
4605 end Build_Task_Image_Prefix;
4607 -----------------------------
4608 -- Build_Task_Record_Image --
4609 -----------------------------
4611 function Build_Task_Record_Image
4612 (Loc : Source_Ptr;
4613 Id_Ref : Node_Id;
4614 Dyn : Boolean := False) return Node_Id
4616 Len : Entity_Id;
4617 -- Total length of generated name
4619 Pos : Entity_Id;
4620 -- Index into result
4622 Res : Entity_Id;
4623 -- String to hold result
4625 Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
4626 -- Name of enclosing variable, prefix of resulting name
4628 Sum : Node_Id;
4629 -- Expression to compute total size of string
4631 Sel : Entity_Id;
4632 -- Entity for selector name
4634 Decls : constant List_Id := New_List;
4635 Stats : constant List_Id := New_List;
4637 begin
4638 -- For a dynamic task, the name comes from the target variable. For a
4639 -- static one it is a formal of the enclosing init proc.
4641 if Dyn then
4642 Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
4643 Append_To (Decls,
4644 Make_Object_Declaration (Loc,
4645 Defining_Identifier => Pref,
4646 Constant_Present => True,
4647 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4648 Expression =>
4649 Make_String_Literal (Loc,
4650 Strval => String_From_Name_Buffer)));
4652 else
4653 Append_To (Decls,
4654 Make_Object_Renaming_Declaration (Loc,
4655 Defining_Identifier => Pref,
4656 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
4657 Name => Make_Identifier (Loc, Name_uTask_Name)));
4658 end if;
4660 Sel := Make_Temporary (Loc, 'S');
4662 Get_Name_String (Chars (Selector_Name (Id_Ref)));
4664 Append_To (Decls,
4665 Make_Object_Declaration (Loc,
4666 Defining_Identifier => Sel,
4667 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4668 Expression =>
4669 Make_String_Literal (Loc,
4670 Strval => String_From_Name_Buffer)));
4672 Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
4674 Sum :=
4675 Make_Op_Add (Loc,
4676 Left_Opnd => Sum,
4677 Right_Opnd =>
4678 Make_Attribute_Reference (Loc,
4679 Attribute_Name => Name_Length,
4680 Prefix =>
4681 New_Occurrence_Of (Pref, Loc),
4682 Expressions => New_List (Make_Integer_Literal (Loc, 1))));
4684 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
4686 Set_Character_Literal_Name (Get_Char_Code ('.'));
4688 -- Res (Pos) := '.';
4690 Append_To (Stats,
4691 Make_Assignment_Statement (Loc,
4692 Name => Make_Indexed_Component (Loc,
4693 Prefix => New_Occurrence_Of (Res, Loc),
4694 Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4695 Expression =>
4696 Make_Character_Literal (Loc,
4697 Chars => Name_Find,
4698 Char_Literal_Value =>
4699 UI_From_CC (Get_Char_Code ('.')))));
4701 Append_To (Stats,
4702 Make_Assignment_Statement (Loc,
4703 Name => New_Occurrence_Of (Pos, Loc),
4704 Expression =>
4705 Make_Op_Add (Loc,
4706 Left_Opnd => New_Occurrence_Of (Pos, Loc),
4707 Right_Opnd => Make_Integer_Literal (Loc, 1))));
4709 -- Res (Pos .. Len) := Selector;
4711 Append_To (Stats,
4712 Make_Assignment_Statement (Loc,
4713 Name => Make_Slice (Loc,
4714 Prefix => New_Occurrence_Of (Res, Loc),
4715 Discrete_Range =>
4716 Make_Range (Loc,
4717 Low_Bound => New_Occurrence_Of (Pos, Loc),
4718 High_Bound => New_Occurrence_Of (Len, Loc))),
4719 Expression => New_Occurrence_Of (Sel, Loc)));
4721 return Build_Task_Image_Function (Loc, Decls, Stats, Res);
4722 end Build_Task_Record_Image;
4724 ----------------------------------------
4725 -- Build_Temporary_On_Secondary_Stack --
4726 ----------------------------------------
4728 function Build_Temporary_On_Secondary_Stack
4729 (Loc : Source_Ptr;
4730 Typ : Entity_Id;
4731 Code : List_Id) return Entity_Id
4733 Acc_Typ : Entity_Id;
4734 Alloc : Node_Id;
4735 Alloc_Obj : Entity_Id;
4737 begin
4738 pragma Assert (RTE_Available (RE_SS_Pool)
4739 and then not Needs_Finalization (Typ));
4741 Acc_Typ := Make_Temporary (Loc, 'A');
4742 Mutate_Ekind (Acc_Typ, E_Access_Type);
4743 Set_Associated_Storage_Pool (Acc_Typ, RTE (RE_SS_Pool));
4745 Append_To (Code,
4746 Make_Full_Type_Declaration (Loc,
4747 Defining_Identifier => Acc_Typ,
4748 Type_Definition =>
4749 Make_Access_To_Object_Definition (Loc,
4750 All_Present => True,
4751 Subtype_Indication =>
4752 New_Occurrence_Of (Typ, Loc))));
4754 Alloc :=
4755 Make_Allocator (Loc, Expression => New_Occurrence_Of (Typ, Loc));
4756 Set_No_Initialization (Alloc);
4758 Alloc_Obj := Make_Temporary (Loc, 'R');
4760 Append_To (Code,
4761 Make_Object_Declaration (Loc,
4762 Defining_Identifier => Alloc_Obj,
4763 Constant_Present => True,
4764 Object_Definition =>
4765 New_Occurrence_Of (Acc_Typ, Loc),
4766 Expression => Alloc));
4768 Set_Uses_Sec_Stack (Current_Scope);
4770 return Alloc_Obj;
4771 end Build_Temporary_On_Secondary_Stack;
4773 ---------------------------------------
4774 -- Build_Transient_Object_Statements --
4775 ---------------------------------------
4777 procedure Build_Transient_Object_Statements
4778 (Obj_Decl : Node_Id;
4779 Fin_Call : out Node_Id;
4780 Hook_Assign : out Node_Id;
4781 Hook_Clear : out Node_Id;
4782 Hook_Decl : out Node_Id;
4783 Ptr_Decl : out Node_Id;
4784 Finalize_Obj : Boolean := True)
4786 Loc : constant Source_Ptr := Sloc (Obj_Decl);
4787 Obj_Id : constant Entity_Id := Defining_Entity (Obj_Decl);
4788 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
4790 Desig_Typ : Entity_Id;
4791 Hook_Expr : Node_Id;
4792 Hook_Id : Entity_Id;
4793 Obj_Ref : Node_Id;
4794 Ptr_Typ : Entity_Id;
4796 begin
4797 -- Recover the type of the object
4799 Desig_Typ := Obj_Typ;
4801 if Is_Access_Type (Desig_Typ) then
4802 Desig_Typ := Available_View (Designated_Type (Desig_Typ));
4803 end if;
4805 -- Create an access type which provides a reference to the transient
4806 -- object. Generate:
4808 -- type Ptr_Typ is access all Desig_Typ;
4810 Ptr_Typ := Make_Temporary (Loc, 'A');
4811 Mutate_Ekind (Ptr_Typ, E_General_Access_Type);
4812 Set_Directly_Designated_Type (Ptr_Typ, Desig_Typ);
4814 Ptr_Decl :=
4815 Make_Full_Type_Declaration (Loc,
4816 Defining_Identifier => Ptr_Typ,
4817 Type_Definition =>
4818 Make_Access_To_Object_Definition (Loc,
4819 All_Present => True,
4820 Subtype_Indication => New_Occurrence_Of (Desig_Typ, Loc)));
4822 -- Create a temporary check which acts as a hook to the transient
4823 -- object. Generate:
4825 -- Hook : Ptr_Typ := null;
4827 Hook_Id := Make_Temporary (Loc, 'T');
4828 Mutate_Ekind (Hook_Id, E_Variable);
4829 Set_Etype (Hook_Id, Ptr_Typ);
4831 Hook_Decl :=
4832 Make_Object_Declaration (Loc,
4833 Defining_Identifier => Hook_Id,
4834 Object_Definition => New_Occurrence_Of (Ptr_Typ, Loc),
4835 Expression => Make_Null (Loc));
4837 -- Mark the temporary as a hook. This signals the machinery in
4838 -- Build_Finalizer to recognize this special case.
4840 Set_Status_Flag_Or_Transient_Decl (Hook_Id, Obj_Decl);
4842 -- Hook the transient object to the temporary. Generate:
4844 -- Hook := Ptr_Typ (Obj_Id);
4845 -- <or>
4846 -- Hool := Obj_Id'Unrestricted_Access;
4848 if Is_Access_Type (Obj_Typ) then
4849 Hook_Expr :=
4850 Unchecked_Convert_To (Ptr_Typ, New_Occurrence_Of (Obj_Id, Loc));
4851 else
4852 Hook_Expr :=
4853 Make_Attribute_Reference (Loc,
4854 Prefix => New_Occurrence_Of (Obj_Id, Loc),
4855 Attribute_Name => Name_Unrestricted_Access);
4856 end if;
4858 Hook_Assign :=
4859 Make_Assignment_Statement (Loc,
4860 Name => New_Occurrence_Of (Hook_Id, Loc),
4861 Expression => Hook_Expr);
4863 -- Crear the hook prior to finalizing the object. Generate:
4865 -- Hook := null;
4867 Hook_Clear :=
4868 Make_Assignment_Statement (Loc,
4869 Name => New_Occurrence_Of (Hook_Id, Loc),
4870 Expression => Make_Null (Loc));
4872 -- Finalize the object. Generate:
4874 -- [Deep_]Finalize (Obj_Ref[.all]);
4876 if Finalize_Obj then
4877 Obj_Ref := New_Occurrence_Of (Obj_Id, Loc);
4879 if Is_Access_Type (Obj_Typ) then
4880 Obj_Ref := Make_Explicit_Dereference (Loc, Obj_Ref);
4881 Set_Etype (Obj_Ref, Desig_Typ);
4882 end if;
4884 Fin_Call :=
4885 Make_Final_Call
4886 (Obj_Ref => Obj_Ref,
4887 Typ => Desig_Typ);
4889 -- Otherwise finalize the hook. Generate:
4891 -- [Deep_]Finalize (Hook.all);
4893 else
4894 Fin_Call :=
4895 Make_Final_Call (
4896 Obj_Ref =>
4897 Make_Explicit_Dereference (Loc,
4898 Prefix => New_Occurrence_Of (Hook_Id, Loc)),
4899 Typ => Desig_Typ);
4900 end if;
4901 end Build_Transient_Object_Statements;
4903 -----------------------------
4904 -- Check_Float_Op_Overflow --
4905 -----------------------------
4907 procedure Check_Float_Op_Overflow (N : Node_Id) is
4908 begin
4909 -- Return if no check needed
4911 if not Is_Floating_Point_Type (Etype (N))
4912 or else not (Do_Overflow_Check (N) and then Check_Float_Overflow)
4914 -- In CodePeer_Mode, rely on the overflow check flag being set instead
4915 -- and do not expand the code for float overflow checking.
4917 or else CodePeer_Mode
4918 then
4919 return;
4920 end if;
4922 -- Otherwise we replace the expression by
4924 -- do Tnn : constant ftype := expression;
4925 -- constraint_error when not Tnn'Valid;
4926 -- in Tnn;
4928 declare
4929 Loc : constant Source_Ptr := Sloc (N);
4930 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
4931 Typ : constant Entity_Id := Etype (N);
4933 begin
4934 -- Turn off the Do_Overflow_Check flag, since we are doing that work
4935 -- right here. We also set the node as analyzed to prevent infinite
4936 -- recursion from repeating the operation in the expansion.
4938 Set_Do_Overflow_Check (N, False);
4939 Set_Analyzed (N, True);
4941 -- Do the rewrite to include the check
4943 Rewrite (N,
4944 Make_Expression_With_Actions (Loc,
4945 Actions => New_List (
4946 Make_Object_Declaration (Loc,
4947 Defining_Identifier => Tnn,
4948 Object_Definition => New_Occurrence_Of (Typ, Loc),
4949 Constant_Present => True,
4950 Expression => Relocate_Node (N)),
4951 Make_Raise_Constraint_Error (Loc,
4952 Condition =>
4953 Make_Op_Not (Loc,
4954 Right_Opnd =>
4955 Make_Attribute_Reference (Loc,
4956 Prefix => New_Occurrence_Of (Tnn, Loc),
4957 Attribute_Name => Name_Valid)),
4958 Reason => CE_Overflow_Check_Failed)),
4959 Expression => New_Occurrence_Of (Tnn, Loc)));
4961 Analyze_And_Resolve (N, Typ);
4962 end;
4963 end Check_Float_Op_Overflow;
4965 ----------------------------------
4966 -- Component_May_Be_Bit_Aligned --
4967 ----------------------------------
4969 function Component_May_Be_Bit_Aligned
4970 (Comp : Entity_Id;
4971 For_Slice : Boolean := False) return Boolean
4973 UT : Entity_Id;
4975 begin
4976 -- If no component clause, then everything is fine, since the back end
4977 -- never misaligns from byte boundaries by default, even if there is a
4978 -- pragma Pack for the record.
4980 if No (Comp) or else No (Component_Clause (Comp)) then
4981 return False;
4982 end if;
4984 UT := Underlying_Type (Etype (Comp));
4986 -- It is only array and record types that cause trouble
4988 if not Is_Record_Type (UT) and then not Is_Array_Type (UT) then
4989 return False;
4991 -- If we know that we have a small (at most the maximum integer size)
4992 -- bit-packed array or record without variant part, then everything is
4993 -- fine, since the back end can handle these cases correctly, except if
4994 -- a slice is involved.
4996 elsif Known_Esize (Comp)
4997 and then Esize (Comp) <= System_Max_Integer_Size
4998 and then (Is_Bit_Packed_Array (UT)
4999 or else (Is_Record_Type (UT)
5000 and then not Has_Variant_Part (UT)))
5001 and then not For_Slice
5002 then
5003 return False;
5005 elsif not Known_Normalized_First_Bit (Comp) then
5006 return True;
5008 -- Otherwise if the component is not byte aligned, we know we have the
5009 -- nasty unaligned case.
5011 elsif Normalized_First_Bit (Comp) /= Uint_0
5012 or else Esize (Comp) mod System_Storage_Unit /= Uint_0
5013 then
5014 return True;
5016 -- If we are large and byte aligned, then OK at this level
5018 else
5019 return False;
5020 end if;
5021 end Component_May_Be_Bit_Aligned;
5023 -------------------------------
5024 -- Convert_To_Actual_Subtype --
5025 -------------------------------
5027 procedure Convert_To_Actual_Subtype (Exp : Node_Id) is
5028 Act_ST : Entity_Id;
5030 begin
5031 Act_ST := Get_Actual_Subtype (Exp);
5033 if Act_ST = Etype (Exp) then
5034 return;
5035 else
5036 Rewrite (Exp, Convert_To (Act_ST, Relocate_Node (Exp)));
5037 Analyze_And_Resolve (Exp, Act_ST);
5038 end if;
5039 end Convert_To_Actual_Subtype;
5041 -----------------------------------
5042 -- Corresponding_Runtime_Package --
5043 -----------------------------------
5045 function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is
5046 function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean;
5047 -- Return True if protected type T has one entry and the maximum queue
5048 -- length is one.
5050 --------------------------------
5051 -- Has_One_Entry_And_No_Queue --
5052 --------------------------------
5054 function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean is
5055 Item : Entity_Id;
5056 Is_First : Boolean := True;
5058 begin
5059 Item := First_Entity (T);
5060 while Present (Item) loop
5061 if Is_Entry (Item) then
5063 -- The protected type has more than one entry
5065 if not Is_First then
5066 return False;
5067 end if;
5069 -- The queue length is not one
5071 if not Restriction_Active (No_Entry_Queue)
5072 and then Get_Max_Queue_Length (Item) /= Uint_1
5073 then
5074 return False;
5075 end if;
5077 Is_First := False;
5078 end if;
5080 Next_Entity (Item);
5081 end loop;
5083 return True;
5084 end Has_One_Entry_And_No_Queue;
5086 -- Local variables
5088 Pkg_Id : RTU_Id := RTU_Null;
5090 -- Start of processing for Corresponding_Runtime_Package
5092 begin
5093 pragma Assert (Is_Concurrent_Type (Typ));
5095 if Is_Protected_Type (Typ) then
5096 if Has_Entries (Typ)
5098 -- A protected type without entries that covers an interface and
5099 -- overrides the abstract routines with protected procedures is
5100 -- considered equivalent to a protected type with entries in the
5101 -- context of dispatching select statements. It is sufficient to
5102 -- check for the presence of an interface list in the declaration
5103 -- node to recognize this case.
5105 or else Present (Interface_List (Parent (Typ)))
5107 -- Protected types with interrupt handlers (when not using a
5108 -- restricted profile) are also considered equivalent to
5109 -- protected types with entries. The types which are used
5110 -- (Static_Interrupt_Protection and Dynamic_Interrupt_Protection)
5111 -- are derived from Protection_Entries.
5113 or else (Has_Attach_Handler (Typ) and then not Restricted_Profile)
5114 or else Has_Interrupt_Handler (Typ)
5115 then
5116 if Abort_Allowed
5117 or else Restriction_Active (No_Select_Statements) = False
5118 or else not Has_One_Entry_And_No_Queue (Typ)
5119 or else (Has_Attach_Handler (Typ)
5120 and then not Restricted_Profile)
5121 then
5122 Pkg_Id := System_Tasking_Protected_Objects_Entries;
5123 else
5124 Pkg_Id := System_Tasking_Protected_Objects_Single_Entry;
5125 end if;
5127 else
5128 Pkg_Id := System_Tasking_Protected_Objects;
5129 end if;
5130 end if;
5132 return Pkg_Id;
5133 end Corresponding_Runtime_Package;
5135 -----------------------------------
5136 -- Current_Sem_Unit_Declarations --
5137 -----------------------------------
5139 function Current_Sem_Unit_Declarations return List_Id is
5140 U : Node_Id := Unit (Cunit (Current_Sem_Unit));
5141 Decls : List_Id;
5143 begin
5144 -- If the current unit is a package body, locate the visible
5145 -- declarations of the package spec.
5147 if Nkind (U) = N_Package_Body then
5148 U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
5149 end if;
5151 if Nkind (U) = N_Package_Declaration then
5152 U := Specification (U);
5153 Decls := Visible_Declarations (U);
5155 if No (Decls) then
5156 Decls := New_List;
5157 Set_Visible_Declarations (U, Decls);
5158 end if;
5160 else
5161 Decls := Declarations (U);
5163 if No (Decls) then
5164 Decls := New_List;
5165 Set_Declarations (U, Decls);
5166 end if;
5167 end if;
5169 return Decls;
5170 end Current_Sem_Unit_Declarations;
5172 -----------------------
5173 -- Duplicate_Subexpr --
5174 -----------------------
5176 function Duplicate_Subexpr
5177 (Exp : Node_Id;
5178 Name_Req : Boolean := False;
5179 Renaming_Req : Boolean := False) return Node_Id
5181 begin
5182 Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
5183 return New_Copy_Tree (Exp);
5184 end Duplicate_Subexpr;
5186 ---------------------------------
5187 -- Duplicate_Subexpr_No_Checks --
5188 ---------------------------------
5190 function Duplicate_Subexpr_No_Checks
5191 (Exp : Node_Id;
5192 Name_Req : Boolean := False;
5193 Renaming_Req : Boolean := False;
5194 Related_Id : Entity_Id := Empty;
5195 Is_Low_Bound : Boolean := False;
5196 Is_High_Bound : Boolean := False) return Node_Id
5198 New_Exp : Node_Id;
5200 begin
5201 Remove_Side_Effects
5202 (Exp => Exp,
5203 Name_Req => Name_Req,
5204 Renaming_Req => Renaming_Req,
5205 Related_Id => Related_Id,
5206 Is_Low_Bound => Is_Low_Bound,
5207 Is_High_Bound => Is_High_Bound);
5209 New_Exp := New_Copy_Tree (Exp);
5210 Remove_Checks (New_Exp);
5211 return New_Exp;
5212 end Duplicate_Subexpr_No_Checks;
5214 -----------------------------------
5215 -- Duplicate_Subexpr_Move_Checks --
5216 -----------------------------------
5218 function Duplicate_Subexpr_Move_Checks
5219 (Exp : Node_Id;
5220 Name_Req : Boolean := False;
5221 Renaming_Req : Boolean := False) return Node_Id
5223 New_Exp : Node_Id;
5225 begin
5226 Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
5227 New_Exp := New_Copy_Tree (Exp);
5228 Remove_Checks (Exp);
5229 return New_Exp;
5230 end Duplicate_Subexpr_Move_Checks;
5232 -------------------------
5233 -- Enclosing_Init_Proc --
5234 -------------------------
5236 function Enclosing_Init_Proc return Entity_Id is
5237 S : Entity_Id;
5239 begin
5240 S := Current_Scope;
5241 while Present (S) and then S /= Standard_Standard loop
5242 if Is_Init_Proc (S) then
5243 return S;
5244 else
5245 S := Scope (S);
5246 end if;
5247 end loop;
5249 return Empty;
5250 end Enclosing_Init_Proc;
5252 --------------------
5253 -- Ensure_Defined --
5254 --------------------
5256 procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
5257 IR : Node_Id;
5259 begin
5260 -- An itype reference must only be created if this is a local itype, so
5261 -- that gigi can elaborate it on the proper objstack.
5263 if Is_Itype (Typ) and then Scope (Typ) = Current_Scope then
5264 IR := Make_Itype_Reference (Sloc (N));
5265 Set_Itype (IR, Typ);
5266 Insert_Action (N, IR);
5267 end if;
5268 end Ensure_Defined;
5270 -------------------
5271 -- Evaluate_Name --
5272 -------------------
5274 procedure Evaluate_Name (Nam : Node_Id) is
5275 begin
5276 case Nkind (Nam) is
5277 -- For an aggregate, force its evaluation
5279 when N_Aggregate =>
5280 Force_Evaluation (Nam);
5282 -- For an attribute reference or an indexed component, evaluate the
5283 -- prefix, which is itself a name, recursively, and then force the
5284 -- evaluation of all the subscripts (or attribute expressions).
5286 when N_Attribute_Reference
5287 | N_Indexed_Component
5289 Evaluate_Name (Prefix (Nam));
5291 declare
5292 E : Node_Id;
5294 begin
5295 E := First (Expressions (Nam));
5296 while Present (E) loop
5297 Force_Evaluation (E);
5299 if Is_Rewrite_Substitution (E) then
5300 Set_Do_Range_Check
5301 (E, Do_Range_Check (Original_Node (E)));
5302 end if;
5304 Next (E);
5305 end loop;
5306 end;
5308 -- For an explicit dereference, we simply force the evaluation of
5309 -- the name expression. The dereference provides a value that is the
5310 -- address for the renamed object, and it is precisely this value
5311 -- that we want to preserve.
5313 when N_Explicit_Dereference =>
5314 Force_Evaluation (Prefix (Nam));
5316 -- For a function call, we evaluate the call; same for an operator
5318 when N_Function_Call
5319 | N_Op
5321 Force_Evaluation (Nam);
5323 -- For a qualified expression, we evaluate the expression
5325 when N_Qualified_Expression =>
5326 Evaluate_Name (Expression (Nam));
5328 -- For a selected component, we simply evaluate the prefix
5330 when N_Selected_Component =>
5331 Evaluate_Name (Prefix (Nam));
5333 -- For a slice, we evaluate the prefix, as for the indexed component
5334 -- case and then, if there is a range present, either directly or as
5335 -- the constraint of a discrete subtype indication, we evaluate the
5336 -- two bounds of this range.
5338 when N_Slice =>
5339 Evaluate_Name (Prefix (Nam));
5340 Evaluate_Slice_Bounds (Nam);
5342 -- For a type conversion, the expression of the conversion must be
5343 -- the name of an object, and we simply need to evaluate this name.
5345 when N_Type_Conversion =>
5346 Evaluate_Name (Expression (Nam));
5348 -- The remaining cases are direct name and character literal. In all
5349 -- these cases, we do nothing, since we want to reevaluate each time
5350 -- the renamed object is used. ??? There are more remaining cases, at
5351 -- least in the GNATprove_Mode, where this routine is called in more
5352 -- contexts than in GNAT.
5354 when others =>
5355 null;
5356 end case;
5357 end Evaluate_Name;
5359 ---------------------------
5360 -- Evaluate_Slice_Bounds --
5361 ---------------------------
5363 procedure Evaluate_Slice_Bounds (Slice : Node_Id) is
5364 DR : constant Node_Id := Discrete_Range (Slice);
5365 Constr : Node_Id;
5366 Rexpr : Node_Id;
5368 begin
5369 if Nkind (DR) = N_Range then
5370 Force_Evaluation (Low_Bound (DR));
5371 Force_Evaluation (High_Bound (DR));
5373 elsif Nkind (DR) = N_Subtype_Indication then
5374 Constr := Constraint (DR);
5376 if Nkind (Constr) = N_Range_Constraint then
5377 Rexpr := Range_Expression (Constr);
5379 Force_Evaluation (Low_Bound (Rexpr));
5380 Force_Evaluation (High_Bound (Rexpr));
5381 end if;
5382 end if;
5383 end Evaluate_Slice_Bounds;
5385 ---------------------
5386 -- Evolve_And_Then --
5387 ---------------------
5389 procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
5390 begin
5391 if No (Cond) then
5392 Cond := Cond1;
5393 else
5394 Cond :=
5395 Make_And_Then (Sloc (Cond1),
5396 Left_Opnd => Cond,
5397 Right_Opnd => Cond1);
5398 end if;
5399 end Evolve_And_Then;
5401 --------------------
5402 -- Evolve_Or_Else --
5403 --------------------
5405 procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
5406 begin
5407 if No (Cond) then
5408 Cond := Cond1;
5409 else
5410 Cond :=
5411 Make_Or_Else (Sloc (Cond1),
5412 Left_Opnd => Cond,
5413 Right_Opnd => Cond1);
5414 end if;
5415 end Evolve_Or_Else;
5417 -------------------------------
5418 -- Expand_Sliding_Conversion --
5419 -------------------------------
5421 procedure Expand_Sliding_Conversion (N : Node_Id; Arr_Typ : Entity_Id) is
5423 pragma Assert (Is_Array_Type (Arr_Typ)
5424 and then not Is_Constrained (Arr_Typ)
5425 and then Is_Fixed_Lower_Bound_Array_Subtype (Arr_Typ));
5427 Constraints : List_Id;
5428 Index : Node_Id := First_Index (Arr_Typ);
5429 Loc : constant Source_Ptr := Sloc (N);
5430 Subt_Decl : Node_Id;
5431 Subt : Entity_Id;
5432 Subt_Low : Node_Id;
5433 Subt_High : Node_Id;
5435 Act_Subt : Entity_Id;
5436 Act_Index : Node_Id;
5437 Act_Low : Node_Id;
5438 Act_High : Node_Id;
5439 Adjust_Incr : Node_Id;
5440 Dimension : Int := 0;
5441 All_FLBs_Match : Boolean := True;
5443 begin
5444 -- This procedure is called during semantic analysis, and we only expand
5445 -- a sliding conversion when Expander_Active, to avoid doing it during
5446 -- preanalysis (which can lead to problems with the target subtype not
5447 -- getting properly expanded during later full analysis). Also, sliding
5448 -- should never be needed for string literals, because their bounds are
5449 -- determined directly based on the fixed lower bound of Arr_Typ and
5450 -- their length.
5452 if Expander_Active and then Nkind (N) /= N_String_Literal then
5453 Constraints := New_List;
5455 Act_Subt := Get_Actual_Subtype (N);
5456 Act_Index := First_Index (Act_Subt);
5458 -- Loop over the indexes of the fixed-lower-bound array type or
5459 -- subtype to build up an index constraint for constructing the
5460 -- subtype that will be the target of a conversion of the array
5461 -- object that may need a sliding conversion.
5463 while Present (Index) loop
5464 pragma Assert (Present (Act_Index));
5466 Dimension := Dimension + 1;
5468 Get_Index_Bounds (Act_Index, Act_Low, Act_High);
5470 -- If Index defines a normal unconstrained range (range <>),
5471 -- then we will simply use the bounds of the actual subtype's
5472 -- corresponding index range.
5474 if not Is_Fixed_Lower_Bound_Index_Subtype (Etype (Index)) then
5475 Subt_Low := Act_Low;
5476 Subt_High := Act_High;
5478 -- Otherwise, a range will be created with a low bound given by
5479 -- the fixed lower bound of the array subtype's index, and with
5480 -- high bound given by (Actual'Length + fixed lower bound - 1).
5482 else
5483 if Nkind (Index) = N_Subtype_Indication then
5484 Subt_Low :=
5485 New_Copy_Tree
5486 (Low_Bound (Range_Expression (Constraint (Index))));
5487 else
5488 pragma Assert (Nkind (Index) = N_Range);
5490 Subt_Low := New_Copy_Tree (Low_Bound (Index));
5491 end if;
5493 -- If either we have a nonstatic lower bound, or the target and
5494 -- source subtypes are statically known to have unequal lower
5495 -- bounds, then we will need to make a subtype conversion to
5496 -- slide the bounds. However, if all of the indexes' lower
5497 -- bounds are static and known to be equal (the common case),
5498 -- then no conversion will be needed, and we'll end up not
5499 -- creating the subtype or the conversion (though we still
5500 -- build up the index constraint, which will simply be unused).
5502 if not (Compile_Time_Known_Value (Subt_Low)
5503 and then Compile_Time_Known_Value (Act_Low))
5504 or else Expr_Value (Subt_Low) /= Expr_Value (Act_Low)
5505 then
5506 All_FLBs_Match := False;
5507 end if;
5509 -- Apply 'Pos to lower bound, which may be of an enumeration
5510 -- type, before subtracting.
5512 Adjust_Incr :=
5513 Make_Op_Subtract (Loc,
5514 Make_Attribute_Reference (Loc,
5515 Prefix =>
5516 New_Occurrence_Of (Etype (Act_Index), Loc),
5517 Attribute_Name =>
5518 Name_Pos,
5519 Expressions =>
5520 New_List (New_Copy_Tree (Subt_Low))),
5521 Make_Integer_Literal (Loc, 1));
5523 -- Apply 'Val to the result of adding the increment to the
5524 -- length, to handle indexes of enumeration types.
5526 Subt_High :=
5527 Make_Attribute_Reference (Loc,
5528 Prefix =>
5529 New_Occurrence_Of (Etype (Act_Index), Loc),
5530 Attribute_Name =>
5531 Name_Val,
5532 Expressions =>
5533 New_List (Make_Op_Add (Loc,
5534 Make_Attribute_Reference (Loc,
5535 Prefix =>
5536 New_Occurrence_Of (Act_Subt, Loc),
5537 Attribute_Name =>
5538 Name_Length,
5539 Expressions =>
5540 New_List
5541 (Make_Integer_Literal
5542 (Loc, Dimension))),
5543 Adjust_Incr)));
5544 end if;
5546 Append (Make_Range (Loc, Subt_Low, Subt_High), Constraints);
5548 Next (Index);
5549 Next (Act_Index);
5550 end loop;
5552 -- If for each index with a fixed lower bound (FLB), the lower bound
5553 -- of the corresponding index of the actual subtype is statically
5554 -- known be equal to the FLB, then a sliding conversion isn't needed
5555 -- at all, so just return without building a subtype or conversion.
5557 if All_FLBs_Match then
5558 return;
5559 end if;
5561 -- A sliding conversion is needed, so create the target subtype using
5562 -- the index constraint created above, and rewrite the expression
5563 -- as a conversion to that subtype.
5565 Subt := Make_Temporary (Loc, 'S', Related_Node => N);
5566 Set_Is_Internal (Subt);
5568 Subt_Decl :=
5569 Make_Subtype_Declaration (Loc,
5570 Defining_Identifier => Subt,
5571 Subtype_Indication =>
5572 Make_Subtype_Indication (Loc,
5573 Subtype_Mark =>
5574 New_Occurrence_Of (Arr_Typ, Loc),
5575 Constraint =>
5576 Make_Index_Or_Discriminant_Constraint (Loc,
5577 Constraints => Constraints)));
5579 Mark_Rewrite_Insertion (Subt_Decl);
5581 -- The actual subtype is an Itype, so we analyze the declaration,
5582 -- but do not attach it to the tree.
5584 Set_Parent (Subt_Decl, N);
5585 Set_Is_Itype (Subt);
5586 Analyze (Subt_Decl, Suppress => All_Checks);
5587 Set_Associated_Node_For_Itype (Subt, N);
5588 Set_Has_Delayed_Freeze (Subt, False);
5590 -- We need to freeze the actual subtype immediately. This is needed
5591 -- because otherwise this Itype will not get frozen at all, and it is
5592 -- always safe to freeze on creation because any associated types
5593 -- must be frozen at this point.
5595 Freeze_Itype (Subt, N);
5597 Rewrite (N,
5598 Make_Type_Conversion (Loc,
5599 Subtype_Mark =>
5600 New_Occurrence_Of (Subt, Loc),
5601 Expression => Relocate_Node (N)));
5602 Analyze (N);
5603 end if;
5604 end Expand_Sliding_Conversion;
5606 -----------------------------------------
5607 -- Expand_Static_Predicates_In_Choices --
5608 -----------------------------------------
5610 procedure Expand_Static_Predicates_In_Choices (N : Node_Id) is
5611 pragma Assert (Nkind (N) in N_Case_Statement_Alternative | N_Variant);
5613 Choices : List_Id := Discrete_Choices (N);
5615 Choice : Node_Id;
5616 Next_C : Node_Id;
5617 P : Node_Id;
5618 C : Node_Id;
5620 begin
5621 -- If this is an "others" alternative, we need to process any static
5622 -- predicates in its Others_Discrete_Choices.
5624 if Nkind (First (Choices)) = N_Others_Choice then
5625 Choices := Others_Discrete_Choices (First (Choices));
5626 end if;
5628 Choice := First (Choices);
5629 while Present (Choice) loop
5630 Next_C := Next (Choice);
5632 -- Check for name of subtype with static predicate
5634 if Is_Entity_Name (Choice)
5635 and then Is_Type (Entity (Choice))
5636 and then Has_Predicates (Entity (Choice))
5637 then
5638 -- Loop through entries in predicate list, converting to choices
5639 -- and inserting in the list before the current choice. Note that
5640 -- if the list is empty, corresponding to a False predicate, then
5641 -- no choices are inserted.
5643 P := First (Static_Discrete_Predicate (Entity (Choice)));
5644 while Present (P) loop
5646 -- If low bound and high bounds are equal, copy simple choice
5648 if Expr_Value (Low_Bound (P)) = Expr_Value (High_Bound (P)) then
5649 C := New_Copy (Low_Bound (P));
5651 -- Otherwise copy a range
5653 else
5654 C := New_Copy (P);
5655 end if;
5657 -- Change Sloc to referencing choice (rather than the Sloc of
5658 -- the predicate declaration element itself).
5660 Set_Sloc (C, Sloc (Choice));
5661 Insert_Before (Choice, C);
5662 Next (P);
5663 end loop;
5665 -- Delete the predicated entry
5667 Remove (Choice);
5668 end if;
5670 -- Move to next choice to check
5672 Choice := Next_C;
5673 end loop;
5675 Set_Has_SP_Choice (N, False);
5676 end Expand_Static_Predicates_In_Choices;
5678 ------------------------------
5679 -- Expand_Subtype_From_Expr --
5680 ------------------------------
5682 -- This function is applicable for both static and dynamic allocation of
5683 -- objects which are constrained by an initial expression. Basically it
5684 -- transforms an unconstrained subtype indication into a constrained one.
5686 -- The expression may also be transformed in certain cases in order to
5687 -- avoid multiple evaluation. In the static allocation case, the general
5688 -- scheme is:
5690 -- Val : T := Expr;
5692 -- is transformed into
5694 -- Val : Constrained_Subtype_Of_T := Maybe_Modified_Expr;
5696 -- Here are the main cases :
5698 -- <if Expr is a Slice>
5699 -- Val : T ([Index_Subtype (Expr)]) := Expr;
5701 -- <elsif Expr is a String Literal>
5702 -- Val : T (T'First .. T'First + Length (string literal) - 1) := Expr;
5704 -- <elsif Expr is Constrained>
5705 -- subtype T is Type_Of_Expr
5706 -- Val : T := Expr;
5708 -- <elsif Expr is an entity_name>
5709 -- Val : T (constraints taken from Expr) := Expr;
5711 -- <else>
5712 -- type Axxx is access all T;
5713 -- Rval : Axxx := Expr'ref;
5714 -- Val : T (constraints taken from Rval) := Rval.all;
5716 -- ??? note: when the Expression is allocated in the secondary stack
5717 -- we could use it directly instead of copying it by declaring
5718 -- Val : T (...) renames Rval.all
5720 procedure Expand_Subtype_From_Expr
5721 (N : Node_Id;
5722 Unc_Type : Entity_Id;
5723 Subtype_Indic : Node_Id;
5724 Exp : Node_Id;
5725 Related_Id : Entity_Id := Empty)
5727 Loc : constant Source_Ptr := Sloc (N);
5728 Exp_Typ : constant Entity_Id := Etype (Exp);
5729 T : Entity_Id;
5731 begin
5732 -- In general we cannot build the subtype if expansion is disabled,
5733 -- because internal entities may not have been defined. However, to
5734 -- avoid some cascaded errors, we try to continue when the expression is
5735 -- an array (or string), because it is safe to compute the bounds. It is
5736 -- in fact required to do so even in a generic context, because there
5737 -- may be constants that depend on the bounds of a string literal, both
5738 -- standard string types and more generally arrays of characters.
5740 -- In GNATprove mode, these extra subtypes are not needed, unless Exp is
5741 -- a static expression. In that case, the subtype will be constrained
5742 -- while the original type might be unconstrained, so expanding the type
5743 -- is necessary both for passing legality checks in GNAT and for precise
5744 -- analysis in GNATprove.
5746 if GNATprove_Mode and then not Is_Static_Expression (Exp) then
5747 return;
5748 end if;
5750 if not Expander_Active
5751 and then (No (Etype (Exp)) or else not Is_String_Type (Etype (Exp)))
5752 then
5753 return;
5754 end if;
5756 if Nkind (Exp) = N_Slice then
5757 declare
5758 Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
5760 begin
5761 Rewrite (Subtype_Indic,
5762 Make_Subtype_Indication (Loc,
5763 Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
5764 Constraint =>
5765 Make_Index_Or_Discriminant_Constraint (Loc,
5766 Constraints => New_List
5767 (New_Occurrence_Of (Slice_Type, Loc)))));
5769 -- This subtype indication may be used later for constraint checks
5770 -- we better make sure that if a variable was used as a bound of
5771 -- the original slice, its value is frozen.
5773 Evaluate_Slice_Bounds (Exp);
5774 end;
5776 elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
5777 Rewrite (Subtype_Indic,
5778 Make_Subtype_Indication (Loc,
5779 Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
5780 Constraint =>
5781 Make_Index_Or_Discriminant_Constraint (Loc,
5782 Constraints => New_List (
5783 Make_Literal_Range (Loc,
5784 Literal_Typ => Exp_Typ)))));
5786 -- If the type of the expression is an internally generated type it
5787 -- may not be necessary to create a new subtype. However there are two
5788 -- exceptions: references to the current instances, and aliased array
5789 -- object declarations for which the back end has to create a template.
5791 elsif Is_Constrained (Exp_Typ)
5792 and then not Is_Class_Wide_Type (Unc_Type)
5793 and then
5794 (Nkind (N) /= N_Object_Declaration
5795 or else not Is_Entity_Name (Expression (N))
5796 or else not Comes_From_Source (Entity (Expression (N)))
5797 or else not Is_Array_Type (Exp_Typ)
5798 or else not Aliased_Present (N))
5799 then
5800 if Is_Itype (Exp_Typ)
5802 -- When this is for an object declaration, the caller may want to
5803 -- set Is_Constr_Subt_For_U_Nominal on the subtype, so we must make
5804 -- sure that either the subtype has been built for the expression,
5805 -- typically for an aggregate, or the flag is already set on it;
5806 -- otherwise it could end up being set on the nominal constrained
5807 -- subtype of an object and thus later cause the failure to detect
5808 -- non-statically-matching subtypes on 'Access of this object.
5810 and then (Nkind (N) /= N_Object_Declaration
5811 or else Nkind (Original_Node (Exp)) = N_Aggregate
5812 or else Is_Constr_Subt_For_U_Nominal (Exp_Typ))
5813 then
5814 -- Within an initialization procedure, a selected component
5815 -- denotes a component of the enclosing record, and it appears as
5816 -- an actual in a call to its own initialization procedure. If
5817 -- this component depends on the outer discriminant, we must
5818 -- generate the proper actual subtype for it.
5820 if Nkind (Exp) = N_Selected_Component
5821 and then Within_Init_Proc
5822 then
5823 declare
5824 Decl : constant Node_Id :=
5825 Build_Actual_Subtype_Of_Component (Exp_Typ, Exp);
5826 begin
5827 if Present (Decl) then
5828 Insert_Action (N, Decl);
5829 T := Defining_Identifier (Decl);
5830 else
5831 T := Exp_Typ;
5832 end if;
5833 end;
5835 -- No need to generate a new subtype
5837 else
5838 T := Exp_Typ;
5839 end if;
5841 else
5842 T := Make_Temporary (Loc, 'T');
5844 Insert_Action (N,
5845 Make_Subtype_Declaration (Loc,
5846 Defining_Identifier => T,
5847 Subtype_Indication => New_Occurrence_Of (Exp_Typ, Loc)));
5849 -- This type is marked as an itype even though it has an explicit
5850 -- declaration since otherwise Is_Generic_Actual_Type can get
5851 -- set, resulting in the generation of spurious errors. (See
5852 -- sem_ch8.Analyze_Package_Renaming and Sem_Type.Covers.)
5854 Set_Is_Itype (T);
5855 Set_Associated_Node_For_Itype (T, Exp);
5856 end if;
5858 Rewrite (Subtype_Indic, New_Occurrence_Of (T, Loc));
5860 -- Nothing needs to be done for private types with unknown discriminants
5861 -- if the underlying type is not an unconstrained composite type or it
5862 -- is an unchecked union.
5864 elsif Is_Private_Type (Unc_Type)
5865 and then Has_Unknown_Discriminants (Unc_Type)
5866 and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
5867 or else Is_Constrained (Underlying_Type (Unc_Type))
5868 or else Is_Unchecked_Union (Underlying_Type (Unc_Type)))
5869 then
5870 null;
5872 -- Case of derived type with unknown discriminants where the parent type
5873 -- also has unknown discriminants.
5875 elsif Is_Record_Type (Unc_Type)
5876 and then not Is_Class_Wide_Type (Unc_Type)
5877 and then Has_Unknown_Discriminants (Unc_Type)
5878 and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type))
5879 then
5880 -- Nothing to be done if no underlying record view available
5882 -- If this is a limited type derived from a type with unknown
5883 -- discriminants, do not expand either, so that subsequent expansion
5884 -- of the call can add build-in-place parameters to call.
5886 if No (Underlying_Record_View (Unc_Type))
5887 or else Is_Limited_Type (Unc_Type)
5888 then
5889 null;
5891 -- Otherwise use the Underlying_Record_View to create the proper
5892 -- constrained subtype for an object of a derived type with unknown
5893 -- discriminants.
5895 else
5896 Rewrite (Subtype_Indic,
5897 Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type)));
5898 end if;
5900 -- Renamings of class-wide interface types require no equivalent
5901 -- constrained type declarations because we only need to reference
5902 -- the tag component associated with the interface. The same is
5903 -- presumably true for class-wide types in general, so this test
5904 -- is broadened to include all class-wide renamings, which also
5905 -- avoids cases of unbounded recursion in Remove_Side_Effects.
5906 -- (Is this really correct, or are there some cases of class-wide
5907 -- renamings that require action in this procedure???)
5909 elsif Present (N)
5910 and then Nkind (N) = N_Object_Renaming_Declaration
5911 and then Is_Class_Wide_Type (Unc_Type)
5912 then
5913 null;
5915 -- In Ada 95 nothing to be done if the type of the expression is limited
5916 -- because in this case the expression cannot be copied, and its use can
5917 -- only be by reference.
5919 -- In Ada 2005 the context can be an object declaration whose expression
5920 -- is a function that returns in place. If the nominal subtype has
5921 -- unknown discriminants, the call still provides constraints on the
5922 -- object, and we have to create an actual subtype from it.
5924 -- If the type is class-wide, the expression is dynamically tagged and
5925 -- we do not create an actual subtype either. Ditto for an interface.
5926 -- For now this applies only if the type is immutably limited, and the
5927 -- function being called is build-in-place. This will have to be revised
5928 -- when build-in-place functions are generalized to other types.
5930 elsif Is_Inherently_Limited_Type (Exp_Typ)
5931 and then
5932 (Is_Class_Wide_Type (Exp_Typ)
5933 or else Is_Interface (Exp_Typ)
5934 or else not Has_Unknown_Discriminants (Exp_Typ)
5935 or else not Is_Composite_Type (Unc_Type))
5936 then
5937 null;
5939 -- For limited objects initialized with build-in-place function calls,
5940 -- nothing to be done; otherwise we prematurely introduce an N_Reference
5941 -- node in the expression initializing the object, which breaks the
5942 -- circuitry that detects and adds the additional arguments to the
5943 -- called function.
5945 elsif Is_Build_In_Place_Function_Call (Exp) then
5946 null;
5948 -- If the expression is an uninitialized aggregate, no need to build
5949 -- a subtype from the expression, because this may require the use of
5950 -- dynamic memory to create the object.
5952 elsif Is_Uninitialized_Aggregate (Exp, Exp_Typ) then
5953 Rewrite (Subtype_Indic, New_Occurrence_Of (Etype (Exp), Sloc (N)));
5954 if Nkind (N) = N_Object_Declaration then
5955 Set_Expression (N, Empty);
5956 Set_No_Initialization (N);
5957 end if;
5959 else
5960 Rewrite (Subtype_Indic,
5961 Make_Subtype_From_Expr (Exp, Unc_Type, Related_Id));
5962 end if;
5963 end Expand_Subtype_From_Expr;
5965 ---------------------------------------------
5966 -- Expression_Contains_Primitives_Calls_Of --
5967 ---------------------------------------------
5969 function Expression_Contains_Primitives_Calls_Of
5970 (Expr : Node_Id;
5971 Typ : Entity_Id) return Boolean
5973 U_Typ : constant Entity_Id := Unique_Entity (Typ);
5975 Calls_OK : Boolean := False;
5976 -- This flag is set to True when expression Expr contains at least one
5977 -- call to a nondispatching primitive function of Typ.
5979 function Search_Primitive_Calls (N : Node_Id) return Traverse_Result;
5980 -- Search for nondispatching calls to primitive functions of type Typ
5982 ----------------------------
5983 -- Search_Primitive_Calls --
5984 ----------------------------
5986 function Search_Primitive_Calls (N : Node_Id) return Traverse_Result is
5987 Disp_Typ : Entity_Id;
5988 Subp : Entity_Id;
5990 begin
5991 -- Detect a function call that could denote a nondispatching
5992 -- primitive of the input type.
5994 if Nkind (N) = N_Function_Call
5995 and then Is_Entity_Name (Name (N))
5996 then
5997 Subp := Entity (Name (N));
5999 -- Do not consider function calls with a controlling argument, as
6000 -- those are always dispatching calls.
6002 if Is_Dispatching_Operation (Subp)
6003 and then No (Controlling_Argument (N))
6004 then
6005 Disp_Typ := Find_Dispatching_Type (Subp);
6007 -- To qualify as a suitable primitive, the dispatching type of
6008 -- the function must be the input type.
6010 if Present (Disp_Typ)
6011 and then Unique_Entity (Disp_Typ) = U_Typ
6012 then
6013 Calls_OK := True;
6015 -- There is no need to continue the traversal, as one such
6016 -- call suffices.
6018 return Abandon;
6019 end if;
6020 end if;
6021 end if;
6023 return OK;
6024 end Search_Primitive_Calls;
6026 procedure Search_Calls is new Traverse_Proc (Search_Primitive_Calls);
6028 -- Start of processing for Expression_Contains_Primitives_Calls_Of_Type
6030 begin
6031 Search_Calls (Expr);
6032 return Calls_OK;
6033 end Expression_Contains_Primitives_Calls_Of;
6035 ----------------------
6036 -- Finalize_Address --
6037 ----------------------
6039 function Finalize_Address (Typ : Entity_Id) return Entity_Id is
6040 Btyp : constant Entity_Id := Base_Type (Typ);
6041 Utyp : Entity_Id := Typ;
6043 begin
6044 -- Handle protected class-wide or task class-wide types
6046 if Is_Class_Wide_Type (Utyp) then
6047 if Is_Concurrent_Type (Root_Type (Utyp)) then
6048 Utyp := Root_Type (Utyp);
6050 elsif Is_Private_Type (Root_Type (Utyp))
6051 and then Present (Full_View (Root_Type (Utyp)))
6052 and then Is_Concurrent_Type (Full_View (Root_Type (Utyp)))
6053 then
6054 Utyp := Full_View (Root_Type (Utyp));
6055 end if;
6056 end if;
6058 -- Handle private types
6060 if Is_Private_Type (Utyp) and then Present (Full_View (Utyp)) then
6061 Utyp := Full_View (Utyp);
6062 end if;
6064 -- Handle protected and task types
6066 if Is_Concurrent_Type (Utyp)
6067 and then Present (Corresponding_Record_Type (Utyp))
6068 then
6069 Utyp := Corresponding_Record_Type (Utyp);
6070 end if;
6072 Utyp := Underlying_Type (Base_Type (Utyp));
6074 -- Deal with untagged derivation of private views. If the parent is
6075 -- now known to be protected, the finalization routine is the one
6076 -- defined on the corresponding record of the ancestor (corresponding
6077 -- records do not automatically inherit operations, but maybe they
6078 -- should???)
6080 if Is_Untagged_Derivation (Btyp) then
6081 if Is_Protected_Type (Btyp) then
6082 Utyp := Corresponding_Record_Type (Root_Type (Btyp));
6084 else
6085 Utyp := Underlying_Type (Root_Type (Btyp));
6087 if Is_Protected_Type (Utyp) then
6088 Utyp := Corresponding_Record_Type (Utyp);
6089 end if;
6090 end if;
6091 end if;
6093 -- If the underlying_type is a subtype, we are dealing with the
6094 -- completion of a private type. We need to access the base type and
6095 -- generate a conversion to it.
6097 if Utyp /= Base_Type (Utyp) then
6098 pragma Assert (Is_Private_Type (Typ));
6100 Utyp := Base_Type (Utyp);
6101 end if;
6103 -- When dealing with an internally built full view for a type with
6104 -- unknown discriminants, use the original record type.
6106 if Is_Underlying_Record_View (Utyp) then
6107 Utyp := Etype (Utyp);
6108 end if;
6110 return TSS (Utyp, TSS_Finalize_Address);
6111 end Finalize_Address;
6113 ------------------------
6114 -- Find_Interface_ADT --
6115 ------------------------
6117 function Find_Interface_ADT
6118 (T : Entity_Id;
6119 Iface : Entity_Id) return Elmt_Id
6121 ADT : Elmt_Id;
6122 Typ : Entity_Id := T;
6124 begin
6125 pragma Assert (Is_Interface (Iface));
6127 -- Handle private types
6129 if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
6130 Typ := Full_View (Typ);
6131 end if;
6133 -- Handle access types
6135 if Is_Access_Type (Typ) then
6136 Typ := Designated_Type (Typ);
6137 end if;
6139 -- Handle task and protected types implementing interfaces
6141 if Is_Concurrent_Type (Typ) then
6142 Typ := Corresponding_Record_Type (Typ);
6143 end if;
6145 pragma Assert
6146 (not Is_Class_Wide_Type (Typ)
6147 and then Ekind (Typ) /= E_Incomplete_Type);
6149 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
6150 return First_Elmt (Access_Disp_Table (Typ));
6152 else
6153 ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
6154 while Present (ADT)
6155 and then Present (Related_Type (Node (ADT)))
6156 and then Related_Type (Node (ADT)) /= Iface
6157 and then not Is_Ancestor (Iface, Related_Type (Node (ADT)),
6158 Use_Full_View => True)
6159 loop
6160 Next_Elmt (ADT);
6161 end loop;
6163 pragma Assert (Present (Related_Type (Node (ADT))));
6164 return ADT;
6165 end if;
6166 end Find_Interface_ADT;
6168 ------------------------
6169 -- Find_Interface_Tag --
6170 ------------------------
6172 function Find_Interface_Tag
6173 (T : Entity_Id;
6174 Iface : Entity_Id) return Entity_Id
6176 AI_Tag : Entity_Id := Empty;
6177 Found : Boolean := False;
6178 Typ : Entity_Id := T;
6180 procedure Find_Tag (Typ : Entity_Id);
6181 -- Internal subprogram used to recursively climb to the ancestors
6183 --------------
6184 -- Find_Tag --
6185 --------------
6187 procedure Find_Tag (Typ : Entity_Id) is
6188 AI_Elmt : Elmt_Id;
6189 AI : Node_Id;
6191 begin
6192 -- This routine does not handle the case in which the interface is an
6193 -- ancestor of Typ. That case is handled by the enclosing subprogram.
6195 pragma Assert (Typ /= Iface);
6197 -- Climb to the root type handling private types
6199 if Present (Full_View (Etype (Typ))) then
6200 if Full_View (Etype (Typ)) /= Typ then
6201 Find_Tag (Full_View (Etype (Typ)));
6202 end if;
6204 elsif Etype (Typ) /= Typ then
6205 Find_Tag (Etype (Typ));
6206 end if;
6208 -- Traverse the list of interfaces implemented by the type
6210 if not Found
6211 and then Present (Interfaces (Typ))
6212 and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
6213 then
6214 -- Skip the tag associated with the primary table
6216 AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
6217 pragma Assert (Present (AI_Tag));
6219 AI_Elmt := First_Elmt (Interfaces (Typ));
6220 while Present (AI_Elmt) loop
6221 AI := Node (AI_Elmt);
6223 if AI = Iface
6224 or else Is_Ancestor (Iface, AI, Use_Full_View => True)
6225 then
6226 Found := True;
6227 return;
6228 end if;
6230 AI_Tag := Next_Tag_Component (AI_Tag);
6231 Next_Elmt (AI_Elmt);
6232 end loop;
6233 end if;
6234 end Find_Tag;
6236 -- Start of processing for Find_Interface_Tag
6238 begin
6239 pragma Assert (Is_Interface (Iface));
6241 -- Handle access types
6243 if Is_Access_Type (Typ) then
6244 Typ := Designated_Type (Typ);
6245 end if;
6247 -- Handle class-wide types
6249 if Is_Class_Wide_Type (Typ) then
6250 Typ := Root_Type (Typ);
6251 end if;
6253 -- Handle private types
6255 if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
6256 Typ := Full_View (Typ);
6257 end if;
6259 -- Handle entities from the limited view
6261 if Ekind (Typ) = E_Incomplete_Type then
6262 pragma Assert (Present (Non_Limited_View (Typ)));
6263 Typ := Non_Limited_View (Typ);
6264 end if;
6266 -- Handle task and protected types implementing interfaces
6268 if Is_Concurrent_Type (Typ) then
6269 Typ := Corresponding_Record_Type (Typ);
6270 end if;
6272 -- If the interface is an ancestor of the type, then it shared the
6273 -- primary dispatch table.
6275 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
6276 return First_Tag_Component (Typ);
6278 -- Otherwise we need to search for its associated tag component
6280 else
6281 Find_Tag (Typ);
6282 return AI_Tag;
6283 end if;
6284 end Find_Interface_Tag;
6286 ---------------------------
6287 -- Find_Optional_Prim_Op --
6288 ---------------------------
6290 function Find_Optional_Prim_Op
6291 (T : Entity_Id; Name : Name_Id) return Entity_Id
6293 Prim : Elmt_Id;
6294 Typ : Entity_Id := T;
6295 Op : Entity_Id;
6297 begin
6298 if Is_Class_Wide_Type (Typ) then
6299 Typ := Root_Type (Typ);
6300 end if;
6302 Typ := Underlying_Type (Typ);
6304 -- We cannot find the operation if there is no full view available
6306 if No (Typ) then
6307 return Empty;
6308 end if;
6310 -- Loop through primitive operations
6312 Prim := First_Elmt (Primitive_Operations (Typ));
6313 while Present (Prim) loop
6314 Op := Node (Prim);
6316 -- We can retrieve primitive operations by name if it is an internal
6317 -- name. For equality we must check that both of its operands have
6318 -- the same type, to avoid confusion with user-defined equalities
6319 -- than may have a asymmetric signature.
6321 exit when Chars (Op) = Name
6322 and then
6323 (Name /= Name_Op_Eq
6324 or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op)));
6326 Next_Elmt (Prim);
6327 end loop;
6329 return Node (Prim); -- Empty if not found
6330 end Find_Optional_Prim_Op;
6332 ---------------------------
6333 -- Find_Optional_Prim_Op --
6334 ---------------------------
6336 function Find_Optional_Prim_Op
6337 (T : Entity_Id;
6338 Name : TSS_Name_Type) return Entity_Id
6340 Inher_Op : Entity_Id := Empty;
6341 Own_Op : Entity_Id := Empty;
6342 Prim_Elmt : Elmt_Id;
6343 Prim_Id : Entity_Id;
6344 Typ : Entity_Id := T;
6346 begin
6347 if Is_Class_Wide_Type (Typ) then
6348 Typ := Root_Type (Typ);
6349 end if;
6351 Typ := Underlying_Type (Typ);
6353 -- This search is based on the assertion that the dispatching version
6354 -- of the TSS routine always precedes the real primitive.
6356 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6357 while Present (Prim_Elmt) loop
6358 Prim_Id := Node (Prim_Elmt);
6360 if Is_TSS (Prim_Id, Name) then
6361 if Present (Alias (Prim_Id)) then
6362 Inher_Op := Prim_Id;
6363 else
6364 Own_Op := Prim_Id;
6365 end if;
6366 end if;
6368 Next_Elmt (Prim_Elmt);
6369 end loop;
6371 if Present (Own_Op) then
6372 return Own_Op;
6373 elsif Present (Inher_Op) then
6374 return Inher_Op;
6375 else
6376 return Empty;
6377 end if;
6378 end Find_Optional_Prim_Op;
6380 ------------------
6381 -- Find_Prim_Op --
6382 ------------------
6384 function Find_Prim_Op
6385 (T : Entity_Id; Name : Name_Id) return Entity_Id
6387 Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
6388 begin
6389 if No (Result) then
6390 raise Program_Error;
6391 end if;
6393 return Result;
6394 end Find_Prim_Op;
6396 ------------------
6397 -- Find_Prim_Op --
6398 ------------------
6400 function Find_Prim_Op
6401 (T : Entity_Id;
6402 Name : TSS_Name_Type) return Entity_Id
6404 Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
6405 begin
6406 if No (Result) then
6407 raise Program_Error;
6408 end if;
6410 return Result;
6411 end Find_Prim_Op;
6413 ----------------------------
6414 -- Find_Protection_Object --
6415 ----------------------------
6417 function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
6418 S : Entity_Id;
6420 begin
6421 S := Scop;
6422 while Present (S) loop
6423 if Ekind (S) in E_Entry | E_Entry_Family | E_Function | E_Procedure
6424 and then Present (Protection_Object (S))
6425 then
6426 return Protection_Object (S);
6427 end if;
6429 S := Scope (S);
6430 end loop;
6432 -- If we do not find a Protection object in the scope chain, then
6433 -- something has gone wrong, most likely the object was never created.
6435 raise Program_Error;
6436 end Find_Protection_Object;
6438 --------------------------
6439 -- Find_Protection_Type --
6440 --------------------------
6442 function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is
6443 Comp : Entity_Id;
6444 Typ : Entity_Id := Conc_Typ;
6446 begin
6447 if Is_Concurrent_Type (Typ) then
6448 Typ := Corresponding_Record_Type (Typ);
6449 end if;
6451 -- Since restriction violations are not considered serious errors, the
6452 -- expander remains active, but may leave the corresponding record type
6453 -- malformed. In such cases, component _object is not available so do
6454 -- not look for it.
6456 if not Analyzed (Typ) then
6457 return Empty;
6458 end if;
6460 Comp := First_Component (Typ);
6461 while Present (Comp) loop
6462 if Chars (Comp) = Name_uObject then
6463 return Base_Type (Etype (Comp));
6464 end if;
6466 Next_Component (Comp);
6467 end loop;
6469 -- The corresponding record of a protected type should always have an
6470 -- _object field.
6472 raise Program_Error;
6473 end Find_Protection_Type;
6475 function Find_Storage_Op
6476 (Typ : Entity_Id;
6477 Nam : Name_Id) return Entity_Id
6479 use Sem_Util.Storage_Model_Support;
6481 begin
6482 if Has_Storage_Model_Type_Aspect (Typ) then
6483 return Get_Storage_Model_Type_Entity (Typ, Nam);
6485 -- Otherwise we assume that Typ is a descendant of Root_Storage_Pool
6487 else
6488 return Find_Prim_Op (Typ, Nam);
6489 end if;
6490 end Find_Storage_Op;
6492 -----------------------
6493 -- Find_Hook_Context --
6494 -----------------------
6496 function Find_Hook_Context (N : Node_Id) return Node_Id is
6497 Par : Node_Id;
6498 Top : Node_Id;
6500 Wrapped_Node : Node_Id;
6501 -- Note: if we are in a transient scope, we want to reuse it as
6502 -- the context for actions insertion, if possible. But if N is itself
6503 -- part of the stored actions for the current transient scope,
6504 -- then we need to insert at the appropriate (inner) location in
6505 -- the not as an action on Node_To_Be_Wrapped.
6507 In_Cond_Expr : constant Boolean := Within_Case_Or_If_Expression (N);
6509 begin
6510 -- When the node is inside a case/if expression, the lifetime of any
6511 -- temporary controlled object is extended. Find a suitable insertion
6512 -- node by locating the topmost case or if expressions.
6514 if In_Cond_Expr then
6515 Par := N;
6516 Top := N;
6517 while Present (Par) loop
6518 if Nkind (Original_Node (Par)) in
6519 N_Case_Expression | N_If_Expression
6520 then
6521 Top := Par;
6523 -- Prevent the search from going too far
6525 elsif Is_Body_Or_Package_Declaration (Par) then
6526 exit;
6527 end if;
6529 Par := Parent (Par);
6530 end loop;
6532 -- The topmost case or if expression is now recovered, but it may
6533 -- still not be the correct place to add generated code. Climb to
6534 -- find a parent that is part of a declarative or statement list,
6535 -- and is not a list of actuals in a call.
6537 Par := Top;
6538 while Present (Par) loop
6539 if Is_List_Member (Par)
6540 and then Nkind (Par) not in N_Component_Association
6541 | N_Discriminant_Association
6542 | N_Parameter_Association
6543 | N_Pragma_Argument_Association
6544 | N_Aggregate
6545 | N_Delta_Aggregate
6546 | N_Extension_Aggregate
6547 and then Nkind (Parent (Par)) not in N_Function_Call
6548 | N_Procedure_Call_Statement
6549 | N_Entry_Call_Statement
6551 then
6552 return Par;
6554 -- Prevent the search from going too far
6556 elsif Is_Body_Or_Package_Declaration (Par) then
6557 exit;
6558 end if;
6560 Par := Parent (Par);
6561 end loop;
6563 return Par;
6565 else
6566 Par := N;
6567 while Present (Par) loop
6569 -- Keep climbing past various operators
6571 if Nkind (Parent (Par)) in N_Op
6572 or else Nkind (Parent (Par)) in N_And_Then | N_Or_Else
6573 then
6574 Par := Parent (Par);
6575 else
6576 exit;
6577 end if;
6578 end loop;
6580 Top := Par;
6582 -- The node may be located in a pragma in which case return the
6583 -- pragma itself:
6585 -- pragma Precondition (... and then Ctrl_Func_Call ...);
6587 -- Similar case occurs when the node is related to an object
6588 -- declaration or assignment:
6590 -- Obj [: Some_Typ] := ... and then Ctrl_Func_Call ...;
6592 -- Another case to consider is when the node is part of a return
6593 -- statement:
6595 -- return ... and then Ctrl_Func_Call ...;
6597 -- Another case is when the node acts as a formal in a procedure
6598 -- call statement:
6600 -- Proc (... and then Ctrl_Func_Call ...);
6602 if Scope_Is_Transient then
6603 Wrapped_Node := Node_To_Be_Wrapped;
6604 else
6605 Wrapped_Node := Empty;
6606 end if;
6608 while Present (Par) loop
6609 if Par = Wrapped_Node
6610 or else Nkind (Par) in N_Assignment_Statement
6611 | N_Object_Declaration
6612 | N_Pragma
6613 | N_Procedure_Call_Statement
6614 | N_Simple_Return_Statement
6615 then
6616 return Par;
6618 -- Prevent the search from going too far
6620 elsif Is_Body_Or_Package_Declaration (Par) then
6621 exit;
6622 end if;
6624 Par := Parent (Par);
6625 end loop;
6627 -- Return the topmost short circuit operator
6629 return Top;
6630 end if;
6631 end Find_Hook_Context;
6633 ------------------------------
6634 -- Following_Address_Clause --
6635 ------------------------------
6637 function Following_Address_Clause (D : Node_Id) return Node_Id is
6638 Id : constant Entity_Id := Defining_Identifier (D);
6639 Result : Node_Id;
6640 Par : Node_Id;
6642 function Check_Decls (D : Node_Id) return Node_Id;
6643 -- This internal function differs from the main function in that it
6644 -- gets called to deal with a following package private part, and
6645 -- it checks declarations starting with D (the main function checks
6646 -- declarations following D). If D is Empty, then Empty is returned.
6648 -----------------
6649 -- Check_Decls --
6650 -----------------
6652 function Check_Decls (D : Node_Id) return Node_Id is
6653 Decl : Node_Id;
6655 begin
6656 Decl := D;
6657 while Present (Decl) loop
6658 if Nkind (Decl) = N_At_Clause
6659 and then Chars (Identifier (Decl)) = Chars (Id)
6660 then
6661 return Decl;
6663 elsif Nkind (Decl) = N_Attribute_Definition_Clause
6664 and then Chars (Decl) = Name_Address
6665 and then Chars (Name (Decl)) = Chars (Id)
6666 then
6667 return Decl;
6668 end if;
6670 Next (Decl);
6671 end loop;
6673 -- Otherwise not found, return Empty
6675 return Empty;
6676 end Check_Decls;
6678 -- Start of processing for Following_Address_Clause
6680 begin
6681 -- If parser detected no address clause for the identifier in question,
6682 -- then the answer is a quick NO, without the need for a search.
6684 if not Get_Name_Table_Boolean1 (Chars (Id)) then
6685 return Empty;
6686 end if;
6688 -- Otherwise search current declarative unit
6690 Result := Check_Decls (Next (D));
6692 if Present (Result) then
6693 return Result;
6694 end if;
6696 -- Check for possible package private part following
6698 Par := Parent (D);
6700 if Nkind (Par) = N_Package_Specification
6701 and then Visible_Declarations (Par) = List_Containing (D)
6702 and then Present (Private_Declarations (Par))
6703 then
6704 -- Private part present, check declarations there
6706 return Check_Decls (First (Private_Declarations (Par)));
6708 else
6709 -- No private part, clause not found, return Empty
6711 return Empty;
6712 end if;
6713 end Following_Address_Clause;
6715 ----------------------
6716 -- Force_Evaluation --
6717 ----------------------
6719 procedure Force_Evaluation
6720 (Exp : Node_Id;
6721 Name_Req : Boolean := False;
6722 Related_Id : Entity_Id := Empty;
6723 Is_Low_Bound : Boolean := False;
6724 Is_High_Bound : Boolean := False;
6725 Discr_Number : Int := 0;
6726 Mode : Force_Evaluation_Mode := Relaxed)
6728 begin
6729 Remove_Side_Effects
6730 (Exp => Exp,
6731 Name_Req => Name_Req,
6732 Variable_Ref => True,
6733 Renaming_Req => False,
6734 Related_Id => Related_Id,
6735 Is_Low_Bound => Is_Low_Bound,
6736 Is_High_Bound => Is_High_Bound,
6737 Discr_Number => Discr_Number,
6738 Check_Side_Effects =>
6739 Is_Static_Expression (Exp)
6740 or else Mode = Relaxed);
6741 end Force_Evaluation;
6743 ---------------------------------
6744 -- Fully_Qualified_Name_String --
6745 ---------------------------------
6747 function Fully_Qualified_Name_String
6748 (E : Entity_Id;
6749 Append_NUL : Boolean := True) return String_Id
6751 procedure Internal_Full_Qualified_Name (E : Entity_Id);
6752 -- Compute recursively the qualified name without NUL at the end, adding
6753 -- it to the currently started string being generated
6755 ----------------------------------
6756 -- Internal_Full_Qualified_Name --
6757 ----------------------------------
6759 procedure Internal_Full_Qualified_Name (E : Entity_Id) is
6760 Ent : Entity_Id;
6762 begin
6763 -- Deal properly with child units
6765 if Nkind (E) = N_Defining_Program_Unit_Name then
6766 Ent := Defining_Identifier (E);
6767 else
6768 Ent := E;
6769 end if;
6771 -- Compute qualification recursively (only "Standard" has no scope)
6773 if Present (Scope (Scope (Ent))) then
6774 Internal_Full_Qualified_Name (Scope (Ent));
6775 Store_String_Char (Get_Char_Code ('.'));
6776 end if;
6778 -- Every entity should have a name except some expanded blocks
6779 -- don't bother about those.
6781 if Chars (Ent) = No_Name then
6782 return;
6783 end if;
6785 -- Generates the entity name in upper case
6787 Get_Decoded_Name_String (Chars (Ent));
6788 Set_Casing (All_Upper_Case);
6789 Store_String_Chars (Name_Buffer (1 .. Name_Len));
6790 return;
6791 end Internal_Full_Qualified_Name;
6793 -- Start of processing for Full_Qualified_Name
6795 begin
6796 Start_String;
6797 Internal_Full_Qualified_Name (E);
6799 if Append_NUL then
6800 Store_String_Char (Get_Char_Code (ASCII.NUL));
6801 end if;
6803 return End_String;
6804 end Fully_Qualified_Name_String;
6806 ---------------------------------
6807 -- Get_Current_Value_Condition --
6808 ---------------------------------
6810 -- Note: the implementation of this procedure is very closely tied to the
6811 -- implementation of Set_Current_Value_Condition. In the Get procedure, we
6812 -- interpret Current_Value fields set by the Set procedure, so the two
6813 -- procedures need to be closely coordinated.
6815 procedure Get_Current_Value_Condition
6816 (Var : Node_Id;
6817 Op : out Node_Kind;
6818 Val : out Node_Id)
6820 Loc : constant Source_Ptr := Sloc (Var);
6821 Ent : constant Entity_Id := Entity (Var);
6823 procedure Process_Current_Value_Condition (N : Node_Id; S : Boolean);
6824 -- N is an expression which holds either True (S = True) or False (S =
6825 -- False) in the condition. This procedure digs out the expression and
6826 -- if it refers to Ent, sets Op and Val appropriately.
6828 -------------------------------------
6829 -- Process_Current_Value_Condition --
6830 -------------------------------------
6832 procedure Process_Current_Value_Condition
6833 (N : Node_Id;
6834 S : Boolean)
6836 Cond : Node_Id;
6837 Prev_Cond : Node_Id;
6838 Sens : Boolean;
6840 begin
6841 Cond := N;
6842 Sens := S;
6844 loop
6845 Prev_Cond := Cond;
6847 -- Deal with NOT operators, inverting sense
6849 while Nkind (Cond) = N_Op_Not loop
6850 Cond := Right_Opnd (Cond);
6851 Sens := not Sens;
6852 end loop;
6854 -- Deal with conversions, qualifications, and expressions with
6855 -- actions.
6857 while Nkind (Cond) in N_Type_Conversion
6858 | N_Qualified_Expression
6859 | N_Expression_With_Actions
6860 loop
6861 Cond := Expression (Cond);
6862 end loop;
6864 exit when Cond = Prev_Cond;
6865 end loop;
6867 -- Deal with AND THEN and AND cases
6869 if Nkind (Cond) in N_And_Then | N_Op_And then
6871 -- Don't ever try to invert a condition that is of the form of an
6872 -- AND or AND THEN (since we are not doing sufficiently general
6873 -- processing to allow this).
6875 if Sens = False then
6876 Op := N_Empty;
6877 Val := Empty;
6878 return;
6879 end if;
6881 -- Recursively process AND and AND THEN branches
6883 Process_Current_Value_Condition (Left_Opnd (Cond), True);
6884 pragma Assert (Op'Valid);
6886 if Op /= N_Empty then
6887 return;
6888 end if;
6890 Process_Current_Value_Condition (Right_Opnd (Cond), True);
6891 return;
6893 -- Case of relational operator
6895 elsif Nkind (Cond) in N_Op_Compare then
6896 Op := Nkind (Cond);
6898 -- Invert sense of test if inverted test
6900 if Sens = False then
6901 case Op is
6902 when N_Op_Eq => Op := N_Op_Ne;
6903 when N_Op_Ne => Op := N_Op_Eq;
6904 when N_Op_Lt => Op := N_Op_Ge;
6905 when N_Op_Gt => Op := N_Op_Le;
6906 when N_Op_Le => Op := N_Op_Gt;
6907 when N_Op_Ge => Op := N_Op_Lt;
6908 when others => raise Program_Error;
6909 end case;
6910 end if;
6912 -- Case of entity op value
6914 if Is_Entity_Name (Left_Opnd (Cond))
6915 and then Ent = Entity (Left_Opnd (Cond))
6916 and then Compile_Time_Known_Value (Right_Opnd (Cond))
6917 then
6918 Val := Right_Opnd (Cond);
6920 -- Case of value op entity
6922 elsif Is_Entity_Name (Right_Opnd (Cond))
6923 and then Ent = Entity (Right_Opnd (Cond))
6924 and then Compile_Time_Known_Value (Left_Opnd (Cond))
6925 then
6926 Val := Left_Opnd (Cond);
6928 -- We are effectively swapping operands
6930 case Op is
6931 when N_Op_Eq => null;
6932 when N_Op_Ne => null;
6933 when N_Op_Lt => Op := N_Op_Gt;
6934 when N_Op_Gt => Op := N_Op_Lt;
6935 when N_Op_Le => Op := N_Op_Ge;
6936 when N_Op_Ge => Op := N_Op_Le;
6937 when others => raise Program_Error;
6938 end case;
6940 else
6941 Op := N_Empty;
6942 end if;
6944 return;
6946 elsif Nkind (Cond) in N_Type_Conversion
6947 | N_Qualified_Expression
6948 | N_Expression_With_Actions
6949 then
6950 Cond := Expression (Cond);
6952 -- Case of Boolean variable reference, return as though the
6953 -- reference had said var = True.
6955 else
6956 if Is_Entity_Name (Cond) and then Ent = Entity (Cond) then
6957 Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
6959 if Sens = False then
6960 Op := N_Op_Ne;
6961 else
6962 Op := N_Op_Eq;
6963 end if;
6964 end if;
6965 end if;
6966 end Process_Current_Value_Condition;
6968 -- Start of processing for Get_Current_Value_Condition
6970 begin
6971 Op := N_Empty;
6972 Val := Empty;
6974 -- Immediate return, nothing doing, if this is not an object
6976 if not Is_Object (Ent) then
6977 return;
6978 end if;
6980 -- In GNATprove mode we don't want to use current value optimizer, in
6981 -- particular for loop invariant expressions and other assertions that
6982 -- act as cut points for proof. The optimizer often folds expressions
6983 -- into True/False where they trivially follow from the previous
6984 -- assignments, but this deprives proof from the information needed to
6985 -- discharge checks that are beyond the scope of the value optimizer.
6987 if GNATprove_Mode then
6988 return;
6989 end if;
6991 -- Otherwise examine current value
6993 declare
6994 CV : constant Node_Id := Current_Value (Ent);
6995 Sens : Boolean;
6996 Stm : Node_Id;
6998 begin
6999 -- If statement. Condition is known true in THEN section, known False
7000 -- in any ELSIF or ELSE part, and unknown outside the IF statement.
7002 if Nkind (CV) = N_If_Statement then
7004 -- Before start of IF statement
7006 if Loc < Sloc (CV) then
7007 return;
7009 -- In condition of IF statement
7011 elsif In_Subtree (N => Var, Root => Condition (CV)) then
7012 return;
7014 -- After end of IF statement
7016 elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
7017 return;
7018 end if;
7020 -- At this stage we know that we are within the IF statement, but
7021 -- unfortunately, the tree does not record the SLOC of the ELSE so
7022 -- we cannot use a simple SLOC comparison to distinguish between
7023 -- the then/else statements, so we have to climb the tree.
7025 declare
7026 N : Node_Id;
7028 begin
7029 N := Parent (Var);
7030 while Parent (N) /= CV loop
7031 N := Parent (N);
7033 -- If we fall off the top of the tree, then that's odd, but
7034 -- perhaps it could occur in some error situation, and the
7035 -- safest response is simply to assume that the outcome of
7036 -- the condition is unknown. No point in bombing during an
7037 -- attempt to optimize things.
7039 if No (N) then
7040 return;
7041 end if;
7042 end loop;
7044 -- Now we have N pointing to a node whose parent is the IF
7045 -- statement in question, so now we can tell if we are within
7046 -- the THEN statements.
7048 if Is_List_Member (N)
7049 and then List_Containing (N) = Then_Statements (CV)
7050 then
7051 Sens := True;
7053 -- If the variable reference does not come from source, we
7054 -- cannot reliably tell whether it appears in the else part.
7055 -- In particular, if it appears in generated code for a node
7056 -- that requires finalization, it may be attached to a list
7057 -- that has not been yet inserted into the code. For now,
7058 -- treat it as unknown.
7060 elsif not Comes_From_Source (N) then
7061 return;
7063 -- Otherwise we must be in ELSIF or ELSE part
7065 else
7066 Sens := False;
7067 end if;
7068 end;
7070 -- ELSIF part. Condition is known true within the referenced
7071 -- ELSIF, known False in any subsequent ELSIF or ELSE part,
7072 -- and unknown before the ELSE part or after the IF statement.
7074 elsif Nkind (CV) = N_Elsif_Part then
7076 -- if the Elsif_Part had condition_actions, the elsif has been
7077 -- rewritten as a nested if, and the original elsif_part is
7078 -- detached from the tree, so there is no way to obtain useful
7079 -- information on the current value of the variable.
7080 -- Can this be improved ???
7082 if No (Parent (CV)) then
7083 return;
7084 end if;
7086 Stm := Parent (CV);
7088 -- If the tree has been otherwise rewritten there is nothing
7089 -- else to be done either.
7091 if Nkind (Stm) /= N_If_Statement then
7092 return;
7093 end if;
7095 -- Before start of ELSIF part
7097 if Loc < Sloc (CV) then
7098 return;
7100 -- In condition of ELSIF part
7102 elsif In_Subtree (N => Var, Root => Condition (CV)) then
7103 return;
7105 -- After end of IF statement
7107 elsif Loc >= Sloc (Stm) +
7108 Text_Ptr (UI_To_Int (End_Span (Stm)))
7109 then
7110 return;
7111 end if;
7113 -- Again we lack the SLOC of the ELSE, so we need to climb the
7114 -- tree to see if we are within the ELSIF part in question.
7116 declare
7117 N : Node_Id;
7119 begin
7120 N := Parent (Var);
7121 while Parent (N) /= Stm loop
7122 N := Parent (N);
7124 -- If we fall off the top of the tree, then that's odd, but
7125 -- perhaps it could occur in some error situation, and the
7126 -- safest response is simply to assume that the outcome of
7127 -- the condition is unknown. No point in bombing during an
7128 -- attempt to optimize things.
7130 if No (N) then
7131 return;
7132 end if;
7133 end loop;
7135 -- Now we have N pointing to a node whose parent is the IF
7136 -- statement in question, so see if is the ELSIF part we want.
7137 -- the THEN statements.
7139 if N = CV then
7140 Sens := True;
7142 -- Otherwise we must be in subsequent ELSIF or ELSE part
7144 else
7145 Sens := False;
7146 end if;
7147 end;
7149 -- Iteration scheme of while loop. The condition is known to be
7150 -- true within the body of the loop.
7152 elsif Nkind (CV) = N_Iteration_Scheme then
7153 declare
7154 Loop_Stmt : constant Node_Id := Parent (CV);
7156 begin
7157 -- Before start of body of loop
7159 if Loc < Sloc (Loop_Stmt) then
7160 return;
7162 -- In condition of while loop
7164 elsif In_Subtree (N => Var, Root => Condition (CV)) then
7165 return;
7167 -- After end of LOOP statement
7169 elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
7170 return;
7172 -- We are within the body of the loop
7174 else
7175 Sens := True;
7176 end if;
7177 end;
7179 -- All other cases of Current_Value settings
7181 else
7182 return;
7183 end if;
7185 -- If we fall through here, then we have a reportable condition, Sens
7186 -- is True if the condition is true and False if it needs inverting.
7188 Process_Current_Value_Condition (Condition (CV), Sens);
7189 end;
7190 end Get_Current_Value_Condition;
7192 -----------------------
7193 -- Get_Index_Subtype --
7194 -----------------------
7196 function Get_Index_Subtype (N : Node_Id) return Entity_Id is
7197 P_Type : Entity_Id := Etype (Prefix (N));
7198 Indx : Node_Id;
7199 J : Int;
7201 begin
7202 if Is_Access_Type (P_Type) then
7203 P_Type := Designated_Type (P_Type);
7204 end if;
7206 if No (Expressions (N)) then
7207 J := 1;
7208 else
7209 J := UI_To_Int (Expr_Value (First (Expressions (N))));
7210 end if;
7212 Indx := First_Index (P_Type);
7213 while J > 1 loop
7214 Next_Index (Indx);
7215 J := J - 1;
7216 end loop;
7218 return Etype (Indx);
7219 end Get_Index_Subtype;
7221 -----------------------
7222 -- Get_Mapped_Entity --
7223 -----------------------
7225 function Get_Mapped_Entity (E : Entity_Id) return Entity_Id is
7226 begin
7227 return Type_Map.Get (E);
7228 end Get_Mapped_Entity;
7230 ---------------------
7231 -- Get_Stream_Size --
7232 ---------------------
7234 function Get_Stream_Size (E : Entity_Id) return Uint is
7235 begin
7236 -- If we have a Stream_Size clause for this type use it
7238 if Has_Stream_Size_Clause (E) then
7239 return Static_Integer (Expression (Stream_Size_Clause (E)));
7241 -- Otherwise the Stream_Size is the size of the type
7243 else
7244 return Esize (E);
7245 end if;
7246 end Get_Stream_Size;
7248 ---------------------------
7249 -- Has_Access_Constraint --
7250 ---------------------------
7252 function Has_Access_Constraint (E : Entity_Id) return Boolean is
7253 Disc : Entity_Id;
7254 T : constant Entity_Id := Etype (E);
7256 begin
7257 if Has_Per_Object_Constraint (E) and then Has_Discriminants (T) then
7258 Disc := First_Discriminant (T);
7259 while Present (Disc) loop
7260 if Is_Access_Type (Etype (Disc)) then
7261 return True;
7262 end if;
7264 Next_Discriminant (Disc);
7265 end loop;
7267 return False;
7268 else
7269 return False;
7270 end if;
7271 end Has_Access_Constraint;
7273 ---------------------
7274 -- Has_Tag_Of_Type --
7275 ---------------------
7277 function Has_Tag_Of_Type (Exp : Node_Id) return Boolean is
7278 Typ : constant Entity_Id := Etype (Exp);
7280 begin
7281 pragma Assert (Is_Tagged_Type (Typ));
7283 -- The tag of an object of a class-wide type is that of its
7284 -- initialization expression.
7286 if Is_Class_Wide_Type (Typ) then
7287 return False;
7288 end if;
7290 -- The tag of a stand-alone object of a specific tagged type T
7291 -- identifies T.
7293 if Is_Entity_Name (Exp)
7294 and then Ekind (Entity (Exp)) in E_Constant | E_Variable
7295 then
7296 return True;
7298 else
7299 case Nkind (Exp) is
7300 -- The tag of a component or an aggregate of a specific tagged
7301 -- type T identifies T.
7303 when N_Indexed_Component
7304 | N_Selected_Component
7305 | N_Aggregate
7306 | N_Extension_Aggregate
7308 return True;
7310 -- The tag of the result returned by a function whose result
7311 -- type is a specific tagged type T identifies T.
7313 when N_Function_Call =>
7314 return True;
7316 when N_Explicit_Dereference =>
7317 return Is_Captured_Function_Call (Exp);
7319 -- For a tagged type, the operand of a qualified expression
7320 -- shall resolve to be of the type of the expression.
7322 when N_Qualified_Expression =>
7323 return Has_Tag_Of_Type (Expression (Exp));
7325 when others =>
7326 return False;
7327 end case;
7328 end if;
7329 end Has_Tag_Of_Type;
7331 --------------------
7332 -- Homonym_Number --
7333 --------------------
7335 function Homonym_Number (Subp : Entity_Id) return Pos is
7336 Hom : Entity_Id := Homonym (Subp);
7337 Count : Pos := 1;
7339 begin
7340 while Present (Hom) loop
7341 if Scope (Hom) = Scope (Subp) then
7342 Count := Count + 1;
7343 end if;
7345 Hom := Homonym (Hom);
7346 end loop;
7348 return Count;
7349 end Homonym_Number;
7351 -----------------------------------
7352 -- In_Library_Level_Package_Body --
7353 -----------------------------------
7355 function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is
7356 begin
7357 -- First determine whether the entity appears at the library level, then
7358 -- look at the containing unit.
7360 if Is_Library_Level_Entity (Id) then
7361 declare
7362 Container : constant Node_Id := Cunit (Get_Source_Unit (Id));
7364 begin
7365 return Nkind (Unit (Container)) = N_Package_Body;
7366 end;
7367 end if;
7369 return False;
7370 end In_Library_Level_Package_Body;
7372 ------------------------------
7373 -- In_Unconditional_Context --
7374 ------------------------------
7376 function In_Unconditional_Context (Node : Node_Id) return Boolean is
7377 P : Node_Id;
7379 begin
7380 P := Node;
7381 while Present (P) loop
7382 case Nkind (P) is
7383 when N_Subprogram_Body => return True;
7384 when N_If_Statement => return False;
7385 when N_Loop_Statement => return False;
7386 when N_Case_Statement => return False;
7387 when others => P := Parent (P);
7388 end case;
7389 end loop;
7391 return False;
7392 end In_Unconditional_Context;
7394 -------------------
7395 -- Insert_Action --
7396 -------------------
7398 procedure Insert_Action
7399 (Assoc_Node : Node_Id;
7400 Ins_Action : Node_Id;
7401 Spec_Expr_OK : Boolean := False)
7403 begin
7404 if Present (Ins_Action) then
7405 Insert_Actions
7406 (Assoc_Node => Assoc_Node,
7407 Ins_Actions => New_List (Ins_Action),
7408 Spec_Expr_OK => Spec_Expr_OK);
7409 end if;
7410 end Insert_Action;
7412 -- Version with check(s) suppressed
7414 procedure Insert_Action
7415 (Assoc_Node : Node_Id;
7416 Ins_Action : Node_Id;
7417 Suppress : Check_Id;
7418 Spec_Expr_OK : Boolean := False)
7420 begin
7421 Insert_Actions
7422 (Assoc_Node => Assoc_Node,
7423 Ins_Actions => New_List (Ins_Action),
7424 Suppress => Suppress,
7425 Spec_Expr_OK => Spec_Expr_OK);
7426 end Insert_Action;
7428 -------------------------
7429 -- Insert_Action_After --
7430 -------------------------
7432 procedure Insert_Action_After
7433 (Assoc_Node : Node_Id;
7434 Ins_Action : Node_Id)
7436 begin
7437 Insert_Actions_After (Assoc_Node, New_List (Ins_Action));
7438 end Insert_Action_After;
7440 --------------------
7441 -- Insert_Actions --
7442 --------------------
7444 procedure Insert_Actions
7445 (Assoc_Node : Node_Id;
7446 Ins_Actions : List_Id;
7447 Spec_Expr_OK : Boolean := False)
7449 N : Node_Id;
7450 P : Node_Id;
7452 Wrapped_Node : Node_Id := Empty;
7454 begin
7455 if Is_Empty_List (Ins_Actions) then
7456 return;
7457 end if;
7459 -- Insert the action when the context is "Handling of Default and Per-
7460 -- Object Expressions" only when requested by the caller.
7462 if Spec_Expr_OK then
7463 null;
7465 -- Ignore insert of actions from inside default expression (or other
7466 -- similar "spec expression") in the special spec-expression analyze
7467 -- mode. Any insertions at this point have no relevance, since we are
7468 -- only doing the analyze to freeze the types of any static expressions.
7469 -- See section "Handling of Default and Per-Object Expressions" in the
7470 -- spec of package Sem for further details.
7472 elsif In_Spec_Expression then
7473 return;
7474 end if;
7476 -- If the action derives from stuff inside a record, then the actions
7477 -- are attached to the current scope, to be inserted and analyzed on
7478 -- exit from the scope. The reason for this is that we may also be
7479 -- generating freeze actions at the same time, and they must eventually
7480 -- be elaborated in the correct order.
7482 if Is_Record_Type (Current_Scope)
7483 and then not Is_Frozen (Current_Scope)
7484 then
7485 if No (Scope_Stack.Table
7486 (Scope_Stack.Last).Pending_Freeze_Actions)
7487 then
7488 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
7489 Ins_Actions;
7490 else
7491 Append_List
7492 (Ins_Actions,
7493 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
7494 end if;
7496 return;
7497 end if;
7499 -- We now intend to climb up the tree to find the right point to
7500 -- insert the actions. We start at Assoc_Node, unless this node is a
7501 -- subexpression in which case we start with its parent. We do this for
7502 -- two reasons. First it speeds things up. Second, if Assoc_Node is
7503 -- itself one of the special nodes like N_And_Then, then we assume that
7504 -- an initial request to insert actions for such a node does not expect
7505 -- the actions to get deposited in the node for later handling when the
7506 -- node is expanded, since clearly the node is being dealt with by the
7507 -- caller. Note that in the subexpression case, N is always the child we
7508 -- came from.
7510 -- N_Raise_xxx_Error is an annoying special case, it is a statement
7511 -- if it has type Standard_Void_Type, and a subexpression otherwise.
7512 -- Procedure calls, and similarly procedure attribute references, are
7513 -- also statements.
7515 if Nkind (Assoc_Node) in N_Subexpr
7516 and then (Nkind (Assoc_Node) not in N_Raise_xxx_Error
7517 or else Etype (Assoc_Node) /= Standard_Void_Type)
7518 and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement
7519 and then (Nkind (Assoc_Node) /= N_Attribute_Reference
7520 or else not Is_Procedure_Attribute_Name
7521 (Attribute_Name (Assoc_Node)))
7522 then
7523 N := Assoc_Node;
7524 P := Parent (Assoc_Node);
7526 -- Nonsubexpression case. Note that N is initially Empty in this case
7527 -- (N is only guaranteed non-Empty in the subexpr case).
7529 else
7530 N := Empty;
7531 P := Assoc_Node;
7532 end if;
7534 -- Capture root of the transient scope
7536 if Scope_Is_Transient then
7537 Wrapped_Node := Node_To_Be_Wrapped;
7538 end if;
7540 loop
7541 pragma Assert (Present (P));
7543 -- Make sure that inserted actions stay in the transient scope
7545 if Present (Wrapped_Node) and then N = Wrapped_Node then
7546 Store_Before_Actions_In_Scope (Ins_Actions);
7547 return;
7548 end if;
7550 case Nkind (P) is
7552 -- Case of right operand of AND THEN or OR ELSE. Put the actions
7553 -- in the Actions field of the right operand. They will be moved
7554 -- out further when the AND THEN or OR ELSE operator is expanded.
7555 -- Nothing special needs to be done for the left operand since
7556 -- in that case the actions are executed unconditionally.
7558 when N_Short_Circuit =>
7559 if N = Right_Opnd (P) then
7561 -- We are now going to either append the actions to the
7562 -- actions field of the short-circuit operation. We will
7563 -- also analyze the actions now.
7565 -- This analysis is really too early, the proper thing would
7566 -- be to just park them there now, and only analyze them if
7567 -- we find we really need them, and to it at the proper
7568 -- final insertion point. However attempting to this proved
7569 -- tricky, so for now we just kill current values before and
7570 -- after the analyze call to make sure we avoid peculiar
7571 -- optimizations from this out of order insertion.
7573 Kill_Current_Values;
7575 -- If P has already been expanded, we can't park new actions
7576 -- on it, so we need to expand them immediately, introducing
7577 -- an Expression_With_Actions. N can't be an expression
7578 -- with actions, or else then the actions would have been
7579 -- inserted at an inner level.
7581 if Analyzed (P) then
7582 pragma Assert (Nkind (N) /= N_Expression_With_Actions);
7583 Rewrite (N,
7584 Make_Expression_With_Actions (Sloc (N),
7585 Actions => Ins_Actions,
7586 Expression => Relocate_Node (N)));
7587 Analyze_And_Resolve (N);
7589 elsif Present (Actions (P)) then
7590 Insert_List_After_And_Analyze
7591 (Last (Actions (P)), Ins_Actions);
7592 else
7593 Set_Actions (P, Ins_Actions);
7594 Analyze_List (Actions (P));
7595 end if;
7597 Kill_Current_Values;
7599 return;
7600 end if;
7602 -- Then or Else dependent expression of an if expression. Add
7603 -- actions to Then_Actions or Else_Actions field as appropriate.
7604 -- The actions will be moved further out when the if is expanded.
7606 when N_If_Expression =>
7607 declare
7608 ThenX : constant Node_Id := Next (First (Expressions (P)));
7609 ElseX : constant Node_Id := Next (ThenX);
7611 begin
7612 -- If the enclosing expression is already analyzed, as
7613 -- is the case for nested elaboration checks, insert the
7614 -- conditional further out.
7616 if Analyzed (P) then
7617 null;
7619 -- Actions belong to the then expression, temporarily place
7620 -- them as Then_Actions of the if expression. They will be
7621 -- moved to the proper place later when the if expression is
7622 -- expanded.
7624 elsif N = ThenX then
7625 if Present (Then_Actions (P)) then
7626 Insert_List_After_And_Analyze
7627 (Last (Then_Actions (P)), Ins_Actions);
7628 else
7629 Set_Then_Actions (P, Ins_Actions);
7630 Analyze_List (Then_Actions (P));
7631 end if;
7633 return;
7635 -- Else_Actions is treated the same as Then_Actions above
7637 elsif N = ElseX then
7638 if Present (Else_Actions (P)) then
7639 Insert_List_After_And_Analyze
7640 (Last (Else_Actions (P)), Ins_Actions);
7641 else
7642 Set_Else_Actions (P, Ins_Actions);
7643 Analyze_List (Else_Actions (P));
7644 end if;
7646 return;
7648 -- Actions belong to the condition. In this case they are
7649 -- unconditionally executed, and so we can continue the
7650 -- search for the proper insert point.
7652 else
7653 null;
7654 end if;
7655 end;
7657 -- Alternative of case expression, we place the action in the
7658 -- Actions field of the case expression alternative, this will
7659 -- be handled when the case expression is expanded.
7661 when N_Case_Expression_Alternative =>
7662 if Present (Actions (P)) then
7663 Insert_List_After_And_Analyze
7664 (Last (Actions (P)), Ins_Actions);
7665 else
7666 Set_Actions (P, Ins_Actions);
7667 Analyze_List (Actions (P));
7668 end if;
7670 return;
7672 -- Case of appearing within an Expressions_With_Actions node. When
7673 -- the new actions come from the expression of the expression with
7674 -- actions, they must be added to the existing actions. The other
7675 -- alternative is when the new actions are related to one of the
7676 -- existing actions of the expression with actions, and should
7677 -- never reach here: if actions are inserted on a statement
7678 -- within the Actions of an expression with actions, or on some
7679 -- subexpression of such a statement, then the outermost proper
7680 -- insertion point is right before the statement, and we should
7681 -- never climb up as far as the N_Expression_With_Actions itself.
7683 when N_Expression_With_Actions =>
7684 if N = Expression (P) then
7685 if Is_Empty_List (Actions (P)) then
7686 Append_List_To (Actions (P), Ins_Actions);
7687 Analyze_List (Actions (P));
7688 else
7689 Insert_List_After_And_Analyze
7690 (Last (Actions (P)), Ins_Actions);
7691 end if;
7693 return;
7695 else
7696 raise Program_Error;
7697 end if;
7699 -- Case of appearing in the condition of a while expression or
7700 -- elsif. We insert the actions into the Condition_Actions field.
7701 -- They will be moved further out when the while loop or elsif
7702 -- is analyzed.
7704 when N_Elsif_Part
7705 | N_Iteration_Scheme
7707 if Present (Condition (P)) and then N = Condition (P) then
7708 if Present (Condition_Actions (P)) then
7709 Insert_List_After_And_Analyze
7710 (Last (Condition_Actions (P)), Ins_Actions);
7711 else
7712 Set_Condition_Actions (P, Ins_Actions);
7714 -- Set the parent of the insert actions explicitly. This
7715 -- is not a syntactic field, but we need the parent field
7716 -- set, in particular so that freeze can understand that
7717 -- it is dealing with condition actions, and properly
7718 -- insert the freezing actions.
7720 Set_Parent (Ins_Actions, P);
7721 Analyze_List (Condition_Actions (P));
7722 end if;
7724 return;
7725 end if;
7727 -- Statements, declarations, pragmas, representation clauses
7729 when
7730 -- Statements
7732 N_Procedure_Call_Statement
7733 | N_Statement_Other_Than_Procedure_Call
7735 -- Pragmas
7737 | N_Pragma
7739 -- Representation_Clause
7741 | N_At_Clause
7742 | N_Attribute_Definition_Clause
7743 | N_Enumeration_Representation_Clause
7744 | N_Record_Representation_Clause
7746 -- Declarations
7748 | N_Abstract_Subprogram_Declaration
7749 | N_Entry_Body
7750 | N_Exception_Declaration
7751 | N_Exception_Renaming_Declaration
7752 | N_Expression_Function
7753 | N_Formal_Abstract_Subprogram_Declaration
7754 | N_Formal_Concrete_Subprogram_Declaration
7755 | N_Formal_Object_Declaration
7756 | N_Formal_Type_Declaration
7757 | N_Full_Type_Declaration
7758 | N_Function_Instantiation
7759 | N_Generic_Function_Renaming_Declaration
7760 | N_Generic_Package_Declaration
7761 | N_Generic_Package_Renaming_Declaration
7762 | N_Generic_Procedure_Renaming_Declaration
7763 | N_Generic_Subprogram_Declaration
7764 | N_Implicit_Label_Declaration
7765 | N_Incomplete_Type_Declaration
7766 | N_Number_Declaration
7767 | N_Object_Declaration
7768 | N_Object_Renaming_Declaration
7769 | N_Package_Body
7770 | N_Package_Body_Stub
7771 | N_Package_Declaration
7772 | N_Package_Instantiation
7773 | N_Package_Renaming_Declaration
7774 | N_Private_Extension_Declaration
7775 | N_Private_Type_Declaration
7776 | N_Procedure_Instantiation
7777 | N_Protected_Body
7778 | N_Protected_Body_Stub
7779 | N_Single_Task_Declaration
7780 | N_Subprogram_Body
7781 | N_Subprogram_Body_Stub
7782 | N_Subprogram_Declaration
7783 | N_Subprogram_Renaming_Declaration
7784 | N_Subtype_Declaration
7785 | N_Task_Body
7786 | N_Task_Body_Stub
7788 -- Use clauses can appear in lists of declarations
7790 | N_Use_Package_Clause
7791 | N_Use_Type_Clause
7793 -- Freeze entity behaves like a declaration or statement
7795 | N_Freeze_Entity
7796 | N_Freeze_Generic_Entity
7798 -- Do not insert here if the item is not a list member (this
7799 -- happens for example with a triggering statement, and the
7800 -- proper approach is to insert before the entire select).
7802 if not Is_List_Member (P) then
7803 null;
7805 -- Do not insert if parent of P is an N_Component_Association
7806 -- node (i.e. we are in the context of an N_Aggregate or
7807 -- N_Extension_Aggregate node. In this case we want to insert
7808 -- before the entire aggregate.
7810 elsif Nkind (Parent (P)) = N_Component_Association then
7811 null;
7813 -- Do not insert if the parent of P is either an N_Variant node
7814 -- or an N_Record_Definition node, meaning in either case that
7815 -- P is a member of a component list, and that therefore the
7816 -- actions should be inserted outside the complete record
7817 -- declaration.
7819 elsif Nkind (Parent (P)) in N_Variant | N_Record_Definition then
7820 null;
7822 -- Do not insert freeze nodes within the loop generated for
7823 -- an aggregate, because they may be elaborated too late for
7824 -- subsequent use in the back end: within a package spec the
7825 -- loop is part of the elaboration procedure and is only
7826 -- elaborated during the second pass.
7828 -- If the loop comes from source, or the entity is local to the
7829 -- loop itself it must remain within.
7831 elsif Nkind (Parent (P)) = N_Loop_Statement
7832 and then not Comes_From_Source (Parent (P))
7833 and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
7834 and then
7835 Scope (Entity (First (Ins_Actions))) /= Current_Scope
7836 then
7837 null;
7839 -- Otherwise we can go ahead and do the insertion
7841 elsif P = Wrapped_Node then
7842 Store_Before_Actions_In_Scope (Ins_Actions);
7843 return;
7845 else
7846 Insert_List_Before_And_Analyze (P, Ins_Actions);
7847 return;
7848 end if;
7850 -- the expansion of Task and protected type declarations can
7851 -- create declarations for temporaries which, like other actions
7852 -- are inserted and analyzed before the current declaraation.
7853 -- However, the current scope is the synchronized type, and
7854 -- for unnesting it is critical that the proper scope for these
7855 -- generated entities be the enclosing one.
7857 when N_Task_Type_Declaration
7858 | N_Protected_Type_Declaration =>
7860 Push_Scope (Scope (Current_Scope));
7861 Insert_List_Before_And_Analyze (P, Ins_Actions);
7862 Pop_Scope;
7863 return;
7865 -- A special case, N_Raise_xxx_Error can act either as a statement
7866 -- or a subexpression. We tell the difference by looking at the
7867 -- Etype. It is set to Standard_Void_Type in the statement case.
7869 when N_Raise_xxx_Error =>
7870 if Etype (P) = Standard_Void_Type then
7871 if P = Wrapped_Node then
7872 Store_Before_Actions_In_Scope (Ins_Actions);
7873 else
7874 Insert_List_Before_And_Analyze (P, Ins_Actions);
7875 end if;
7877 return;
7879 -- In the subexpression case, keep climbing
7881 else
7882 null;
7883 end if;
7885 -- If a component association appears within a loop created for
7886 -- an array aggregate, attach the actions to the association so
7887 -- they can be subsequently inserted within the loop. For other
7888 -- component associations insert outside of the aggregate. For
7889 -- an association that will generate a loop, its Loop_Actions
7890 -- attribute is already initialized (see exp_aggr.adb).
7892 -- The list of Loop_Actions can in turn generate additional ones,
7893 -- that are inserted before the associated node. If the associated
7894 -- node is outside the aggregate, the new actions are collected
7895 -- at the end of the Loop_Actions, to respect the order in which
7896 -- they are to be elaborated.
7898 when N_Component_Association
7899 | N_Iterated_Component_Association
7900 | N_Iterated_Element_Association
7902 if Nkind (Parent (P)) in N_Aggregate | N_Delta_Aggregate
7904 -- We must not climb up out of an N_Iterated_xxx_Association
7905 -- because the actions might contain references to the loop
7906 -- parameter, except if we come from the Discrete_Choices of
7907 -- N_Iterated_Component_Association which cannot contain any.
7908 -- But it turns out that setting the Loop_Actions field in
7909 -- the case of an N_Component_Association when the field was
7910 -- not already set can lead to gigi assertion failures that
7911 -- are presumably due to malformed trees, so don't do that.
7913 and then (Nkind (P) /= N_Iterated_Component_Association
7914 or else not Is_List_Member (N)
7915 or else
7916 List_Containing (N) /= Discrete_Choices (P))
7917 and then (Nkind (P) /= N_Component_Association
7918 or else Present (Loop_Actions (P)))
7919 then
7920 if Is_Empty_List (Loop_Actions (P)) then
7921 Set_Loop_Actions (P, Ins_Actions);
7922 Analyze_List (Ins_Actions);
7923 else
7924 declare
7925 Decl : Node_Id;
7927 begin
7928 -- Check whether these actions were generated by a
7929 -- declaration that is part of the Loop_Actions for
7930 -- the component_association.
7932 Decl := Assoc_Node;
7933 while Present (Decl) loop
7934 exit when Parent (Decl) = P
7935 and then Is_List_Member (Decl)
7936 and then
7937 List_Containing (Decl) = Loop_Actions (P);
7938 Decl := Parent (Decl);
7939 end loop;
7941 if Present (Decl) then
7942 Insert_List_Before_And_Analyze
7943 (Decl, Ins_Actions);
7944 else
7945 Insert_List_After_And_Analyze
7946 (Last (Loop_Actions (P)), Ins_Actions);
7947 end if;
7948 end;
7949 end if;
7951 return;
7953 else
7954 null;
7955 end if;
7957 -- Special case: an attribute denoting a procedure call
7959 when N_Attribute_Reference =>
7960 if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
7961 if P = Wrapped_Node then
7962 Store_Before_Actions_In_Scope (Ins_Actions);
7963 else
7964 Insert_List_Before_And_Analyze (P, Ins_Actions);
7965 end if;
7967 return;
7969 -- In the subexpression case, keep climbing
7971 else
7972 null;
7973 end if;
7975 -- Special case: a marker
7977 when N_Call_Marker
7978 | N_Variable_Reference_Marker
7980 if Is_List_Member (P) then
7981 Insert_List_Before_And_Analyze (P, Ins_Actions);
7982 return;
7983 end if;
7985 -- A contract node should not belong to the tree
7987 when N_Contract =>
7988 raise Program_Error;
7990 -- For all other node types, keep climbing tree
7992 when N_Abortable_Part
7993 | N_Accept_Alternative
7994 | N_Access_Definition
7995 | N_Access_Function_Definition
7996 | N_Access_Procedure_Definition
7997 | N_Access_To_Object_Definition
7998 | N_Aggregate
7999 | N_Allocator
8000 | N_Aspect_Specification
8001 | N_Case_Expression
8002 | N_Case_Statement_Alternative
8003 | N_Character_Literal
8004 | N_Compilation_Unit
8005 | N_Compilation_Unit_Aux
8006 | N_Component_Clause
8007 | N_Component_Declaration
8008 | N_Component_Definition
8009 | N_Component_List
8010 | N_Constrained_Array_Definition
8011 | N_Decimal_Fixed_Point_Definition
8012 | N_Defining_Character_Literal
8013 | N_Defining_Identifier
8014 | N_Defining_Operator_Symbol
8015 | N_Defining_Program_Unit_Name
8016 | N_Delay_Alternative
8017 | N_Delta_Aggregate
8018 | N_Delta_Constraint
8019 | N_Derived_Type_Definition
8020 | N_Designator
8021 | N_Digits_Constraint
8022 | N_Discriminant_Association
8023 | N_Discriminant_Specification
8024 | N_Empty
8025 | N_Entry_Body_Formal_Part
8026 | N_Entry_Call_Alternative
8027 | N_Entry_Declaration
8028 | N_Entry_Index_Specification
8029 | N_Enumeration_Type_Definition
8030 | N_Error
8031 | N_Exception_Handler
8032 | N_Expanded_Name
8033 | N_Explicit_Dereference
8034 | N_Extension_Aggregate
8035 | N_Floating_Point_Definition
8036 | N_Formal_Decimal_Fixed_Point_Definition
8037 | N_Formal_Derived_Type_Definition
8038 | N_Formal_Discrete_Type_Definition
8039 | N_Formal_Floating_Point_Definition
8040 | N_Formal_Modular_Type_Definition
8041 | N_Formal_Ordinary_Fixed_Point_Definition
8042 | N_Formal_Package_Declaration
8043 | N_Formal_Private_Type_Definition
8044 | N_Formal_Incomplete_Type_Definition
8045 | N_Formal_Signed_Integer_Type_Definition
8046 | N_Function_Call
8047 | N_Function_Specification
8048 | N_Generic_Association
8049 | N_Handled_Sequence_Of_Statements
8050 | N_Identifier
8051 | N_In
8052 | N_Index_Or_Discriminant_Constraint
8053 | N_Indexed_Component
8054 | N_Integer_Literal
8055 | N_Iterator_Specification
8056 | N_Interpolated_String_Literal
8057 | N_Itype_Reference
8058 | N_Label
8059 | N_Loop_Parameter_Specification
8060 | N_Mod_Clause
8061 | N_Modular_Type_Definition
8062 | N_Not_In
8063 | N_Null
8064 | N_Op_Abs
8065 | N_Op_Add
8066 | N_Op_And
8067 | N_Op_Concat
8068 | N_Op_Divide
8069 | N_Op_Eq
8070 | N_Op_Expon
8071 | N_Op_Ge
8072 | N_Op_Gt
8073 | N_Op_Le
8074 | N_Op_Lt
8075 | N_Op_Minus
8076 | N_Op_Mod
8077 | N_Op_Multiply
8078 | N_Op_Ne
8079 | N_Op_Not
8080 | N_Op_Or
8081 | N_Op_Plus
8082 | N_Op_Rem
8083 | N_Op_Rotate_Left
8084 | N_Op_Rotate_Right
8085 | N_Op_Shift_Left
8086 | N_Op_Shift_Right
8087 | N_Op_Shift_Right_Arithmetic
8088 | N_Op_Subtract
8089 | N_Op_Xor
8090 | N_Operator_Symbol
8091 | N_Ordinary_Fixed_Point_Definition
8092 | N_Others_Choice
8093 | N_Package_Specification
8094 | N_Parameter_Association
8095 | N_Parameter_Specification
8096 | N_Pop_Constraint_Error_Label
8097 | N_Pop_Program_Error_Label
8098 | N_Pop_Storage_Error_Label
8099 | N_Pragma_Argument_Association
8100 | N_Procedure_Specification
8101 | N_Protected_Definition
8102 | N_Push_Constraint_Error_Label
8103 | N_Push_Program_Error_Label
8104 | N_Push_Storage_Error_Label
8105 | N_Qualified_Expression
8106 | N_Quantified_Expression
8107 | N_Raise_Expression
8108 | N_Range
8109 | N_Range_Constraint
8110 | N_Real_Literal
8111 | N_Real_Range_Specification
8112 | N_Record_Definition
8113 | N_Reference
8114 | N_SCIL_Dispatch_Table_Tag_Init
8115 | N_SCIL_Dispatching_Call
8116 | N_SCIL_Membership_Test
8117 | N_Selected_Component
8118 | N_Signed_Integer_Type_Definition
8119 | N_Single_Protected_Declaration
8120 | N_Slice
8121 | N_String_Literal
8122 | N_Subtype_Indication
8123 | N_Subunit
8124 | N_Target_Name
8125 | N_Task_Definition
8126 | N_Terminate_Alternative
8127 | N_Triggering_Alternative
8128 | N_Type_Conversion
8129 | N_Unchecked_Expression
8130 | N_Unchecked_Type_Conversion
8131 | N_Unconstrained_Array_Definition
8132 | N_Unused_At_End
8133 | N_Unused_At_Start
8134 | N_Variant
8135 | N_Variant_Part
8136 | N_Validate_Unchecked_Conversion
8137 | N_With_Clause
8139 null;
8140 end case;
8142 -- If we fall through above tests, keep climbing tree
8144 N := P;
8146 if Nkind (Parent (N)) = N_Subunit then
8148 -- This is the proper body corresponding to a stub. Insertion must
8149 -- be done at the point of the stub, which is in the declarative
8150 -- part of the parent unit.
8152 P := Corresponding_Stub (Parent (N));
8154 else
8155 P := Parent (N);
8156 end if;
8157 end loop;
8158 end Insert_Actions;
8160 -- Version with check(s) suppressed
8162 procedure Insert_Actions
8163 (Assoc_Node : Node_Id;
8164 Ins_Actions : List_Id;
8165 Suppress : Check_Id;
8166 Spec_Expr_OK : Boolean := False)
8168 begin
8169 if Suppress = All_Checks then
8170 declare
8171 Sva : constant Suppress_Array := Scope_Suppress.Suppress;
8172 begin
8173 Scope_Suppress.Suppress := (others => True);
8174 Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK);
8175 Scope_Suppress.Suppress := Sva;
8176 end;
8178 else
8179 declare
8180 Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
8181 begin
8182 Scope_Suppress.Suppress (Suppress) := True;
8183 Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK);
8184 Scope_Suppress.Suppress (Suppress) := Svg;
8185 end;
8186 end if;
8187 end Insert_Actions;
8189 --------------------------
8190 -- Insert_Actions_After --
8191 --------------------------
8193 procedure Insert_Actions_After
8194 (Assoc_Node : Node_Id;
8195 Ins_Actions : List_Id)
8197 begin
8198 if Scope_Is_Transient and then Assoc_Node = Node_To_Be_Wrapped then
8199 Store_After_Actions_In_Scope (Ins_Actions);
8200 else
8201 Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
8202 end if;
8203 end Insert_Actions_After;
8205 ---------------------------------
8206 -- Insert_Library_Level_Action --
8207 ---------------------------------
8209 procedure Insert_Library_Level_Action (N : Node_Id) is
8210 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
8212 begin
8213 Push_Scope (Cunit_Entity (Current_Sem_Unit));
8214 -- And not Main_Unit as previously. If the main unit is a body,
8215 -- the scope needed to analyze the actions is the entity of the
8216 -- corresponding declaration.
8218 if No (Actions (Aux)) then
8219 Set_Actions (Aux, New_List (N));
8220 else
8221 Append (N, Actions (Aux));
8222 end if;
8224 Analyze (N);
8225 Pop_Scope;
8226 end Insert_Library_Level_Action;
8228 ----------------------------------
8229 -- Insert_Library_Level_Actions --
8230 ----------------------------------
8232 procedure Insert_Library_Level_Actions (L : List_Id) is
8233 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
8235 begin
8236 if Is_Non_Empty_List (L) then
8237 Push_Scope (Cunit_Entity (Main_Unit));
8238 -- ??? should this be Current_Sem_Unit instead of Main_Unit?
8240 if No (Actions (Aux)) then
8241 Set_Actions (Aux, L);
8242 Analyze_List (L);
8243 else
8244 Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
8245 end if;
8247 Pop_Scope;
8248 end if;
8249 end Insert_Library_Level_Actions;
8251 ----------------------
8252 -- Inside_Init_Proc --
8253 ----------------------
8255 function Inside_Init_Proc return Boolean is
8256 begin
8257 return Present (Enclosing_Init_Proc);
8258 end Inside_Init_Proc;
8260 ----------------------
8261 -- Integer_Type_For --
8262 ----------------------
8264 function Integer_Type_For (S : Uint; Uns : Boolean) return Entity_Id is
8265 begin
8266 pragma Assert
8267 (Standard_Long_Integer_Size in
8268 Standard_Integer_Size | Standard_Long_Long_Integer_Size);
8269 -- So we don't need to check for Standard_Long_Integer_Size below
8270 pragma Assert (S <= System_Max_Integer_Size);
8272 -- This is the canonical 32-bit type
8274 if S <= Standard_Integer_Size then
8275 if Uns then
8276 return Standard_Unsigned;
8277 else
8278 return Standard_Integer;
8279 end if;
8281 -- This is the canonical 64-bit type
8283 elsif S <= Standard_Long_Long_Integer_Size then
8284 if Uns then
8285 return Standard_Long_Long_Unsigned;
8286 else
8287 return Standard_Long_Long_Integer;
8288 end if;
8290 -- This is the canonical 128-bit type
8292 elsif S <= Standard_Long_Long_Long_Integer_Size then
8293 if Uns then
8294 return Standard_Long_Long_Long_Unsigned;
8295 else
8296 return Standard_Long_Long_Long_Integer;
8297 end if;
8299 else
8300 raise Program_Error;
8301 end if;
8302 end Integer_Type_For;
8304 -------------------------------
8305 -- Is_Captured_Function_Call --
8306 -------------------------------
8308 function Is_Captured_Function_Call (N : Node_Id) return Boolean is
8309 begin
8310 if Nkind (N) = N_Explicit_Dereference
8311 and then Is_Entity_Name (Prefix (N))
8312 and then Ekind (Entity (Prefix (N))) = E_Constant
8313 then
8314 declare
8315 Value : constant Node_Id := Constant_Value (Entity (Prefix (N)));
8317 begin
8318 return Present (Value)
8319 and then Nkind (Value) = N_Reference
8320 and then Nkind (Prefix (Value)) = N_Function_Call;
8321 end;
8323 else
8324 return False;
8325 end if;
8326 end Is_Captured_Function_Call;
8328 ------------------------------
8329 -- Is_Finalizable_Transient --
8330 ------------------------------
8332 function Is_Finalizable_Transient
8333 (Decl : Node_Id;
8334 Rel_Node : Node_Id) return Boolean
8336 Obj_Id : constant Entity_Id := Defining_Identifier (Decl);
8337 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
8339 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean;
8340 -- Determine whether transient object Trans_Id is initialized either
8341 -- by a function call which returns an access type or simply renames
8342 -- another pointer.
8344 function Initialized_By_Aliased_BIP_Func_Call
8345 (Trans_Id : Entity_Id) return Boolean;
8346 -- Determine whether transient object Trans_Id is initialized by a
8347 -- build-in-place function call where the BIPalloc parameter either
8348 -- does not exist or is Caller_Allocation, and BIPaccess is not null.
8349 -- This case creates an aliasing between the returned value and the
8350 -- value denoted by BIPaccess.
8352 function Is_Aliased
8353 (Trans_Id : Entity_Id;
8354 First_Stmt : Node_Id) return Boolean;
8355 -- Determine whether transient object Trans_Id has been renamed or
8356 -- aliased through 'reference in the statement list starting from
8357 -- First_Stmt.
8359 function Is_Allocated (Trans_Id : Entity_Id) return Boolean;
8360 -- Determine whether transient object Trans_Id is allocated on the heap
8362 function Is_Indexed_Container
8363 (Trans_Id : Entity_Id;
8364 First_Stmt : Node_Id) return Boolean;
8365 -- Determine whether transient object Trans_Id denotes a container which
8366 -- is in the process of being indexed in the statement list starting
8367 -- from First_Stmt.
8369 function Is_Iterated_Container
8370 (Trans_Id : Entity_Id;
8371 First_Stmt : Node_Id) return Boolean;
8372 -- Determine whether transient object Trans_Id denotes a container which
8373 -- is in the process of being iterated in the statement list starting
8374 -- from First_Stmt.
8376 function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean;
8377 -- Return True if N is directly part of a build-in-place return
8378 -- statement.
8380 ---------------------------
8381 -- Initialized_By_Access --
8382 ---------------------------
8384 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is
8385 Expr : constant Node_Id := Expression (Parent (Trans_Id));
8387 begin
8388 return
8389 Present (Expr)
8390 and then Nkind (Expr) /= N_Reference
8391 and then Is_Access_Type (Etype (Expr));
8392 end Initialized_By_Access;
8394 ------------------------------------------
8395 -- Initialized_By_Aliased_BIP_Func_Call --
8396 ------------------------------------------
8398 function Initialized_By_Aliased_BIP_Func_Call
8399 (Trans_Id : Entity_Id) return Boolean
8401 Call : Node_Id := Expression (Parent (Trans_Id));
8403 begin
8404 -- Build-in-place calls usually appear in 'reference format
8406 if Nkind (Call) = N_Reference then
8407 Call := Prefix (Call);
8408 end if;
8410 Call := Unqual_Conv (Call);
8412 -- We search for a formal with a matching suffix. We can't search
8413 -- for the full name, because of the code at the end of Sem_Ch6.-
8414 -- Create_Extra_Formals, which copies the Extra_Formals over to
8415 -- the Alias of an instance, which will cause the formals to have
8416 -- "incorrect" names. See also Exp_Ch6.Build_In_Place_Formal.
8418 if Is_Build_In_Place_Function_Call (Call) then
8419 declare
8420 Caller_Allocation_Val : constant Uint :=
8421 UI_From_Int (BIP_Allocation_Form'Pos (Caller_Allocation));
8422 Access_Suffix : constant String :=
8423 BIP_Formal_Suffix (BIP_Object_Access);
8424 Alloc_Suffix : constant String :=
8425 BIP_Formal_Suffix (BIP_Alloc_Form);
8427 function Has_Suffix (Name, Suffix : String) return Boolean;
8428 -- Return True if Name has suffix Suffix
8430 ----------------
8431 -- Has_Suffix --
8432 ----------------
8434 function Has_Suffix (Name, Suffix : String) return Boolean is
8435 Len : constant Natural := Suffix'Length;
8437 begin
8438 return Name'Length > Len
8439 and then Name (Name'Last - Len + 1 .. Name'Last) = Suffix;
8440 end Has_Suffix;
8442 Access_OK : Boolean := False;
8443 Alloc_OK : Boolean := True;
8444 Param : Node_Id;
8446 begin
8447 -- Examine all parameter associations of the function call
8449 Param := First (Parameter_Associations (Call));
8451 while Present (Param) loop
8452 if Nkind (Param) = N_Parameter_Association
8453 and then Nkind (Selector_Name (Param)) = N_Identifier
8454 then
8455 declare
8456 Actual : constant Node_Id
8457 := Explicit_Actual_Parameter (Param);
8458 Formal : constant Node_Id
8459 := Selector_Name (Param);
8460 Name : constant String
8461 := Get_Name_String (Chars (Formal));
8463 begin
8464 -- A nonnull BIPaccess has been found
8466 if Has_Suffix (Name, Access_Suffix)
8467 and then Nkind (Actual) /= N_Null
8468 then
8469 Access_OK := True;
8471 -- A BIPalloc has been found
8473 elsif Has_Suffix (Name, Alloc_Suffix)
8474 and then Nkind (Actual) = N_Integer_Literal
8475 then
8476 Alloc_OK := Intval (Actual) = Caller_Allocation_Val;
8477 end if;
8478 end;
8479 end if;
8481 Next (Param);
8482 end loop;
8484 return Access_OK and Alloc_OK;
8485 end;
8486 end if;
8488 return False;
8489 end Initialized_By_Aliased_BIP_Func_Call;
8491 ----------------
8492 -- Is_Aliased --
8493 ----------------
8495 function Is_Aliased
8496 (Trans_Id : Entity_Id;
8497 First_Stmt : Node_Id) return Boolean
8499 function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id;
8500 -- Given an object renaming declaration, retrieve the entity of the
8501 -- renamed name. Return Empty if the renamed name is anything other
8502 -- than a variable or a constant.
8504 -------------------------
8505 -- Find_Renamed_Object --
8506 -------------------------
8508 function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id is
8509 Ren_Obj : Node_Id := Empty;
8511 function Find_Object (N : Node_Id) return Traverse_Result;
8512 -- Try to detect an object which is either a constant or a
8513 -- variable.
8515 -----------------
8516 -- Find_Object --
8517 -----------------
8519 function Find_Object (N : Node_Id) return Traverse_Result is
8520 begin
8521 -- Stop the search once a constant or a variable has been
8522 -- detected.
8524 if Nkind (N) = N_Identifier
8525 and then Present (Entity (N))
8526 and then Ekind (Entity (N)) in E_Constant | E_Variable
8527 then
8528 Ren_Obj := Entity (N);
8529 return Abandon;
8530 end if;
8532 return OK;
8533 end Find_Object;
8535 procedure Search is new Traverse_Proc (Find_Object);
8537 -- Local variables
8539 Typ : constant Entity_Id := Etype (Defining_Identifier (Ren_Decl));
8541 -- Start of processing for Find_Renamed_Object
8543 begin
8544 -- Actions related to dispatching calls may appear as renamings of
8545 -- tags. Do not process this type of renaming because it does not
8546 -- use the actual value of the object.
8548 if not Is_RTE (Typ, RE_Tag_Ptr) then
8549 Search (Name (Ren_Decl));
8550 end if;
8552 -- For renamings generated by Expand_N_Object_Declaration to deal
8553 -- with (class-wide) interface objects, there is an intermediate
8554 -- temporary of an anonymous access type used to hold the result
8555 -- of the displacement of the address of the renamed object.
8557 if Present (Ren_Obj)
8558 and then Ekind (Ren_Obj) = E_Constant
8559 and then Is_Itype (Etype (Ren_Obj))
8560 and then Ekind (Etype (Ren_Obj)) = E_Anonymous_Access_Type
8561 and then
8562 Is_Class_Wide_Type (Directly_Designated_Type (Etype (Ren_Obj)))
8563 and then
8564 Is_Interface (Directly_Designated_Type (Etype (Ren_Obj)))
8565 then
8566 Search (Constant_Value (Ren_Obj));
8567 end if;
8569 return Ren_Obj;
8570 end Find_Renamed_Object;
8572 -- Local variables
8574 Expr : Node_Id;
8575 Ren_Obj : Entity_Id;
8576 Stmt : Node_Id;
8578 -- Start of processing for Is_Aliased
8580 begin
8581 -- A controlled transient object is not considered aliased when it
8582 -- appears inside an expression_with_actions node even when there are
8583 -- explicit aliases of it:
8585 -- do
8586 -- Trans_Id : Ctrl_Typ ...; -- transient object
8587 -- Alias : ... := Trans_Id; -- object is aliased
8588 -- Val : constant Boolean :=
8589 -- ... Alias ...; -- aliasing ends
8590 -- <finalize Trans_Id> -- object safe to finalize
8591 -- in Val end;
8593 -- Expansion ensures that all aliases are encapsulated in the actions
8594 -- list and do not leak to the expression by forcing the evaluation
8595 -- of the expression.
8597 if Nkind (Rel_Node) = N_Expression_With_Actions then
8598 return False;
8600 -- Otherwise examine the statements after the controlled transient
8601 -- object and look for various forms of aliasing.
8603 else
8604 Stmt := First_Stmt;
8605 while Present (Stmt) loop
8606 if Nkind (Stmt) = N_Object_Declaration then
8607 Expr := Expression (Stmt);
8609 -- Aliasing of the form:
8610 -- Obj : ... := Trans_Id'reference;
8612 if Present (Expr)
8613 and then Nkind (Expr) = N_Reference
8614 and then Nkind (Prefix (Expr)) = N_Identifier
8615 and then Entity (Prefix (Expr)) = Trans_Id
8616 then
8617 return True;
8618 end if;
8620 elsif Nkind (Stmt) = N_Object_Renaming_Declaration then
8621 Ren_Obj := Find_Renamed_Object (Stmt);
8623 -- Aliasing of the form:
8624 -- Obj : ... renames ... Trans_Id ...;
8626 if Present (Ren_Obj) and then Ren_Obj = Trans_Id then
8627 return True;
8628 end if;
8629 end if;
8631 Next (Stmt);
8632 end loop;
8634 return False;
8635 end if;
8636 end Is_Aliased;
8638 ------------------
8639 -- Is_Allocated --
8640 ------------------
8642 function Is_Allocated (Trans_Id : Entity_Id) return Boolean is
8643 Expr : constant Node_Id := Expression (Parent (Trans_Id));
8644 begin
8645 return
8646 Is_Access_Type (Etype (Trans_Id))
8647 and then Present (Expr)
8648 and then Nkind (Expr) = N_Allocator;
8649 end Is_Allocated;
8651 --------------------------
8652 -- Is_Indexed_Container --
8653 --------------------------
8655 function Is_Indexed_Container
8656 (Trans_Id : Entity_Id;
8657 First_Stmt : Node_Id) return Boolean
8659 Aspect : Node_Id;
8660 Call : Node_Id;
8661 Index : Entity_Id;
8662 Param : Node_Id;
8663 Stmt : Node_Id;
8664 Typ : Entity_Id;
8666 begin
8667 -- It is not possible to iterate over containers in non-Ada 2012 code
8669 if Ada_Version < Ada_2012 then
8670 return False;
8671 end if;
8673 Typ := Etype (Trans_Id);
8675 -- Handle access type created for the reference below
8677 if Is_Access_Type (Typ) then
8678 Typ := Designated_Type (Typ);
8679 end if;
8681 -- Look for aspect Constant_Indexing. It may be part of a type
8682 -- declaration for a container, or inherited from a base type
8683 -- or parent type.
8685 Aspect := Find_Value_Of_Aspect (Typ, Aspect_Constant_Indexing);
8687 if Present (Aspect) then
8688 Index := Entity (Aspect);
8690 -- Examine the statements following the container object and
8691 -- look for a call to the default indexing routine where the
8692 -- first parameter is the transient. Such a call appears as:
8694 -- It : Access_To_Constant_Reference_Type :=
8695 -- Constant_Indexing (Trans_Id.all, ...)'reference;
8697 Stmt := First_Stmt;
8698 while Present (Stmt) loop
8700 -- Detect an object declaration which is initialized by a
8701 -- controlled function call.
8703 if Nkind (Stmt) = N_Object_Declaration
8704 and then Present (Expression (Stmt))
8705 and then Nkind (Expression (Stmt)) = N_Reference
8706 and then Nkind (Prefix (Expression (Stmt))) = N_Function_Call
8707 then
8708 Call := Prefix (Expression (Stmt));
8710 -- The call must invoke the default indexing routine of
8711 -- the container and the transient object must appear as
8712 -- the first actual parameter. Skip any calls whose names
8713 -- are not entities.
8715 if Is_Entity_Name (Name (Call))
8716 and then Entity (Name (Call)) = Index
8717 and then Present (Parameter_Associations (Call))
8718 then
8719 Param := First (Parameter_Associations (Call));
8721 if Nkind (Param) = N_Explicit_Dereference
8722 and then Entity (Prefix (Param)) = Trans_Id
8723 then
8724 return True;
8725 end if;
8726 end if;
8727 end if;
8729 Next (Stmt);
8730 end loop;
8731 end if;
8733 return False;
8734 end Is_Indexed_Container;
8736 ---------------------------
8737 -- Is_Iterated_Container --
8738 ---------------------------
8740 function Is_Iterated_Container
8741 (Trans_Id : Entity_Id;
8742 First_Stmt : Node_Id) return Boolean
8744 Aspect : Node_Id;
8745 Call : Node_Id;
8746 Iter : Entity_Id;
8747 Param : Node_Id;
8748 Stmt : Node_Id;
8749 Typ : Entity_Id;
8751 begin
8752 -- It is not possible to iterate over containers in non-Ada 2012 code
8754 if Ada_Version < Ada_2012 then
8755 return False;
8756 end if;
8758 Typ := Etype (Trans_Id);
8760 -- Handle access type created for the reference below
8762 if Is_Access_Type (Typ) then
8763 Typ := Designated_Type (Typ);
8764 end if;
8766 -- Look for aspect Default_Iterator. It may be part of a type
8767 -- declaration for a container, or inherited from a base type
8768 -- or parent type.
8770 Aspect := Find_Value_Of_Aspect (Typ, Aspect_Default_Iterator);
8772 if Present (Aspect) then
8773 Iter := Entity (Aspect);
8775 -- Examine the statements following the container object and
8776 -- look for a call to the default iterate routine where the
8777 -- first parameter is the transient. Such a call appears as:
8779 -- It : Access_To_CW_Iterator :=
8780 -- Iterate (Trans_Id.all, ...)'reference;
8782 Stmt := First_Stmt;
8783 while Present (Stmt) loop
8785 -- Detect an object declaration which is initialized by a
8786 -- controlled function call.
8788 if Nkind (Stmt) = N_Object_Declaration
8789 and then Present (Expression (Stmt))
8790 and then Nkind (Expression (Stmt)) = N_Reference
8791 and then Nkind (Prefix (Expression (Stmt))) = N_Function_Call
8792 then
8793 Call := Prefix (Expression (Stmt));
8795 -- The call must invoke the default iterate routine of
8796 -- the container and the transient object must appear as
8797 -- the first actual parameter. Skip any calls whose names
8798 -- are not entities.
8800 if Is_Entity_Name (Name (Call))
8801 and then Entity (Name (Call)) = Iter
8802 and then Present (Parameter_Associations (Call))
8803 then
8804 Param := First (Parameter_Associations (Call));
8806 if Nkind (Param) = N_Explicit_Dereference
8807 and then Entity (Prefix (Param)) = Trans_Id
8808 then
8809 return True;
8810 end if;
8811 end if;
8812 end if;
8814 Next (Stmt);
8815 end loop;
8816 end if;
8818 return False;
8819 end Is_Iterated_Container;
8821 -------------------------------------
8822 -- Is_Part_Of_BIP_Return_Statement --
8823 -------------------------------------
8825 function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean is
8826 Subp : constant Entity_Id := Current_Subprogram;
8827 Context : Node_Id;
8828 begin
8829 -- First check if N is part of a BIP function
8831 if No (Subp)
8832 or else not Is_Build_In_Place_Function (Subp)
8833 then
8834 return False;
8835 end if;
8837 -- Then check whether N is a complete part of a return statement
8838 -- Should we consider other node kinds to go up the tree???
8840 Context := N;
8841 loop
8842 case Nkind (Context) is
8843 when N_Expression_With_Actions => Context := Parent (Context);
8844 when N_Simple_Return_Statement => return True;
8845 when others => return False;
8846 end case;
8847 end loop;
8848 end Is_Part_Of_BIP_Return_Statement;
8850 -- Local variables
8852 Desig : Entity_Id := Obj_Typ;
8854 -- Start of processing for Is_Finalizable_Transient
8856 begin
8857 -- Handle access types
8859 if Is_Access_Type (Desig) then
8860 Desig := Available_View (Designated_Type (Desig));
8861 end if;
8863 return
8864 Ekind (Obj_Id) in E_Constant | E_Variable
8865 and then Needs_Finalization (Desig)
8866 and then Nkind (Rel_Node) /= N_Simple_Return_Statement
8867 and then not Is_Part_Of_BIP_Return_Statement (Rel_Node)
8869 -- Do not consider a transient object that was already processed
8871 and then not Is_Finalized_Transient (Obj_Id)
8873 -- Do not consider renamed or 'reference-d transient objects because
8874 -- the act of renaming extends the object's lifetime.
8876 and then not Is_Aliased (Obj_Id, Decl)
8878 -- Do not consider transient objects allocated on the heap since
8879 -- they are attached to a finalization master.
8881 and then not Is_Allocated (Obj_Id)
8883 -- If the transient object is a pointer, check that it is not
8884 -- initialized by a function that returns a pointer or acts as a
8885 -- renaming of another pointer.
8887 and then not
8888 (Is_Access_Type (Obj_Typ) and then Initialized_By_Access (Obj_Id))
8890 -- Do not consider transient objects which act as indirect aliases
8891 -- of build-in-place function results.
8893 and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id)
8895 -- Do not consider iterators because those are treated as normal
8896 -- controlled objects and are processed by the usual finalization
8897 -- machinery. This avoids the double finalization of an iterator.
8899 and then not Is_Iterator (Desig)
8901 -- Do not consider containers in the context of iterator loops. Such
8902 -- transient objects must exist for as long as the loop is around,
8903 -- otherwise any operation carried out by the iterator will fail.
8905 and then not Is_Iterated_Container (Obj_Id, Decl)
8907 -- Likewise for indexed containers in the context of iterator loops
8909 and then not Is_Indexed_Container (Obj_Id, Decl);
8910 end Is_Finalizable_Transient;
8912 ---------------------------------
8913 -- Is_Fully_Repped_Tagged_Type --
8914 ---------------------------------
8916 function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is
8917 U : constant Entity_Id := Underlying_Type (T);
8918 Comp : Entity_Id;
8920 begin
8921 if No (U) or else not Is_Tagged_Type (U) then
8922 return False;
8923 elsif Has_Discriminants (U) then
8924 return False;
8925 elsif not Has_Specified_Layout (U) then
8926 return False;
8927 end if;
8929 -- Here we have a tagged type, see if it has any component (other than
8930 -- tag and parent) with no component_clause. If so, we return False.
8932 Comp := First_Component (U);
8933 while Present (Comp) loop
8934 if not Is_Tag (Comp)
8935 and then Chars (Comp) /= Name_uParent
8936 and then No (Component_Clause (Comp))
8937 then
8938 return False;
8939 else
8940 Next_Component (Comp);
8941 end if;
8942 end loop;
8944 -- All components have clauses
8946 return True;
8947 end Is_Fully_Repped_Tagged_Type;
8949 ----------------------------------
8950 -- Is_Library_Level_Tagged_Type --
8951 ----------------------------------
8953 function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
8954 begin
8955 return Is_Tagged_Type (Typ) and then Is_Library_Level_Entity (Typ);
8956 end Is_Library_Level_Tagged_Type;
8958 --------------------------
8959 -- Is_Non_BIP_Func_Call --
8960 --------------------------
8962 function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is
8963 begin
8964 -- The expected call is of the format
8966 -- Func_Call'reference
8968 return
8969 Nkind (Expr) = N_Reference
8970 and then Nkind (Prefix (Expr)) = N_Function_Call
8971 and then not Is_Build_In_Place_Function_Call (Prefix (Expr));
8972 end Is_Non_BIP_Func_Call;
8974 ----------------------------------
8975 -- Is_Possibly_Unaligned_Object --
8976 ----------------------------------
8978 function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
8979 T : constant Entity_Id := Etype (N);
8981 begin
8982 -- If renamed object, apply test to underlying object
8984 if Is_Entity_Name (N)
8985 and then Is_Object (Entity (N))
8986 and then Present (Renamed_Object (Entity (N)))
8987 then
8988 return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
8989 end if;
8991 -- Tagged and controlled types and aliased types are always aligned, as
8992 -- are concurrent types.
8994 if Is_Aliased (T)
8995 or else Has_Controlled_Component (T)
8996 or else Is_Concurrent_Type (T)
8997 or else Is_Tagged_Type (T)
8998 or else Is_Controlled (T)
8999 then
9000 return False;
9001 end if;
9003 -- If this is an element of a packed array, may be unaligned
9005 if Is_Ref_To_Bit_Packed_Array (N) then
9006 return True;
9007 end if;
9009 -- Case of indexed component reference: test whether prefix is unaligned
9011 if Nkind (N) = N_Indexed_Component then
9012 return Is_Possibly_Unaligned_Object (Prefix (N));
9014 -- Case of selected component reference
9016 elsif Nkind (N) = N_Selected_Component then
9017 declare
9018 P : constant Node_Id := Prefix (N);
9019 C : constant Entity_Id := Entity (Selector_Name (N));
9020 M : Nat;
9021 S : Nat;
9023 begin
9024 -- If component reference is for an array with nonstatic bounds,
9025 -- then it is always aligned: we can only process unaligned arrays
9026 -- with static bounds (more precisely compile time known bounds).
9028 if Is_Array_Type (T)
9029 and then not Compile_Time_Known_Bounds (T)
9030 then
9031 return False;
9032 end if;
9034 -- If component is aliased, it is definitely properly aligned
9036 if Is_Aliased (C) then
9037 return False;
9038 end if;
9040 -- If component is for a type implemented as a scalar, and the
9041 -- record is packed, and the component is other than the first
9042 -- component of the record, then the component may be unaligned.
9044 if Is_Packed (Etype (P))
9045 and then Represented_As_Scalar (Etype (C))
9046 and then First_Entity (Scope (C)) /= C
9047 then
9048 return True;
9049 end if;
9051 -- Compute maximum possible alignment for T
9053 -- If alignment is known, then that settles things
9055 if Known_Alignment (T) then
9056 M := UI_To_Int (Alignment (T));
9058 -- If alignment is not known, tentatively set max alignment
9060 else
9061 M := Ttypes.Maximum_Alignment;
9063 -- We can reduce this if the Esize is known since the default
9064 -- alignment will never be more than the smallest power of 2
9065 -- that does not exceed this Esize value.
9067 if Known_Esize (T) then
9068 S := UI_To_Int (Esize (T));
9070 while (M / 2) >= S loop
9071 M := M / 2;
9072 end loop;
9073 end if;
9074 end if;
9076 -- Case of component clause present which may specify an
9077 -- unaligned position.
9079 if Present (Component_Clause (C)) then
9081 -- Otherwise we can do a test to make sure that the actual
9082 -- start position in the record, and the length, are both
9083 -- consistent with the required alignment. If not, we know
9084 -- that we are unaligned.
9086 declare
9087 Align_In_Bits : constant Nat := M * System_Storage_Unit;
9088 Comp : Entity_Id;
9090 begin
9091 Comp := C;
9093 -- For a component inherited in a record extension, the
9094 -- clause is inherited but position and size are not set.
9096 if Is_Base_Type (Etype (P))
9097 and then Is_Tagged_Type (Etype (P))
9098 and then Present (Original_Record_Component (Comp))
9099 then
9100 Comp := Original_Record_Component (Comp);
9101 end if;
9103 if Component_Bit_Offset (Comp) mod Align_In_Bits /= 0
9104 or else Esize (Comp) mod Align_In_Bits /= 0
9105 then
9106 return True;
9107 end if;
9108 end;
9109 end if;
9111 -- Otherwise, for a component reference, test prefix
9113 return Is_Possibly_Unaligned_Object (P);
9114 end;
9116 -- If not a component reference, must be aligned
9118 else
9119 return False;
9120 end if;
9121 end Is_Possibly_Unaligned_Object;
9123 ---------------------------------
9124 -- Is_Possibly_Unaligned_Slice --
9125 ---------------------------------
9127 function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
9128 begin
9129 -- Go to renamed object
9131 if Is_Entity_Name (N)
9132 and then Is_Object (Entity (N))
9133 and then Present (Renamed_Object (Entity (N)))
9134 then
9135 return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
9136 end if;
9138 -- The reference must be a slice
9140 if Nkind (N) /= N_Slice then
9141 return False;
9142 end if;
9144 -- If it is a slice, then look at the array type being sliced
9146 declare
9147 Sarr : constant Node_Id := Prefix (N);
9148 -- Prefix of the slice, i.e. the array being sliced
9150 Styp : constant Entity_Id := Etype (Prefix (N));
9151 -- Type of the array being sliced
9153 Pref : Node_Id;
9154 Ptyp : Entity_Id;
9156 begin
9157 -- The problems arise if the array object that is being sliced
9158 -- is a component of a record or array, and we cannot guarantee
9159 -- the alignment of the array within its containing object.
9161 -- To investigate this, we look at successive prefixes to see
9162 -- if we have a worrisome indexed or selected component.
9164 Pref := Sarr;
9165 loop
9166 -- Case of array is part of an indexed component reference
9168 if Nkind (Pref) = N_Indexed_Component then
9169 Ptyp := Etype (Prefix (Pref));
9171 -- The only problematic case is when the array is packed, in
9172 -- which case we really know nothing about the alignment of
9173 -- individual components.
9175 if Is_Bit_Packed_Array (Ptyp) then
9176 return True;
9177 end if;
9179 -- Case of array is part of a selected component reference
9181 elsif Nkind (Pref) = N_Selected_Component then
9182 Ptyp := Etype (Prefix (Pref));
9184 -- We are definitely in trouble if the record in question
9185 -- has an alignment, and either we know this alignment is
9186 -- inconsistent with the alignment of the slice, or we don't
9187 -- know what the alignment of the slice should be. But this
9188 -- really matters only if the target has strict alignment.
9190 if Target_Strict_Alignment
9191 and then Known_Alignment (Ptyp)
9192 and then (not Known_Alignment (Styp)
9193 or else Alignment (Styp) > Alignment (Ptyp))
9194 then
9195 return True;
9196 end if;
9198 -- We are in potential trouble if the record type is packed.
9199 -- We could special case when we know that the array is the
9200 -- first component, but that's not such a simple case ???
9202 if Is_Packed (Ptyp) then
9203 return True;
9204 end if;
9206 -- We are in trouble if there is a component clause, and
9207 -- either we do not know the alignment of the slice, or
9208 -- the alignment of the slice is inconsistent with the
9209 -- bit position specified by the component clause.
9211 declare
9212 Field : constant Entity_Id := Entity (Selector_Name (Pref));
9213 begin
9214 if Present (Component_Clause (Field))
9215 and then
9216 (not Known_Alignment (Styp)
9217 or else
9218 (Component_Bit_Offset (Field) mod
9219 (System_Storage_Unit * Alignment (Styp))) /= 0)
9220 then
9221 return True;
9222 end if;
9223 end;
9225 -- For cases other than selected or indexed components we know we
9226 -- are OK, since no issues arise over alignment.
9228 else
9229 return False;
9230 end if;
9232 -- We processed an indexed component or selected component
9233 -- reference that looked safe, so keep checking prefixes.
9235 Pref := Prefix (Pref);
9236 end loop;
9237 end;
9238 end Is_Possibly_Unaligned_Slice;
9240 -------------------------------
9241 -- Is_Related_To_Func_Return --
9242 -------------------------------
9244 function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is
9245 Expr : constant Node_Id := Related_Expression (Id);
9246 begin
9247 -- In the case of a function with a class-wide result that returns
9248 -- a call to a function with a specific result, we introduce a
9249 -- type conversion for the return expression. We do not want that
9250 -- type conversion to influence the result of this function.
9252 return
9253 Present (Expr)
9254 and then Nkind (Unqual_Conv (Expr)) = N_Explicit_Dereference
9255 and then (Nkind (Parent (Expr)) = N_Simple_Return_Statement
9256 or else
9257 (Nkind (Parent (Expr)) in N_Object_Declaration
9258 | N_Object_Renaming_Declaration
9259 and then
9260 Is_Return_Object (Defining_Entity (Parent (Expr)))));
9261 end Is_Related_To_Func_Return;
9263 --------------------------------
9264 -- Is_Ref_To_Bit_Packed_Array --
9265 --------------------------------
9267 function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
9268 Result : Boolean;
9269 Expr : Node_Id;
9271 begin
9272 if Is_Entity_Name (N)
9273 and then Is_Object (Entity (N))
9274 and then Present (Renamed_Object (Entity (N)))
9275 then
9276 return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
9277 end if;
9279 if Nkind (N) in N_Indexed_Component | N_Selected_Component then
9280 if Is_Bit_Packed_Array (Etype (Prefix (N))) then
9281 Result := True;
9282 else
9283 Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
9284 end if;
9286 if Result and then Nkind (N) = N_Indexed_Component then
9287 Expr := First (Expressions (N));
9288 while Present (Expr) loop
9289 Force_Evaluation (Expr);
9290 Next (Expr);
9291 end loop;
9292 end if;
9294 return Result;
9296 else
9297 return False;
9298 end if;
9299 end Is_Ref_To_Bit_Packed_Array;
9301 --------------------------------
9302 -- Is_Ref_To_Bit_Packed_Slice --
9303 --------------------------------
9305 function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
9306 begin
9307 if Nkind (N) = N_Type_Conversion then
9308 return Is_Ref_To_Bit_Packed_Slice (Expression (N));
9310 elsif Is_Entity_Name (N)
9311 and then Is_Object (Entity (N))
9312 and then Present (Renamed_Object (Entity (N)))
9313 then
9314 return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
9316 elsif Nkind (N) = N_Slice
9317 and then Is_Bit_Packed_Array (Etype (Prefix (N)))
9318 then
9319 return True;
9321 elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then
9322 return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
9324 else
9325 return False;
9326 end if;
9327 end Is_Ref_To_Bit_Packed_Slice;
9329 -----------------------
9330 -- Is_Renamed_Object --
9331 -----------------------
9333 function Is_Renamed_Object (N : Node_Id) return Boolean is
9334 Pnod : constant Node_Id := Parent (N);
9335 Kind : constant Node_Kind := Nkind (Pnod);
9336 begin
9337 if Kind = N_Object_Renaming_Declaration then
9338 return True;
9339 elsif Kind in N_Indexed_Component | N_Selected_Component then
9340 return Is_Renamed_Object (Pnod);
9341 else
9342 return False;
9343 end if;
9344 end Is_Renamed_Object;
9346 --------------------------------------
9347 -- Is_Secondary_Stack_BIP_Func_Call --
9348 --------------------------------------
9350 function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is
9351 Actual : Node_Id;
9352 Call : Node_Id := Expr;
9353 Formal : Node_Id;
9354 Param : Node_Id;
9356 begin
9357 -- Build-in-place calls usually appear in 'reference format. Note that
9358 -- the accessibility check machinery may add an extra 'reference due to
9359 -- side-effect removal.
9361 while Nkind (Call) = N_Reference loop
9362 Call := Prefix (Call);
9363 end loop;
9365 Call := Unqual_Conv (Call);
9367 if Is_Build_In_Place_Function_Call (Call) then
9369 -- Examine all parameter associations of the function call
9371 Param := First (Parameter_Associations (Call));
9372 while Present (Param) loop
9373 if Nkind (Param) = N_Parameter_Association then
9374 Formal := Selector_Name (Param);
9375 Actual := Explicit_Actual_Parameter (Param);
9377 -- A match for BIPalloc => 2 has been found
9379 if Is_Build_In_Place_Entity (Formal)
9380 and then BIP_Suffix_Kind (Formal) = BIP_Alloc_Form
9381 and then Nkind (Actual) = N_Integer_Literal
9382 and then Intval (Actual) = Uint_2
9383 then
9384 return True;
9385 end if;
9386 end if;
9388 Next (Param);
9389 end loop;
9390 end if;
9392 return False;
9393 end Is_Secondary_Stack_BIP_Func_Call;
9395 ------------------------------
9396 -- Is_Secondary_Stack_Thunk --
9397 ------------------------------
9399 function Is_Secondary_Stack_Thunk (Id : Entity_Id) return Boolean is
9400 begin
9401 return Ekind (Id) = E_Function
9402 and then Is_Thunk (Id)
9403 and then Has_Controlling_Result (Id);
9404 end Is_Secondary_Stack_Thunk;
9406 ----------------------------
9407 -- Is_Statically_Disabled --
9408 ----------------------------
9410 function Is_Statically_Disabled
9411 (N : Node_Id;
9412 Value : Boolean;
9413 Include_Valid : Boolean)
9414 return Boolean
9416 function Is_Discrete_Literal (N : Node_Id) return Boolean;
9417 -- Returns whether N is an integer, character or enumeration literal
9419 -------------------------
9420 -- Is_Discrete_Literal --
9421 -------------------------
9423 function Is_Discrete_Literal (N : Node_Id) return Boolean is
9424 (Nkind (N) in N_Integer_Literal | N_Character_Literal
9425 or else (Nkind (N) in N_Identifier | N_Expanded_Name
9426 and then Ekind (Entity (N)) = E_Enumeration_Literal));
9428 Expr_N : constant Node_Id :=
9429 (if Is_Static_Expression (N)
9430 and then Entity (N) in Standard_True | Standard_False
9431 and then Is_Rewrite_Substitution (N)
9432 then Original_Node (N)
9433 else N);
9435 -- Start of processing for Is_Statically_Disabled
9437 begin
9438 -- A "statically disabled" condition which evaluates to Value is either:
9440 case Nkind (Expr_N) is
9442 -- an AND or AND THEN operator when:
9443 -- - Value is True and both operands are statically disabled
9444 -- conditions evaluated to True.
9445 -- - Value is False and at least one operand is a statically disabled
9446 -- condition evaluated to False.
9448 when N_Op_And | N_And_Then =>
9449 return
9450 (if Value then
9451 (Is_Statically_Disabled
9452 (Left_Opnd (Expr_N), Value, Include_Valid)
9453 and then Is_Statically_Disabled
9454 (Right_Opnd (Expr_N), Value, Include_Valid))
9455 else
9456 (Is_Statically_Disabled
9457 (Left_Opnd (Expr_N), Value, Include_Valid)
9458 or else Is_Statically_Disabled
9459 (Right_Opnd (Expr_N), Value, Include_Valid)));
9461 -- an OR or OR ELSE operator when:
9462 -- - Value is True and at least one operand is a statically disabled
9463 -- condition evaluated to True.
9464 -- - Value is False and both operands are statically disabled
9465 -- conditions evaluated to False.
9467 when N_Op_Or | N_Or_Else =>
9468 return
9469 (if Value then
9470 (Is_Statically_Disabled
9471 (Left_Opnd (Expr_N), Value, Include_Valid)
9472 or else Is_Statically_Disabled
9473 (Right_Opnd (Expr_N), Value, Include_Valid))
9474 else
9475 (Is_Statically_Disabled
9476 (Left_Opnd (Expr_N), Value, Include_Valid)
9477 and then Is_Statically_Disabled
9478 (Right_Opnd (Expr_N), Value, Include_Valid)));
9480 -- a NOT operator when the right operand is a statically disabled
9481 -- condition evaluated to the negation of Value.
9483 when N_Op_Not =>
9484 return Is_Statically_Disabled
9485 (Right_Opnd (Expr_N), not Value, Include_Valid);
9487 -- a static constant when it is of a boolean type with aspect
9488 -- Warnings Off.
9490 when N_Identifier | N_Expanded_Name =>
9491 return Is_Static_Expression (Expr_N)
9492 and then Value = Is_True (Expr_Value (Expr_N))
9493 and then Ekind (Entity (Expr_N)) = E_Constant
9494 and then Has_Warnings_Off (Entity (Expr_N));
9496 -- a relational_operator where one operand is a static constant with
9497 -- aspect Warnings Off and the other operand is a literal of the
9498 -- corresponding type.
9500 when N_Op_Compare =>
9501 declare
9502 Left : constant Node_Id := Left_Opnd (Expr_N);
9503 Right : constant Node_Id := Right_Opnd (Expr_N);
9504 begin
9505 return
9506 Is_Static_Expression (N)
9507 and then Value = Is_True (Expr_Value (N))
9508 and then
9509 ((Is_Discrete_Literal (Right)
9510 and then Nkind (Left) in N_Identifier
9511 | N_Expanded_Name
9512 and then Ekind (Entity (Left)) = E_Constant
9513 and then Has_Warnings_Off (Entity (Left)))
9514 or else
9515 (Is_Discrete_Literal (Left)
9516 and then Nkind (Right) in N_Identifier
9517 | N_Expanded_Name
9518 and then Ekind (Entity (Right)) = E_Constant
9519 and then Has_Warnings_Off (Entity (Right))));
9520 end;
9522 -- a reference to 'Valid or 'Valid_Scalar if Include_Valid is True
9524 when N_Attribute_Reference =>
9525 return Include_Valid
9526 and then Get_Attribute_Id (Attribute_Name (Expr_N)) in
9527 Attribute_Valid | Attribute_Valid_Scalars
9528 and then Value;
9530 when others =>
9531 return False;
9532 end case;
9533 end Is_Statically_Disabled;
9535 --------------------------------
9536 -- Is_Uninitialized_Aggregate --
9537 --------------------------------
9539 function Is_Uninitialized_Aggregate
9540 (Exp : Node_Id;
9541 T : Entity_Id) return Boolean
9543 Comp : Node_Id;
9544 Comp_Type : Entity_Id;
9545 Typ : Entity_Id;
9547 begin
9548 if Nkind (Exp) /= N_Aggregate then
9549 return False;
9550 end if;
9552 Preanalyze_And_Resolve (Exp, T);
9553 Typ := Etype (Exp);
9555 if No (Typ)
9556 or else Ekind (Typ) /= E_Array_Subtype
9557 or else Present (Expressions (Exp))
9558 or else No (Component_Associations (Exp))
9559 then
9560 return False;
9561 else
9562 Comp_Type := Component_Type (Typ);
9563 Comp := First (Component_Associations (Exp));
9565 if not Box_Present (Comp)
9566 or else Present (Next (Comp))
9567 then
9568 return False;
9569 end if;
9571 return Is_Scalar_Type (Comp_Type)
9572 and then No (Default_Aspect_Component_Value (Typ));
9573 end if;
9574 end Is_Uninitialized_Aggregate;
9576 ----------------------------
9577 -- Is_Untagged_Derivation --
9578 ----------------------------
9580 function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
9581 begin
9582 return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
9583 or else
9584 (Is_Private_Type (T) and then Present (Full_View (T))
9585 and then not Is_Tagged_Type (Full_View (T))
9586 and then Is_Derived_Type (Full_View (T))
9587 and then Etype (Full_View (T)) /= T);
9588 end Is_Untagged_Derivation;
9590 ------------------------------------
9591 -- Is_Untagged_Private_Derivation --
9592 ------------------------------------
9594 function Is_Untagged_Private_Derivation
9595 (Priv_Typ : Entity_Id;
9596 Full_Typ : Entity_Id) return Boolean
9598 begin
9599 return
9600 Present (Priv_Typ)
9601 and then Is_Untagged_Derivation (Priv_Typ)
9602 and then Is_Private_Type (Etype (Priv_Typ))
9603 and then Present (Full_Typ)
9604 and then Is_Itype (Full_Typ);
9605 end Is_Untagged_Private_Derivation;
9607 ------------------------------
9608 -- Is_Verifiable_DIC_Pragma --
9609 ------------------------------
9611 function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean is
9612 Args : constant List_Id := Pragma_Argument_Associations (Prag);
9614 begin
9615 -- To qualify as verifiable, a DIC pragma must have a non-null argument
9617 return
9618 Present (Args)
9620 -- If there are args, but the first arg is Empty, then treat the
9621 -- pragma the same as having no args (there may be a second arg that
9622 -- is an implicitly added type arg, and Empty is a placeholder).
9624 and then Present (Get_Pragma_Arg (First (Args)))
9626 and then Nkind (Get_Pragma_Arg (First (Args))) /= N_Null;
9627 end Is_Verifiable_DIC_Pragma;
9629 ---------------------------
9630 -- Is_Volatile_Reference --
9631 ---------------------------
9633 function Is_Volatile_Reference (N : Node_Id) return Boolean is
9634 begin
9635 -- Only source references are to be treated as volatile, internally
9636 -- generated stuff cannot have volatile external effects.
9638 if not Comes_From_Source (N) then
9639 return False;
9641 -- Never true for reference to a type
9643 elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then
9644 return False;
9646 -- Never true for a compile time known constant
9648 elsif Compile_Time_Known_Value (N) then
9649 return False;
9651 -- True if object reference with volatile type
9653 elsif Is_Volatile_Object_Ref (N) then
9654 return True;
9656 -- True if reference to volatile entity
9658 elsif Is_Entity_Name (N) then
9659 return Treat_As_Volatile (Entity (N));
9661 -- True for slice of volatile array
9663 elsif Nkind (N) = N_Slice then
9664 return Is_Volatile_Reference (Prefix (N));
9666 -- True if volatile component
9668 elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then
9669 if (Is_Entity_Name (Prefix (N))
9670 and then Has_Volatile_Components (Entity (Prefix (N))))
9671 or else (Present (Etype (Prefix (N)))
9672 and then Has_Volatile_Components (Etype (Prefix (N))))
9673 then
9674 return True;
9675 else
9676 return Is_Volatile_Reference (Prefix (N));
9677 end if;
9679 -- Otherwise false
9681 else
9682 return False;
9683 end if;
9684 end Is_Volatile_Reference;
9686 --------------------
9687 -- Kill_Dead_Code --
9688 --------------------
9690 procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
9691 W : Boolean := Warn;
9692 -- Set False if warnings suppressed
9694 begin
9695 if Present (N) then
9696 Remove_Warning_Messages (N);
9698 -- Update the internal structures of the ABE mechanism in case the
9699 -- dead node is an elaboration scenario.
9701 Kill_Elaboration_Scenario (N);
9703 -- Generate warning if appropriate
9705 if W then
9707 -- We suppress the warning if this code is under control of an
9708 -- if/case statement and either
9709 -- a) we are in an instance and the condition/selector
9710 -- has a statically known value; or
9711 -- b) the selector of a case statement is a simple identifier
9712 -- and warnings off is set for this identifier; or
9713 -- c) the condition of an if statement is a "statically
9714 -- disabled" condition which evaluates to False as described
9715 -- in section 7.3.2 of SPARK User's Guide.
9716 -- Dead code is common and reasonable in instances, so we don't
9717 -- want a warning in that case.
9719 declare
9720 C : Node_Id := Empty;
9721 begin
9722 if Nkind (Parent (N)) = N_If_Statement then
9723 C := Condition (Parent (N));
9725 if Is_Statically_Disabled
9726 (C, Value => False, Include_Valid => False)
9727 then
9728 W := False;
9729 end if;
9731 elsif Nkind (Parent (N)) = N_Case_Statement_Alternative then
9732 C := Expression (Parent (Parent (N)));
9734 if Nkind (C) = N_Identifier
9735 and then Present (Entity (C))
9736 and then Has_Warnings_Off (Entity (C))
9737 then
9738 W := False;
9739 end if;
9740 end if;
9742 if Present (C)
9743 and then (In_Instance and Compile_Time_Known_Value (C))
9744 then
9745 W := False;
9746 end if;
9747 end;
9749 -- Generate warning if not suppressed
9751 if W then
9752 Error_Msg_F
9753 ("?t?this code can never be executed and has been deleted!",
9755 end if;
9756 end if;
9758 -- Recurse into block statements and bodies to process declarations
9759 -- and statements.
9761 if Nkind (N) = N_Block_Statement
9762 or else Nkind (N) = N_Subprogram_Body
9763 or else Nkind (N) = N_Package_Body
9764 then
9765 Kill_Dead_Code (Declarations (N), False);
9766 Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
9768 if Nkind (N) = N_Subprogram_Body then
9769 Set_Is_Eliminated (Defining_Entity (N));
9770 end if;
9772 elsif Nkind (N) = N_Package_Declaration then
9773 Kill_Dead_Code (Visible_Declarations (Specification (N)));
9774 Kill_Dead_Code (Private_Declarations (Specification (N)));
9776 -- ??? After this point, Delete_Tree has been called on all
9777 -- declarations in Specification (N), so references to entities
9778 -- therein look suspicious.
9780 declare
9781 E : Entity_Id := First_Entity (Defining_Entity (N));
9783 begin
9784 while Present (E) loop
9785 if Ekind (E) = E_Operator then
9786 Set_Is_Eliminated (E);
9787 end if;
9789 Next_Entity (E);
9790 end loop;
9791 end;
9793 -- Recurse into composite statement to kill individual statements in
9794 -- particular instantiations.
9796 elsif Nkind (N) = N_If_Statement then
9797 Kill_Dead_Code (Then_Statements (N));
9798 Kill_Dead_Code (Elsif_Parts (N));
9799 Kill_Dead_Code (Else_Statements (N));
9801 elsif Nkind (N) = N_Loop_Statement then
9802 Kill_Dead_Code (Statements (N));
9804 elsif Nkind (N) = N_Case_Statement then
9805 declare
9806 Alt : Node_Id;
9807 begin
9808 Alt := First (Alternatives (N));
9809 while Present (Alt) loop
9810 Kill_Dead_Code (Statements (Alt));
9811 Next (Alt);
9812 end loop;
9813 end;
9815 elsif Nkind (N) = N_Case_Statement_Alternative then
9816 Kill_Dead_Code (Statements (N));
9818 -- Deal with dead instances caused by deleting instantiations
9820 elsif Nkind (N) in N_Generic_Instantiation then
9821 Remove_Dead_Instance (N);
9822 end if;
9823 end if;
9824 end Kill_Dead_Code;
9826 -- Case where argument is a list of nodes to be killed
9828 procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
9829 N : Node_Id;
9830 W : Boolean;
9832 begin
9833 W := Warn;
9835 N := First (L);
9836 while Present (N) loop
9837 Kill_Dead_Code (N, W);
9838 W := False;
9839 Next (N);
9840 end loop;
9841 end Kill_Dead_Code;
9843 -----------------------------
9844 -- Make_CW_Equivalent_Type --
9845 -----------------------------
9847 -- Create a record type used as an equivalent of any member of the class
9848 -- which takes its size from exp.
9850 -- Generate the following code:
9852 -- type Equiv_T is record
9853 -- _parent : T (List of discriminant constraints taken from Exp);
9854 -- Cnn : Storage_Array (1 .. (Exp'size - Typ'object_size)/Storage_Unit);
9855 -- end Equiv_T;
9857 -- Note that this type does not guarantee same alignment as all derived
9858 -- types.
9860 -- Note: for the freezing circuitry, this looks like a record extension,
9861 -- and so we need to make sure that the scalar storage order is the same
9862 -- as that of the parent type. (This does not change anything for the
9863 -- representation of the extension part.)
9865 function Make_CW_Equivalent_Type
9866 (T : Entity_Id;
9867 E : Node_Id) return Entity_Id
9869 Loc : constant Source_Ptr := Sloc (E);
9870 Root_Typ : constant Entity_Id := Root_Type (T);
9871 Root_Utyp : constant Entity_Id := Underlying_Type (Root_Typ);
9872 List_Def : constant List_Id := Empty_List;
9873 Comp_List : constant List_Id := New_List;
9875 Equiv_Type : Entity_Id;
9876 Range_Type : Entity_Id;
9877 Str_Type : Entity_Id;
9878 Constr_Root : Entity_Id;
9879 Size_Attr : Node_Id;
9880 Size_Expr : Node_Id;
9882 begin
9883 -- If the root type is already constrained, there are no discriminants
9884 -- in the expression.
9886 if not Has_Discriminants (Root_Typ)
9887 or else Is_Constrained (Root_Typ)
9888 then
9889 Constr_Root := Root_Typ;
9891 -- At this point in the expansion, nonlimited view of the type
9892 -- must be available, otherwise the error will be reported later.
9894 if From_Limited_With (Constr_Root)
9895 and then Present (Non_Limited_View (Constr_Root))
9896 then
9897 Constr_Root := Non_Limited_View (Constr_Root);
9898 end if;
9900 else
9901 Constr_Root := Make_Temporary (Loc, 'R');
9903 -- subtype cstr__n is T (List of discr constraints taken from Exp)
9905 Append_To (List_Def,
9906 Make_Subtype_Declaration (Loc,
9907 Defining_Identifier => Constr_Root,
9908 Subtype_Indication => Make_Subtype_From_Expr (E, Root_Typ)));
9909 end if;
9911 -- Generate the range subtype declaration
9913 Range_Type := Make_Temporary (Loc, 'G');
9915 -- If the expression is known to have the tag of its type, then we can
9916 -- use it directly for the prefix of the Size attribute; otherwise we
9917 -- need to convert it first to the class-wide type to force a call to
9918 -- the _Size primitive operation.
9920 if Has_Tag_Of_Type (E) then
9921 if not Has_Discriminants (Etype (E))
9922 or else Is_Constrained (Etype (E))
9923 then
9924 Size_Attr :=
9925 Make_Attribute_Reference (Loc,
9926 Prefix => New_Occurrence_Of (Etype (E), Loc),
9927 Attribute_Name => Name_Object_Size);
9929 else
9930 Size_Attr :=
9931 Make_Attribute_Reference (Loc,
9932 Prefix => Duplicate_Subexpr_No_Checks (E),
9933 Attribute_Name => Name_Size);
9934 end if;
9936 else
9937 Size_Attr :=
9938 Make_Attribute_Reference (Loc,
9939 Prefix => OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
9940 Attribute_Name => Name_Size);
9941 end if;
9943 if not Is_Interface (Root_Typ) then
9945 -- subtype rg__xx is
9946 -- Storage_Offset range 1 .. (Exp'size - Typ'object_size)
9947 -- / Storage_Unit
9949 Size_Expr :=
9950 Make_Op_Subtract (Loc,
9951 Left_Opnd => Size_Attr,
9952 Right_Opnd =>
9953 Make_Attribute_Reference (Loc,
9954 Prefix => New_Occurrence_Of (Constr_Root, Loc),
9955 Attribute_Name => Name_Object_Size));
9956 else
9957 -- subtype rg__xx is
9958 -- Storage_Offset range 1 .. (Exp'size - Ada.Tags.Tag'object_size)
9959 -- / Storage_Unit
9961 Size_Expr :=
9962 Make_Op_Subtract (Loc,
9963 Left_Opnd => Size_Attr,
9964 Right_Opnd =>
9965 Make_Attribute_Reference (Loc,
9966 Prefix => New_Occurrence_Of (RTE (RE_Tag), Loc),
9967 Attribute_Name => Name_Object_Size));
9968 end if;
9970 Set_Paren_Count (Size_Expr, 1);
9972 Append_To (List_Def,
9973 Make_Subtype_Declaration (Loc,
9974 Defining_Identifier => Range_Type,
9975 Subtype_Indication =>
9976 Make_Subtype_Indication (Loc,
9977 Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
9978 Constraint => Make_Range_Constraint (Loc,
9979 Range_Expression =>
9980 Make_Range (Loc,
9981 Low_Bound => Make_Integer_Literal (Loc, 1),
9982 High_Bound =>
9983 Make_Op_Divide (Loc,
9984 Left_Opnd => Size_Expr,
9985 Right_Opnd => Make_Integer_Literal (Loc,
9986 Intval => System_Storage_Unit)))))));
9988 -- subtype str__nn is Storage_Array (rg__x);
9990 Str_Type := Make_Temporary (Loc, 'S');
9991 Append_To (List_Def,
9992 Make_Subtype_Declaration (Loc,
9993 Defining_Identifier => Str_Type,
9994 Subtype_Indication =>
9995 Make_Subtype_Indication (Loc,
9996 Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Array), Loc),
9997 Constraint =>
9998 Make_Index_Or_Discriminant_Constraint (Loc,
9999 Constraints =>
10000 New_List (New_Occurrence_Of (Range_Type, Loc))))));
10002 -- type Equiv_T is record
10003 -- _Parent : Snn; -- not interface
10004 -- _Tag : Ada.Tags.Tag -- interface
10005 -- Cnn : Str_Type;
10006 -- end Equiv_T;
10008 Equiv_Type := Make_Temporary (Loc, 'T');
10009 Mutate_Ekind (Equiv_Type, E_Record_Type);
10011 if not Is_Interface (Root_Typ) then
10012 Set_Parent_Subtype (Equiv_Type, Constr_Root);
10013 end if;
10015 -- Set Is_Class_Wide_Equivalent_Type very early to trigger the special
10016 -- treatment for this type. In particular, even though _parent's type
10017 -- is a controlled type or contains controlled components, we do not
10018 -- want to set Has_Controlled_Component on it to avoid making it gain
10019 -- an unwanted _controller component.
10021 Set_Is_Class_Wide_Equivalent_Type (Equiv_Type);
10023 -- A class-wide equivalent type does not require initialization
10025 Set_Suppress_Initialization (Equiv_Type);
10027 if not Is_Interface (Root_Typ) then
10028 Append_To (Comp_List,
10029 Make_Component_Declaration (Loc,
10030 Defining_Identifier =>
10031 Make_Defining_Identifier (Loc, Name_uParent),
10032 Component_Definition =>
10033 Make_Component_Definition (Loc,
10034 Aliased_Present => False,
10035 Subtype_Indication => New_Occurrence_Of (Constr_Root, Loc))));
10037 Set_Reverse_Storage_Order
10038 (Equiv_Type, Reverse_Storage_Order (Base_Type (Root_Utyp)));
10039 Set_Reverse_Bit_Order
10040 (Equiv_Type, Reverse_Bit_Order (Base_Type (Root_Utyp)));
10042 else
10043 Append_To (Comp_List,
10044 Make_Component_Declaration (Loc,
10045 Defining_Identifier =>
10046 Make_Defining_Identifier (Loc, Name_uTag),
10047 Component_Definition =>
10048 Make_Component_Definition (Loc,
10049 Aliased_Present => False,
10050 Subtype_Indication =>
10051 New_Occurrence_Of (RTE (RE_Tag), Loc))));
10052 end if;
10054 Append_To (Comp_List,
10055 Make_Component_Declaration (Loc,
10056 Defining_Identifier => Make_Temporary (Loc, 'C'),
10057 Component_Definition =>
10058 Make_Component_Definition (Loc,
10059 Aliased_Present => False,
10060 Subtype_Indication => New_Occurrence_Of (Str_Type, Loc))));
10062 Append_To (List_Def,
10063 Make_Full_Type_Declaration (Loc,
10064 Defining_Identifier => Equiv_Type,
10065 Type_Definition =>
10066 Make_Record_Definition (Loc,
10067 Component_List =>
10068 Make_Component_List (Loc,
10069 Component_Items => Comp_List,
10070 Variant_Part => Empty))));
10072 -- Suppress all checks during the analysis of the expanded code to avoid
10073 -- the generation of spurious warnings under ZFP run-time.
10075 Insert_Actions (E, List_Def, Suppress => All_Checks);
10077 -- In the case of an interface type mark the tag for First_Tag_Component
10079 if Is_Interface (Root_Typ) then
10080 Set_Is_Tag (First_Entity (Equiv_Type));
10081 end if;
10083 return Equiv_Type;
10084 end Make_CW_Equivalent_Type;
10086 -------------------------
10087 -- Make_Invariant_Call --
10088 -------------------------
10090 function Make_Invariant_Call (Expr : Node_Id) return Node_Id is
10091 Loc : constant Source_Ptr := Sloc (Expr);
10092 Typ : constant Entity_Id := Base_Type (Etype (Expr));
10093 pragma Assert (Has_Invariants (Typ));
10094 Proc_Id : constant Entity_Id := Invariant_Procedure (Typ);
10095 pragma Assert (Present (Proc_Id));
10096 Inv_Typ : constant Entity_Id
10097 := Base_Type (Etype (First_Formal (Proc_Id)));
10099 Arg : Node_Id;
10101 begin
10102 -- The invariant procedure has a null body if assertions are disabled or
10103 -- Assertion_Policy Ignore is in effect. In that case, generate a null
10104 -- statement instead of a call to the invariant procedure.
10106 if Has_Null_Body (Proc_Id) then
10107 return Make_Null_Statement (Loc);
10109 else
10110 -- As done elsewhere, for example in Build_Initialization_Call, we
10111 -- may need to bridge the gap between views of the type.
10113 if Inv_Typ /= Typ then
10114 Arg := OK_Convert_To (Inv_Typ, Expr);
10115 else
10116 Arg := Relocate_Node (Expr);
10117 end if;
10119 return
10120 Make_Procedure_Call_Statement (Loc,
10121 Name => New_Occurrence_Of (Proc_Id, Loc),
10122 Parameter_Associations => New_List (Arg));
10123 end if;
10124 end Make_Invariant_Call;
10126 ------------------------
10127 -- Make_Literal_Range --
10128 ------------------------
10130 function Make_Literal_Range
10131 (Loc : Source_Ptr;
10132 Literal_Typ : Entity_Id) return Node_Id
10134 Lo : constant Node_Id :=
10135 New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
10136 Index : constant Entity_Id := Etype (Lo);
10137 Length_Expr : constant Node_Id :=
10138 Make_Op_Subtract (Loc,
10139 Left_Opnd =>
10140 Make_Integer_Literal (Loc,
10141 Intval => String_Literal_Length (Literal_Typ)),
10142 Right_Opnd => Make_Integer_Literal (Loc, 1));
10144 Hi : Node_Id;
10146 begin
10147 Set_Analyzed (Lo, False);
10149 if Is_Integer_Type (Index) then
10150 Hi :=
10151 Make_Op_Add (Loc,
10152 Left_Opnd => New_Copy_Tree (Lo),
10153 Right_Opnd => Length_Expr);
10154 else
10155 Hi :=
10156 Make_Attribute_Reference (Loc,
10157 Attribute_Name => Name_Val,
10158 Prefix => New_Occurrence_Of (Index, Loc),
10159 Expressions => New_List (
10160 Make_Op_Add (Loc,
10161 Left_Opnd =>
10162 Make_Attribute_Reference (Loc,
10163 Attribute_Name => Name_Pos,
10164 Prefix => New_Occurrence_Of (Index, Loc),
10165 Expressions => New_List (New_Copy_Tree (Lo))),
10166 Right_Opnd => Length_Expr)));
10167 end if;
10169 return
10170 Make_Range (Loc,
10171 Low_Bound => Lo,
10172 High_Bound => Hi);
10173 end Make_Literal_Range;
10175 --------------------------
10176 -- Make_Non_Empty_Check --
10177 --------------------------
10179 function Make_Non_Empty_Check
10180 (Loc : Source_Ptr;
10181 N : Node_Id) return Node_Id
10183 begin
10184 return
10185 Make_Op_Ne (Loc,
10186 Left_Opnd =>
10187 Make_Attribute_Reference (Loc,
10188 Attribute_Name => Name_Length,
10189 Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
10190 Right_Opnd =>
10191 Make_Integer_Literal (Loc, 0));
10192 end Make_Non_Empty_Check;
10194 -------------------------
10195 -- Make_Predicate_Call --
10196 -------------------------
10198 -- WARNING: This routine manages Ghost regions. Return statements must be
10199 -- replaced by gotos which jump to the end of the routine and restore the
10200 -- Ghost mode.
10202 function Make_Predicate_Call
10203 (Typ : Entity_Id;
10204 Expr : Node_Id;
10205 Static_Mem : Boolean := False;
10206 Dynamic_Mem : Node_Id := Empty) return Node_Id
10208 Loc : constant Source_Ptr := Sloc (Expr);
10210 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
10211 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
10212 -- Save the Ghost-related attributes to restore on exit
10214 Call : Node_Id;
10215 Func_Id : Entity_Id;
10216 Param_Assocs : List_Id;
10217 begin
10218 Func_Id := Predicate_Function (Typ);
10219 pragma Assert (Present (Func_Id));
10221 -- The related type may be subject to pragma Ghost. Set the mode now to
10222 -- ensure that the call is properly marked as Ghost.
10224 Set_Ghost_Mode (Typ);
10226 -- Case of calling normal predicate function
10228 -- If the type is tagged, the expression may be class-wide, in which
10229 -- case it has to be converted to its root type, given that the
10230 -- generated predicate function is not dispatching. The conversion is
10231 -- type-safe and does not need validation, which matters when private
10232 -- extensions are involved.
10234 if Is_Tagged_Type (Typ) then
10235 Param_Assocs := New_List (OK_Convert_To (Typ, Relocate_Node (Expr)));
10236 else
10237 Param_Assocs := New_List (Relocate_Node (Expr));
10238 end if;
10240 if Predicate_Function_Needs_Membership_Parameter (Typ) then
10241 -- Pass in parameter indicating whether this call is for a
10242 -- membership test.
10243 Append ((if Present (Dynamic_Mem)
10244 then Dynamic_Mem
10245 else New_Occurrence_Of
10246 (Boolean_Literals (Static_Mem), Loc)),
10247 Param_Assocs);
10248 end if;
10250 Call :=
10251 Make_Function_Call (Loc,
10252 Name => New_Occurrence_Of (Func_Id, Loc),
10253 Parameter_Associations => Param_Assocs);
10255 Restore_Ghost_Region (Saved_GM, Saved_IGR);
10257 return Call;
10258 end Make_Predicate_Call;
10260 --------------------------
10261 -- Make_Predicate_Check --
10262 --------------------------
10264 function Make_Predicate_Check
10265 (Typ : Entity_Id;
10266 Expr : Node_Id) return Node_Id
10268 Loc : constant Source_Ptr := Sloc (Expr);
10270 -- Local variables
10272 Args : List_Id;
10273 Nam : Name_Id;
10275 -- Start of processing for Make_Predicate_Check
10277 begin
10278 -- If predicate checks are suppressed, then return a null statement. For
10279 -- this call, we check only the scope setting. If the caller wants to
10280 -- check a specific entity's setting, they must do it manually.
10282 if Predicate_Checks_Suppressed (Empty) then
10283 return Make_Null_Statement (Loc);
10284 end if;
10286 -- Do not generate a check within stream functions and the like.
10288 if not Predicate_Check_In_Scope (Expr) then
10289 return Make_Null_Statement (Loc);
10290 end if;
10292 -- Compute proper name to use, we need to get this right so that the
10293 -- right set of check policies apply to the Check pragma we are making.
10294 -- The presence or not of a Ghost_Predicate does not influence the
10295 -- choice of the applicable check policy.
10297 if Has_Dynamic_Predicate_Aspect (Typ) then
10298 Nam := Name_Dynamic_Predicate;
10299 elsif Has_Static_Predicate_Aspect (Typ) then
10300 Nam := Name_Static_Predicate;
10301 else
10302 Nam := Name_Predicate;
10303 end if;
10305 Args := New_List (
10306 Make_Pragma_Argument_Association (Loc,
10307 Expression => Make_Identifier (Loc, Nam)),
10308 Make_Pragma_Argument_Association (Loc,
10309 Expression => Make_Predicate_Call (Typ, Expr)));
10311 -- If the subtype is subject to pragma Predicate_Failure, add the
10312 -- failure expression as an additional parameter.
10314 return
10315 Make_Pragma (Loc,
10316 Chars => Name_Check,
10317 Pragma_Argument_Associations => Args);
10318 end Make_Predicate_Check;
10320 ----------------------------
10321 -- Make_Subtype_From_Expr --
10322 ----------------------------
10324 -- 1. If Expr is an unconstrained array expression, creates
10325 -- Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
10327 -- 2. If Expr is a unconstrained discriminated type expression, creates
10328 -- Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
10330 -- 3. If Expr is class-wide, creates an implicit class-wide subtype
10332 function Make_Subtype_From_Expr
10333 (E : Node_Id;
10334 Unc_Typ : Entity_Id;
10335 Related_Id : Entity_Id := Empty) return Node_Id
10337 List_Constr : constant List_Id := New_List;
10338 Loc : constant Source_Ptr := Sloc (E);
10339 D : Entity_Id;
10340 Full_Exp : Node_Id;
10341 Full_Subtyp : Entity_Id;
10342 High_Bound : Entity_Id;
10343 Index_Typ : Entity_Id;
10344 Low_Bound : Entity_Id;
10345 Priv_Subtyp : Entity_Id;
10346 Utyp : Entity_Id;
10348 begin
10349 if Is_Private_Type (Unc_Typ)
10350 and then Has_Unknown_Discriminants (Unc_Typ)
10351 then
10352 -- The caller requests a unique external name for both the private
10353 -- and the full subtype.
10355 if Present (Related_Id) then
10356 Full_Subtyp :=
10357 Make_Defining_Identifier (Loc,
10358 Chars => New_External_Name (Chars (Related_Id), 'C'));
10359 Priv_Subtyp :=
10360 Make_Defining_Identifier (Loc,
10361 Chars => New_External_Name (Chars (Related_Id), 'P'));
10363 else
10364 Full_Subtyp := Make_Temporary (Loc, 'C');
10365 Priv_Subtyp := Make_Temporary (Loc, 'P');
10366 end if;
10368 -- Prepare the subtype completion. Use the base type to find the
10369 -- underlying type because the type may be a generic actual or an
10370 -- explicit subtype.
10372 Utyp := Underlying_Type (Base_Type (Unc_Typ));
10374 Full_Exp :=
10375 Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E));
10376 Set_Parent (Full_Exp, Parent (E));
10378 Insert_Action (E,
10379 Make_Subtype_Declaration (Loc,
10380 Defining_Identifier => Full_Subtyp,
10381 Subtype_Indication => Make_Subtype_From_Expr (Full_Exp, Utyp)));
10383 -- Define the dummy private subtype
10385 Mutate_Ekind (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
10386 Set_Etype (Priv_Subtyp, Base_Type (Unc_Typ));
10387 Set_Scope (Priv_Subtyp, Full_Subtyp);
10388 Set_Is_Constrained (Priv_Subtyp);
10389 Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
10390 Set_Is_Itype (Priv_Subtyp);
10391 Set_Associated_Node_For_Itype (Priv_Subtyp, E);
10393 if Is_Tagged_Type (Priv_Subtyp) then
10394 Set_Class_Wide_Type
10395 (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
10396 Set_Direct_Primitive_Operations (Priv_Subtyp,
10397 Direct_Primitive_Operations (Unc_Typ));
10398 end if;
10400 Set_Full_View (Priv_Subtyp, Full_Subtyp);
10402 return New_Occurrence_Of (Priv_Subtyp, Loc);
10404 elsif Is_Array_Type (Unc_Typ) then
10405 Index_Typ := First_Index (Unc_Typ);
10406 for J in 1 .. Number_Dimensions (Unc_Typ) loop
10408 -- Capture the bounds of each index constraint in case the context
10409 -- is an object declaration of an unconstrained type initialized
10410 -- by a function call:
10412 -- Obj : Unconstr_Typ := Func_Call;
10414 -- This scenario requires secondary scope management and the index
10415 -- constraint cannot depend on the temporary used to capture the
10416 -- result of the function call.
10418 -- SS_Mark;
10419 -- Temp : Unconstr_Typ_Ptr := Func_Call'reference;
10420 -- subtype S is Unconstr_Typ (Temp.all'First .. Temp.all'Last);
10421 -- Obj : S := Temp.all;
10422 -- SS_Release; -- Temp is gone at this point, bounds of S are
10423 -- -- non existent.
10425 -- Generate:
10426 -- Low_Bound : constant Base_Type (Index_Typ) := E'First (J);
10428 Low_Bound := Make_Temporary (Loc, 'B');
10429 Insert_Action (E,
10430 Make_Object_Declaration (Loc,
10431 Defining_Identifier => Low_Bound,
10432 Object_Definition =>
10433 New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
10434 Constant_Present => True,
10435 Expression =>
10436 Make_Attribute_Reference (Loc,
10437 Prefix => Duplicate_Subexpr_No_Checks (E),
10438 Attribute_Name => Name_First,
10439 Expressions => New_List (
10440 Make_Integer_Literal (Loc, J)))));
10442 -- Generate:
10443 -- High_Bound : constant Base_Type (Index_Typ) := E'Last (J);
10445 High_Bound := Make_Temporary (Loc, 'B');
10446 Insert_Action (E,
10447 Make_Object_Declaration (Loc,
10448 Defining_Identifier => High_Bound,
10449 Object_Definition =>
10450 New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
10451 Constant_Present => True,
10452 Expression =>
10453 Make_Attribute_Reference (Loc,
10454 Prefix => Duplicate_Subexpr_No_Checks (E),
10455 Attribute_Name => Name_Last,
10456 Expressions => New_List (
10457 Make_Integer_Literal (Loc, J)))));
10459 Append_To (List_Constr,
10460 Make_Range (Loc,
10461 Low_Bound => New_Occurrence_Of (Low_Bound, Loc),
10462 High_Bound => New_Occurrence_Of (High_Bound, Loc)));
10464 Next_Index (Index_Typ);
10465 end loop;
10467 elsif Is_Class_Wide_Type (Unc_Typ) then
10468 declare
10469 CW_Subtype : constant Entity_Id :=
10470 New_Class_Wide_Subtype (Unc_Typ, E);
10472 begin
10473 -- A class-wide equivalent type is not needed on VM targets
10474 -- because the VM back-ends handle the class-wide object
10475 -- initialization itself (and doesn't need or want the
10476 -- additional intermediate type to handle the assignment).
10478 if Expander_Active and then Tagged_Type_Expansion then
10480 -- If this is the class-wide type of a completion that is a
10481 -- record subtype, set the type of the class-wide type to be
10482 -- the full base type, for use in the expanded code for the
10483 -- equivalent type. Should this be done earlier when the
10484 -- completion is analyzed ???
10486 if Is_Private_Type (Etype (Unc_Typ))
10487 and then
10488 Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype
10489 then
10490 Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ))));
10491 end if;
10493 Set_Equivalent_Type
10494 (CW_Subtype, Make_CW_Equivalent_Type (Unc_Typ, E));
10495 end if;
10497 Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
10499 return New_Occurrence_Of (CW_Subtype, Loc);
10500 end;
10502 -- Indefinite record type with discriminants
10504 else
10505 D := First_Discriminant (Unc_Typ);
10506 while Present (D) loop
10507 Append_To (List_Constr,
10508 Make_Selected_Component (Loc,
10509 Prefix => Duplicate_Subexpr_No_Checks (E),
10510 Selector_Name => New_Occurrence_Of (D, Loc)));
10512 Next_Discriminant (D);
10513 end loop;
10514 end if;
10516 return
10517 Make_Subtype_Indication (Loc,
10518 Subtype_Mark => New_Occurrence_Of (Unc_Typ, Loc),
10519 Constraint =>
10520 Make_Index_Or_Discriminant_Constraint (Loc,
10521 Constraints => List_Constr));
10522 end Make_Subtype_From_Expr;
10524 -----------------------------------
10525 -- Make_Tag_Assignment_From_Type --
10526 -----------------------------------
10528 function Make_Tag_Assignment_From_Type
10529 (Loc : Source_Ptr;
10530 Target : Node_Id;
10531 Typ : Entity_Id) return Node_Id
10533 Nam : constant Node_Id :=
10534 Make_Selected_Component (Loc,
10535 Prefix => Target,
10536 Selector_Name =>
10537 New_Occurrence_Of (First_Tag_Component (Typ), Loc));
10539 begin
10540 Set_Assignment_OK (Nam);
10542 return
10543 Make_Assignment_Statement (Loc,
10544 Name => Nam,
10545 Expression =>
10546 Unchecked_Convert_To (RTE (RE_Tag),
10547 New_Occurrence_Of
10548 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
10549 end Make_Tag_Assignment_From_Type;
10551 -----------------------------
10552 -- Make_Variant_Comparison --
10553 -----------------------------
10555 function Make_Variant_Comparison
10556 (Loc : Source_Ptr;
10557 Typ : Entity_Id;
10558 Mode : Name_Id;
10559 Curr_Val : Node_Id;
10560 Old_Val : Node_Id) return Node_Id
10562 function Big_Integer_Lt return Entity_Id;
10563 -- Returns the entity of the predefined "<" function from
10564 -- Ada.Numerics.Big_Numbers.Big_Integers.
10566 --------------------
10567 -- Big_Integer_Lt --
10568 --------------------
10570 function Big_Integer_Lt return Entity_Id is
10571 Big_Integers : constant Entity_Id :=
10572 RTU_Entity (Ada_Numerics_Big_Numbers_Big_Integers);
10574 E : Entity_Id := First_Entity (Big_Integers);
10576 begin
10577 while Present (E) loop
10578 if Chars (E) = Name_Op_Lt then
10579 return E;
10580 end if;
10581 Next_Entity (E);
10582 end loop;
10584 raise Program_Error;
10585 end Big_Integer_Lt;
10587 -- Start of processing for Make_Variant_Comparison
10589 begin
10590 if Mode = Name_Increases then
10591 return Make_Op_Gt (Loc, Curr_Val, Old_Val);
10593 else pragma Assert (Mode = Name_Decreases);
10595 -- For discrete expressions use the "<" operator
10597 if Is_Discrete_Type (Typ) then
10598 return Make_Op_Lt (Loc, Curr_Val, Old_Val);
10600 -- For Big_Integer expressions use the "<" function, because the
10601 -- operator on private type might not be visible and won't be
10602 -- resolved.
10604 else pragma Assert (Is_RTE (Base_Type (Typ), RE_Big_Integer));
10605 return
10606 Make_Function_Call (Loc,
10607 Name =>
10608 New_Occurrence_Of (Big_Integer_Lt, Loc),
10609 Parameter_Associations =>
10610 New_List (Curr_Val, Old_Val));
10611 end if;
10612 end if;
10613 end Make_Variant_Comparison;
10615 -----------------
10616 -- Map_Formals --
10617 -----------------
10619 procedure Map_Formals
10620 (Parent_Subp : Entity_Id;
10621 Derived_Subp : Entity_Id;
10622 Force_Update : Boolean := False)
10624 Par_Formal : Entity_Id := First_Formal (Parent_Subp);
10625 Subp_Formal : Entity_Id := First_Formal (Derived_Subp);
10627 begin
10628 if Force_Update then
10629 Type_Map.Set (Parent_Subp, Derived_Subp);
10630 end if;
10632 -- At this stage either we are under regular processing and the caller
10633 -- has previously ensured that these primitives are already mapped (by
10634 -- means of calling previously to Update_Primitives_Mapping), or we are
10635 -- processing a late-overriding primitive and Force_Update updated above
10636 -- the mapping of these primitives.
10638 while Present (Par_Formal) and then Present (Subp_Formal) loop
10639 Type_Map.Set (Par_Formal, Subp_Formal);
10640 Next_Formal (Par_Formal);
10641 Next_Formal (Subp_Formal);
10642 end loop;
10643 end Map_Formals;
10645 ---------------
10646 -- Map_Types --
10647 ---------------
10649 procedure Map_Types (Parent_Type : Entity_Id; Derived_Type : Entity_Id) is
10651 -- NOTE: Most of the routines in Map_Types are intentionally unnested to
10652 -- avoid deep indentation of code.
10654 -- NOTE: Routines which deal with discriminant mapping operate on the
10655 -- [underlying/record] full view of various types because those views
10656 -- contain all discriminants and stored constraints.
10658 procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id);
10659 -- Subsidiary to Map_Primitives. Find a primitive in the inheritance or
10660 -- overriding chain starting from Prim whose dispatching type is parent
10661 -- type Par_Typ and add a mapping between the result and primitive Prim.
10663 function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id;
10664 -- Subsidiary to Map_Primitives. Return the next ancestor primitive in
10665 -- the inheritance or overriding chain of subprogram Subp. Return Empty
10666 -- if no such primitive is available.
10668 function Build_Chain
10669 (Par_Typ : Entity_Id;
10670 Deriv_Typ : Entity_Id) return Elist_Id;
10671 -- Subsidiary to Map_Discriminants. Recreate the derivation chain from
10672 -- parent type Par_Typ leading down towards derived type Deriv_Typ. The
10673 -- list has the form:
10675 -- head tail
10676 -- v v
10677 -- <Ancestor_N> -> <Ancestor_N-1> -> <Ancestor_1> -> Deriv_Typ
10679 -- Note that Par_Typ is not part of the resulting derivation chain
10681 function Discriminated_View (Typ : Entity_Id) return Entity_Id;
10682 -- Return the view of type Typ which could potentially contains either
10683 -- the discriminants or stored constraints of the type.
10685 function Find_Discriminant_Value
10686 (Discr : Entity_Id;
10687 Par_Typ : Entity_Id;
10688 Deriv_Typ : Entity_Id;
10689 Typ_Elmt : Elmt_Id) return Node_Or_Entity_Id;
10690 -- Subsidiary to Map_Discriminants. Find the value of discriminant Discr
10691 -- in the derivation chain starting from parent type Par_Typ leading to
10692 -- derived type Deriv_Typ. The returned value is one of the following:
10694 -- * An entity which is either a discriminant or a nondiscriminant
10695 -- name, and renames/constraints Discr.
10697 -- * An expression which constraints Discr
10699 -- Typ_Elmt is an element of the derivation chain created by routine
10700 -- Build_Chain and denotes the current ancestor being examined.
10702 procedure Map_Discriminants
10703 (Par_Typ : Entity_Id;
10704 Deriv_Typ : Entity_Id);
10705 -- Map each discriminant of type Par_Typ to a meaningful constraint
10706 -- from the point of view of type Deriv_Typ.
10708 procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id);
10709 -- Map each primitive of type Par_Typ to a corresponding primitive of
10710 -- type Deriv_Typ.
10712 -------------------
10713 -- Add_Primitive --
10714 -------------------
10716 procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id) is
10717 Par_Prim : Entity_Id;
10719 begin
10720 -- Inspect the inheritance chain through the Alias attribute and the
10721 -- overriding chain through the Overridden_Operation looking for an
10722 -- ancestor primitive with the appropriate dispatching type.
10724 Par_Prim := Prim;
10725 while Present (Par_Prim) loop
10726 exit when Find_Dispatching_Type (Par_Prim) = Par_Typ;
10727 Par_Prim := Ancestor_Primitive (Par_Prim);
10728 end loop;
10730 -- Create a mapping of the form:
10732 -- parent type primitive -> derived type primitive
10734 if Present (Par_Prim) then
10735 Type_Map.Set (Par_Prim, Prim);
10736 end if;
10737 end Add_Primitive;
10739 ------------------------
10740 -- Ancestor_Primitive --
10741 ------------------------
10743 function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id is
10744 Inher_Prim : constant Entity_Id := Alias (Subp);
10745 Over_Prim : constant Entity_Id := Overridden_Operation (Subp);
10747 begin
10748 -- The current subprogram overrides an ancestor primitive
10750 if Present (Over_Prim) then
10751 return Over_Prim;
10753 -- The current subprogram is an internally generated alias of an
10754 -- inherited ancestor primitive.
10756 elsif Present (Inher_Prim) then
10757 -- It is possible that an internally generated alias could be
10758 -- set to a subprogram which overrides the same aliased primitive,
10759 -- so return Empty in this case.
10761 if Ancestor_Primitive (Inher_Prim) = Subp then
10762 return Empty;
10763 end if;
10765 return Inher_Prim;
10767 -- Otherwise the current subprogram is the root of the inheritance or
10768 -- overriding chain.
10770 else
10771 return Empty;
10772 end if;
10773 end Ancestor_Primitive;
10775 -----------------
10776 -- Build_Chain --
10777 -----------------
10779 function Build_Chain
10780 (Par_Typ : Entity_Id;
10781 Deriv_Typ : Entity_Id) return Elist_Id
10783 Anc_Typ : Entity_Id;
10784 Chain : Elist_Id;
10785 Curr_Typ : Entity_Id;
10787 begin
10788 Chain := New_Elmt_List;
10790 -- Add the derived type to the derivation chain
10792 Prepend_Elmt (Deriv_Typ, Chain);
10794 -- Examine all ancestors starting from the derived type climbing
10795 -- towards parent type Par_Typ.
10797 Curr_Typ := Deriv_Typ;
10798 loop
10799 -- Handle the case where the current type is a record which
10800 -- derives from a subtype.
10802 -- subtype Sub_Typ is Par_Typ ...
10803 -- type Deriv_Typ is Sub_Typ ...
10805 if Ekind (Curr_Typ) = E_Record_Type
10806 and then Present (Parent_Subtype (Curr_Typ))
10807 then
10808 Anc_Typ := Parent_Subtype (Curr_Typ);
10810 -- Handle the case where the current type is a record subtype of
10811 -- another subtype.
10813 -- subtype Sub_Typ1 is Par_Typ ...
10814 -- subtype Sub_Typ2 is Sub_Typ1 ...
10816 elsif Ekind (Curr_Typ) = E_Record_Subtype
10817 and then Present (Cloned_Subtype (Curr_Typ))
10818 then
10819 Anc_Typ := Cloned_Subtype (Curr_Typ);
10821 -- Otherwise use the direct parent type
10823 else
10824 Anc_Typ := Etype (Curr_Typ);
10825 end if;
10827 -- Use the first subtype when dealing with itypes
10829 if Is_Itype (Anc_Typ) then
10830 Anc_Typ := First_Subtype (Anc_Typ);
10831 end if;
10833 -- Work with the view which contains the discriminants and stored
10834 -- constraints.
10836 Anc_Typ := Discriminated_View (Anc_Typ);
10838 -- Stop the climb when either the parent type has been reached or
10839 -- there are no more ancestors left to examine.
10841 exit when Anc_Typ = Curr_Typ or else Anc_Typ = Par_Typ;
10843 Prepend_Unique_Elmt (Anc_Typ, Chain);
10844 Curr_Typ := Anc_Typ;
10845 end loop;
10847 return Chain;
10848 end Build_Chain;
10850 ------------------------
10851 -- Discriminated_View --
10852 ------------------------
10854 function Discriminated_View (Typ : Entity_Id) return Entity_Id is
10855 T : Entity_Id;
10857 begin
10858 T := Typ;
10860 -- Use the [underlying] full view when dealing with private types
10861 -- because the view contains all inherited discriminants or stored
10862 -- constraints.
10864 if Is_Private_Type (T) then
10865 if Present (Underlying_Full_View (T)) then
10866 T := Underlying_Full_View (T);
10868 elsif Present (Full_View (T)) then
10869 T := Full_View (T);
10870 end if;
10871 end if;
10873 -- Use the underlying record view when the type is an extenstion of
10874 -- a parent type with unknown discriminants because the view contains
10875 -- all inherited discriminants or stored constraints.
10877 if Ekind (T) = E_Record_Type
10878 and then Present (Underlying_Record_View (T))
10879 then
10880 T := Underlying_Record_View (T);
10881 end if;
10883 return T;
10884 end Discriminated_View;
10886 -----------------------------
10887 -- Find_Discriminant_Value --
10888 -----------------------------
10890 function Find_Discriminant_Value
10891 (Discr : Entity_Id;
10892 Par_Typ : Entity_Id;
10893 Deriv_Typ : Entity_Id;
10894 Typ_Elmt : Elmt_Id) return Node_Or_Entity_Id
10896 Discr_Pos : constant Uint := Discriminant_Number (Discr);
10897 Typ : constant Entity_Id := Node (Typ_Elmt);
10899 function Find_Constraint_Value
10900 (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id;
10901 -- Given constraint Constr, find what it denotes. This is either:
10903 -- * An entity which is either a discriminant or a name
10905 -- * An expression
10907 ---------------------------
10908 -- Find_Constraint_Value --
10909 ---------------------------
10911 function Find_Constraint_Value
10912 (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id
10914 begin
10915 if Nkind (Constr) in N_Entity then
10917 -- The constraint denotes a discriminant of the curren type
10918 -- which renames the ancestor discriminant:
10920 -- vv
10921 -- type Typ (D1 : ...; DN : ...) is
10922 -- new Anc (Discr => D1) with ...
10923 -- ^^
10925 if Ekind (Constr) = E_Discriminant then
10927 -- The discriminant belongs to derived type Deriv_Typ. This
10928 -- is the final value for the ancestor discriminant as the
10929 -- derivations chain has been fully exhausted.
10931 if Typ = Deriv_Typ then
10932 return Constr;
10934 -- Otherwise the discriminant may be renamed or constrained
10935 -- at a lower level. Continue looking down the derivation
10936 -- chain.
10938 else
10939 return
10940 Find_Discriminant_Value
10941 (Discr => Constr,
10942 Par_Typ => Par_Typ,
10943 Deriv_Typ => Deriv_Typ,
10944 Typ_Elmt => Next_Elmt (Typ_Elmt));
10945 end if;
10947 -- Otherwise the constraint denotes a reference to some name
10948 -- which results in a Stored discriminant:
10950 -- vvvv
10951 -- Name : ...;
10952 -- type Typ (D1 : ...; DN : ...) is
10953 -- new Anc (Discr => Name) with ...
10954 -- ^^^^
10956 -- Return the name as this is the proper constraint of the
10957 -- discriminant.
10959 else
10960 return Constr;
10961 end if;
10963 -- The constraint denotes a reference to a name
10965 elsif Is_Entity_Name (Constr) then
10966 return Find_Constraint_Value (Entity (Constr));
10968 -- Otherwise the current constraint is an expression which yields
10969 -- a Stored discriminant:
10971 -- type Typ (D1 : ...; DN : ...) is
10972 -- new Anc (Discr => <expression>) with ...
10973 -- ^^^^^^^^^^
10975 -- Return the expression as this is the proper constraint of the
10976 -- discriminant.
10978 else
10979 return Constr;
10980 end if;
10981 end Find_Constraint_Value;
10983 -- Local variables
10985 Constrs : constant Elist_Id := Stored_Constraint (Typ);
10987 Constr_Elmt : Elmt_Id;
10988 Pos : Uint;
10989 Typ_Discr : Entity_Id;
10991 -- Start of processing for Find_Discriminant_Value
10993 begin
10994 -- The algorithm for finding the value of a discriminant works as
10995 -- follows. First, it recreates the derivation chain from Par_Typ
10996 -- to Deriv_Typ as a list:
10998 -- Par_Typ (shown for completeness)
10999 -- v
11000 -- Ancestor_N <-- head of chain
11001 -- v
11002 -- Ancestor_1
11003 -- v
11004 -- Deriv_Typ <-- tail of chain
11006 -- The algorithm then traces the fate of a parent discriminant down
11007 -- the derivation chain. At each derivation level, the discriminant
11008 -- may be either inherited or constrained.
11010 -- 1) Discriminant is inherited: there are two cases, depending on
11011 -- which type is inheriting.
11013 -- 1.1) Deriv_Typ is inheriting:
11015 -- type Ancestor (D_1 : ...) is tagged ...
11016 -- type Deriv_Typ is new Ancestor ...
11018 -- In this case the inherited discriminant is the final value of
11019 -- the parent discriminant because the end of the derivation chain
11020 -- has been reached.
11022 -- 1.2) Some other type is inheriting:
11024 -- type Ancestor_1 (D_1 : ...) is tagged ...
11025 -- type Ancestor_2 is new Ancestor_1 ...
11027 -- In this case the algorithm continues to trace the fate of the
11028 -- inherited discriminant down the derivation chain because it may
11029 -- be further inherited or constrained.
11031 -- 2) Discriminant is constrained: there are three cases, depending
11032 -- on what the constraint is.
11034 -- 2.1) The constraint is another discriminant (aka renaming):
11036 -- type Ancestor_1 (D_1 : ...) is tagged ...
11037 -- type Ancestor_2 (D_2 : ...) is new Ancestor_1 (D_1 => D_2) ...
11039 -- In this case the constraining discriminant becomes the one to
11040 -- track down the derivation chain. The algorithm already knows
11041 -- that D_2 constrains D_1, therefore if the algorithm finds the
11042 -- value of D_2, then this would also be the value for D_1.
11044 -- 2.2) The constraint is a name (aka Stored):
11046 -- Name : ...
11047 -- type Ancestor_1 (D_1 : ...) is tagged ...
11048 -- type Ancestor_2 is new Ancestor_1 (D_1 => Name) ...
11050 -- In this case the name is the final value of D_1 because the
11051 -- discriminant cannot be further constrained.
11053 -- 2.3) The constraint is an expression (aka Stored):
11055 -- type Ancestor_1 (D_1 : ...) is tagged ...
11056 -- type Ancestor_2 is new Ancestor_1 (D_1 => 1 + 2) ...
11058 -- Similar to 2.2, the expression is the final value of D_1
11060 Pos := Uint_1;
11062 -- When a derived type constrains its parent type, all constaints
11063 -- appear in the Stored_Constraint list. Examine the list looking
11064 -- for a positional match.
11066 if Present (Constrs) then
11067 Constr_Elmt := First_Elmt (Constrs);
11068 while Present (Constr_Elmt) loop
11070 -- The position of the current constraint matches that of the
11071 -- ancestor discriminant.
11073 if Pos = Discr_Pos then
11074 return Find_Constraint_Value (Node (Constr_Elmt));
11075 end if;
11077 Next_Elmt (Constr_Elmt);
11078 Pos := Pos + 1;
11079 end loop;
11081 -- Otherwise the derived type does not constraint its parent type in
11082 -- which case it inherits the parent discriminants.
11084 else
11085 Typ_Discr := First_Discriminant (Typ);
11086 while Present (Typ_Discr) loop
11088 -- The position of the current discriminant matches that of the
11089 -- ancestor discriminant.
11091 if Pos = Discr_Pos then
11092 return Find_Constraint_Value (Typ_Discr);
11093 end if;
11095 Next_Discriminant (Typ_Discr);
11096 Pos := Pos + 1;
11097 end loop;
11098 end if;
11100 -- A discriminant must always have a corresponding value. This is
11101 -- either another discriminant, a name, or an expression. If this
11102 -- point is reached, them most likely the derivation chain employs
11103 -- the wrong views of types.
11105 pragma Assert (False);
11107 return Empty;
11108 end Find_Discriminant_Value;
11110 -----------------------
11111 -- Map_Discriminants --
11112 -----------------------
11114 procedure Map_Discriminants
11115 (Par_Typ : Entity_Id;
11116 Deriv_Typ : Entity_Id)
11118 Deriv_Chain : constant Elist_Id := Build_Chain (Par_Typ, Deriv_Typ);
11120 Discr : Entity_Id;
11121 Discr_Val : Node_Or_Entity_Id;
11123 begin
11124 -- Examine each discriminant of parent type Par_Typ and find a
11125 -- suitable value for it from the point of view of derived type
11126 -- Deriv_Typ.
11128 if Has_Discriminants (Par_Typ) then
11129 Discr := First_Discriminant (Par_Typ);
11130 while Present (Discr) loop
11131 Discr_Val :=
11132 Find_Discriminant_Value
11133 (Discr => Discr,
11134 Par_Typ => Par_Typ,
11135 Deriv_Typ => Deriv_Typ,
11136 Typ_Elmt => First_Elmt (Deriv_Chain));
11138 -- Create a mapping of the form:
11140 -- parent type discriminant -> value
11142 Type_Map.Set (Discr, Discr_Val);
11144 Next_Discriminant (Discr);
11145 end loop;
11146 end if;
11147 end Map_Discriminants;
11149 --------------------
11150 -- Map_Primitives --
11151 --------------------
11153 procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id) is
11154 Deriv_Prim : Entity_Id;
11155 Par_Prim : Entity_Id;
11156 Par_Prims : Elist_Id;
11157 Prim_Elmt : Elmt_Id;
11159 begin
11160 -- Inspect the primitives of the derived type and determine whether
11161 -- they relate to the primitives of the parent type. If there is a
11162 -- meaningful relation, create a mapping of the form:
11164 -- parent type primitive -> derived type primitive
11166 if Present (Direct_Primitive_Operations (Deriv_Typ)) then
11167 Prim_Elmt := First_Elmt (Direct_Primitive_Operations (Deriv_Typ));
11168 while Present (Prim_Elmt) loop
11169 Deriv_Prim := Node (Prim_Elmt);
11171 if Is_Subprogram (Deriv_Prim)
11172 and then Find_Dispatching_Type (Deriv_Prim) = Deriv_Typ
11173 then
11174 Add_Primitive (Deriv_Prim, Par_Typ);
11175 end if;
11177 Next_Elmt (Prim_Elmt);
11178 end loop;
11179 end if;
11181 -- If the parent operation is an interface operation, the overriding
11182 -- indicator is not present. Instead, we get from the interface
11183 -- operation the primitive of the current type that implements it.
11185 if Is_Interface (Par_Typ) then
11186 Par_Prims := Collect_Primitive_Operations (Par_Typ);
11188 if Present (Par_Prims) then
11189 Prim_Elmt := First_Elmt (Par_Prims);
11191 while Present (Prim_Elmt) loop
11192 Par_Prim := Node (Prim_Elmt);
11193 Deriv_Prim :=
11194 Find_Primitive_Covering_Interface (Deriv_Typ, Par_Prim);
11196 if Present (Deriv_Prim) then
11197 Type_Map.Set (Par_Prim, Deriv_Prim);
11198 end if;
11200 Next_Elmt (Prim_Elmt);
11201 end loop;
11202 end if;
11203 end if;
11204 end Map_Primitives;
11206 -- Start of processing for Map_Types
11208 begin
11209 -- Nothing to do if there are no types to work with
11211 if No (Parent_Type) or else No (Derived_Type) then
11212 return;
11214 -- Nothing to do if the mapping already exists
11216 elsif Type_Map.Get (Parent_Type) = Derived_Type then
11217 return;
11219 -- Nothing to do if both types are not tagged. Note that untagged types
11220 -- do not have primitive operations and their discriminants are already
11221 -- handled by gigi.
11223 elsif not Is_Tagged_Type (Parent_Type)
11224 or else not Is_Tagged_Type (Derived_Type)
11225 then
11226 return;
11227 end if;
11229 -- Create a mapping of the form
11231 -- parent type -> derived type
11233 -- to prevent any subsequent attempts to produce the same relations
11235 Type_Map.Set (Parent_Type, Derived_Type);
11237 -- Create mappings of the form
11239 -- parent type discriminant -> derived type discriminant
11240 -- <or>
11241 -- parent type discriminant -> constraint
11243 -- Note that mapping of discriminants breaks privacy because it needs to
11244 -- work with those views which contains the discriminants and any stored
11245 -- constraints.
11247 Map_Discriminants
11248 (Par_Typ => Discriminated_View (Parent_Type),
11249 Deriv_Typ => Discriminated_View (Derived_Type));
11251 -- Create mappings of the form
11253 -- parent type primitive -> derived type primitive
11255 Map_Primitives
11256 (Par_Typ => Parent_Type,
11257 Deriv_Typ => Derived_Type);
11258 end Map_Types;
11260 ----------------------------
11261 -- Matching_Standard_Type --
11262 ----------------------------
11264 function Matching_Standard_Type (Typ : Entity_Id) return Entity_Id is
11265 pragma Assert (Is_Scalar_Type (Typ));
11266 Siz : constant Uint := Esize (Typ);
11268 begin
11269 -- Floating-point cases
11271 if Is_Floating_Point_Type (Typ) then
11272 if Siz <= Esize (Standard_Short_Float) then
11273 return Standard_Short_Float;
11274 elsif Siz <= Esize (Standard_Float) then
11275 return Standard_Float;
11276 elsif Siz <= Esize (Standard_Long_Float) then
11277 return Standard_Long_Float;
11278 elsif Siz <= Esize (Standard_Long_Long_Float) then
11279 return Standard_Long_Long_Float;
11280 else
11281 raise Program_Error;
11282 end if;
11284 -- Integer cases (includes fixed-point types)
11286 -- Unsigned integer cases (includes normal enumeration types)
11288 else
11289 return Small_Integer_Type_For (Siz, Is_Unsigned_Type (Typ));
11290 end if;
11291 end Matching_Standard_Type;
11293 -----------------------------
11294 -- May_Generate_Large_Temp --
11295 -----------------------------
11297 -- At the current time, the only types that we return False for (i.e. where
11298 -- we decide we know they cannot generate large temps) are ones where we
11299 -- know the size is 256 bits or less at compile time, and we are still not
11300 -- doing a thorough job on arrays and records.
11302 function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
11303 begin
11304 if not Size_Known_At_Compile_Time (Typ) then
11305 return False;
11306 end if;
11308 if Known_Esize (Typ) and then Esize (Typ) <= 256 then
11309 return False;
11310 end if;
11312 if Is_Array_Type (Typ)
11313 and then Present (Packed_Array_Impl_Type (Typ))
11314 then
11315 return May_Generate_Large_Temp (Packed_Array_Impl_Type (Typ));
11316 end if;
11318 return True;
11319 end May_Generate_Large_Temp;
11321 --------------------------------------------
11322 -- Needs_Conditional_Null_Excluding_Check --
11323 --------------------------------------------
11325 function Needs_Conditional_Null_Excluding_Check
11326 (Typ : Entity_Id) return Boolean
11328 begin
11329 return
11330 Is_Array_Type (Typ) and then Can_Never_Be_Null (Component_Type (Typ));
11331 end Needs_Conditional_Null_Excluding_Check;
11333 ----------------------------
11334 -- Needs_Constant_Address --
11335 ----------------------------
11337 function Needs_Constant_Address
11338 (Decl : Node_Id;
11339 Typ : Entity_Id) return Boolean
11341 begin
11342 -- If we have no initialization of any kind, then we don't need to place
11343 -- any restrictions on the address clause, because the object will be
11344 -- elaborated after the address clause is evaluated. This happens if the
11345 -- declaration has no initial expression, or the type has no implicit
11346 -- initialization, or the object is imported.
11348 -- The same holds for all initialized scalar types and all access types.
11349 -- Packed bit array types of size up to the maximum integer size are
11350 -- represented using a modular type with an initialization (to zero) and
11351 -- can be processed like other initialized scalar types.
11353 -- If the type is controlled, code to attach the object to a
11354 -- finalization chain is generated at the point of declaration, and
11355 -- therefore the elaboration of the object cannot be delayed: the
11356 -- address expression must be a constant.
11358 if No (Expression (Decl))
11359 and then not Needs_Finalization (Typ)
11360 and then
11361 (not Has_Non_Null_Base_Init_Proc (Typ)
11362 or else Is_Imported (Defining_Identifier (Decl)))
11363 then
11364 return False;
11366 elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ))
11367 or else Is_Access_Type (Typ)
11368 or else
11369 (Is_Bit_Packed_Array (Typ)
11370 and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ)))
11371 then
11372 return False;
11374 else
11375 -- Otherwise, we require the address clause to be constant because
11376 -- the call to the initialization procedure (or the attach code) has
11377 -- to happen at the point of the declaration.
11379 -- Actually the IP call has been moved to the freeze actions anyway,
11380 -- so maybe we can relax this restriction???
11382 return True;
11383 end if;
11384 end Needs_Constant_Address;
11386 ----------------------------
11387 -- New_Class_Wide_Subtype --
11388 ----------------------------
11390 function New_Class_Wide_Subtype
11391 (CW_Typ : Entity_Id;
11392 N : Node_Id) return Entity_Id
11394 Res : constant Entity_Id := Create_Itype (E_Void, N);
11396 -- Capture relevant attributes of the class-wide subtype which must be
11397 -- restored after the copy.
11399 Res_Chars : constant Name_Id := Chars (Res);
11400 Res_Is_CGE : constant Boolean := Is_Checked_Ghost_Entity (Res);
11401 Res_Is_IGE : constant Boolean := Is_Ignored_Ghost_Entity (Res);
11402 Res_Is_IGN : constant Boolean := Is_Ignored_Ghost_Node (Res);
11403 Res_Scope : constant Entity_Id := Scope (Res);
11405 begin
11406 Copy_Node (CW_Typ, Res);
11408 -- Restore the relevant attributes of the class-wide subtype
11410 Set_Chars (Res, Res_Chars);
11411 Set_Is_Checked_Ghost_Entity (Res, Res_Is_CGE);
11412 Set_Is_Ignored_Ghost_Entity (Res, Res_Is_IGE);
11413 Set_Is_Ignored_Ghost_Node (Res, Res_Is_IGN);
11414 Set_Scope (Res, Res_Scope);
11416 -- Decorate the class-wide subtype
11418 Set_Associated_Node_For_Itype (Res, N);
11419 Set_Comes_From_Source (Res, False);
11420 Mutate_Ekind (Res, E_Class_Wide_Subtype);
11421 Set_Etype (Res, Base_Type (CW_Typ));
11422 Set_Freeze_Node (Res, Empty);
11423 Set_Is_Frozen (Res, False);
11424 Set_Is_Itype (Res);
11425 Set_Is_Public (Res, False);
11426 Set_Next_Entity (Res, Empty);
11427 Set_Prev_Entity (Res, Empty);
11428 Set_Sloc (Res, Sloc (N));
11430 Set_Public_Status (Res);
11432 return Res;
11433 end New_Class_Wide_Subtype;
11435 -----------------------------------
11436 -- OK_To_Do_Constant_Replacement --
11437 -----------------------------------
11439 function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
11440 ES : constant Entity_Id := Scope (E);
11441 CS : Entity_Id;
11443 begin
11444 -- Do not replace statically allocated objects, because they may be
11445 -- modified outside the current scope.
11447 if Is_Statically_Allocated (E) then
11448 return False;
11450 -- Do not replace aliased or volatile objects, since we don't know what
11451 -- else might change the value.
11453 elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
11454 return False;
11456 -- Debug flag -gnatdM disconnects this optimization
11458 elsif Debug_Flag_MM then
11459 return False;
11461 -- Otherwise check scopes
11463 else
11464 CS := Current_Scope;
11466 loop
11467 -- If we are in right scope, replacement is safe
11469 if CS = ES then
11470 return True;
11472 -- Packages do not affect the determination of safety
11474 elsif Ekind (CS) = E_Package then
11475 exit when CS = Standard_Standard;
11476 CS := Scope (CS);
11478 -- Blocks do not affect the determination of safety
11480 elsif Ekind (CS) = E_Block then
11481 CS := Scope (CS);
11483 -- Loops do not affect the determination of safety. Note that we
11484 -- kill all current values on entry to a loop, so we are just
11485 -- talking about processing within a loop here.
11487 elsif Ekind (CS) = E_Loop then
11488 CS := Scope (CS);
11490 -- Otherwise, the reference is dubious, and we cannot be sure that
11491 -- it is safe to do the replacement.
11493 else
11494 exit;
11495 end if;
11496 end loop;
11498 return False;
11499 end if;
11500 end OK_To_Do_Constant_Replacement;
11502 ------------------------------------
11503 -- Possible_Bit_Aligned_Component --
11504 ------------------------------------
11506 function Possible_Bit_Aligned_Component
11507 (N : Node_Id;
11508 For_Slice : Boolean := False) return Boolean
11510 begin
11511 -- Do not process an unanalyzed node because it is not yet decorated and
11512 -- most checks performed below will fail.
11514 if not Analyzed (N) then
11515 return False;
11516 end if;
11518 -- There are never alignment issues in CodePeer mode
11520 if CodePeer_Mode then
11521 return False;
11522 end if;
11524 case Nkind (N) is
11526 -- Case of indexed component
11528 when N_Indexed_Component =>
11529 declare
11530 P : constant Node_Id := Prefix (N);
11531 Ptyp : constant Entity_Id := Etype (P);
11533 begin
11534 -- If we know the component size and it is not larger than the
11535 -- maximum integer size, then we are OK. The back end does the
11536 -- assignment of small misaligned objects correctly.
11538 if Known_Static_Component_Size (Ptyp)
11539 and then Component_Size (Ptyp) <= System_Max_Integer_Size
11540 then
11541 return False;
11543 -- Otherwise, we need to test the prefix, to see if we are
11544 -- indexing from a possibly unaligned component.
11546 else
11547 return Possible_Bit_Aligned_Component (P, For_Slice);
11548 end if;
11549 end;
11551 -- Case of selected component
11553 when N_Selected_Component =>
11554 declare
11555 P : constant Node_Id := Prefix (N);
11556 Comp : constant Entity_Id := Entity (Selector_Name (N));
11558 begin
11559 -- This is the crucial test: if the component itself causes
11560 -- trouble, then we can stop and return True.
11562 if Component_May_Be_Bit_Aligned (Comp, For_Slice) then
11563 return True;
11565 -- Otherwise, we need to test the prefix, to see if we are
11566 -- selecting from a possibly unaligned component.
11568 else
11569 return Possible_Bit_Aligned_Component (P, For_Slice);
11570 end if;
11571 end;
11573 -- For a slice, test the prefix, if that is possibly misaligned,
11574 -- then for sure the slice is.
11576 when N_Slice =>
11577 return Possible_Bit_Aligned_Component (Prefix (N), True);
11579 -- For an unchecked conversion, check whether the expression may
11580 -- be bit aligned.
11582 when N_Unchecked_Type_Conversion =>
11583 return Possible_Bit_Aligned_Component (Expression (N), For_Slice);
11585 -- If we have none of the above, it means that we have fallen off the
11586 -- top testing prefixes recursively, and we now have a stand alone
11587 -- object, where we don't have a problem, unless this is a renaming,
11588 -- in which case we need to look into the renamed object.
11590 when others =>
11591 return Is_Entity_Name (N)
11592 and then Is_Object (Entity (N))
11593 and then Present (Renamed_Object (Entity (N)))
11594 and then Possible_Bit_Aligned_Component
11595 (Renamed_Object (Entity (N)), For_Slice);
11596 end case;
11597 end Possible_Bit_Aligned_Component;
11599 -----------------------------------------------
11600 -- Process_Statements_For_Controlled_Objects --
11601 -----------------------------------------------
11603 procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is
11604 Loc : constant Source_Ptr := Sloc (N);
11606 function Are_Wrapped (L : List_Id) return Boolean;
11607 -- Determine whether list L contains only one statement which is a block
11609 function Wrap_Statements_In_Block
11610 (L : List_Id;
11611 Scop : Entity_Id := Current_Scope) return Node_Id;
11612 -- Given a list of statements L, wrap it in a block statement and return
11613 -- the generated node. Scop is either the current scope or the scope of
11614 -- the context (if applicable).
11616 -----------------
11617 -- Are_Wrapped --
11618 -----------------
11620 function Are_Wrapped (L : List_Id) return Boolean is
11621 Stmt : constant Node_Id := First (L);
11622 begin
11623 return
11624 Present (Stmt)
11625 and then No (Next (Stmt))
11626 and then Nkind (Stmt) = N_Block_Statement;
11627 end Are_Wrapped;
11629 ------------------------------
11630 -- Wrap_Statements_In_Block --
11631 ------------------------------
11633 function Wrap_Statements_In_Block
11634 (L : List_Id;
11635 Scop : Entity_Id := Current_Scope) return Node_Id
11637 Block_Id : Entity_Id;
11638 Block_Nod : Node_Id;
11639 Iter_Loop : Entity_Id;
11641 begin
11642 Block_Nod :=
11643 Make_Block_Statement (Loc,
11644 Declarations => No_List,
11645 Handled_Statement_Sequence =>
11646 Make_Handled_Sequence_Of_Statements (Loc,
11647 Statements => L));
11649 -- Create a label for the block in case the block needs to manage the
11650 -- secondary stack. A label allows for flag Uses_Sec_Stack to be set.
11652 Add_Block_Identifier (Block_Nod, Block_Id, Scop);
11654 -- When wrapping the statements of an iterator loop, check whether
11655 -- the loop requires secondary stack management and if so, propagate
11656 -- the appropriate flags to the block. This ensures that the cursor
11657 -- is properly cleaned up at each iteration of the loop.
11659 Iter_Loop := Find_Enclosing_Iterator_Loop (Scop);
11661 if Present (Iter_Loop) then
11662 Set_Uses_Sec_Stack (Block_Id, Uses_Sec_Stack (Iter_Loop));
11664 -- Secondary stack reclamation is suppressed when the associated
11665 -- iterator loop contains a return statement which uses the stack.
11667 Set_Sec_Stack_Needed_For_Return
11668 (Block_Id, Sec_Stack_Needed_For_Return (Iter_Loop));
11669 end if;
11671 return Block_Nod;
11672 end Wrap_Statements_In_Block;
11674 -- Local variables
11676 Block : Node_Id;
11678 -- Start of processing for Process_Statements_For_Controlled_Objects
11680 begin
11681 -- Whenever a non-handled statement list is wrapped in a block, the
11682 -- block must be explicitly analyzed to redecorate all entities in the
11683 -- list and ensure that a finalizer is properly built.
11685 case Nkind (N) is
11686 when N_Conditional_Entry_Call
11687 | N_Elsif_Part
11688 | N_If_Statement
11689 | N_Selective_Accept
11691 -- Check the "then statements" for elsif parts and if statements
11693 if Nkind (N) in N_Elsif_Part | N_If_Statement
11694 and then not Is_Empty_List (Then_Statements (N))
11695 and then not Are_Wrapped (Then_Statements (N))
11696 and then Requires_Cleanup_Actions
11697 (L => Then_Statements (N),
11698 Lib_Level => False,
11699 Nested_Constructs => False)
11700 then
11701 Block := Wrap_Statements_In_Block (Then_Statements (N));
11702 Set_Then_Statements (N, New_List (Block));
11704 Analyze (Block);
11705 end if;
11707 -- Check the "else statements" for conditional entry calls, if
11708 -- statements and selective accepts.
11710 if Nkind (N) in
11711 N_Conditional_Entry_Call | N_If_Statement | N_Selective_Accept
11712 and then not Is_Empty_List (Else_Statements (N))
11713 and then not Are_Wrapped (Else_Statements (N))
11714 and then Requires_Cleanup_Actions
11715 (L => Else_Statements (N),
11716 Lib_Level => False,
11717 Nested_Constructs => False)
11718 then
11719 Block := Wrap_Statements_In_Block (Else_Statements (N));
11720 Set_Else_Statements (N, New_List (Block));
11722 Analyze (Block);
11723 end if;
11725 when N_Abortable_Part
11726 | N_Accept_Alternative
11727 | N_Case_Statement_Alternative
11728 | N_Delay_Alternative
11729 | N_Entry_Call_Alternative
11730 | N_Exception_Handler
11731 | N_Loop_Statement
11732 | N_Triggering_Alternative
11734 if not Is_Empty_List (Statements (N))
11735 and then not Are_Wrapped (Statements (N))
11736 and then Requires_Cleanup_Actions
11737 (L => Statements (N),
11738 Lib_Level => False,
11739 Nested_Constructs => False)
11740 then
11741 if Nkind (N) = N_Loop_Statement
11742 and then Present (Identifier (N))
11743 then
11744 Block :=
11745 Wrap_Statements_In_Block
11746 (L => Statements (N),
11747 Scop => Entity (Identifier (N)));
11748 else
11749 Block := Wrap_Statements_In_Block (Statements (N));
11750 end if;
11752 Set_Statements (N, New_List (Block));
11753 Analyze (Block);
11754 end if;
11756 -- Could be e.g. a loop that was transformed into a block or null
11757 -- statement. Do nothing for terminate alternatives.
11759 when N_Block_Statement
11760 | N_Null_Statement
11761 | N_Terminate_Alternative
11763 null;
11765 when others =>
11766 raise Program_Error;
11767 end case;
11768 end Process_Statements_For_Controlled_Objects;
11770 ------------------
11771 -- Power_Of_Two --
11772 ------------------
11774 function Power_Of_Two (N : Node_Id) return Nat is
11775 Typ : constant Entity_Id := Etype (N);
11776 pragma Assert (Is_Integer_Type (Typ));
11778 Siz : constant Nat := UI_To_Int (Esize (Typ));
11779 Val : Uint;
11781 begin
11782 if not Compile_Time_Known_Value (N) then
11783 return 0;
11785 else
11786 Val := Expr_Value (N);
11787 for J in 1 .. Siz - 1 loop
11788 if Val = Uint_2 ** J then
11789 return J;
11790 end if;
11791 end loop;
11793 return 0;
11794 end if;
11795 end Power_Of_Two;
11797 ----------------------
11798 -- Remove_Init_Call --
11799 ----------------------
11801 function Remove_Init_Call
11802 (Var : Entity_Id;
11803 Rep_Clause : Node_Id) return Node_Id
11805 Par : constant Node_Id := Parent (Var);
11806 Typ : constant Entity_Id := Etype (Var);
11808 Init_Proc : Entity_Id;
11809 -- Initialization procedure for Typ
11811 function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
11812 -- Look for init call for Var starting at From and scanning the
11813 -- enclosing list until Rep_Clause or the end of the list is reached.
11815 ----------------------------
11816 -- Find_Init_Call_In_List --
11817 ----------------------------
11819 function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
11820 Init_Call : Node_Id;
11822 begin
11823 Init_Call := From;
11824 while Present (Init_Call) and then Init_Call /= Rep_Clause loop
11825 if Nkind (Init_Call) = N_Procedure_Call_Statement
11826 and then Is_Entity_Name (Name (Init_Call))
11827 and then Entity (Name (Init_Call)) = Init_Proc
11828 then
11829 return Init_Call;
11830 end if;
11832 Next (Init_Call);
11833 end loop;
11835 return Empty;
11836 end Find_Init_Call_In_List;
11838 Init_Call : Node_Id;
11840 -- Start of processing for Remove_Init_Call
11842 begin
11843 if Present (Initialization_Statements (Var)) then
11844 Init_Call := Initialization_Statements (Var);
11845 Set_Initialization_Statements (Var, Empty);
11847 elsif not Has_Non_Null_Base_Init_Proc (Typ) then
11849 -- No init proc for the type, so obviously no call to be found
11851 return Empty;
11853 else
11854 -- We might be able to handle other cases below by just properly
11855 -- setting Initialization_Statements at the point where the init proc
11856 -- call is generated???
11858 Init_Proc := Base_Init_Proc (Typ);
11860 -- First scan the list containing the declaration of Var
11862 Init_Call := Find_Init_Call_In_List (From => Next (Par));
11864 -- If not found, also look on Var's freeze actions list, if any,
11865 -- since the init call may have been moved there (case of an address
11866 -- clause applying to Var).
11868 if No (Init_Call) and then Present (Freeze_Node (Var)) then
11869 Init_Call :=
11870 Find_Init_Call_In_List (First (Actions (Freeze_Node (Var))));
11871 end if;
11873 -- If the initialization call has actuals that use the secondary
11874 -- stack, the call may have been wrapped into a temporary block, in
11875 -- which case the block itself has to be removed.
11877 if No (Init_Call) and then Nkind (Next (Par)) = N_Block_Statement then
11878 declare
11879 Blk : constant Node_Id := Next (Par);
11880 begin
11881 if Present
11882 (Find_Init_Call_In_List
11883 (First (Statements (Handled_Statement_Sequence (Blk)))))
11884 then
11885 Init_Call := Blk;
11886 end if;
11887 end;
11888 end if;
11889 end if;
11891 if Present (Init_Call) then
11892 -- If restrictions have forbidden Aborts, the initialization call
11893 -- for objects that require deep initialization has not been wrapped
11894 -- into the following block (see Exp_Ch3, Default_Initialize_Object)
11895 -- so if present remove it as well, and include the IP call in it,
11896 -- in the rare case the caller may need to simply displace the
11897 -- initialization, as is done for a later address specification.
11899 if Nkind (Next (Init_Call)) = N_Block_Statement
11900 and then Is_Initialization_Block (Next (Init_Call))
11901 then
11902 declare
11903 IP_Call : constant Node_Id := Init_Call;
11904 begin
11905 Init_Call := Next (IP_Call);
11906 Remove (IP_Call);
11907 Prepend (IP_Call,
11908 Statements (Handled_Statement_Sequence (Init_Call)));
11909 end;
11910 end if;
11912 Remove (Init_Call);
11913 end if;
11915 return Init_Call;
11916 end Remove_Init_Call;
11918 -------------------------
11919 -- Remove_Side_Effects --
11920 -------------------------
11922 procedure Remove_Side_Effects
11923 (Exp : Node_Id;
11924 Name_Req : Boolean := False;
11925 Renaming_Req : Boolean := False;
11926 Variable_Ref : Boolean := False;
11927 Related_Id : Entity_Id := Empty;
11928 Is_Low_Bound : Boolean := False;
11929 Is_High_Bound : Boolean := False;
11930 Discr_Number : Int := 0;
11931 Check_Side_Effects : Boolean := True)
11933 function Build_Temporary
11934 (Loc : Source_Ptr;
11935 Id : Character;
11936 Related_Nod : Node_Id := Empty) return Entity_Id;
11937 -- Create an external symbol of the form xxx_FIRST/_LAST if Related_Nod
11938 -- is present (xxx is taken from the Chars field of Related_Nod),
11939 -- otherwise it generates an internal temporary. The created temporary
11940 -- entity is marked as internal.
11942 function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean;
11943 -- Computes whether a side effect is possible in SPARK, which should
11944 -- be handled by removing it from the expression for GNATprove. Note
11945 -- that other side effects related to volatile variables are handled
11946 -- separately.
11948 ---------------------
11949 -- Build_Temporary --
11950 ---------------------
11952 function Build_Temporary
11953 (Loc : Source_Ptr;
11954 Id : Character;
11955 Related_Nod : Node_Id := Empty) return Entity_Id
11957 Temp_Id : Entity_Id;
11958 Temp_Nam : Name_Id;
11959 Should_Set_Related_Expression : Boolean := False;
11961 begin
11962 -- The context requires an external symbol : expression is
11963 -- the bound of an array, or a discriminant value. We create
11964 -- a unique string using the related entity and an appropriate
11965 -- suffix, rather than a numeric serial number (used for internal
11966 -- entities) that may vary depending on compilation options, in
11967 -- particular on the Assertions_Enabled mode. This avoids spurious
11968 -- link errors.
11970 if Present (Related_Id) then
11971 if Is_Low_Bound then
11972 Temp_Nam := New_External_Name (Chars (Related_Id), "_FIRST");
11974 elsif Is_High_Bound then
11975 Temp_Nam := New_External_Name (Chars (Related_Id), "_LAST");
11977 else
11978 pragma Assert (Discr_Number > 0);
11980 -- We don't have any intelligible way of printing T_DISCR in
11981 -- CodePeer. Thus, set a related expression in this case.
11983 Should_Set_Related_Expression := True;
11985 -- Use fully qualified name to avoid ambiguities.
11987 Temp_Nam :=
11988 New_External_Name
11989 (Get_Qualified_Name (Related_Id), "_DISCR", Discr_Number);
11990 end if;
11992 Temp_Id := Make_Defining_Identifier (Loc, Temp_Nam);
11994 if Should_Set_Related_Expression then
11995 Set_Related_Expression (Temp_Id, Related_Nod);
11996 end if;
11998 -- Otherwise generate an internal temporary
12000 else
12001 Temp_Id := Make_Temporary (Loc, Id, Related_Nod);
12002 end if;
12004 Set_Is_Internal (Temp_Id);
12006 return Temp_Id;
12007 end Build_Temporary;
12009 -----------------------------------
12010 -- Possible_Side_Effect_In_SPARK --
12011 -----------------------------------
12013 function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean is
12014 begin
12015 -- Side-effect removal in SPARK should only occur when not inside a
12016 -- generic and not doing a preanalysis, inside an object renaming or
12017 -- a type declaration or a for-loop iteration scheme.
12019 if not Inside_A_Generic
12020 and then Full_Analysis
12021 then
12023 case Nkind (Enclosing_Declaration (Exp)) is
12024 when N_Component_Declaration
12025 | N_Full_Type_Declaration
12026 | N_Iterator_Specification
12027 | N_Loop_Parameter_Specification
12028 | N_Object_Renaming_Declaration
12030 return True;
12032 -- If the expression belongs to an itype declaration, then
12033 -- check if side effects are allowed in the original
12034 -- associated node.
12036 when N_Subtype_Declaration =>
12037 declare
12038 Subt : constant Entity_Id :=
12039 Defining_Identifier (Enclosing_Declaration (Exp));
12040 begin
12041 if Is_Itype (Subt) then
12043 -- When this routine is called while the itype
12044 -- is being created, the entity might not yet be
12045 -- decorated with the associated node, but should
12046 -- have the related expression.
12048 if Present (Associated_Node_For_Itype (Subt)) then
12049 return
12050 Possible_Side_Effect_In_SPARK
12051 (Associated_Node_For_Itype (Subt));
12053 elsif Present (Related_Expression (Subt)) then
12054 return
12055 Possible_Side_Effect_In_SPARK
12056 (Related_Expression (Subt));
12058 -- When the itype doesn't have any indication of its
12059 -- origin (which currently only happens for packed
12060 -- array types created by freezing that shouldn't
12061 -- be picked by GNATprove anyway), then we can
12062 -- conservatively assume that the expression can
12063 -- be kept as it appears in the source code.
12065 else
12066 pragma Assert (Is_Packed_Array_Impl_Type (Subt));
12067 return False;
12068 end if;
12069 else
12070 return True;
12071 end if;
12072 end;
12074 when others =>
12075 return False;
12076 end case;
12077 else
12078 return False;
12079 end if;
12080 end Possible_Side_Effect_In_SPARK;
12082 -- Local variables
12084 Loc : constant Source_Ptr := Sloc (Exp);
12085 Exp_Type : constant Entity_Id := Etype (Exp);
12086 Svg_Suppress : constant Suppress_Record := Scope_Suppress;
12087 Def_Id : Entity_Id;
12088 E : Node_Id;
12089 New_Exp : Node_Id;
12090 Ptr_Typ_Decl : Node_Id;
12091 Ref_Type : Entity_Id;
12092 Res : Node_Id;
12094 -- Start of processing for Remove_Side_Effects
12096 begin
12097 -- Handle cases in which there is nothing to do. In GNATprove mode,
12098 -- removal of side effects is useful for the light expansion of
12099 -- renamings.
12101 if not Expander_Active
12102 and then not
12103 (GNATprove_Mode and then Possible_Side_Effect_In_SPARK (Exp))
12104 then
12105 return;
12107 -- Cannot generate temporaries if the invocation to remove side effects
12108 -- was issued too early and the type of the expression is not resolved
12109 -- (this happens because routines Duplicate_Subexpr_XX implicitly invoke
12110 -- Remove_Side_Effects).
12112 elsif No (Exp_Type)
12113 or else Ekind (Exp_Type) = E_Access_Attribute_Type
12114 then
12115 return;
12117 -- No action needed for side-effect-free expressions
12119 elsif Check_Side_Effects
12120 and then Side_Effect_Free (Exp, Name_Req, Variable_Ref)
12121 then
12122 return;
12124 -- Generating C code we cannot remove side effect of function returning
12125 -- class-wide types since there is no secondary stack (required to use
12126 -- 'reference).
12128 elsif Modify_Tree_For_C
12129 and then Nkind (Exp) = N_Function_Call
12130 and then Is_Class_Wide_Type (Etype (Exp))
12131 then
12132 return;
12133 end if;
12135 -- The remaining processing is done with all checks suppressed
12137 -- Note: from now on, don't use return statements, instead do a goto
12138 -- Leave, to ensure that we properly restore Scope_Suppress.Suppress.
12140 Scope_Suppress.Suppress := (others => True);
12142 -- If this is a side-effect-free attribute reference whose expressions
12143 -- are also side-effect-free and whose prefix is not a name, remove the
12144 -- side effects of the prefix. A copy of the prefix is required in this
12145 -- case and it is better not to make an additional one for the attribute
12146 -- itself, because the return type of many of them is universal integer,
12147 -- which is a very large type for a temporary.
12148 -- The prefix of an attribute reference Reduce may be syntactically an
12149 -- aggregate, but will be expanded into a loop, so no need to remove
12150 -- side effects.
12152 if Nkind (Exp) = N_Attribute_Reference
12153 and then Side_Effect_Free_Attribute (Attribute_Name (Exp))
12154 and then Side_Effect_Free (Expressions (Exp), Name_Req, Variable_Ref)
12155 and then (Attribute_Name (Exp) /= Name_Reduce
12156 or else Nkind (Prefix (Exp)) /= N_Aggregate)
12157 and then not Is_Name_Reference (Prefix (Exp))
12158 then
12159 Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref);
12160 goto Leave;
12162 -- If this is an elementary or a small not-by-reference record type, and
12163 -- we need to capture the value, just make a constant; this is cheap and
12164 -- objects of both kinds of types can be bit aligned, so it might not be
12165 -- possible to generate a reference to them. Likewise if this is not a
12166 -- name reference, except for a type conversion, because we would enter
12167 -- an infinite recursion with Checks.Apply_Predicate_Check if the target
12168 -- type has predicates (and type conversions need a specific treatment
12169 -- anyway, see below). Also do it if we have a volatile reference and
12170 -- Name_Req is not set (see comments for Side_Effect_Free).
12172 elsif (Is_Elementary_Type (Exp_Type)
12173 or else (Is_Record_Type (Exp_Type)
12174 and then Known_Static_RM_Size (Exp_Type)
12175 and then RM_Size (Exp_Type) <= System_Max_Integer_Size
12176 and then not Has_Discriminants (Exp_Type)
12177 and then not Is_By_Reference_Type (Exp_Type)))
12178 and then (Variable_Ref
12179 or else (not Is_Name_Reference (Exp)
12180 and then Nkind (Exp) /= N_Type_Conversion)
12181 or else (not Name_Req
12182 and then Is_Volatile_Reference (Exp)))
12183 then
12184 Def_Id := Build_Temporary (Loc, 'R', Exp);
12185 Set_Etype (Def_Id, Exp_Type);
12186 Res := New_Occurrence_Of (Def_Id, Loc);
12188 -- If the expression is a packed reference, it must be reanalyzed and
12189 -- expanded, depending on context. This is the case for actuals where
12190 -- a constraint check may capture the actual before expansion of the
12191 -- call is complete.
12193 if Nkind (Exp) = N_Indexed_Component
12194 and then Is_Packed (Etype (Prefix (Exp)))
12195 then
12196 Set_Analyzed (Exp, False);
12197 Set_Analyzed (Prefix (Exp), False);
12198 end if;
12200 -- Generate:
12201 -- Rnn : Exp_Type renames Expr;
12203 -- In GNATprove mode, we prefer to use renamings for intermediate
12204 -- variables to definition of constants, due to the implicit move
12205 -- operation that such a constant definition causes as part of the
12206 -- support in GNATprove for ownership pointers. Hence, we generate
12207 -- a renaming for a reference to an object of a nonscalar type.
12209 if Renaming_Req
12210 or else (GNATprove_Mode
12211 and then Is_Object_Reference (Exp)
12212 and then not Is_Scalar_Type (Exp_Type))
12213 then
12214 E :=
12215 Make_Object_Renaming_Declaration (Loc,
12216 Defining_Identifier => Def_Id,
12217 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc),
12218 Name => Relocate_Node (Exp));
12220 -- Generate:
12221 -- Rnn : constant Exp_Type := Expr;
12223 else
12224 E :=
12225 Make_Object_Declaration (Loc,
12226 Defining_Identifier => Def_Id,
12227 Object_Definition => New_Occurrence_Of (Exp_Type, Loc),
12228 Constant_Present => True,
12229 Expression => Relocate_Node (Exp));
12231 Set_Assignment_OK (E);
12232 end if;
12234 Insert_Action (Exp, E);
12236 -- If the expression has the form v.all then we can just capture the
12237 -- pointer, and then do an explicit dereference on the result, but
12238 -- this is not right if this is a volatile reference.
12240 elsif Nkind (Exp) = N_Explicit_Dereference
12241 and then not Is_Volatile_Reference (Exp)
12242 then
12243 Def_Id := Build_Temporary (Loc, 'R', Exp);
12244 Res :=
12245 Make_Explicit_Dereference (Loc, New_Occurrence_Of (Def_Id, Loc));
12247 Insert_Action (Exp,
12248 Make_Object_Declaration (Loc,
12249 Defining_Identifier => Def_Id,
12250 Object_Definition =>
12251 New_Occurrence_Of (Etype (Prefix (Exp)), Loc),
12252 Constant_Present => True,
12253 Expression => Relocate_Node (Prefix (Exp))));
12255 -- Similar processing for an unchecked conversion of an expression of
12256 -- the form v.all, where we want the same kind of treatment.
12258 elsif Nkind (Exp) = N_Unchecked_Type_Conversion
12259 and then Nkind (Expression (Exp)) = N_Explicit_Dereference
12260 then
12261 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
12262 goto Leave;
12264 -- If this is a type conversion, leave the type conversion and remove
12265 -- side effects in the expression, unless it is of universal integer,
12266 -- which is a very large type for a temporary. This is important in
12267 -- several circumstances: for change of representations and also when
12268 -- this is a view conversion to a smaller object, where gigi can end
12269 -- up creating its own temporary of the wrong size.
12271 elsif Nkind (Exp) = N_Type_Conversion
12272 and then Etype (Expression (Exp)) /= Universal_Integer
12273 then
12274 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
12276 -- Generating C code the type conversion of an access to constrained
12277 -- array type into an access to unconstrained array type involves
12278 -- initializing a fat pointer and the expression must be free of
12279 -- side effects to safely compute its bounds.
12281 if Modify_Tree_For_C
12282 and then Is_Access_Type (Etype (Exp))
12283 and then Is_Array_Type (Designated_Type (Etype (Exp)))
12284 and then not Is_Constrained (Designated_Type (Etype (Exp)))
12285 then
12286 Def_Id := Build_Temporary (Loc, 'R', Exp);
12287 Set_Etype (Def_Id, Exp_Type);
12288 Res := New_Occurrence_Of (Def_Id, Loc);
12290 Insert_Action (Exp,
12291 Make_Object_Declaration (Loc,
12292 Defining_Identifier => Def_Id,
12293 Object_Definition => New_Occurrence_Of (Exp_Type, Loc),
12294 Constant_Present => True,
12295 Expression => Relocate_Node (Exp)));
12296 else
12297 goto Leave;
12298 end if;
12300 -- If this is an unchecked conversion that Gigi can't handle, make
12301 -- a copy or a use a renaming to capture the value.
12303 elsif Nkind (Exp) = N_Unchecked_Type_Conversion
12304 and then not Safe_Unchecked_Type_Conversion (Exp)
12305 then
12306 if CW_Or_Needs_Finalization (Exp_Type) then
12308 -- Use a renaming to capture the expression, rather than create
12309 -- a controlled temporary.
12311 Def_Id := Build_Temporary (Loc, 'R', Exp);
12312 Res := New_Occurrence_Of (Def_Id, Loc);
12314 Insert_Action (Exp,
12315 Make_Object_Renaming_Declaration (Loc,
12316 Defining_Identifier => Def_Id,
12317 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc),
12318 Name => Relocate_Node (Exp)));
12320 else
12321 Def_Id := Build_Temporary (Loc, 'R', Exp);
12322 Set_Etype (Def_Id, Exp_Type);
12323 Res := New_Occurrence_Of (Def_Id, Loc);
12325 E :=
12326 Make_Object_Declaration (Loc,
12327 Defining_Identifier => Def_Id,
12328 Object_Definition => New_Occurrence_Of (Exp_Type, Loc),
12329 Constant_Present => not Is_Variable (Exp),
12330 Expression => Relocate_Node (Exp));
12332 Set_Assignment_OK (E);
12333 Insert_Action (Exp, E);
12334 end if;
12336 -- If this is a packed array component or a selected component with a
12337 -- nonstandard representation, we cannot generate a reference because
12338 -- the component may be unaligned, so we must use a renaming and this
12339 -- renaming is handled by the front end, as the back end may balk at
12340 -- the nonstandard representation (see Evaluation_Required in Exp_Ch8).
12342 elsif (Nkind (Exp) in N_Indexed_Component | N_Selected_Component
12343 and then Has_Non_Standard_Rep (Etype (Prefix (Exp))))
12345 -- For an expression that denotes a name, we can use a renaming
12346 -- scheme. This is needed for correctness in the case of a volatile
12347 -- object of a nonvolatile type because the Make_Reference call of the
12348 -- "default" approach would generate an illegal access value (an
12349 -- access value cannot designate such an object - see
12350 -- Analyze_Reference).
12352 or else (Is_Name_Reference (Exp)
12354 -- We skip using this scheme if we have an object of a volatile
12355 -- type and we do not have Name_Req set true (see comments for
12356 -- Side_Effect_Free).
12358 and then (Name_Req or else not Treat_As_Volatile (Exp_Type)))
12359 then
12360 Def_Id := Build_Temporary (Loc, 'R', Exp);
12361 Res := New_Occurrence_Of (Def_Id, Loc);
12363 Insert_Action (Exp,
12364 Make_Object_Renaming_Declaration (Loc,
12365 Defining_Identifier => Def_Id,
12366 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc),
12367 Name => Relocate_Node (Exp)));
12369 -- Avoid generating a variable-sized temporary, by generating the
12370 -- reference just for the function call. The transformation could be
12371 -- refined to apply only when the array component is constrained by a
12372 -- discriminant???
12374 elsif Nkind (Exp) = N_Selected_Component
12375 and then Nkind (Prefix (Exp)) = N_Function_Call
12376 and then Is_Array_Type (Exp_Type)
12377 then
12378 Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref);
12379 goto Leave;
12381 -- Otherwise we generate a reference to the expression
12383 else
12384 -- When generating C code we cannot consider side-effect-free object
12385 -- declarations that have discriminants and are initialized by means
12386 -- of a function call since on this target there is no secondary
12387 -- stack to store the return value and the expander may generate an
12388 -- extra call to the function to compute the discriminant value. In
12389 -- addition, for targets that have secondary stack, the expansion of
12390 -- functions with side effects involves the generation of an access
12391 -- type to capture the return value stored in the secondary stack;
12392 -- by contrast when generating C code such expansion generates an
12393 -- internal object declaration (no access type involved) which must
12394 -- be identified here to avoid entering into a never-ending loop
12395 -- generating internal object declarations.
12397 if Modify_Tree_For_C
12398 and then Nkind (Parent (Exp)) = N_Object_Declaration
12399 and then
12400 (Nkind (Exp) /= N_Function_Call
12401 or else not Has_Discriminants (Exp_Type)
12402 or else Is_Internal_Name
12403 (Chars (Defining_Identifier (Parent (Exp)))))
12404 then
12405 goto Leave;
12406 end if;
12408 -- Special processing for function calls that return a limited type.
12409 -- We need to build a declaration that will enable build-in-place
12410 -- expansion of the call. This is not done if the context is already
12411 -- an object declaration, to prevent infinite recursion.
12413 -- This is relevant only in Ada 2005 mode. In Ada 95 programs we have
12414 -- to accommodate functions returning limited objects by reference.
12416 if Ada_Version >= Ada_2005
12417 and then Nkind (Exp) = N_Function_Call
12418 and then Is_Inherently_Limited_Type (Etype (Exp))
12419 and then Nkind (Parent (Exp)) /= N_Object_Declaration
12420 then
12421 declare
12422 Obj : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
12423 Decl : Node_Id;
12425 begin
12426 Decl :=
12427 Make_Object_Declaration (Loc,
12428 Defining_Identifier => Obj,
12429 Object_Definition => New_Occurrence_Of (Exp_Type, Loc),
12430 Expression => Relocate_Node (Exp));
12432 Insert_Action (Exp, Decl);
12433 Set_Etype (Obj, Exp_Type);
12434 Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
12435 goto Leave;
12436 end;
12437 end if;
12439 Def_Id := Build_Temporary (Loc, 'R', Exp);
12441 -- The regular expansion of functions with side effects involves the
12442 -- generation of an access type to capture the return value found on
12443 -- the secondary stack. Since SPARK (and why) cannot process access
12444 -- types, use a different approach which ignores the secondary stack
12445 -- and "copies" the returned object.
12446 -- When generating C code, no need for a 'reference since the
12447 -- secondary stack is not supported.
12449 if GNATprove_Mode or Modify_Tree_For_C then
12450 Res := New_Occurrence_Of (Def_Id, Loc);
12451 Ref_Type := Exp_Type;
12453 -- Regular expansion utilizing an access type and 'reference
12455 else
12456 Res :=
12457 Make_Explicit_Dereference (Loc,
12458 Prefix => New_Occurrence_Of (Def_Id, Loc));
12460 -- Generate:
12461 -- type Ann is access all <Exp_Type>;
12463 Ref_Type := Make_Temporary (Loc, 'A');
12465 Ptr_Typ_Decl :=
12466 Make_Full_Type_Declaration (Loc,
12467 Defining_Identifier => Ref_Type,
12468 Type_Definition =>
12469 Make_Access_To_Object_Definition (Loc,
12470 All_Present => True,
12471 Subtype_Indication =>
12472 New_Occurrence_Of (Exp_Type, Loc)));
12474 Insert_Action (Exp, Ptr_Typ_Decl);
12475 end if;
12477 E := Exp;
12478 if Nkind (E) = N_Explicit_Dereference then
12479 New_Exp := Relocate_Node (Prefix (E));
12481 else
12482 E := Relocate_Node (E);
12484 -- Do not generate a 'reference in SPARK mode or C generation
12485 -- since the access type is not created in the first place.
12487 if GNATprove_Mode or Modify_Tree_For_C then
12488 New_Exp := E;
12490 -- Otherwise generate reference, marking the value as non-null
12491 -- since we know it cannot be null and we don't want a check.
12493 else
12494 New_Exp := Make_Reference (Loc, E);
12495 Set_Is_Known_Non_Null (Def_Id);
12496 end if;
12497 end if;
12499 if Is_Delayed_Aggregate (E) then
12501 -- The expansion of nested aggregates is delayed until the
12502 -- enclosing aggregate is expanded. As aggregates are often
12503 -- qualified, the predicate applies to qualified expressions as
12504 -- well, indicating that the enclosing aggregate has not been
12505 -- expanded yet. At this point the aggregate is part of a
12506 -- stand-alone declaration, and must be fully expanded.
12508 if Nkind (E) = N_Qualified_Expression then
12509 Set_Expansion_Delayed (Expression (E), False);
12510 Set_Analyzed (Expression (E), False);
12511 else
12512 Set_Expansion_Delayed (E, False);
12513 end if;
12515 Set_Analyzed (E, False);
12516 end if;
12518 -- Generating C code of object declarations that have discriminants
12519 -- and are initialized by means of a function call we propagate the
12520 -- discriminants of the parent type to the internally built object.
12521 -- This is needed to avoid generating an extra call to the called
12522 -- function.
12524 -- For example, if we generate here the following declaration, it
12525 -- will be expanded later adding an extra call to evaluate the value
12526 -- of the discriminant (needed to compute the size of the object).
12528 -- type Rec (D : Integer) is ...
12529 -- Obj : constant Rec := SomeFunc;
12531 if Modify_Tree_For_C
12532 and then Nkind (Parent (Exp)) = N_Object_Declaration
12533 and then Has_Discriminants (Exp_Type)
12534 and then Nkind (Exp) = N_Function_Call
12535 then
12536 Insert_Action (Exp,
12537 Make_Object_Declaration (Loc,
12538 Defining_Identifier => Def_Id,
12539 Object_Definition => New_Copy_Tree
12540 (Object_Definition (Parent (Exp))),
12541 Constant_Present => True,
12542 Expression => New_Exp));
12543 else
12544 Insert_Action (Exp,
12545 Make_Object_Declaration (Loc,
12546 Defining_Identifier => Def_Id,
12547 Object_Definition => New_Occurrence_Of (Ref_Type, Loc),
12548 Constant_Present => True,
12549 Expression => New_Exp));
12550 end if;
12551 end if;
12553 -- Preserve the Assignment_OK flag in all copies, since at least one
12554 -- copy may be used in a context where this flag must be set (otherwise
12555 -- why would the flag be set in the first place).
12557 Set_Assignment_OK (Res, Assignment_OK (Exp));
12559 -- Preserve the Do_Range_Check flag in all copies
12561 Set_Do_Range_Check (Res, Do_Range_Check (Exp));
12563 -- Finally rewrite the original expression and we are done
12565 Rewrite (Exp, Res);
12566 Analyze_And_Resolve (Exp, Exp_Type);
12568 <<Leave>>
12569 Scope_Suppress := Svg_Suppress;
12570 end Remove_Side_Effects;
12572 ------------------------
12573 -- Replace_References --
12574 ------------------------
12576 procedure Replace_References
12577 (Expr : Node_Id;
12578 Par_Typ : Entity_Id;
12579 Deriv_Typ : Entity_Id;
12580 Par_Obj : Entity_Id := Empty;
12581 Deriv_Obj : Entity_Id := Empty)
12583 function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean;
12584 -- Determine whether node Ref denotes some component of Deriv_Obj
12586 function Replace_Ref (Ref : Node_Id) return Traverse_Result;
12587 -- Substitute a reference to an entity with the corresponding value
12588 -- stored in table Type_Map.
12590 function Type_Of_Formal
12591 (Call : Node_Id;
12592 Actual : Node_Id) return Entity_Id;
12593 -- Find the type of the formal parameter which corresponds to actual
12594 -- parameter Actual in subprogram call Call.
12596 ----------------------
12597 -- Is_Deriv_Obj_Ref --
12598 ----------------------
12600 function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean is
12601 Par : constant Node_Id := Parent (Ref);
12603 begin
12604 -- Detect the folowing selected component form:
12606 -- Deriv_Obj.(something)
12608 return
12609 Nkind (Par) = N_Selected_Component
12610 and then Is_Entity_Name (Prefix (Par))
12611 and then Entity (Prefix (Par)) = Deriv_Obj;
12612 end Is_Deriv_Obj_Ref;
12614 -----------------
12615 -- Replace_Ref --
12616 -----------------
12618 function Replace_Ref (Ref : Node_Id) return Traverse_Result is
12619 procedure Remove_Controlling_Arguments (From_Arg : Node_Id);
12620 -- Reset the Controlling_Argument of all function calls that
12621 -- encapsulate node From_Arg.
12623 ----------------------------------
12624 -- Remove_Controlling_Arguments --
12625 ----------------------------------
12627 procedure Remove_Controlling_Arguments (From_Arg : Node_Id) is
12628 Par : Node_Id;
12630 begin
12631 Par := From_Arg;
12632 while Present (Par) loop
12633 if Nkind (Par) = N_Function_Call
12634 and then Present (Controlling_Argument (Par))
12635 then
12636 Set_Controlling_Argument (Par, Empty);
12638 -- Prevent the search from going too far
12640 elsif Is_Body_Or_Package_Declaration (Par) then
12641 exit;
12642 end if;
12644 Par := Parent (Par);
12645 end loop;
12646 end Remove_Controlling_Arguments;
12648 -- Local variables
12650 Context : constant Node_Id :=
12651 (if No (Ref) then Empty else Parent (Ref));
12653 Loc : constant Source_Ptr := Sloc (Ref);
12654 Ref_Id : Entity_Id;
12655 Result : Traverse_Result;
12657 New_Ref : Node_Id;
12658 -- The new reference which is intended to substitute the old one
12660 Old_Ref : Node_Id;
12661 -- The reference designated for replacement. In certain cases this
12662 -- may be a node other than Ref.
12664 Val : Node_Or_Entity_Id;
12665 -- The corresponding value of Ref from the type map
12667 -- Start of processing for Replace_Ref
12669 begin
12670 -- Assume that the input reference is to be replaced and that the
12671 -- traversal should examine the children of the reference.
12673 Old_Ref := Ref;
12674 Result := OK;
12676 -- The input denotes a meaningful reference
12678 if Nkind (Ref) in N_Has_Entity and then Present (Entity (Ref)) then
12679 Ref_Id := Entity (Ref);
12680 Val := Type_Map.Get (Ref_Id);
12682 -- The reference has a corresponding value in the type map, a
12683 -- substitution is possible.
12685 if Present (Val) then
12687 -- The reference denotes a discriminant
12689 if Ekind (Ref_Id) = E_Discriminant then
12690 if Nkind (Val) in N_Entity then
12692 -- The value denotes another discriminant. Replace as
12693 -- follows:
12695 -- _object.Discr -> _object.Val
12697 if Ekind (Val) = E_Discriminant then
12698 New_Ref := New_Occurrence_Of (Val, Loc);
12700 -- Otherwise the value denotes the entity of a name which
12701 -- constraints the discriminant. Replace as follows:
12703 -- _object.Discr -> Val
12705 else
12706 pragma Assert (Is_Deriv_Obj_Ref (Old_Ref));
12708 New_Ref := New_Occurrence_Of (Val, Loc);
12709 Old_Ref := Parent (Old_Ref);
12710 end if;
12712 -- Otherwise the value denotes an arbitrary expression which
12713 -- constraints the discriminant. Replace as follows:
12715 -- _object.Discr -> Val
12717 else
12718 pragma Assert (Is_Deriv_Obj_Ref (Old_Ref));
12720 New_Ref := New_Copy_Tree (Val);
12721 Old_Ref := Parent (Old_Ref);
12722 end if;
12724 -- Otherwise the reference denotes a primitive. Replace as
12725 -- follows:
12727 -- Primitive -> Val
12729 else
12730 pragma Assert (Nkind (Val) in N_Entity);
12731 New_Ref := New_Occurrence_Of (Val, Loc);
12732 end if;
12734 -- The reference mentions the _object parameter of the parent
12735 -- type's DIC or type invariant procedure. Replace as follows:
12737 -- _object -> _object
12739 elsif Present (Par_Obj)
12740 and then Present (Deriv_Obj)
12741 and then Ref_Id = Par_Obj
12742 then
12743 New_Ref := New_Occurrence_Of (Deriv_Obj, Loc);
12745 -- The type of the _object parameter is class-wide when the
12746 -- expression comes from an assertion pragma that applies to
12747 -- an abstract parent type or an interface. The class-wide type
12748 -- facilitates the preanalysis of the expression by treating
12749 -- calls to abstract primitives that mention the current
12750 -- instance of the type as dispatching. Once the calls are
12751 -- remapped to invoke overriding or inherited primitives, the
12752 -- calls no longer need to be dispatching. Examine all function
12753 -- calls that encapsulate the _object parameter and reset their
12754 -- Controlling_Argument attribute.
12756 if Is_Class_Wide_Type (Etype (Par_Obj))
12757 and then Is_Abstract_Type (Root_Type (Etype (Par_Obj)))
12758 then
12759 Remove_Controlling_Arguments (Old_Ref);
12760 end if;
12762 -- The reference to _object acts as an actual parameter in a
12763 -- subprogram call which may be invoking a primitive of the
12764 -- parent type:
12766 -- Primitive (... _object ...);
12768 -- The parent type primitive may not be overridden nor
12769 -- inherited when it is declared after the derived type
12770 -- definition:
12772 -- type Parent is tagged private;
12773 -- type Child is new Parent with private;
12774 -- procedure Primitive (Obj : Parent);
12776 -- In this scenario the _object parameter is converted to the
12777 -- parent type. Due to complications with partial/full views
12778 -- and view swaps, the parent type is taken from the formal
12779 -- parameter of the subprogram being called.
12781 if Nkind (Context) in N_Subprogram_Call
12782 and then No (Type_Map.Get (Entity (Name (Context))))
12783 then
12784 declare
12785 -- We need to use the Original_Node of the callee, in
12786 -- case it was already modified. Note that we are using
12787 -- Traverse_Proc to walk the tree, and it is defined to
12788 -- walk subtrees in an arbitrary order.
12790 Callee : constant Entity_Id :=
12791 Entity (Original_Node (Name (Context)));
12792 begin
12793 if No (Type_Map.Get (Callee)) then
12794 New_Ref :=
12795 Convert_To
12796 (Type_Of_Formal (Context, Old_Ref), New_Ref);
12798 -- Do not process the generated type conversion
12799 -- because both the parent type and the derived type
12800 -- are in the Type_Map table. This will clobber the
12801 -- type conversion by resetting its subtype mark.
12803 Result := Skip;
12804 end if;
12805 end;
12806 end if;
12808 -- Otherwise there is nothing to replace
12810 else
12811 New_Ref := Empty;
12812 end if;
12814 if Present (New_Ref) then
12815 Rewrite (Old_Ref, New_Ref);
12817 -- Update the return type when the context of the reference
12818 -- acts as the name of a function call. Note that the update
12819 -- should not be performed when the reference appears as an
12820 -- actual in the call.
12822 if Nkind (Context) = N_Function_Call
12823 and then Name (Context) = Old_Ref
12824 then
12825 Set_Etype (Context, Etype (Val));
12826 end if;
12827 end if;
12828 end if;
12830 -- Reanalyze the reference due to potential replacements
12832 if Nkind (Old_Ref) in N_Has_Etype then
12833 Set_Analyzed (Old_Ref, False);
12834 end if;
12836 return Result;
12837 end Replace_Ref;
12839 procedure Replace_Refs is new Traverse_Proc (Replace_Ref);
12841 --------------------
12842 -- Type_Of_Formal --
12843 --------------------
12845 function Type_Of_Formal
12846 (Call : Node_Id;
12847 Actual : Node_Id) return Entity_Id
12849 A : Node_Id;
12850 F : Entity_Id;
12852 begin
12853 -- Examine the list of actual and formal parameters in parallel
12855 A := First (Parameter_Associations (Call));
12856 F := First_Formal (Entity (Name (Call)));
12857 while Present (A) and then Present (F) loop
12858 if A = Actual then
12859 return Etype (F);
12860 end if;
12862 Next (A);
12863 Next_Formal (F);
12864 end loop;
12866 -- The actual parameter must always have a corresponding formal
12868 pragma Assert (False);
12870 return Empty;
12871 end Type_Of_Formal;
12873 -- Start of processing for Replace_References
12875 begin
12876 -- Map the attributes of the parent type to the proper corresponding
12877 -- attributes of the derived type.
12879 Map_Types
12880 (Parent_Type => Par_Typ,
12881 Derived_Type => Deriv_Typ);
12883 -- Inspect the input expression and perform substitutions where
12884 -- necessary.
12886 Replace_Refs (Expr);
12887 end Replace_References;
12889 -----------------------------
12890 -- Replace_Type_References --
12891 -----------------------------
12893 procedure Replace_Type_References
12894 (Expr : Node_Id;
12895 Typ : Entity_Id;
12896 Obj_Id : Entity_Id)
12898 procedure Replace_Type_Ref (N : Node_Id);
12899 -- Substitute a single reference of the current instance of type Typ
12900 -- with a reference to Obj_Id.
12902 ----------------------
12903 -- Replace_Type_Ref --
12904 ----------------------
12906 procedure Replace_Type_Ref (N : Node_Id) is
12907 begin
12908 -- Decorate the reference to Typ even though it may be rewritten
12909 -- further down. This is done so that routines which examine
12910 -- properties of the Original_Node have some semantic information.
12912 if Nkind (N) = N_Identifier then
12913 Set_Entity (N, Typ);
12914 Set_Etype (N, Typ);
12916 elsif Nkind (N) = N_Selected_Component then
12917 Analyze (Prefix (N));
12918 Set_Entity (Selector_Name (N), Typ);
12919 Set_Etype (Selector_Name (N), Typ);
12920 end if;
12922 -- Perform the following substitution:
12924 -- Typ --> _object
12926 Rewrite (N, New_Occurrence_Of (Obj_Id, Sloc (N)));
12927 Set_Comes_From_Source (N, True);
12928 end Replace_Type_Ref;
12930 procedure Replace_Type_Refs is
12931 new Replace_Type_References_Generic (Replace_Type_Ref);
12933 -- Start of processing for Replace_Type_References
12935 begin
12936 Replace_Type_Refs (Expr, Typ);
12937 end Replace_Type_References;
12939 ---------------------------
12940 -- Represented_As_Scalar --
12941 ---------------------------
12943 function Represented_As_Scalar (T : Entity_Id) return Boolean is
12944 UT : constant Entity_Id := Underlying_Type (T);
12945 begin
12946 return Is_Scalar_Type (UT)
12947 or else (Is_Bit_Packed_Array (UT)
12948 and then Is_Scalar_Type (Packed_Array_Impl_Type (UT)));
12949 end Represented_As_Scalar;
12951 ------------------------------
12952 -- Requires_Cleanup_Actions --
12953 ------------------------------
12955 function Requires_Cleanup_Actions
12956 (N : Node_Id;
12957 Lib_Level : Boolean) return Boolean
12959 At_Lib_Level : constant Boolean :=
12960 Lib_Level
12961 and then Nkind (N) in N_Package_Body | N_Package_Specification;
12962 -- N is at the library level if the top-most context is a package and
12963 -- the path taken to reach N does not include nonpackage constructs.
12965 begin
12966 case Nkind (N) is
12967 when N_Accept_Statement
12968 | N_Block_Statement
12969 | N_Entry_Body
12970 | N_Package_Body
12971 | N_Subprogram_Body
12972 | N_Task_Body
12974 return
12975 Requires_Cleanup_Actions
12976 (L => Declarations (N),
12977 Lib_Level => At_Lib_Level,
12978 Nested_Constructs => True)
12979 or else
12980 (Present (Handled_Statement_Sequence (N))
12981 and then
12982 Requires_Cleanup_Actions
12983 (L =>
12984 Statements (Handled_Statement_Sequence (N)),
12985 Lib_Level => At_Lib_Level,
12986 Nested_Constructs => True));
12988 -- Extended return statements are the same as the above, except that
12989 -- there is no Declarations field. We do not want to clean up the
12990 -- Return_Object_Declarations.
12992 when N_Extended_Return_Statement =>
12993 return
12994 Present (Handled_Statement_Sequence (N))
12995 and then Requires_Cleanup_Actions
12996 (L =>
12997 Statements (Handled_Statement_Sequence (N)),
12998 Lib_Level => At_Lib_Level,
12999 Nested_Constructs => True);
13001 when N_Package_Specification =>
13002 return
13003 Requires_Cleanup_Actions
13004 (L => Visible_Declarations (N),
13005 Lib_Level => At_Lib_Level,
13006 Nested_Constructs => True)
13007 or else
13008 Requires_Cleanup_Actions
13009 (L => Private_Declarations (N),
13010 Lib_Level => At_Lib_Level,
13011 Nested_Constructs => True);
13013 when others =>
13014 raise Program_Error;
13015 end case;
13016 end Requires_Cleanup_Actions;
13018 ------------------------------
13019 -- Requires_Cleanup_Actions --
13020 ------------------------------
13022 function Requires_Cleanup_Actions
13023 (L : List_Id;
13024 Lib_Level : Boolean;
13025 Nested_Constructs : Boolean) return Boolean
13027 Decl : Node_Id;
13028 Expr : Node_Id;
13029 Obj_Id : Entity_Id;
13030 Obj_Typ : Entity_Id;
13031 Pack_Id : Entity_Id;
13032 Typ : Entity_Id;
13034 begin
13035 Decl := First (L);
13036 while Present (Decl) loop
13038 -- Library-level tagged types
13040 if Nkind (Decl) = N_Full_Type_Declaration then
13041 Typ := Defining_Identifier (Decl);
13043 -- Ignored Ghost types do not need any cleanup actions because
13044 -- they will not appear in the final tree.
13046 if Is_Ignored_Ghost_Entity (Typ) then
13047 null;
13049 elsif Is_Tagged_Type (Typ)
13050 and then Is_Library_Level_Entity (Typ)
13051 and then Convention (Typ) = Convention_Ada
13052 and then Present (Access_Disp_Table (Typ))
13053 and then not Is_Abstract_Type (Typ)
13054 and then not No_Run_Time_Mode
13055 and then not Restriction_Active (No_Tagged_Type_Registration)
13056 and then RTE_Available (RE_Unregister_Tag)
13057 then
13058 return True;
13059 end if;
13061 -- Regular object declarations
13063 elsif Nkind (Decl) = N_Object_Declaration then
13064 Obj_Id := Defining_Identifier (Decl);
13065 Obj_Typ := Base_Type (Etype (Obj_Id));
13066 Expr := Expression (Decl);
13068 -- Bypass any form of processing for objects which have their
13069 -- finalization disabled. This applies only to objects at the
13070 -- library level.
13072 if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
13073 null;
13075 -- Finalization of transient objects is treated separately in
13076 -- order to handle sensitive cases. These include:
13078 -- * Conditional expressions
13079 -- * Expressions with actions
13080 -- * Transient scopes
13082 elsif Is_Finalized_Transient (Obj_Id) then
13083 null;
13085 -- Finalization of specific objects is also treated separately
13087 elsif Is_Ignored_For_Finalization (Obj_Id) then
13088 null;
13090 -- Ignored Ghost objects do not need any cleanup actions because
13091 -- they will not appear in the final tree.
13093 elsif Is_Ignored_Ghost_Entity (Obj_Id) then
13094 null;
13096 -- The object is of the form:
13097 -- Obj : [constant] Typ [:= Expr];
13099 -- Do not process the incomplete view of a deferred constant.
13100 -- Note that an object initialized by means of a BIP function
13101 -- call may appear as a deferred constant after expansion
13102 -- activities. These kinds of objects must be finalized.
13104 elsif not Is_Imported (Obj_Id)
13105 and then Needs_Finalization (Obj_Typ)
13106 and then not (Ekind (Obj_Id) = E_Constant
13107 and then not Has_Completion (Obj_Id)
13108 and then No (BIP_Initialization_Call (Obj_Id)))
13109 then
13110 return True;
13112 -- The object is of the form:
13113 -- Obj : Access_Typ := Non_BIP_Function_Call'reference;
13115 -- Obj : Access_Typ :=
13116 -- BIP_Function_Call (BIPalloc => 2, ...)'reference;
13118 elsif Is_Access_Type (Obj_Typ)
13119 and then Needs_Finalization
13120 (Available_View (Designated_Type (Obj_Typ)))
13121 and then Present (Expr)
13122 and then
13123 (Is_Secondary_Stack_BIP_Func_Call (Expr)
13124 or else
13125 (Is_Non_BIP_Func_Call (Expr)
13126 and then not Is_Related_To_Func_Return (Obj_Id)))
13127 then
13128 return True;
13130 -- Processing for "hook" objects generated for transient objects
13131 -- declared inside an Expression_With_Actions.
13133 elsif Is_Access_Type (Obj_Typ)
13134 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
13135 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
13136 N_Object_Declaration
13137 then
13138 return True;
13140 -- Processing for intermediate results of if expressions where
13141 -- one of the alternatives uses a controlled function call.
13143 elsif Is_Access_Type (Obj_Typ)
13144 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
13145 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
13146 N_Defining_Identifier
13147 and then Present (Expr)
13148 and then Nkind (Expr) = N_Null
13149 then
13150 return True;
13152 -- Simple protected objects which use type System.Tasking.
13153 -- Protected_Objects.Protection to manage their locks should be
13154 -- treated as controlled since they require manual cleanup.
13155 -- The only exception is illustrated in the following example:
13157 -- package Pkg is
13158 -- type Ctrl is new Controlled ...
13159 -- procedure Finalize (Obj : in out Ctrl);
13160 -- Lib_Obj : Ctrl;
13161 -- end Pkg;
13163 -- package body Pkg is
13164 -- protected Prot is
13165 -- procedure Do_Something (Obj : in out Ctrl);
13166 -- end Prot;
13168 -- protected body Prot is
13169 -- procedure Do_Something (Obj : in out Ctrl) is ...
13170 -- end Prot;
13172 -- procedure Finalize (Obj : in out Ctrl) is
13173 -- begin
13174 -- Prot.Do_Something (Obj);
13175 -- end Finalize;
13176 -- end Pkg;
13178 -- Since for the most part entities in package bodies depend on
13179 -- those in package specs, Prot's lock should be cleaned up
13180 -- first. The subsequent cleanup of the spec finalizes Lib_Obj.
13181 -- This act however attempts to invoke Do_Something and fails
13182 -- because the lock has disappeared.
13184 elsif Ekind (Obj_Id) = E_Variable
13185 and then not In_Library_Level_Package_Body (Obj_Id)
13186 and then Has_Simple_Protected_Object (Obj_Typ)
13187 then
13188 return True;
13189 end if;
13191 -- Specific cases of object renamings
13193 elsif Nkind (Decl) = N_Object_Renaming_Declaration then
13194 Obj_Id := Defining_Identifier (Decl);
13195 Obj_Typ := Base_Type (Etype (Obj_Id));
13197 -- Bypass any form of processing for objects which have their
13198 -- finalization disabled. This applies only to objects at the
13199 -- library level.
13201 if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
13202 null;
13204 -- Ignored Ghost object renamings do not need any cleanup actions
13205 -- because they will not appear in the final tree.
13207 elsif Is_Ignored_Ghost_Entity (Obj_Id) then
13208 null;
13210 -- Return object of extended return statements. This case is
13211 -- recognized and marked by the expansion of extended return
13212 -- statements (see Expand_N_Extended_Return_Statement).
13214 elsif Needs_Finalization (Obj_Typ)
13215 and then Is_Return_Object (Obj_Id)
13216 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
13217 then
13218 return True;
13219 end if;
13221 -- Inspect the freeze node of an access-to-controlled type and look
13222 -- for a delayed finalization master. This case arises when the
13223 -- freeze actions are inserted at a later time than the expansion of
13224 -- the context. Since Build_Finalizer is never called on a single
13225 -- construct twice, the master will be ultimately left out and never
13226 -- finalized. This is also needed for freeze actions of designated
13227 -- types themselves, since in some cases the finalization master is
13228 -- associated with a designated type's freeze node rather than that
13229 -- of the access type (see handling for freeze actions in
13230 -- Build_Finalization_Master).
13232 elsif Nkind (Decl) = N_Freeze_Entity
13233 and then Present (Actions (Decl))
13234 then
13235 Typ := Entity (Decl);
13237 -- Freeze nodes for ignored Ghost types do not need cleanup
13238 -- actions because they will never appear in the final tree.
13240 if Is_Ignored_Ghost_Entity (Typ) then
13241 null;
13243 elsif ((Is_Access_Object_Type (Typ)
13244 and then Needs_Finalization
13245 (Available_View (Designated_Type (Typ))))
13246 or else (Is_Type (Typ) and then Needs_Finalization (Typ)))
13247 and then Requires_Cleanup_Actions
13248 (Actions (Decl), Lib_Level, Nested_Constructs)
13249 then
13250 return True;
13251 end if;
13253 -- Nested package declarations
13255 elsif Nested_Constructs
13256 and then Nkind (Decl) = N_Package_Declaration
13257 then
13258 Pack_Id := Defining_Entity (Decl);
13260 -- Do not inspect an ignored Ghost package because all code found
13261 -- within will not appear in the final tree.
13263 if Is_Ignored_Ghost_Entity (Pack_Id) then
13264 null;
13266 elsif Ekind (Pack_Id) /= E_Generic_Package
13267 and then Requires_Cleanup_Actions
13268 (Specification (Decl), Lib_Level)
13269 then
13270 return True;
13271 end if;
13273 -- Nested package bodies
13275 elsif Nested_Constructs and then Nkind (Decl) = N_Package_Body then
13277 -- Do not inspect an ignored Ghost package body because all code
13278 -- found within will not appear in the final tree.
13280 if Is_Ignored_Ghost_Entity (Defining_Entity (Decl)) then
13281 null;
13283 elsif Ekind (Corresponding_Spec (Decl)) /= E_Generic_Package
13284 and then Requires_Cleanup_Actions (Decl, Lib_Level)
13285 then
13286 return True;
13287 end if;
13288 end if;
13290 Next (Decl);
13291 end loop;
13293 return False;
13294 end Requires_Cleanup_Actions;
13296 ------------------------------------
13297 -- Safe_Unchecked_Type_Conversion --
13298 ------------------------------------
13300 -- Note: this function knows quite a bit about the exact requirements of
13301 -- Gigi with respect to unchecked type conversions, and its code must be
13302 -- coordinated with any changes in Gigi in this area.
13304 -- The above requirements should be documented in Sinfo ???
13306 function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
13307 Otyp : Entity_Id;
13308 Ityp : Entity_Id;
13309 Oalign : Uint;
13310 Ialign : Uint;
13311 Pexp : constant Node_Id := Parent (Exp);
13313 begin
13314 -- If the expression is the RHS of an assignment or object declaration
13315 -- we are always OK because there will always be a target.
13317 -- Object renaming declarations, (generated for view conversions of
13318 -- actuals in inlined calls), like object declarations, provide an
13319 -- explicit type, and are safe as well.
13321 if (Nkind (Pexp) = N_Assignment_Statement
13322 and then Expression (Pexp) = Exp)
13323 or else Nkind (Pexp)
13324 in N_Object_Declaration | N_Object_Renaming_Declaration
13325 then
13326 return True;
13328 -- If the expression is the prefix of an N_Selected_Component we should
13329 -- also be OK because GCC knows to look inside the conversion except if
13330 -- the type is discriminated. We assume that we are OK anyway if the
13331 -- type is not set yet or if it is controlled since we can't afford to
13332 -- introduce a temporary in this case.
13334 elsif Nkind (Pexp) = N_Selected_Component
13335 and then Prefix (Pexp) = Exp
13336 then
13337 return No (Etype (Pexp))
13338 or else not Is_Type (Etype (Pexp))
13339 or else not Has_Discriminants (Etype (Pexp))
13340 or else Is_Constrained (Etype (Pexp));
13341 end if;
13343 -- Set the output type, this comes from Etype if it is set, otherwise we
13344 -- take it from the subtype mark, which we assume was already fully
13345 -- analyzed.
13347 if Present (Etype (Exp)) then
13348 Otyp := Etype (Exp);
13349 else
13350 Otyp := Entity (Subtype_Mark (Exp));
13351 end if;
13353 -- The input type always comes from the expression, and we assume this
13354 -- is indeed always analyzed, so we can simply get the Etype.
13356 Ityp := Etype (Expression (Exp));
13358 -- Initialize alignments to unknown so far
13360 Oalign := No_Uint;
13361 Ialign := No_Uint;
13363 -- Replace a concurrent type by its corresponding record type and each
13364 -- type by its underlying type and do the tests on those. The original
13365 -- type may be a private type whose completion is a concurrent type, so
13366 -- find the underlying type first.
13368 if Present (Underlying_Type (Otyp)) then
13369 Otyp := Underlying_Type (Otyp);
13370 end if;
13372 if Present (Underlying_Type (Ityp)) then
13373 Ityp := Underlying_Type (Ityp);
13374 end if;
13376 if Is_Concurrent_Type (Otyp) then
13377 Otyp := Corresponding_Record_Type (Otyp);
13378 end if;
13380 if Is_Concurrent_Type (Ityp) then
13381 Ityp := Corresponding_Record_Type (Ityp);
13382 end if;
13384 -- If the base types are the same, we know there is no problem since
13385 -- this conversion will be a noop.
13387 if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
13388 return True;
13390 -- Same if this is an upwards conversion of an untagged type, and there
13391 -- are no constraints involved (could be more general???)
13393 elsif Etype (Ityp) = Otyp
13394 and then not Is_Tagged_Type (Ityp)
13395 and then not Has_Discriminants (Ityp)
13396 and then No (First_Rep_Item (Base_Type (Ityp)))
13397 then
13398 return True;
13400 -- If the expression has an access type (object or subprogram) we assume
13401 -- that the conversion is safe, because the size of the target is safe,
13402 -- even if it is a record (which might be treated as having unknown size
13403 -- at this point).
13405 elsif Is_Access_Type (Ityp) then
13406 return True;
13408 -- If the size of output type is known at compile time, there is never
13409 -- a problem. Note that unconstrained records are considered to be of
13410 -- known size, but we can't consider them that way here, because we are
13411 -- talking about the actual size of the object.
13413 -- We also make sure that in addition to the size being known, we do not
13414 -- have a case which might generate an embarrassingly large temp in
13415 -- stack checking mode.
13417 elsif Size_Known_At_Compile_Time (Otyp)
13418 and then
13419 (not Stack_Checking_Enabled
13420 or else not May_Generate_Large_Temp (Otyp))
13421 and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
13422 then
13423 return True;
13425 -- If either type is tagged, then we know the alignment is OK so Gigi
13426 -- will be able to use pointer punning.
13428 elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
13429 return True;
13431 -- If either type is a limited record type, we cannot do a copy, so say
13432 -- safe since there's nothing else we can do.
13434 elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
13435 return True;
13437 -- Conversions to and from packed array types are always ignored and
13438 -- hence are safe.
13440 elsif Is_Packed_Array_Impl_Type (Otyp)
13441 or else Is_Packed_Array_Impl_Type (Ityp)
13442 then
13443 return True;
13444 end if;
13446 -- The only other cases known to be safe is if the input type's
13447 -- alignment is known to be at least the maximum alignment for the
13448 -- target or if both alignments are known and the output type's
13449 -- alignment is no stricter than the input's. We can use the component
13450 -- type alignment for an array if a type is an unpacked array type.
13452 if Present (Alignment_Clause (Otyp)) then
13453 Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
13455 elsif Is_Array_Type (Otyp)
13456 and then Present (Alignment_Clause (Component_Type (Otyp)))
13457 then
13458 Oalign := Expr_Value (Expression (Alignment_Clause
13459 (Component_Type (Otyp))));
13460 end if;
13462 if Present (Alignment_Clause (Ityp)) then
13463 Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
13465 elsif Is_Array_Type (Ityp)
13466 and then Present (Alignment_Clause (Component_Type (Ityp)))
13467 then
13468 Ialign := Expr_Value (Expression (Alignment_Clause
13469 (Component_Type (Ityp))));
13470 end if;
13472 if Present (Ialign) and then Ialign > Maximum_Alignment then
13473 return True;
13475 elsif Present (Ialign)
13476 and then Present (Oalign)
13477 and then Ialign <= Oalign
13478 then
13479 return True;
13481 -- Otherwise, Gigi cannot handle this and we must make a temporary
13483 else
13484 return False;
13485 end if;
13486 end Safe_Unchecked_Type_Conversion;
13488 ---------------------------------
13489 -- Set_Current_Value_Condition --
13490 ---------------------------------
13492 -- Note: the implementation of this procedure is very closely tied to the
13493 -- implementation of Get_Current_Value_Condition. Here we set required
13494 -- Current_Value fields, and in Get_Current_Value_Condition, we interpret
13495 -- them, so they must have a consistent view.
13497 procedure Set_Current_Value_Condition (Cnode : Node_Id) is
13499 procedure Set_Entity_Current_Value (N : Node_Id);
13500 -- If N is an entity reference, where the entity is of an appropriate
13501 -- kind, then set the current value of this entity to Cnode, unless
13502 -- there is already a definite value set there.
13504 procedure Set_Expression_Current_Value (N : Node_Id);
13505 -- If N is of an appropriate form, sets an appropriate entry in current
13506 -- value fields of relevant entities. Multiple entities can be affected
13507 -- in the case of an AND or AND THEN.
13509 ------------------------------
13510 -- Set_Entity_Current_Value --
13511 ------------------------------
13513 procedure Set_Entity_Current_Value (N : Node_Id) is
13514 begin
13515 if Is_Entity_Name (N) then
13516 declare
13517 Ent : constant Entity_Id := Entity (N);
13519 begin
13520 -- Don't capture if not safe to do so
13522 if not Safe_To_Capture_Value (N, Ent, Cond => True) then
13523 return;
13524 end if;
13526 -- Here we have a case where the Current_Value field may need
13527 -- to be set. We set it if it is not already set to a compile
13528 -- time expression value.
13530 -- Note that this represents a decision that one condition
13531 -- blots out another previous one. That's certainly right if
13532 -- they occur at the same level. If the second one is nested,
13533 -- then the decision is neither right nor wrong (it would be
13534 -- equally OK to leave the outer one in place, or take the new
13535 -- inner one). Really we should record both, but our data
13536 -- structures are not that elaborate.
13538 if Nkind (Current_Value (Ent)) not in N_Subexpr then
13539 Set_Current_Value (Ent, Cnode);
13540 end if;
13541 end;
13542 end if;
13543 end Set_Entity_Current_Value;
13545 ----------------------------------
13546 -- Set_Expression_Current_Value --
13547 ----------------------------------
13549 procedure Set_Expression_Current_Value (N : Node_Id) is
13550 Cond : Node_Id;
13552 begin
13553 Cond := N;
13555 -- Loop to deal with (ignore for now) any NOT operators present. The
13556 -- presence of NOT operators will be handled properly when we call
13557 -- Get_Current_Value_Condition.
13559 while Nkind (Cond) = N_Op_Not loop
13560 Cond := Right_Opnd (Cond);
13561 end loop;
13563 -- For an AND or AND THEN, recursively process operands
13565 if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
13566 Set_Expression_Current_Value (Left_Opnd (Cond));
13567 Set_Expression_Current_Value (Right_Opnd (Cond));
13568 return;
13569 end if;
13571 -- Check possible relational operator
13573 if Nkind (Cond) in N_Op_Compare then
13574 if Compile_Time_Known_Value (Right_Opnd (Cond)) then
13575 Set_Entity_Current_Value (Left_Opnd (Cond));
13576 elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
13577 Set_Entity_Current_Value (Right_Opnd (Cond));
13578 end if;
13580 elsif Nkind (Cond) in N_Type_Conversion
13581 | N_Qualified_Expression
13582 | N_Expression_With_Actions
13583 then
13584 Set_Expression_Current_Value (Expression (Cond));
13586 -- Check possible boolean variable reference
13588 else
13589 Set_Entity_Current_Value (Cond);
13590 end if;
13591 end Set_Expression_Current_Value;
13593 -- Start of processing for Set_Current_Value_Condition
13595 begin
13596 Set_Expression_Current_Value (Condition (Cnode));
13597 end Set_Current_Value_Condition;
13599 --------------------------
13600 -- Set_Elaboration_Flag --
13601 --------------------------
13603 procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
13604 Loc : constant Source_Ptr := Sloc (N);
13605 Ent : constant Entity_Id := Elaboration_Entity (Spec_Id);
13606 Asn : Node_Id;
13608 begin
13609 if Present (Ent) then
13611 -- Nothing to do if at the compilation unit level, because in this
13612 -- case the flag is set by the binder generated elaboration routine.
13614 if Nkind (Parent (N)) = N_Compilation_Unit then
13615 null;
13617 -- Here we do need to generate an assignment statement
13619 else
13620 Check_Restriction (No_Elaboration_Code, N);
13622 Asn :=
13623 Make_Assignment_Statement (Loc,
13624 Name => New_Occurrence_Of (Ent, Loc),
13625 Expression => Make_Integer_Literal (Loc, Uint_1));
13627 -- Mark the assignment statement as elaboration code. This allows
13628 -- the early call region mechanism (see Sem_Elab) to properly
13629 -- ignore such assignments even though they are nonpreelaborable
13630 -- code.
13632 Set_Is_Elaboration_Code (Asn);
13634 if Nkind (Parent (N)) = N_Subunit then
13635 Insert_After (Corresponding_Stub (Parent (N)), Asn);
13636 else
13637 Insert_After (N, Asn);
13638 end if;
13640 Analyze (Asn);
13642 -- Kill current value indication. This is necessary because the
13643 -- tests of this flag are inserted out of sequence and must not
13644 -- pick up bogus indications of the wrong constant value.
13646 Set_Current_Value (Ent, Empty);
13648 -- If the subprogram is in the current declarative part and
13649 -- 'access has been applied to it, generate an elaboration
13650 -- check at the beginning of the declarations of the body.
13652 if Nkind (N) = N_Subprogram_Body
13653 and then Address_Taken (Spec_Id)
13654 and then
13655 Ekind (Scope (Spec_Id)) in E_Block | E_Procedure | E_Function
13656 then
13657 declare
13658 Loc : constant Source_Ptr := Sloc (N);
13659 Decls : constant List_Id := Declarations (N);
13660 Chk : Node_Id;
13662 begin
13663 -- No need to generate this check if first entry in the
13664 -- declaration list is a raise of Program_Error now.
13666 if Present (Decls)
13667 and then Nkind (First (Decls)) = N_Raise_Program_Error
13668 then
13669 return;
13670 end if;
13672 -- Otherwise generate the check
13674 Chk :=
13675 Make_Raise_Program_Error (Loc,
13676 Condition =>
13677 Make_Op_Eq (Loc,
13678 Left_Opnd => New_Occurrence_Of (Ent, Loc),
13679 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
13680 Reason => PE_Access_Before_Elaboration);
13682 if No (Decls) then
13683 Set_Declarations (N, New_List (Chk));
13684 else
13685 Prepend (Chk, Decls);
13686 end if;
13688 Analyze (Chk);
13689 end;
13690 end if;
13691 end if;
13692 end if;
13693 end Set_Elaboration_Flag;
13695 ----------------------------
13696 -- Set_Renamed_Subprogram --
13697 ----------------------------
13699 procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
13700 begin
13701 -- If input node is an identifier, we can just reset it
13703 if Nkind (N) = N_Identifier then
13704 Set_Chars (N, Chars (E));
13705 Set_Entity (N, E);
13707 -- Otherwise we have to do a rewrite, preserving Comes_From_Source
13709 else
13710 declare
13711 CS : constant Boolean := Comes_From_Source (N);
13712 begin
13713 Rewrite (N, Make_Identifier (Sloc (N), Chars (E)));
13714 Set_Entity (N, E);
13715 Set_Comes_From_Source (N, CS);
13716 Set_Analyzed (N, True);
13717 end;
13718 end if;
13719 end Set_Renamed_Subprogram;
13721 ----------------------
13722 -- Side_Effect_Free --
13723 ----------------------
13725 function Side_Effect_Free
13726 (N : Node_Id;
13727 Name_Req : Boolean := False;
13728 Variable_Ref : Boolean := False) return Boolean
13730 Typ : constant Entity_Id := Etype (N);
13731 -- Result type of the expression
13733 function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
13734 -- The argument N is a construct where the Prefix is dereferenced if it
13735 -- is an access type and the result is a variable. The call returns True
13736 -- if the construct is side-effect-free (not considering side effects in
13737 -- other than the prefix which are to be tested by the caller).
13739 function Within_In_Parameter (N : Node_Id) return Boolean;
13740 -- Determines if N is a subcomponent of a composite in-parameter. If so,
13741 -- N is not side-effect-free when the actual is global and modifiable
13742 -- indirectly from within a subprogram, because it may be passed by
13743 -- reference. The front-end must be conservative here and assume that
13744 -- this may happen with any array or record type. On the other hand, we
13745 -- cannot create temporaries for all expressions for which this
13746 -- condition is true, for various reasons that might require clearing up
13747 -- ??? For example, discriminant references that appear out of place, or
13748 -- spurious type errors with class-wide expressions. As a result, we
13749 -- limit the transformation to loop bounds, which is so far the only
13750 -- case that requires it.
13752 -----------------------------
13753 -- Safe_Prefixed_Reference --
13754 -----------------------------
13756 function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
13757 begin
13758 -- If prefix is not side-effect-free, definitely not safe
13760 if not Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref) then
13761 return False;
13763 -- If the prefix is of an access type that is not access-to-constant,
13764 -- then this construct is a variable reference, which means it is to
13765 -- be considered to have side effects if Variable_Ref is set True.
13767 elsif Is_Access_Type (Etype (Prefix (N)))
13768 and then not Is_Access_Constant (Etype (Prefix (N)))
13769 and then Variable_Ref
13770 then
13771 -- Exception is a prefix that is the result of a previous removal
13772 -- of side effects.
13774 return Is_Entity_Name (Prefix (N))
13775 and then not Comes_From_Source (Prefix (N))
13776 and then Ekind (Entity (Prefix (N))) = E_Constant
13777 and then Is_Internal_Name (Chars (Entity (Prefix (N))));
13779 -- If the prefix is an explicit dereference then this construct is a
13780 -- variable reference, which means it is to be considered to have
13781 -- side effects if Variable_Ref is True.
13783 -- We do NOT exclude dereferences of access-to-constant types because
13784 -- we handle them as constant view of variables.
13786 elsif Nkind (Prefix (N)) = N_Explicit_Dereference
13787 and then Variable_Ref
13788 then
13789 return False;
13791 -- Note: The following test is the simplest way of solving a complex
13792 -- problem uncovered by the following test (Side effect on loop bound
13793 -- that is a subcomponent of a global variable:
13795 -- with Text_Io; use Text_Io;
13796 -- procedure Tloop is
13797 -- type X is
13798 -- record
13799 -- V : Natural := 4;
13800 -- S : String (1..5) := (others => 'a');
13801 -- end record;
13802 -- X1 : X;
13804 -- procedure Modi;
13806 -- generic
13807 -- with procedure Action;
13808 -- procedure Loop_G (Arg : X; Msg : String)
13810 -- procedure Loop_G (Arg : X; Msg : String) is
13811 -- begin
13812 -- Put_Line ("begin loop_g " & Msg & " will loop till: "
13813 -- & Natural'Image (Arg.V));
13814 -- for Index in 1 .. Arg.V loop
13815 -- Text_Io.Put_Line
13816 -- (Natural'Image (Index) & " " & Arg.S (Index));
13817 -- if Index > 2 then
13818 -- Modi;
13819 -- end if;
13820 -- end loop;
13821 -- Put_Line ("end loop_g " & Msg);
13822 -- end;
13824 -- procedure Loop1 is new Loop_G (Modi);
13825 -- procedure Modi is
13826 -- begin
13827 -- X1.V := 1;
13828 -- Loop1 (X1, "from modi");
13829 -- end;
13831 -- begin
13832 -- Loop1 (X1, "initial");
13833 -- end;
13835 -- The output of the above program should be:
13837 -- begin loop_g initial will loop till: 4
13838 -- 1 a
13839 -- 2 a
13840 -- 3 a
13841 -- begin loop_g from modi will loop till: 1
13842 -- 1 a
13843 -- end loop_g from modi
13844 -- 4 a
13845 -- begin loop_g from modi will loop till: 1
13846 -- 1 a
13847 -- end loop_g from modi
13848 -- end loop_g initial
13850 -- If a loop bound is a subcomponent of a global variable, a
13851 -- modification of that variable within the loop may incorrectly
13852 -- affect the execution of the loop.
13854 elsif Parent_Kind (Parent (N)) = N_Loop_Parameter_Specification
13855 and then Within_In_Parameter (Prefix (N))
13856 and then Variable_Ref
13857 then
13858 return False;
13860 -- All other cases are side-effect-free
13862 else
13863 return True;
13864 end if;
13865 end Safe_Prefixed_Reference;
13867 -------------------------
13868 -- Within_In_Parameter --
13869 -------------------------
13871 function Within_In_Parameter (N : Node_Id) return Boolean is
13872 begin
13873 if not Comes_From_Source (N) then
13874 return False;
13876 elsif Is_Entity_Name (N) then
13877 return Ekind (Entity (N)) = E_In_Parameter;
13879 elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then
13880 return Within_In_Parameter (Prefix (N));
13882 else
13883 return False;
13884 end if;
13885 end Within_In_Parameter;
13887 -- Start of processing for Side_Effect_Free
13889 begin
13890 -- If volatile reference, always consider it to have side effects
13892 if Is_Volatile_Reference (N) then
13893 return False;
13894 end if;
13896 -- Note on checks that could raise Constraint_Error. Strictly, if we
13897 -- take advantage of 11.6, these checks do not count as side effects.
13898 -- However, we would prefer to consider that they are side effects,
13899 -- since the back end CSE does not work very well on expressions which
13900 -- can raise Constraint_Error. On the other hand if we don't consider
13901 -- them to be side-effect-free, then we get some awkward expansions
13902 -- in -gnato mode, resulting in code insertions at a point where we
13903 -- do not have a clear model for performing the insertions.
13905 -- Special handling for entity names
13907 if Is_Entity_Name (N) then
13909 -- A type reference is always side-effect-free
13911 if Is_Type (Entity (N)) then
13912 return True;
13914 -- Variables are considered to be a side effect if Variable_Ref
13915 -- is set or if we have a volatile reference and Name_Req is off.
13916 -- If Name_Req is True then we can't help returning a name which
13917 -- effectively allows multiple references in any case.
13919 elsif Is_Variable (N, Use_Original_Node => False) then
13920 return not Variable_Ref
13921 and then (not Is_Volatile_Reference (N) or else Name_Req);
13923 -- Any other entity (e.g. a subtype name) is definitely side
13924 -- effect free.
13926 else
13927 return True;
13928 end if;
13930 -- A value known at compile time is always side-effect-free
13932 elsif Compile_Time_Known_Value (N) then
13933 return True;
13935 -- A variable renaming is not side-effect-free, because the renaming
13936 -- will function like a macro in the front-end in some cases, and an
13937 -- assignment can modify the component designated by N, so we need to
13938 -- create a temporary for it.
13940 -- The guard testing for Entity being present is needed at least in
13941 -- the case of rewritten predicate expressions, and may well also be
13942 -- appropriate elsewhere. Obviously we can't go testing the entity
13943 -- field if it does not exist, so it's reasonable to say that this is
13944 -- not the renaming case if it does not exist.
13946 elsif Is_Entity_Name (Original_Node (N))
13947 and then Present (Entity (Original_Node (N)))
13948 and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
13949 and then Ekind (Entity (Original_Node (N))) /= E_Constant
13950 then
13951 declare
13952 RO : constant Node_Id :=
13953 Renamed_Object (Entity (Original_Node (N)));
13955 begin
13956 -- If the renamed object is an indexed component, or an
13957 -- explicit dereference, then the designated object could
13958 -- be modified by an assignment.
13960 if Nkind (RO) in N_Indexed_Component | N_Explicit_Dereference then
13961 return False;
13963 -- A selected component must have a safe prefix
13965 elsif Nkind (RO) = N_Selected_Component then
13966 return Safe_Prefixed_Reference (RO);
13968 -- In all other cases, designated object cannot be changed so
13969 -- we are side-effect-free.
13971 else
13972 return True;
13973 end if;
13974 end;
13976 -- Remove_Side_Effects generates an object renaming declaration to
13977 -- capture the expression of a class-wide expression. In VM targets
13978 -- the frontend performs no expansion for dispatching calls to
13979 -- class- wide types since they are handled by the VM. Hence, we must
13980 -- locate here if this node corresponds to a previous invocation of
13981 -- Remove_Side_Effects to avoid a never ending loop in the frontend.
13983 elsif not Tagged_Type_Expansion
13984 and then not Comes_From_Source (N)
13985 and then Nkind (Parent (N)) = N_Object_Renaming_Declaration
13986 and then Is_Class_Wide_Type (Typ)
13987 then
13988 return True;
13990 -- Generating C the type conversion of an access to constrained array
13991 -- type into an access to unconstrained array type involves initializing
13992 -- a fat pointer and the expression cannot be assumed to be free of side
13993 -- effects since it must referenced several times to compute its bounds.
13995 elsif Modify_Tree_For_C
13996 and then Nkind (N) = N_Type_Conversion
13997 and then Is_Access_Type (Typ)
13998 and then Is_Array_Type (Designated_Type (Typ))
13999 and then not Is_Constrained (Designated_Type (Typ))
14000 then
14001 return False;
14002 end if;
14004 -- For other than entity names and compile time known values,
14005 -- check the node kind for special processing.
14007 case Nkind (N) is
14009 -- An attribute reference is side-effect-free if its expressions
14010 -- are side-effect-free and its prefix is side-effect-free or is
14011 -- an entity reference.
14013 when N_Attribute_Reference =>
14014 return Side_Effect_Free_Attribute (Attribute_Name (N))
14015 and then
14016 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
14017 and then
14018 (Is_Entity_Name (Prefix (N))
14019 or else
14020 Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref));
14022 -- A binary operator is side-effect-free if and both operands are
14023 -- side-effect-free. For this purpose binary operators include
14024 -- short circuit forms.
14026 when N_Binary_Op
14027 | N_Short_Circuit
14029 return Side_Effect_Free (Left_Opnd (N), Name_Req, Variable_Ref)
14030 and then
14031 Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
14033 -- Membership tests may have either Right_Opnd or Alternatives set
14035 when N_Membership_Test =>
14036 return Side_Effect_Free (Left_Opnd (N), Name_Req, Variable_Ref)
14037 and then
14038 (if Present (Right_Opnd (N))
14039 then Side_Effect_Free
14040 (Right_Opnd (N), Name_Req, Variable_Ref)
14041 else Side_Effect_Free
14042 (Alternatives (N), Name_Req, Variable_Ref));
14044 -- An explicit dereference is side-effect-free only if it is
14045 -- a side-effect-free prefixed reference.
14047 when N_Explicit_Dereference =>
14048 return Safe_Prefixed_Reference (N);
14050 -- An expression with action is side-effect-free if its expression
14051 -- is side-effect-free and it has no actions.
14053 when N_Expression_With_Actions =>
14054 return
14055 Is_Empty_List (Actions (N))
14056 and then Side_Effect_Free
14057 (Expression (N), Name_Req, Variable_Ref);
14059 -- A call to _rep_to_pos is side-effect-free, since we generate
14060 -- this pure function call ourselves. Moreover it is critically
14061 -- important to make this exception, since otherwise we can have
14062 -- discriminants in array components which don't look side-effect
14063 -- free in the case of an array whose index type is an enumeration
14064 -- type with an enumeration rep clause.
14066 -- All other function calls are not side-effect-free
14068 when N_Function_Call =>
14069 return
14070 Nkind (Name (N)) = N_Identifier
14071 and then Is_TSS (Name (N), TSS_Rep_To_Pos)
14072 and then Side_Effect_Free
14073 (First (Parameter_Associations (N)),
14074 Name_Req, Variable_Ref);
14076 -- An IF expression is side-effect-free if it's of a scalar type, and
14077 -- all its components are all side-effect-free (conditions and then
14078 -- actions and else actions). We restrict to scalar types, since it
14079 -- is annoying to deal with things like (if A then B else C)'First
14080 -- where the type involved is a string type.
14082 when N_If_Expression =>
14083 return
14084 Is_Scalar_Type (Typ)
14085 and then Side_Effect_Free
14086 (Expressions (N), Name_Req, Variable_Ref);
14088 -- An indexed component is side-effect-free if it is a side
14089 -- effect free prefixed reference and all the indexing
14090 -- expressions are side-effect-free.
14092 when N_Indexed_Component =>
14093 return
14094 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
14095 and then Safe_Prefixed_Reference (N);
14097 -- A type qualification, type conversion, or unchecked expression is
14098 -- side-effect-free if the expression is side-effect-free.
14100 when N_Qualified_Expression
14101 | N_Type_Conversion
14102 | N_Unchecked_Expression
14104 return Side_Effect_Free (Expression (N), Name_Req, Variable_Ref);
14106 -- A selected component is side-effect-free only if it is a side
14107 -- effect free prefixed reference.
14109 when N_Selected_Component =>
14110 return Safe_Prefixed_Reference (N);
14112 -- A range is side-effect-free if the bounds are side-effect-free
14114 when N_Range =>
14115 return Side_Effect_Free (Low_Bound (N), Name_Req, Variable_Ref)
14116 and then
14117 Side_Effect_Free (High_Bound (N), Name_Req, Variable_Ref);
14119 -- A slice is side-effect-free if it is a side-effect-free
14120 -- prefixed reference and the bounds are side-effect-free.
14122 when N_Slice =>
14123 return
14124 Side_Effect_Free (Discrete_Range (N), Name_Req, Variable_Ref)
14125 and then Safe_Prefixed_Reference (N);
14127 -- A unary operator is side-effect-free if the operand
14128 -- is side-effect-free.
14130 when N_Unary_Op =>
14131 return Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
14133 -- An unchecked type conversion is side-effect-free only if it
14134 -- is safe and its argument is side-effect-free.
14136 when N_Unchecked_Type_Conversion =>
14137 return
14138 Safe_Unchecked_Type_Conversion (N)
14139 and then Side_Effect_Free
14140 (Expression (N), Name_Req, Variable_Ref);
14142 -- A literal is side-effect-free
14144 when N_Character_Literal
14145 | N_Integer_Literal
14146 | N_Real_Literal
14147 | N_String_Literal
14149 return True;
14151 -- An aggregate is side-effect-free if all its values are compile
14152 -- time known.
14154 when N_Aggregate =>
14155 return Compile_Time_Known_Aggregate (N);
14157 -- We consider that anything else has side effects. This is a bit
14158 -- crude, but we are pretty close for most common cases, and we
14159 -- are certainly correct (i.e. we never return True when the
14160 -- answer should be False).
14162 when others =>
14163 return False;
14164 end case;
14165 end Side_Effect_Free;
14167 -- A list is side-effect-free if all elements of the list are side
14168 -- effect free.
14170 function Side_Effect_Free
14171 (L : List_Id;
14172 Name_Req : Boolean := False;
14173 Variable_Ref : Boolean := False) return Boolean
14175 N : Node_Id;
14177 begin
14178 if L = No_List or else L = Error_List then
14179 return True;
14181 else
14182 N := First (L);
14183 while Present (N) loop
14184 if not Side_Effect_Free (N, Name_Req, Variable_Ref) then
14185 return False;
14186 else
14187 Next (N);
14188 end if;
14189 end loop;
14191 return True;
14192 end if;
14193 end Side_Effect_Free;
14195 --------------------------------
14196 -- Side_Effect_Free_Attribute --
14197 --------------------------------
14199 function Side_Effect_Free_Attribute (Name : Name_Id) return Boolean is
14200 begin
14201 case Name is
14202 when Name_Input =>
14203 return False;
14205 when Name_Image
14206 | Name_Img
14207 | Name_Wide_Image
14208 | Name_Wide_Wide_Image
14210 -- CodePeer doesn't want to see replicated copies of 'Image calls
14212 return not CodePeer_Mode;
14214 when others =>
14215 return True;
14216 end case;
14217 end Side_Effect_Free_Attribute;
14219 ----------------------------------
14220 -- Silly_Boolean_Array_Not_Test --
14221 ----------------------------------
14223 -- This procedure implements an odd and silly test. We explicitly check
14224 -- for the case where the 'First of the component type is equal to the
14225 -- 'Last of this component type, and if this is the case, we make sure
14226 -- that constraint error is raised. The reason is that the NOT is bound
14227 -- to cause CE in this case, and we will not otherwise catch it.
14229 -- No such check is required for AND and OR, since for both these cases
14230 -- False op False = False, and True op True = True. For the XOR case,
14231 -- see Silly_Boolean_Array_Xor_Test.
14233 -- Believe it or not, this was reported as a bug. Note that nearly always,
14234 -- the test will evaluate statically to False, so the code will be
14235 -- statically removed, and no extra overhead caused.
14237 procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
14238 Loc : constant Source_Ptr := Sloc (N);
14239 CT : constant Entity_Id := Component_Type (T);
14241 begin
14242 -- The check we install is
14244 -- constraint_error when
14245 -- component_type'first = component_type'last
14246 -- and then array_type'Length /= 0)
14248 -- We need the last guard because we don't want to raise CE for empty
14249 -- arrays since no out of range values result. (Empty arrays with a
14250 -- component type of True .. True -- very useful -- even the ACATS
14251 -- does not test that marginal case).
14253 Insert_Action (N,
14254 Make_Raise_Constraint_Error (Loc,
14255 Condition =>
14256 Make_And_Then (Loc,
14257 Left_Opnd =>
14258 Make_Op_Eq (Loc,
14259 Left_Opnd =>
14260 Make_Attribute_Reference (Loc,
14261 Prefix => New_Occurrence_Of (CT, Loc),
14262 Attribute_Name => Name_First),
14264 Right_Opnd =>
14265 Make_Attribute_Reference (Loc,
14266 Prefix => New_Occurrence_Of (CT, Loc),
14267 Attribute_Name => Name_Last)),
14269 Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
14270 Reason => CE_Range_Check_Failed));
14271 end Silly_Boolean_Array_Not_Test;
14273 ----------------------------------
14274 -- Silly_Boolean_Array_Xor_Test --
14275 ----------------------------------
14277 -- This procedure implements an odd and silly test. We explicitly check
14278 -- for the XOR case where the component type is True .. True, since this
14279 -- will raise constraint error. A special check is required since CE
14280 -- will not be generated otherwise (cf Expand_Packed_Not).
14282 -- No such check is required for AND and OR, since for both these cases
14283 -- False op False = False, and True op True = True, and no check is
14284 -- required for the case of False .. False, since False xor False = False.
14285 -- See also Silly_Boolean_Array_Not_Test
14287 procedure Silly_Boolean_Array_Xor_Test
14288 (N : Node_Id;
14289 R : Node_Id;
14290 T : Entity_Id)
14292 Loc : constant Source_Ptr := Sloc (N);
14293 CT : constant Entity_Id := Component_Type (T);
14295 begin
14296 -- The check we install is
14298 -- constraint_error when
14299 -- Boolean (component_type'First)
14300 -- and then Boolean (component_type'Last)
14301 -- and then array_type'Length /= 0)
14303 -- We need the last guard because we don't want to raise CE for empty
14304 -- arrays since no out of range values result (Empty arrays with a
14305 -- component type of True .. True -- very useful -- even the ACATS
14306 -- does not test that marginal case).
14308 Insert_Action (N,
14309 Make_Raise_Constraint_Error (Loc,
14310 Condition =>
14311 Make_And_Then (Loc,
14312 Left_Opnd =>
14313 Make_And_Then (Loc,
14314 Left_Opnd =>
14315 Convert_To (Standard_Boolean,
14316 Make_Attribute_Reference (Loc,
14317 Prefix => New_Occurrence_Of (CT, Loc),
14318 Attribute_Name => Name_First)),
14320 Right_Opnd =>
14321 Convert_To (Standard_Boolean,
14322 Make_Attribute_Reference (Loc,
14323 Prefix => New_Occurrence_Of (CT, Loc),
14324 Attribute_Name => Name_Last))),
14326 Right_Opnd => Make_Non_Empty_Check (Loc, R)),
14327 Reason => CE_Range_Check_Failed));
14328 end Silly_Boolean_Array_Xor_Test;
14330 ----------------------------
14331 -- Small_Integer_Type_For --
14332 ----------------------------
14334 function Small_Integer_Type_For (S : Uint; Uns : Boolean) return Entity_Id
14336 begin
14337 -- The only difference between this and Integer_Type_For is that this
14338 -- can return small (8- or 16-bit) types.
14340 if S <= Standard_Short_Short_Integer_Size then
14341 if Uns then
14342 return Standard_Short_Short_Unsigned;
14343 else
14344 return Standard_Short_Short_Integer;
14345 end if;
14347 elsif S <= Standard_Short_Integer_Size then
14348 if Uns then
14349 return Standard_Short_Unsigned;
14350 else
14351 return Standard_Short_Integer;
14352 end if;
14354 else
14355 return Integer_Type_For (S, Uns);
14356 end if;
14357 end Small_Integer_Type_For;
14359 ------------------
14360 -- Thunk_Target --
14361 ------------------
14363 function Thunk_Target (Thunk : Entity_Id) return Entity_Id is
14364 Target : Entity_Id := Thunk;
14366 begin
14367 pragma Assert (Is_Thunk (Thunk));
14369 while Is_Thunk (Target) loop
14370 Target := Thunk_Entity (Target);
14371 end loop;
14373 return Target;
14374 end Thunk_Target;
14376 -------------------
14377 -- Type_Map_Hash --
14378 -------------------
14380 function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header is
14381 begin
14382 return Type_Map_Header (Id mod Type_Map_Size);
14383 end Type_Map_Hash;
14385 ------------------------------------------
14386 -- Type_May_Have_Bit_Aligned_Components --
14387 ------------------------------------------
14389 function Type_May_Have_Bit_Aligned_Components
14390 (Typ : Entity_Id) return Boolean
14392 begin
14393 -- Array type, check component type
14395 if Is_Array_Type (Typ) then
14396 return
14397 Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
14399 -- Record type, check components
14401 elsif Is_Record_Type (Typ) then
14402 declare
14403 E : Entity_Id;
14405 begin
14406 E := First_Component_Or_Discriminant (Typ);
14407 while Present (E) loop
14408 -- This is the crucial test: if the component itself causes
14409 -- trouble, then we can stop and return True.
14411 if Component_May_Be_Bit_Aligned (E) then
14412 return True;
14413 end if;
14415 -- Otherwise, we need to test its type, to see if it may
14416 -- itself contain a troublesome component.
14418 if Type_May_Have_Bit_Aligned_Components (Etype (E)) then
14419 return True;
14420 end if;
14422 Next_Component_Or_Discriminant (E);
14423 end loop;
14425 return False;
14426 end;
14428 -- Type other than array or record is always OK
14430 else
14431 return False;
14432 end if;
14433 end Type_May_Have_Bit_Aligned_Components;
14435 -------------------------------
14436 -- Update_Primitives_Mapping --
14437 -------------------------------
14439 procedure Update_Primitives_Mapping
14440 (Inher_Id : Entity_Id;
14441 Subp_Id : Entity_Id)
14443 Parent_Type : constant Entity_Id := Find_Dispatching_Type (Inher_Id);
14444 Derived_Type : constant Entity_Id := Find_Dispatching_Type (Subp_Id);
14446 begin
14447 pragma Assert (Parent_Type /= Derived_Type);
14448 Map_Types (Parent_Type, Derived_Type);
14449 end Update_Primitives_Mapping;
14451 ----------------------------------
14452 -- Within_Case_Or_If_Expression --
14453 ----------------------------------
14455 function Within_Case_Or_If_Expression (N : Node_Id) return Boolean is
14456 Nod : Node_Id;
14457 Par : Node_Id;
14459 begin
14460 -- Locate an enclosing case or if expression. Note that these constructs
14461 -- can be expanded into Expression_With_Actions, hence the test of the
14462 -- original node.
14464 Nod := N;
14465 Par := Parent (Nod);
14467 while Present (Par) loop
14468 if Nkind (Original_Node (Par)) = N_Case_Expression
14469 and then Nod /= Expression (Original_Node (Par))
14470 then
14471 return True;
14473 elsif Nkind (Original_Node (Par)) = N_If_Expression
14474 and then Nod /= First (Expressions (Original_Node (Par)))
14475 then
14476 return True;
14478 -- Stop at contexts where temporaries may be contained
14480 elsif Nkind (Par) in N_Aggregate
14481 | N_Delta_Aggregate
14482 | N_Extension_Aggregate
14483 | N_Block_Statement
14484 | N_Loop_Statement
14485 then
14486 return False;
14488 -- Prevent the search from going too far
14490 elsif Is_Body_Or_Package_Declaration (Par) then
14491 return False;
14492 end if;
14494 Nod := Par;
14495 Par := Parent (Nod);
14496 end loop;
14498 return False;
14499 end Within_Case_Or_If_Expression;
14501 ------------------------------
14502 -- Predicate_Check_In_Scope --
14503 ------------------------------
14505 function Predicate_Check_In_Scope (N : Node_Id) return Boolean is
14506 S : Entity_Id;
14508 begin
14509 S := Current_Scope;
14510 while Present (S) and then not Is_Subprogram (S) loop
14511 S := Scope (S);
14512 end loop;
14514 if Present (S) then
14516 -- Predicate checks should only be enabled in init procs for
14517 -- expressions coming from source.
14519 if Is_Init_Proc (S) then
14520 return Comes_From_Source (N);
14522 elsif Get_TSS_Name (S) /= TSS_Null
14523 and then not Is_Predicate_Function (S)
14524 then
14525 return False;
14526 end if;
14527 end if;
14529 return True;
14530 end Predicate_Check_In_Scope;
14532 end Exp_Util;