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-2019, 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------------------------------------------------------------------------------
25
26with Aspects;  use Aspects;
27with Atree;    use Atree;
28with Casing;   use Casing;
29with Checks;   use Checks;
30with Debug;    use Debug;
31with Einfo;    use Einfo;
32with Elists;   use Elists;
33with Errout;   use Errout;
34with Exp_Aggr; use Exp_Aggr;
35with Exp_Ch2;  use Exp_Ch2;
36with Exp_Ch6;  use Exp_Ch6;
37with Exp_Ch7;  use Exp_Ch7;
38with Exp_Ch11; use Exp_Ch11;
39with Ghost;    use Ghost;
40with Inline;   use Inline;
41with Itypes;   use Itypes;
42with Lib;      use Lib;
43with Nlists;   use Nlists;
44with Nmake;    use Nmake;
45with Opt;      use Opt;
46with Restrict; use Restrict;
47with Rident;   use Rident;
48with Sem;      use Sem;
49with Sem_Aux;  use Sem_Aux;
50with Sem_Ch3;  use Sem_Ch3;
51with Sem_Ch6;  use Sem_Ch6;
52with Sem_Ch8;  use Sem_Ch8;
53with Sem_Ch12; use Sem_Ch12;
54with Sem_Ch13; use Sem_Ch13;
55with Sem_Disp; use Sem_Disp;
56with Sem_Elab; use Sem_Elab;
57with Sem_Eval; use Sem_Eval;
58with Sem_Res;  use Sem_Res;
59with Sem_Type; use Sem_Type;
60with Sem_Util; use Sem_Util;
61with Snames;   use Snames;
62with Stand;    use Stand;
63with Stringt;  use Stringt;
64with Targparm; use Targparm;
65with Tbuild;   use Tbuild;
66with Ttypes;   use Ttypes;
67with Urealp;   use Urealp;
68with Validsw;  use Validsw;
69
70with GNAT.HTable;
71package body Exp_Util is
72
73   ---------------------------------------------------------
74   -- Handling of inherited class-wide pre/postconditions --
75   ---------------------------------------------------------
76
77   --  Following AI12-0113, the expression for a class-wide condition is
78   --  transformed for a subprogram that inherits it, by replacing calls
79   --  to primitive operations of the original controlling type into the
80   --  corresponding overriding operations of the derived type. The following
81   --  hash table manages this mapping, and is expanded on demand whenever
82   --  such inherited expression needs to be constructed.
83
84   --  The mapping is also used to check whether an inherited operation has
85   --  a condition that depends on overridden operations. For such an
86   --  operation we must create a wrapper that is then treated as a normal
87   --  overriding. In SPARK mode such operations are illegal.
88
89   --  For a given root type there may be several type extensions with their
90   --  own overriding operations, so at various times a given operation of
91   --  the root will be mapped into different overridings. The root type is
92   --  also mapped into the current type extension to indicate that its
93   --  operations are mapped into the overriding operations of that current
94   --  type extension.
95
96   --  The contents of the map are as follows:
97
98   --    Key                                Value
99
100   --    Discriminant (Entity_Id)           Discriminant (Entity_Id)
101   --    Discriminant (Entity_Id)           Non-discriminant name (Entity_Id)
102   --    Discriminant (Entity_Id)           Expression (Node_Id)
103   --    Primitive subprogram (Entity_Id)   Primitive subprogram (Entity_Id)
104   --    Type (Entity_Id)                   Type (Entity_Id)
105
106   Type_Map_Size : constant := 511;
107
108   subtype Type_Map_Header is Integer range 0 .. Type_Map_Size - 1;
109   function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header;
110
111   package Type_Map is new GNAT.HTable.Simple_HTable
112     (Header_Num => Type_Map_Header,
113      Key        => Entity_Id,
114      Element    => Node_Or_Entity_Id,
115      No_element => Empty,
116      Hash       => Type_Map_Hash,
117      Equal      => "=");
118
119   -----------------------
120   -- Local Subprograms --
121   -----------------------
122
123   function Build_Task_Array_Image
124     (Loc    : Source_Ptr;
125      Id_Ref : Node_Id;
126      A_Type : Entity_Id;
127      Dyn    : Boolean := False) return Node_Id;
128   --  Build function to generate the image string for a task that is an array
129   --  component, concatenating the images of each index. To avoid storage
130   --  leaks, the string is built with successive slice assignments. The flag
131   --  Dyn indicates whether this is called for the initialization procedure of
132   --  an array of tasks, or for the name of a dynamically created task that is
133   --  assigned to an indexed component.
134
135   function Build_Task_Image_Function
136     (Loc   : Source_Ptr;
137      Decls : List_Id;
138      Stats : List_Id;
139      Res   : Entity_Id) return Node_Id;
140   --  Common processing for Task_Array_Image and Task_Record_Image. Build
141   --  function body that computes image.
142
143   procedure Build_Task_Image_Prefix
144      (Loc    : Source_Ptr;
145       Len    : out Entity_Id;
146       Res    : out Entity_Id;
147       Pos    : out Entity_Id;
148       Prefix : Entity_Id;
149       Sum    : Node_Id;
150       Decls  : List_Id;
151       Stats  : List_Id);
152   --  Common processing for Task_Array_Image and Task_Record_Image. Create
153   --  local variables and assign prefix of name to result string.
154
155   function Build_Task_Record_Image
156     (Loc    : Source_Ptr;
157      Id_Ref : Node_Id;
158      Dyn    : Boolean := False) return Node_Id;
159   --  Build function to generate the image string for a task that is a record
160   --  component. Concatenate name of variable with that of selector. The flag
161   --  Dyn indicates whether this is called for the initialization procedure of
162   --  record with task components, or for a dynamically created task that is
163   --  assigned to a selected component.
164
165   procedure Evaluate_Slice_Bounds (Slice : Node_Id);
166   --  Force evaluation of bounds of a slice, which may be given by a range
167   --  or by a subtype indication with or without a constraint.
168
169   function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean;
170   --  Determine whether pragma Default_Initial_Condition denoted by Prag has
171   --  an assertion expression that should be verified at run time.
172
173   function Make_CW_Equivalent_Type
174     (T : Entity_Id;
175      E : Node_Id) return Entity_Id;
176   --  T is a class-wide type entity, E is the initial expression node that
177   --  constrains T in case such as: " X: T := E" or "new T'(E)". This function
178   --  returns the entity of the Equivalent type and inserts on the fly the
179   --  necessary declaration such as:
180   --
181   --    type anon is record
182   --       _parent : Root_Type (T); constrained with E discriminants (if any)
183   --       Extension : String (1 .. expr to match size of E);
184   --    end record;
185   --
186   --  This record is compatible with any object of the class of T thanks to
187   --  the first field and has the same size as E thanks to the second.
188
189   function Make_Literal_Range
190     (Loc         : Source_Ptr;
191      Literal_Typ : Entity_Id) return Node_Id;
192   --  Produce a Range node whose bounds are:
193   --    Low_Bound (Literal_Type) ..
194   --        Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1)
195   --  this is used for expanding declarations like X : String := "sdfgdfg";
196   --
197   --  If the index type of the target array is not integer, we generate:
198   --     Low_Bound (Literal_Type) ..
199   --        Literal_Type'Val
200   --          (Literal_Type'Pos (Low_Bound (Literal_Type))
201   --             + (Length (Literal_Typ) -1))
202
203   function Make_Non_Empty_Check
204     (Loc : Source_Ptr;
205      N   : Node_Id) return Node_Id;
206   --  Produce a boolean expression checking that the unidimensional array
207   --  node N is not empty.
208
209   function New_Class_Wide_Subtype
210     (CW_Typ : Entity_Id;
211      N      : Node_Id) return Entity_Id;
212   --  Create an implicit subtype of CW_Typ attached to node N
213
214   function Requires_Cleanup_Actions
215     (L                 : List_Id;
216      Lib_Level         : Boolean;
217      Nested_Constructs : Boolean) return Boolean;
218   --  Given a list L, determine whether it contains one of the following:
219   --
220   --    1) controlled objects
221   --    2) library-level tagged types
222   --
223   --  Lib_Level is True when the list comes from a construct at the library
224   --  level, and False otherwise. Nested_Constructs is True when any nested
225   --  packages declared in L must be processed, and False otherwise.
226
227   -------------------------------------
228   -- Activate_Atomic_Synchronization --
229   -------------------------------------
230
231   procedure Activate_Atomic_Synchronization (N : Node_Id) is
232      Msg_Node : Node_Id;
233
234   begin
235      case Nkind (Parent (N)) is
236
237         --  Check for cases of appearing in the prefix of a construct where we
238         --  don't need atomic synchronization for this kind of usage.
239
240         when
241            --  Nothing to do if we are the prefix of an attribute, since we
242            --  do not want an atomic sync operation for things like 'Size.
243
244              N_Attribute_Reference
245
246            --  The N_Reference node is like an attribute
247
248            | N_Reference
249
250            --  Nothing to do for a reference to a component (or components)
251            --  of a composite object. Only reads and updates of the object
252            --  as a whole require atomic synchronization (RM C.6 (15)).
253
254            | N_Indexed_Component
255            | N_Selected_Component
256            | N_Slice
257         =>
258            --  For all the above cases, nothing to do if we are the prefix
259
260            if Prefix (Parent (N)) = N then
261               return;
262            end if;
263
264         when others =>
265            null;
266      end case;
267
268      --  Nothing to do for the identifier in an object renaming declaration,
269      --  the renaming itself does not need atomic synchronization.
270
271      if Nkind (Parent (N)) = N_Object_Renaming_Declaration then
272         return;
273      end if;
274
275      --  Go ahead and set the flag
276
277      Set_Atomic_Sync_Required (N);
278
279      --  Generate info message if requested
280
281      if Warn_On_Atomic_Synchronization then
282         case Nkind (N) is
283            when N_Identifier =>
284               Msg_Node := N;
285
286            when N_Expanded_Name
287               | N_Selected_Component
288            =>
289               Msg_Node := Selector_Name (N);
290
291            when N_Explicit_Dereference
292               | N_Indexed_Component
293            =>
294               Msg_Node := Empty;
295
296            when others =>
297               pragma Assert (False);
298               return;
299         end case;
300
301         if Present (Msg_Node) then
302            Error_Msg_N
303              ("info: atomic synchronization set for &?N?", Msg_Node);
304         else
305            Error_Msg_N
306              ("info: atomic synchronization set?N?", N);
307         end if;
308      end if;
309   end Activate_Atomic_Synchronization;
310
311   ----------------------
312   -- Adjust_Condition --
313   ----------------------
314
315   procedure Adjust_Condition (N : Node_Id) is
316   begin
317      if No (N) then
318         return;
319      end if;
320
321      declare
322         Loc : constant Source_Ptr := Sloc (N);
323         T   : constant Entity_Id  := Etype (N);
324         Ti  : Entity_Id;
325
326      begin
327         --  Defend against a call where the argument has no type, or has a
328         --  type that is not Boolean. This can occur because of prior errors.
329
330         if No (T) or else not Is_Boolean_Type (T) then
331            return;
332         end if;
333
334         --  Apply validity checking if needed
335
336         if Validity_Checks_On and Validity_Check_Tests then
337            Ensure_Valid (N);
338         end if;
339
340         --  Immediate return if standard boolean, the most common case,
341         --  where nothing needs to be done.
342
343         if Base_Type (T) = Standard_Boolean then
344            return;
345         end if;
346
347         --  Case of zero/nonzero semantics or nonstandard enumeration
348         --  representation. In each case, we rewrite the node as:
349
350         --      ityp!(N) /= False'Enum_Rep
351
352         --  where ityp is an integer type with large enough size to hold any
353         --  value of type T.
354
355         if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
356            if Esize (T) <= Esize (Standard_Integer) then
357               Ti := Standard_Integer;
358            else
359               Ti := Standard_Long_Long_Integer;
360            end if;
361
362            Rewrite (N,
363              Make_Op_Ne (Loc,
364                Left_Opnd  => Unchecked_Convert_To (Ti, N),
365                Right_Opnd =>
366                  Make_Attribute_Reference (Loc,
367                    Attribute_Name => Name_Enum_Rep,
368                    Prefix         =>
369                      New_Occurrence_Of (First_Literal (T), Loc))));
370            Analyze_And_Resolve (N, Standard_Boolean);
371
372         else
373            Rewrite (N, Convert_To (Standard_Boolean, N));
374            Analyze_And_Resolve (N, Standard_Boolean);
375         end if;
376      end;
377   end Adjust_Condition;
378
379   ------------------------
380   -- Adjust_Result_Type --
381   ------------------------
382
383   procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
384   begin
385      --  Ignore call if current type is not Standard.Boolean
386
387      if Etype (N) /= Standard_Boolean then
388         return;
389      end if;
390
391      --  If result is already of correct type, nothing to do. Note that
392      --  this will get the most common case where everything has a type
393      --  of Standard.Boolean.
394
395      if Base_Type (T) = Standard_Boolean then
396         return;
397
398      else
399         declare
400            KP : constant Node_Kind := Nkind (Parent (N));
401
402         begin
403            --  If result is to be used as a Condition in the syntax, no need
404            --  to convert it back, since if it was changed to Standard.Boolean
405            --  using Adjust_Condition, that is just fine for this usage.
406
407            if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
408               return;
409
410            --  If result is an operand of another logical operation, no need
411            --  to reset its type, since Standard.Boolean is just fine, and
412            --  such operations always do Adjust_Condition on their operands.
413
414            elsif     KP in N_Op_Boolean
415              or else KP in N_Short_Circuit
416              or else KP = N_Op_Not
417            then
418               return;
419
420            --  Otherwise we perform a conversion from the current type, which
421            --  must be Standard.Boolean, to the desired type. Use the base
422            --  type to prevent spurious constraint checks that are extraneous
423            --  to the transformation. The type and its base have the same
424            --  representation, standard or otherwise.
425
426            else
427               Set_Analyzed (N);
428               Rewrite (N, Convert_To (Base_Type (T), N));
429               Analyze_And_Resolve (N, Base_Type (T));
430            end if;
431         end;
432      end if;
433   end Adjust_Result_Type;
434
435   --------------------------
436   -- Append_Freeze_Action --
437   --------------------------
438
439   procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
440      Fnode : Node_Id;
441
442   begin
443      Ensure_Freeze_Node (T);
444      Fnode := Freeze_Node (T);
445
446      if No (Actions (Fnode)) then
447         Set_Actions (Fnode, New_List (N));
448      else
449         Append (N, Actions (Fnode));
450      end if;
451
452   end Append_Freeze_Action;
453
454   ---------------------------
455   -- Append_Freeze_Actions --
456   ---------------------------
457
458   procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
459      Fnode : Node_Id;
460
461   begin
462      if No (L) then
463         return;
464      end if;
465
466      Ensure_Freeze_Node (T);
467      Fnode := Freeze_Node (T);
468
469      if No (Actions (Fnode)) then
470         Set_Actions (Fnode, L);
471      else
472         Append_List (L, Actions (Fnode));
473      end if;
474   end Append_Freeze_Actions;
475
476   --------------------------------------
477   -- Attr_Constrained_Statically_True --
478   --------------------------------------
479
480   function Attribute_Constrained_Static_Value (Pref : Node_Id) return Boolean
481   is
482      Ptyp       : constant Entity_Id := Etype (Pref);
483      Formal_Ent : constant Entity_Id := Param_Entity (Pref);
484
485      function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean;
486      --  Ada 2005 (AI-363): Returns True if the object name Obj denotes a
487      --  view of an aliased object whose subtype is constrained.
488
489      ---------------------------------
490      -- Is_Constrained_Aliased_View --
491      ---------------------------------
492
493      function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean is
494         E : Entity_Id;
495
496      begin
497         if Is_Entity_Name (Obj) then
498            E := Entity (Obj);
499
500            if Present (Renamed_Object (E)) then
501               return Is_Constrained_Aliased_View (Renamed_Object (E));
502            else
503               return Is_Aliased (E) and then Is_Constrained (Etype (E));
504            end if;
505
506         else
507            return Is_Aliased_View (Obj)
508              and then
509                (Is_Constrained (Etype (Obj))
510                 or else
511                   (Nkind (Obj) = N_Explicit_Dereference
512                    and then
513                      not Object_Type_Has_Constrained_Partial_View
514                        (Typ  => Base_Type (Etype (Obj)),
515                         Scop => Current_Scope)));
516         end if;
517      end Is_Constrained_Aliased_View;
518
519   --  Start of processing for Attribute_Constrained_Static_Value
520
521   begin
522      --  We are in a case where the attribute is known statically, and
523      --  implicit dereferences have been rewritten.
524
525      pragma Assert
526        (not (Present (Formal_Ent)
527              and then Ekind (Formal_Ent) /= E_Constant
528              and then Present (Extra_Constrained (Formal_Ent)))
529         and then
530           not (Is_Access_Type (Etype (Pref))
531                and then (not Is_Entity_Name (Pref)
532                          or else Is_Object (Entity (Pref))))
533         and then
534           not (Nkind (Pref) = N_Identifier
535                and then Ekind (Entity (Pref)) = E_Variable
536                and then Present (Extra_Constrained (Entity (Pref)))));
537
538      if Is_Entity_Name (Pref) then
539         declare
540            Ent : constant Entity_Id   := Entity (Pref);
541            Res : Boolean;
542
543         begin
544            --  (RM J.4) obsolescent cases
545
546            if Is_Type (Ent) then
547
548               --  Private type
549
550               if Is_Private_Type (Ent) then
551                  Res := not Has_Discriminants (Ent)
552                    or else Is_Constrained (Ent);
553
554               --  It not a private type, must be a generic actual type
555               --  that corresponded to a private type. We know that this
556               --  correspondence holds, since otherwise the reference
557               --  within the generic template would have been illegal.
558
559               else
560                  if Is_Composite_Type (Underlying_Type (Ent)) then
561                     Res := Is_Constrained (Ent);
562                  else
563                     Res := True;
564                  end if;
565               end if;
566
567            else
568
569               --  If the prefix is not a variable or is aliased, then
570               --  definitely true; if it's a formal parameter without an
571               --  associated extra formal, then treat it as constrained.
572
573               --  Ada 2005 (AI-363): An aliased prefix must be known to be
574               --  constrained in order to set the attribute to True.
575
576               if not Is_Variable (Pref)
577                 or else Present (Formal_Ent)
578                 or else (Ada_Version < Ada_2005
579                          and then Is_Aliased_View (Pref))
580                 or else (Ada_Version >= Ada_2005
581                          and then Is_Constrained_Aliased_View (Pref))
582               then
583                  Res := True;
584
585               --  Variable case, look at type to see if it is constrained.
586               --  Note that the one case where this is not accurate (the
587               --  procedure formal case), has been handled above.
588
589               --  We use the Underlying_Type here (and below) in case the
590               --  type is private without discriminants, but the full type
591               --  has discriminants. This case is illegal, but we generate
592               --  it internally for passing to the Extra_Constrained
593               --  parameter.
594
595               else
596                  --  In Ada 2012, test for case of a limited tagged type,
597                  --  in which case the attribute is always required to
598                  --  return True. The underlying type is tested, to make
599                  --  sure we also return True for cases where there is an
600                  --  unconstrained object with an untagged limited partial
601                  --  view which has defaulted discriminants (such objects
602                  --  always produce a False in earlier versions of
603                  --  Ada). (Ada 2012: AI05-0214)
604
605                  Res :=
606                    Is_Constrained (Underlying_Type (Etype (Ent)))
607                    or else
608                      (Ada_Version >= Ada_2012
609                       and then Is_Tagged_Type (Underlying_Type (Ptyp))
610                       and then Is_Limited_Type (Ptyp));
611               end if;
612            end if;
613
614            return Res;
615         end;
616
617      --  Prefix is not an entity name. These are also cases where we can
618      --  always tell at compile time by looking at the form and type of the
619      --  prefix. If an explicit dereference of an object with constrained
620      --  partial view, this is unconstrained (Ada 2005: AI95-0363). If the
621      --  underlying type is a limited tagged type, then Constrained is
622      --  required to always return True (Ada 2012: AI05-0214).
623
624      else
625         return not Is_Variable (Pref)
626           or else
627             (Nkind (Pref) = N_Explicit_Dereference
628              and then
629                not Object_Type_Has_Constrained_Partial_View
630                  (Typ  => Base_Type (Ptyp),
631                   Scop => Current_Scope))
632           or else Is_Constrained (Underlying_Type (Ptyp))
633           or else (Ada_Version >= Ada_2012
634                    and then Is_Tagged_Type (Underlying_Type (Ptyp))
635                    and then Is_Limited_Type (Ptyp));
636      end if;
637   end Attribute_Constrained_Static_Value;
638
639   ------------------------------------
640   -- Build_Allocate_Deallocate_Proc --
641   ------------------------------------
642
643   procedure Build_Allocate_Deallocate_Proc
644     (N           : Node_Id;
645      Is_Allocate : Boolean)
646   is
647      function Find_Object (E : Node_Id) return Node_Id;
648      --  Given an arbitrary expression of an allocator, try to find an object
649      --  reference in it, otherwise return the original expression.
650
651      function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean;
652      --  Determine whether subprogram Subp denotes a custom allocate or
653      --  deallocate.
654
655      -----------------
656      -- Find_Object --
657      -----------------
658
659      function Find_Object (E : Node_Id) return Node_Id is
660         Expr : Node_Id;
661
662      begin
663         pragma Assert (Is_Allocate);
664
665         Expr := E;
666         loop
667            if Nkind (Expr) = N_Explicit_Dereference then
668               Expr := Prefix (Expr);
669
670            elsif Nkind (Expr) = N_Qualified_Expression then
671               Expr := Expression (Expr);
672
673            elsif Nkind (Expr) = N_Unchecked_Type_Conversion then
674
675               --  When interface class-wide types are involved in allocation,
676               --  the expander introduces several levels of address arithmetic
677               --  to perform dispatch table displacement. In this scenario the
678               --  object appears as:
679
680               --    Tag_Ptr (Base_Address (<object>'Address))
681
682               --  Detect this case and utilize the whole expression as the
683               --  "object" since it now points to the proper dispatch table.
684
685               if Is_RTE (Etype (Expr), RE_Tag_Ptr) then
686                  exit;
687
688               --  Continue to strip the object
689
690               else
691                  Expr := Expression (Expr);
692               end if;
693
694            else
695               exit;
696            end if;
697         end loop;
698
699         return Expr;
700      end Find_Object;
701
702      ---------------------------------
703      -- Is_Allocate_Deallocate_Proc --
704      ---------------------------------
705
706      function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is
707      begin
708         --  Look for a subprogram body with only one statement which is a
709         --  call to Allocate_Any_Controlled / Deallocate_Any_Controlled.
710
711         if Ekind (Subp) = E_Procedure
712           and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body
713         then
714            declare
715               HSS  : constant Node_Id :=
716                        Handled_Statement_Sequence (Parent (Parent (Subp)));
717               Proc : Entity_Id;
718
719            begin
720               if Present (Statements (HSS))
721                 and then Nkind (First (Statements (HSS))) =
722                            N_Procedure_Call_Statement
723               then
724                  Proc := Entity (Name (First (Statements (HSS))));
725
726                  return
727                    Is_RTE (Proc, RE_Allocate_Any_Controlled)
728                      or else Is_RTE (Proc, RE_Deallocate_Any_Controlled);
729               end if;
730            end;
731         end if;
732
733         return False;
734      end Is_Allocate_Deallocate_Proc;
735
736      --  Local variables
737
738      Desig_Typ    : Entity_Id;
739      Expr         : Node_Id;
740      Needs_Fin    : Boolean;
741      Pool_Id      : Entity_Id;
742      Proc_To_Call : Node_Id := Empty;
743      Ptr_Typ      : Entity_Id;
744
745   --  Start of processing for Build_Allocate_Deallocate_Proc
746
747   begin
748      --  Obtain the attributes of the allocation / deallocation
749
750      if Nkind (N) = N_Free_Statement then
751         Expr := Expression (N);
752         Ptr_Typ := Base_Type (Etype (Expr));
753         Proc_To_Call := Procedure_To_Call (N);
754
755      else
756         if Nkind (N) = N_Object_Declaration then
757            Expr := Expression (N);
758         else
759            Expr := N;
760         end if;
761
762         --  In certain cases an allocator with a qualified expression may
763         --  be relocated and used as the initialization expression of a
764         --  temporary:
765
766         --    before:
767         --       Obj : Ptr_Typ := new Desig_Typ'(...);
768
769         --    after:
770         --       Tmp : Ptr_Typ := new Desig_Typ'(...);
771         --       Obj : Ptr_Typ := Tmp;
772
773         --  Since the allocator is always marked as analyzed to avoid infinite
774         --  expansion, it will never be processed by this routine given that
775         --  the designated type needs finalization actions. Detect this case
776         --  and complete the expansion of the allocator.
777
778         if Nkind (Expr) = N_Identifier
779           and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration
780           and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator
781         then
782            Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True);
783            return;
784         end if;
785
786         --  The allocator may have been rewritten into something else in which
787         --  case the expansion performed by this routine does not apply.
788
789         if Nkind (Expr) /= N_Allocator then
790            return;
791         end if;
792
793         Ptr_Typ := Base_Type (Etype (Expr));
794         Proc_To_Call := Procedure_To_Call (Expr);
795      end if;
796
797      Pool_Id := Associated_Storage_Pool (Ptr_Typ);
798      Desig_Typ := Available_View (Designated_Type (Ptr_Typ));
799
800      --  Handle concurrent types
801
802      if Is_Concurrent_Type (Desig_Typ)
803        and then Present (Corresponding_Record_Type (Desig_Typ))
804      then
805         Desig_Typ := Corresponding_Record_Type (Desig_Typ);
806      end if;
807
808      --  Do not process allocations / deallocations without a pool
809
810      if No (Pool_Id) then
811         return;
812
813      --  Do not process allocations on / deallocations from the secondary
814      --  stack.
815
816      elsif Is_RTE (Pool_Id, RE_SS_Pool)
817        or else (Nkind (Expr) = N_Allocator
818                  and then Is_RTE (Storage_Pool (Expr), RE_SS_Pool))
819      then
820         return;
821
822      --  Optimize the case where we are using the default Global_Pool_Object,
823      --  and we don't need the heavy finalization machinery.
824
825      elsif Pool_Id = RTE (RE_Global_Pool_Object)
826        and then not Needs_Finalization (Desig_Typ)
827      then
828         return;
829
830      --  Do not replicate the machinery if the allocator / free has already
831      --  been expanded and has a custom Allocate / Deallocate.
832
833      elsif Present (Proc_To_Call)
834        and then Is_Allocate_Deallocate_Proc (Proc_To_Call)
835      then
836         return;
837      end if;
838
839      --  Finalization actions are required when the object to be allocated or
840      --  deallocated needs these actions and the associated access type is not
841      --  subject to pragma No_Heap_Finalization.
842
843      Needs_Fin :=
844        Needs_Finalization (Desig_Typ)
845          and then not No_Heap_Finalization (Ptr_Typ);
846
847      if Needs_Fin then
848
849         --  Do nothing if the access type may never allocate / deallocate
850         --  objects.
851
852         if No_Pool_Assigned (Ptr_Typ) then
853            return;
854         end if;
855
856         --  The allocation / deallocation of a controlled object must be
857         --  chained on / detached from a finalization master.
858
859         pragma Assert (Present (Finalization_Master (Ptr_Typ)));
860
861      --  The only other kind of allocation / deallocation supported by this
862      --  routine is on / from a subpool.
863
864      elsif Nkind (Expr) = N_Allocator
865        and then No (Subpool_Handle_Name (Expr))
866      then
867         return;
868      end if;
869
870      declare
871         Loc     : constant Source_Ptr := Sloc (N);
872         Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A');
873         Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L');
874         Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
875         Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
876
877         Actuals      : List_Id;
878         Fin_Addr_Id  : Entity_Id;
879         Fin_Mas_Act  : Node_Id;
880         Fin_Mas_Id   : Entity_Id;
881         Proc_To_Call : Entity_Id;
882         Subpool      : Node_Id := Empty;
883
884      begin
885         --  Step 1: Construct all the actuals for the call to library routine
886         --  Allocate_Any_Controlled / Deallocate_Any_Controlled.
887
888         --  a) Storage pool
889
890         Actuals := New_List (New_Occurrence_Of (Pool_Id, Loc));
891
892         if Is_Allocate then
893
894            --  b) Subpool
895
896            if Nkind (Expr) = N_Allocator then
897               Subpool := Subpool_Handle_Name (Expr);
898            end if;
899
900            --  If a subpool is present it can be an arbitrary name, so make
901            --  the actual by copying the tree.
902
903            if Present (Subpool) then
904               Append_To (Actuals, New_Copy_Tree (Subpool, New_Sloc => Loc));
905            else
906               Append_To (Actuals, Make_Null (Loc));
907            end if;
908
909            --  c) Finalization master
910
911            if Needs_Fin then
912               Fin_Mas_Id  := Finalization_Master (Ptr_Typ);
913               Fin_Mas_Act := New_Occurrence_Of (Fin_Mas_Id, Loc);
914
915               --  Handle the case where the master is actually a pointer to a
916               --  master. This case arises in build-in-place functions.
917
918               if Is_Access_Type (Etype (Fin_Mas_Id)) then
919                  Append_To (Actuals, Fin_Mas_Act);
920               else
921                  Append_To (Actuals,
922                    Make_Attribute_Reference (Loc,
923                      Prefix         => Fin_Mas_Act,
924                      Attribute_Name => Name_Unrestricted_Access));
925               end if;
926            else
927               Append_To (Actuals, Make_Null (Loc));
928            end if;
929
930            --  d) Finalize_Address
931
932            --  Primitive Finalize_Address is never generated in CodePeer mode
933            --  since it contains an Unchecked_Conversion.
934
935            if Needs_Fin and then not CodePeer_Mode then
936               Fin_Addr_Id := Finalize_Address (Desig_Typ);
937               pragma Assert (Present (Fin_Addr_Id));
938
939               Append_To (Actuals,
940                 Make_Attribute_Reference (Loc,
941                   Prefix         => New_Occurrence_Of (Fin_Addr_Id, Loc),
942                   Attribute_Name => Name_Unrestricted_Access));
943            else
944               Append_To (Actuals, Make_Null (Loc));
945            end if;
946         end if;
947
948         --  e) Address
949         --  f) Storage_Size
950         --  g) Alignment
951
952         Append_To (Actuals, New_Occurrence_Of (Addr_Id, Loc));
953         Append_To (Actuals, New_Occurrence_Of (Size_Id, Loc));
954
955         if Is_Allocate or else not Is_Class_Wide_Type (Desig_Typ) then
956            Append_To (Actuals, New_Occurrence_Of (Alig_Id, Loc));
957
958         --  For deallocation of class-wide types we obtain the value of
959         --  alignment from the Type Specific Record of the deallocated object.
960         --  This is needed because the frontend expansion of class-wide types
961         --  into equivalent types confuses the back end.
962
963         else
964            --  Generate:
965            --     Obj.all'Alignment
966
967            --  ... because 'Alignment applied to class-wide types is expanded
968            --  into the code that reads the value of alignment from the TSD
969            --  (see Expand_N_Attribute_Reference)
970
971            Append_To (Actuals,
972              Unchecked_Convert_To (RTE (RE_Storage_Offset),
973                Make_Attribute_Reference (Loc,
974                  Prefix         =>
975                    Make_Explicit_Dereference (Loc, Relocate_Node (Expr)),
976                  Attribute_Name => Name_Alignment)));
977         end if;
978
979         --  h) Is_Controlled
980
981         if Needs_Fin then
982            Is_Controlled : declare
983               Flag_Id   : constant Entity_Id := Make_Temporary (Loc, 'F');
984               Flag_Expr : Node_Id;
985               Param     : Node_Id;
986               Pref      : Node_Id;
987               Temp      : Node_Id;
988
989            begin
990               if Is_Allocate then
991                  Temp := Find_Object (Expression (Expr));
992               else
993                  Temp := Expr;
994               end if;
995
996               --  Processing for allocations where the expression is a subtype
997               --  indication.
998
999               if Is_Allocate
1000                 and then Is_Entity_Name (Temp)
1001                 and then Is_Type (Entity (Temp))
1002               then
1003                  Flag_Expr :=
1004                    New_Occurrence_Of
1005                      (Boolean_Literals
1006                         (Needs_Finalization (Entity (Temp))), Loc);
1007
1008               --  The allocation / deallocation of a class-wide object relies
1009               --  on a runtime check to determine whether the object is truly
1010               --  controlled or not. Depending on this check, the finalization
1011               --  machinery will request or reclaim extra storage reserved for
1012               --  a list header.
1013
1014               elsif Is_Class_Wide_Type (Desig_Typ) then
1015
1016                  --  Detect a special case where interface class-wide types
1017                  --  are involved as the object appears as:
1018
1019                  --    Tag_Ptr (Base_Address (<object>'Address))
1020
1021                  --  The expression already yields the proper tag, generate:
1022
1023                  --    Temp.all
1024
1025                  if Is_RTE (Etype (Temp), RE_Tag_Ptr) then
1026                     Param :=
1027                       Make_Explicit_Dereference (Loc,
1028                         Prefix => Relocate_Node (Temp));
1029
1030                  --  In the default case, obtain the tag of the object about
1031                  --  to be allocated / deallocated. Generate:
1032
1033                  --    Temp'Tag
1034
1035                  --  If the object is an unchecked conversion (typically to
1036                  --  an access to class-wide type), we must preserve the
1037                  --  conversion to ensure that the object is seen as tagged
1038                  --  in the code that follows.
1039
1040                  else
1041                     Pref := Temp;
1042
1043                     if Nkind (Parent (Pref)) = N_Unchecked_Type_Conversion
1044                     then
1045                        Pref := Parent (Pref);
1046                     end if;
1047
1048                     Param :=
1049                       Make_Attribute_Reference (Loc,
1050                         Prefix         => Relocate_Node (Pref),
1051                         Attribute_Name => Name_Tag);
1052                  end if;
1053
1054                  --  Generate:
1055                  --    Needs_Finalization (<Param>)
1056
1057                  Flag_Expr :=
1058                    Make_Function_Call (Loc,
1059                      Name                   =>
1060                        New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc),
1061                      Parameter_Associations => New_List (Param));
1062
1063               --  Processing for generic actuals
1064
1065               elsif Is_Generic_Actual_Type (Desig_Typ) then
1066                  Flag_Expr :=
1067                    New_Occurrence_Of (Boolean_Literals
1068                      (Needs_Finalization (Base_Type (Desig_Typ))), Loc);
1069
1070               --  The object does not require any specialized checks, it is
1071               --  known to be controlled.
1072
1073               else
1074                  Flag_Expr := New_Occurrence_Of (Standard_True, Loc);
1075               end if;
1076
1077               --  Create the temporary which represents the finalization state
1078               --  of the expression. Generate:
1079               --
1080               --    F : constant Boolean := <Flag_Expr>;
1081
1082               Insert_Action (N,
1083                 Make_Object_Declaration (Loc,
1084                   Defining_Identifier => Flag_Id,
1085                   Constant_Present    => True,
1086                   Object_Definition   =>
1087                     New_Occurrence_Of (Standard_Boolean, Loc),
1088                    Expression          => Flag_Expr));
1089
1090               Append_To (Actuals, New_Occurrence_Of (Flag_Id, Loc));
1091            end Is_Controlled;
1092
1093         --  The object is not controlled
1094
1095         else
1096            Append_To (Actuals, New_Occurrence_Of (Standard_False, Loc));
1097         end if;
1098
1099         --  i) On_Subpool
1100
1101         if Is_Allocate then
1102            Append_To (Actuals,
1103              New_Occurrence_Of (Boolean_Literals (Present (Subpool)), Loc));
1104         end if;
1105
1106         --  Step 2: Build a wrapper Allocate / Deallocate which internally
1107         --  calls Allocate_Any_Controlled / Deallocate_Any_Controlled.
1108
1109         --  Select the proper routine to call
1110
1111         if Is_Allocate then
1112            Proc_To_Call := RTE (RE_Allocate_Any_Controlled);
1113         else
1114            Proc_To_Call := RTE (RE_Deallocate_Any_Controlled);
1115         end if;
1116
1117         --  Create a custom Allocate / Deallocate routine which has identical
1118         --  profile to that of System.Storage_Pools.
1119
1120         Insert_Action (N,
1121           Make_Subprogram_Body (Loc,
1122             Specification              =>
1123
1124               --  procedure Pnn
1125
1126               Make_Procedure_Specification (Loc,
1127                 Defining_Unit_Name       => Proc_Id,
1128                 Parameter_Specifications => New_List (
1129
1130                  --  P : Root_Storage_Pool
1131
1132                   Make_Parameter_Specification (Loc,
1133                     Defining_Identifier => Make_Temporary (Loc, 'P'),
1134                     Parameter_Type      =>
1135                       New_Occurrence_Of (RTE (RE_Root_Storage_Pool), Loc)),
1136
1137                  --  A : [out] Address
1138
1139                   Make_Parameter_Specification (Loc,
1140                     Defining_Identifier => Addr_Id,
1141                     Out_Present         => Is_Allocate,
1142                     Parameter_Type      =>
1143                       New_Occurrence_Of (RTE (RE_Address), Loc)),
1144
1145                  --  S : Storage_Count
1146
1147                   Make_Parameter_Specification (Loc,
1148                     Defining_Identifier => Size_Id,
1149                     Parameter_Type      =>
1150                       New_Occurrence_Of (RTE (RE_Storage_Count), Loc)),
1151
1152                  --  L : Storage_Count
1153
1154                   Make_Parameter_Specification (Loc,
1155                     Defining_Identifier => Alig_Id,
1156                     Parameter_Type      =>
1157                       New_Occurrence_Of (RTE (RE_Storage_Count), Loc)))),
1158
1159             Declarations               => No_List,
1160
1161             Handled_Statement_Sequence =>
1162               Make_Handled_Sequence_Of_Statements (Loc,
1163                 Statements => New_List (
1164                   Make_Procedure_Call_Statement (Loc,
1165                     Name                   =>
1166                       New_Occurrence_Of (Proc_To_Call, Loc),
1167                     Parameter_Associations => Actuals)))),
1168           Suppress => All_Checks);
1169
1170         --  The newly generated Allocate / Deallocate becomes the default
1171         --  procedure to call when the back end processes the allocation /
1172         --  deallocation.
1173
1174         if Is_Allocate then
1175            Set_Procedure_To_Call (Expr, Proc_Id);
1176         else
1177            Set_Procedure_To_Call (N, Proc_Id);
1178         end if;
1179      end;
1180   end Build_Allocate_Deallocate_Proc;
1181
1182   -------------------------------
1183   -- Build_Abort_Undefer_Block --
1184   -------------------------------
1185
1186   function Build_Abort_Undefer_Block
1187     (Loc     : Source_Ptr;
1188      Stmts   : List_Id;
1189      Context : Node_Id) return Node_Id
1190   is
1191      Exceptions_OK : constant Boolean :=
1192                        not Restriction_Active (No_Exception_Propagation);
1193
1194      AUD    : Entity_Id;
1195      Blk    : Node_Id;
1196      Blk_Id : Entity_Id;
1197      HSS    : Node_Id;
1198
1199   begin
1200      --  The block should be generated only when undeferring abort in the
1201      --  context of a potential exception.
1202
1203      pragma Assert (Abort_Allowed and Exceptions_OK);
1204
1205      --  Generate:
1206      --    begin
1207      --       <Stmts>
1208      --    at end
1209      --       Abort_Undefer_Direct;
1210      --    end;
1211
1212      AUD := RTE (RE_Abort_Undefer_Direct);
1213
1214      HSS :=
1215        Make_Handled_Sequence_Of_Statements (Loc,
1216          Statements  => Stmts,
1217          At_End_Proc => New_Occurrence_Of (AUD, Loc));
1218
1219      Blk :=
1220        Make_Block_Statement (Loc,
1221          Handled_Statement_Sequence => HSS);
1222      Set_Is_Abort_Block (Blk);
1223
1224      Add_Block_Identifier  (Blk, Blk_Id);
1225      Expand_At_End_Handler (HSS, Blk_Id);
1226
1227      --  Present the Abort_Undefer_Direct function to the back end to inline
1228      --  the call to the routine.
1229
1230      Add_Inlined_Body (AUD, Context);
1231
1232      return Blk;
1233   end Build_Abort_Undefer_Block;
1234
1235   ---------------------------------
1236   -- Build_Class_Wide_Expression --
1237   ---------------------------------
1238
1239   procedure Build_Class_Wide_Expression
1240     (Prag          : Node_Id;
1241      Subp          : Entity_Id;
1242      Par_Subp      : Entity_Id;
1243      Adjust_Sloc   : Boolean;
1244      Needs_Wrapper : out Boolean)
1245   is
1246      function Replace_Entity (N : Node_Id) return Traverse_Result;
1247      --  Replace reference to formal of inherited operation or to primitive
1248      --  operation of root type, with corresponding entity for derived type,
1249      --  when constructing the class-wide condition of an overriding
1250      --  subprogram.
1251
1252      --------------------
1253      -- Replace_Entity --
1254      --------------------
1255
1256      function Replace_Entity (N : Node_Id) return Traverse_Result is
1257         New_E : Entity_Id;
1258
1259      begin
1260         if Adjust_Sloc then
1261            Adjust_Inherited_Pragma_Sloc (N);
1262         end if;
1263
1264         if Nkind (N) = N_Identifier
1265           and then Present (Entity (N))
1266           and then
1267             (Is_Formal (Entity (N)) or else Is_Subprogram (Entity (N)))
1268           and then
1269             (Nkind (Parent (N)) /= N_Attribute_Reference
1270               or else Attribute_Name (Parent (N)) /= Name_Class)
1271         then
1272            --  The replacement does not apply to dispatching calls within the
1273            --  condition, but only to calls whose static tag is that of the
1274            --  parent type.
1275
1276            if Is_Subprogram (Entity (N))
1277              and then Nkind (Parent (N)) = N_Function_Call
1278              and then Present (Controlling_Argument (Parent (N)))
1279            then
1280               return OK;
1281            end if;
1282
1283            --  Determine whether entity has a renaming
1284
1285            New_E := Type_Map.Get (Entity (N));
1286
1287            if Present (New_E) then
1288               Rewrite (N, New_Occurrence_Of (New_E, Sloc (N)));
1289
1290               --  AI12-0166: a precondition for a protected operation
1291               --  cannot include an internal call to a protected function
1292               --  of the type. In the case of an inherited condition for an
1293               --  overriding operation, both the operation and the function
1294               --  are given by primitive wrappers.
1295
1296               if Ekind (New_E) = E_Function
1297                 and then Is_Primitive_Wrapper (New_E)
1298                 and then Is_Primitive_Wrapper (Subp)
1299                 and then Scope (Subp) = Scope (New_E)
1300               then
1301                  Error_Msg_Node_2 := Wrapped_Entity (Subp);
1302                  Error_Msg_NE
1303                    ("internal call to& cannot appear in inherited "
1304                     & "precondition of protected operation&",
1305                     N, Wrapped_Entity (New_E));
1306               end if;
1307
1308               --  If the entity is an overridden primitive and we are not
1309               --  in GNATprove mode, we must build a wrapper for the current
1310               --  inherited operation. If the reference is the prefix of an
1311               --  attribute such as 'Result (or others ???) there is no need
1312               --  for a wrapper: the condition is just rewritten in terms of
1313               --  the inherited subprogram.
1314
1315               if Is_Subprogram (New_E)
1316                  and then Nkind (Parent (N)) /= N_Attribute_Reference
1317                  and then not GNATprove_Mode
1318               then
1319                  Needs_Wrapper := True;
1320               end if;
1321            end if;
1322
1323            --  Check that there are no calls left to abstract operations if
1324            --  the current subprogram is not abstract.
1325
1326            if Nkind (Parent (N)) = N_Function_Call
1327              and then N = Name (Parent (N))
1328            then
1329               if not Is_Abstract_Subprogram (Subp)
1330                 and then Is_Abstract_Subprogram (Entity (N))
1331               then
1332                  Error_Msg_Sloc   := Sloc (Current_Scope);
1333                  Error_Msg_Node_2 := Subp;
1334                  if Comes_From_Source (Subp) then
1335                     Error_Msg_NE
1336                       ("cannot call abstract subprogram & in inherited "
1337                        & "condition for&#", Subp, Entity (N));
1338                  else
1339                     Error_Msg_NE
1340                       ("cannot call abstract subprogram & in inherited "
1341                        & "condition for inherited&#", Subp, Entity (N));
1342                  end if;
1343
1344               --  In SPARK mode, reject an inherited condition for an
1345               --  inherited operation if it contains a call to an overriding
1346               --  operation, because this implies that the pre/postconditions
1347               --  of the inherited operation have changed silently.
1348
1349               elsif SPARK_Mode = On
1350                 and then Warn_On_Suspicious_Contract
1351                 and then Present (Alias (Subp))
1352                 and then Present (New_E)
1353                 and then Comes_From_Source (New_E)
1354               then
1355                  Error_Msg_N
1356                    ("cannot modify inherited condition (SPARK RM 6.1.1(1))",
1357                     Parent (Subp));
1358                  Error_Msg_Sloc   := Sloc (New_E);
1359                  Error_Msg_Node_2 := Subp;
1360                  Error_Msg_NE
1361                    ("\overriding of&# forces overriding of&",
1362                     Parent (Subp), New_E);
1363               end if;
1364            end if;
1365
1366            --  Update type of function call node, which should be the same as
1367            --  the function's return type.
1368
1369            if Is_Subprogram (Entity (N))
1370              and then Nkind (Parent (N)) = N_Function_Call
1371            then
1372               Set_Etype (Parent (N), Etype (Entity (N)));
1373            end if;
1374
1375         --  The whole expression will be reanalyzed
1376
1377         elsif Nkind (N) in N_Has_Etype then
1378            Set_Analyzed (N, False);
1379         end if;
1380
1381         return OK;
1382      end Replace_Entity;
1383
1384      procedure Replace_Condition_Entities is
1385        new Traverse_Proc (Replace_Entity);
1386
1387      --  Local variables
1388
1389      Par_Formal  : Entity_Id;
1390      Subp_Formal : Entity_Id;
1391
1392   --  Start of processing for Build_Class_Wide_Expression
1393
1394   begin
1395      Needs_Wrapper := False;
1396
1397      --  Add mapping from old formals to new formals
1398
1399      Par_Formal  := First_Formal (Par_Subp);
1400      Subp_Formal := First_Formal (Subp);
1401
1402      while Present (Par_Formal) and then Present (Subp_Formal) loop
1403         Type_Map.Set (Par_Formal, Subp_Formal);
1404         Next_Formal (Par_Formal);
1405         Next_Formal (Subp_Formal);
1406      end loop;
1407
1408      Replace_Condition_Entities (Prag);
1409   end Build_Class_Wide_Expression;
1410
1411   --------------------
1412   -- Build_DIC_Call --
1413   --------------------
1414
1415   function Build_DIC_Call
1416     (Loc    : Source_Ptr;
1417      Obj_Id : Entity_Id;
1418      Typ    : Entity_Id) return Node_Id
1419   is
1420      Proc_Id    : constant Entity_Id := DIC_Procedure (Typ);
1421      Formal_Typ : constant Entity_Id := Etype (First_Formal (Proc_Id));
1422
1423   begin
1424      return
1425        Make_Procedure_Call_Statement (Loc,
1426          Name                   => New_Occurrence_Of (Proc_Id, Loc),
1427          Parameter_Associations => New_List (
1428            Make_Unchecked_Type_Conversion (Loc,
1429              Subtype_Mark => New_Occurrence_Of (Formal_Typ, Loc),
1430              Expression   => New_Occurrence_Of (Obj_Id, Loc))));
1431   end Build_DIC_Call;
1432
1433   ------------------------------
1434   -- Build_DIC_Procedure_Body --
1435   ------------------------------
1436
1437   --  WARNING: This routine manages Ghost regions. Return statements must be
1438   --  replaced by gotos which jump to the end of the routine and restore the
1439   --  Ghost mode.
1440
1441   procedure Build_DIC_Procedure_Body
1442     (Typ        : Entity_Id;
1443      For_Freeze : Boolean := False)
1444   is
1445      procedure Add_DIC_Check
1446        (DIC_Prag : Node_Id;
1447         DIC_Expr : Node_Id;
1448         Stmts    : in out List_Id);
1449      --  Subsidiary to all Add_xxx_DIC routines. Add a runtime check to verify
1450      --  assertion expression DIC_Expr of pragma DIC_Prag. All generated code
1451      --  is added to list Stmts.
1452
1453      procedure Add_Inherited_DIC
1454        (DIC_Prag  : Node_Id;
1455         Par_Typ   : Entity_Id;
1456         Deriv_Typ : Entity_Id;
1457         Stmts     : in out List_Id);
1458      --  Add a runtime check to verify the assertion expression of inherited
1459      --  pragma DIC_Prag. Par_Typ is parent type, which is also the owner of
1460      --  the DIC pragma. Deriv_Typ is the derived type inheriting the DIC
1461      --  pragma. All generated code is added to list Stmts.
1462
1463      procedure Add_Inherited_Tagged_DIC
1464        (DIC_Prag  : Node_Id;
1465         Par_Typ   : Entity_Id;
1466         Deriv_Typ : Entity_Id;
1467         Stmts     : in out List_Id);
1468      --  Add a runtime check to verify assertion expression DIC_Expr of
1469      --  inherited pragma DIC_Prag. This routine applies class-wide pre- and
1470      --  postcondition-like runtime semantics to the check. Par_Typ is the
1471      --  parent type whose DIC pragma is being inherited. Deriv_Typ is the
1472      --  derived type inheriting the DIC pragma. All generated code is added
1473      --  to list Stmts.
1474
1475      procedure Add_Own_DIC
1476        (DIC_Prag : Node_Id;
1477         DIC_Typ  : Entity_Id;
1478         Stmts    : in out List_Id);
1479      --  Add a runtime check to verify the assertion expression of pragma
1480      --  DIC_Prag. DIC_Typ is the owner of the DIC pragma. All generated code
1481      --  is added to list Stmts.
1482
1483      -------------------
1484      -- Add_DIC_Check --
1485      -------------------
1486
1487      procedure Add_DIC_Check
1488        (DIC_Prag : Node_Id;
1489         DIC_Expr : Node_Id;
1490         Stmts    : in out List_Id)
1491      is
1492         Loc : constant Source_Ptr := Sloc (DIC_Prag);
1493         Nam : constant Name_Id    := Original_Aspect_Pragma_Name (DIC_Prag);
1494
1495      begin
1496         --  The DIC pragma is ignored, nothing left to do
1497
1498         if Is_Ignored (DIC_Prag) then
1499            null;
1500
1501         --  Otherwise the DIC expression must be checked at run time.
1502         --  Generate:
1503
1504         --    pragma Check (<Nam>, <DIC_Expr>);
1505
1506         else
1507            Append_New_To (Stmts,
1508              Make_Pragma (Loc,
1509                Pragma_Identifier            =>
1510                  Make_Identifier (Loc, Name_Check),
1511
1512                Pragma_Argument_Associations => New_List (
1513                  Make_Pragma_Argument_Association (Loc,
1514                    Expression => Make_Identifier (Loc, Nam)),
1515
1516                  Make_Pragma_Argument_Association (Loc,
1517                    Expression => DIC_Expr))));
1518         end if;
1519      end Add_DIC_Check;
1520
1521      -----------------------
1522      -- Add_Inherited_DIC --
1523      -----------------------
1524
1525      procedure Add_Inherited_DIC
1526        (DIC_Prag  : Node_Id;
1527         Par_Typ   : Entity_Id;
1528         Deriv_Typ : Entity_Id;
1529         Stmts     : in out List_Id)
1530      is
1531         Deriv_Proc : constant Entity_Id  := DIC_Procedure (Deriv_Typ);
1532         Deriv_Obj  : constant Entity_Id  := First_Entity  (Deriv_Proc);
1533         Par_Proc   : constant Entity_Id  := DIC_Procedure (Par_Typ);
1534         Par_Obj    : constant Entity_Id  := First_Entity  (Par_Proc);
1535         Loc        : constant Source_Ptr := Sloc (DIC_Prag);
1536
1537      begin
1538         pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc));
1539
1540         --  Verify the inherited DIC assertion expression by calling the DIC
1541         --  procedure of the parent type.
1542
1543         --  Generate:
1544         --    <Par_Typ>DIC (Par_Typ (_object));
1545
1546         Append_New_To (Stmts,
1547           Make_Procedure_Call_Statement (Loc,
1548             Name                   => New_Occurrence_Of (Par_Proc, Loc),
1549             Parameter_Associations => New_List (
1550               Convert_To
1551                 (Typ  => Etype (Par_Obj),
1552                  Expr => New_Occurrence_Of (Deriv_Obj, Loc)))));
1553      end Add_Inherited_DIC;
1554
1555      ------------------------------
1556      -- Add_Inherited_Tagged_DIC --
1557      ------------------------------
1558
1559      procedure Add_Inherited_Tagged_DIC
1560        (DIC_Prag  : Node_Id;
1561         Par_Typ   : Entity_Id;
1562         Deriv_Typ : Entity_Id;
1563         Stmts     : in out List_Id)
1564      is
1565         Deriv_Proc : constant Entity_Id := DIC_Procedure (Deriv_Typ);
1566         DIC_Args   : constant List_Id   :=
1567                        Pragma_Argument_Associations (DIC_Prag);
1568         DIC_Arg    : constant Node_Id   := First (DIC_Args);
1569         DIC_Expr   : constant Node_Id   := Expression_Copy (DIC_Arg);
1570         Par_Proc   : constant Entity_Id := DIC_Procedure (Par_Typ);
1571
1572         Expr : Node_Id;
1573
1574      begin
1575         --  The processing of an inherited DIC assertion expression starts off
1576         --  with a copy of the original parent expression where all references
1577         --  to the parent type have already been replaced with references to
1578         --  the _object formal parameter of the parent type's DIC procedure.
1579
1580         pragma Assert (Present (DIC_Expr));
1581         Expr := New_Copy_Tree (DIC_Expr);
1582
1583         --  Perform the following substitutions:
1584
1585         --    * Replace a reference to the _object parameter of the parent
1586         --      type's DIC procedure with a reference to the _object parameter
1587         --      of the derived types' DIC procedure.
1588
1589         --    * Replace a reference to a discriminant of the parent type with
1590         --      a suitable value from the point of view of the derived type.
1591
1592         --    * Replace a call to an overridden parent primitive with a call
1593         --      to the overriding derived type primitive.
1594
1595         --    * Replace a call to an inherited parent primitive with a call to
1596         --      the internally-generated inherited derived type primitive.
1597
1598         --  Note that primitives defined in the private part are automatically
1599         --  handled by the overriding/inheritance mechanism and do not require
1600         --  an extra replacement pass.
1601
1602         pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc));
1603
1604         Replace_References
1605           (Expr      => Expr,
1606            Par_Typ   => Par_Typ,
1607            Deriv_Typ => Deriv_Typ,
1608            Par_Obj   => First_Formal (Par_Proc),
1609            Deriv_Obj => First_Formal (Deriv_Proc));
1610
1611         --  Once the DIC assertion expression is fully processed, add a check
1612         --  to the statements of the DIC procedure.
1613
1614         Add_DIC_Check
1615           (DIC_Prag => DIC_Prag,
1616            DIC_Expr => Expr,
1617            Stmts    => Stmts);
1618      end Add_Inherited_Tagged_DIC;
1619
1620      -----------------
1621      -- Add_Own_DIC --
1622      -----------------
1623
1624      procedure Add_Own_DIC
1625        (DIC_Prag : Node_Id;
1626         DIC_Typ  : Entity_Id;
1627         Stmts    : in out List_Id)
1628      is
1629         DIC_Args : constant List_Id   :=
1630                      Pragma_Argument_Associations (DIC_Prag);
1631         DIC_Arg  : constant Node_Id   := First (DIC_Args);
1632         DIC_Asp  : constant Node_Id   := Corresponding_Aspect (DIC_Prag);
1633         DIC_Expr : constant Node_Id   := Get_Pragma_Arg (DIC_Arg);
1634         DIC_Proc : constant Entity_Id := DIC_Procedure (DIC_Typ);
1635         Obj_Id   : constant Entity_Id := First_Formal (DIC_Proc);
1636
1637         procedure Preanalyze_Own_DIC_For_ASIS;
1638         --  Preanalyze the original DIC expression of an aspect or a source
1639         --  pragma for ASIS.
1640
1641         ---------------------------------
1642         -- Preanalyze_Own_DIC_For_ASIS --
1643         ---------------------------------
1644
1645         procedure Preanalyze_Own_DIC_For_ASIS is
1646            Expr : Node_Id := Empty;
1647
1648         begin
1649            --  The DIC pragma is a source construct, preanalyze the original
1650            --  expression of the pragma.
1651
1652            if Comes_From_Source (DIC_Prag) then
1653               Expr := DIC_Expr;
1654
1655            --  Otherwise preanalyze the expression of the corresponding aspect
1656
1657            elsif Present (DIC_Asp) then
1658               Expr := Expression (DIC_Asp);
1659            end if;
1660
1661            --  The expression must be subjected to the same substitutions as
1662            --  the copy used in the generation of the runtime check.
1663
1664            if Present (Expr) then
1665               Replace_Type_References
1666                 (Expr   => Expr,
1667                  Typ    => DIC_Typ,
1668                  Obj_Id => Obj_Id);
1669
1670               Preanalyze_Assert_Expression (Expr, Any_Boolean);
1671            end if;
1672         end Preanalyze_Own_DIC_For_ASIS;
1673
1674         --  Local variables
1675
1676         Typ_Decl : constant Node_Id := Declaration_Node (DIC_Typ);
1677
1678         Expr : Node_Id;
1679
1680      --  Start of processing for Add_Own_DIC
1681
1682      begin
1683         pragma Assert (Present (DIC_Expr));
1684         Expr := New_Copy_Tree (DIC_Expr);
1685
1686         --  Perform the following substitution:
1687
1688         --    * Replace the current instance of DIC_Typ with a reference to
1689         --    the _object formal parameter of the DIC procedure.
1690
1691         Replace_Type_References
1692           (Expr   => Expr,
1693            Typ    => DIC_Typ,
1694            Obj_Id => Obj_Id);
1695
1696         --  Preanalyze the DIC expression to detect errors and at the same
1697         --  time capture the visibility of the proper package part.
1698
1699         Set_Parent (Expr, Typ_Decl);
1700         Preanalyze_Assert_Expression (Expr, Any_Boolean);
1701
1702         --  Save a copy of the expression with all replacements and analysis
1703         --  already taken place in case a derived type inherits the pragma.
1704         --  The copy will be used as the foundation of the derived type's own
1705         --  version of the DIC assertion expression.
1706
1707         if Is_Tagged_Type (DIC_Typ) then
1708            Set_Expression_Copy (DIC_Arg, New_Copy_Tree (Expr));
1709         end if;
1710
1711         --  If the pragma comes from an aspect specification, replace the
1712         --  saved expression because all type references must be substituted
1713         --  for the call to Preanalyze_Spec_Expression in Check_Aspect_At_xxx
1714         --  routines.
1715
1716         if Present (DIC_Asp) then
1717            Set_Entity (Identifier (DIC_Asp), New_Copy_Tree (Expr));
1718         end if;
1719
1720         --  Preanalyze the original DIC expression for ASIS
1721
1722         if ASIS_Mode then
1723            Preanalyze_Own_DIC_For_ASIS;
1724         end if;
1725
1726         --  Once the DIC assertion expression is fully processed, add a check
1727         --  to the statements of the DIC procedure.
1728
1729         Add_DIC_Check
1730           (DIC_Prag => DIC_Prag,
1731            DIC_Expr => Expr,
1732            Stmts    => Stmts);
1733      end Add_Own_DIC;
1734
1735      --  Local variables
1736
1737      Loc : constant Source_Ptr := Sloc (Typ);
1738
1739      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
1740      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
1741      --  Save the Ghost-related attributes to restore on exit
1742
1743      DIC_Prag     : Node_Id;
1744      DIC_Typ      : Entity_Id;
1745      Dummy_1      : Entity_Id;
1746      Dummy_2      : Entity_Id;
1747      Proc_Body    : Node_Id;
1748      Proc_Body_Id : Entity_Id;
1749      Proc_Decl    : Node_Id;
1750      Proc_Id      : Entity_Id;
1751      Stmts        : List_Id := No_List;
1752
1753      Build_Body : Boolean := False;
1754      --  Flag set when the type requires a DIC procedure body to be built
1755
1756      Work_Typ : Entity_Id;
1757      --  The working type
1758
1759   --  Start of processing for Build_DIC_Procedure_Body
1760
1761   begin
1762      Work_Typ := Base_Type (Typ);
1763
1764      --  Do not process class-wide types as these are Itypes, but lack a first
1765      --  subtype (see below).
1766
1767      if Is_Class_Wide_Type (Work_Typ) then
1768         return;
1769
1770      --  Do not process the underlying full view of a private type. There is
1771      --  no way to get back to the partial view, plus the body will be built
1772      --  by the full view or the base type.
1773
1774      elsif Is_Underlying_Full_View (Work_Typ) then
1775         return;
1776
1777      --  Use the first subtype when dealing with various base types
1778
1779      elsif Is_Itype (Work_Typ) then
1780         Work_Typ := First_Subtype (Work_Typ);
1781
1782      --  The input denotes the corresponding record type of a protected or a
1783      --  task type. Work with the concurrent type because the corresponding
1784      --  record type may not be visible to clients of the type.
1785
1786      elsif Ekind (Work_Typ) = E_Record_Type
1787        and then Is_Concurrent_Record_Type (Work_Typ)
1788      then
1789         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
1790      end if;
1791
1792      --  The working type may be subject to pragma Ghost. Set the mode now to
1793      --  ensure that the DIC procedure is properly marked as Ghost.
1794
1795      Set_Ghost_Mode (Work_Typ);
1796
1797      --  The working type must be either define a DIC pragma of its own or
1798      --  inherit one from a parent type.
1799
1800      pragma Assert (Has_DIC (Work_Typ));
1801
1802      --  Recover the type which defines the DIC pragma. This is either the
1803      --  working type itself or a parent type when the pragma is inherited.
1804
1805      DIC_Typ := Find_DIC_Type (Work_Typ);
1806      pragma Assert (Present (DIC_Typ));
1807
1808      DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
1809      pragma Assert (Present (DIC_Prag));
1810
1811      --  Nothing to do if pragma DIC appears without an argument or its sole
1812      --  argument is "null".
1813
1814      if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
1815         goto Leave;
1816      end if;
1817
1818      --  The working type may lack a DIC procedure declaration. This may be
1819      --  due to several reasons:
1820
1821      --    * The working type's own DIC pragma does not contain a verifiable
1822      --      assertion expression. In this case there is no need to build a
1823      --      DIC procedure because there is nothing to check.
1824
1825      --    * The working type derives from a parent type. In this case a DIC
1826      --      procedure should be built only when the inherited DIC pragma has
1827      --      a verifiable assertion expression.
1828
1829      Proc_Id := DIC_Procedure (Work_Typ);
1830
1831      --  Build a DIC procedure declaration when the working type derives from
1832      --  a parent type.
1833
1834      if No (Proc_Id) then
1835         Build_DIC_Procedure_Declaration (Work_Typ);
1836         Proc_Id := DIC_Procedure (Work_Typ);
1837      end if;
1838
1839      --  At this point there should be a DIC procedure declaration
1840
1841      pragma Assert (Present (Proc_Id));
1842      Proc_Decl := Unit_Declaration_Node (Proc_Id);
1843
1844      --  Nothing to do if the DIC procedure already has a body
1845
1846      if Present (Corresponding_Body (Proc_Decl)) then
1847         goto Leave;
1848      end if;
1849
1850      --  Emulate the environment of the DIC procedure by installing its scope
1851      --  and formal parameters.
1852
1853      Push_Scope (Proc_Id);
1854      Install_Formals (Proc_Id);
1855
1856      --  The working type defines its own DIC pragma. Replace the current
1857      --  instance of the working type with the formal of the DIC procedure.
1858      --  Note that there is no need to consider inherited DIC pragmas from
1859      --  parent types because the working type's DIC pragma "hides" all
1860      --  inherited DIC pragmas.
1861
1862      if Has_Own_DIC (Work_Typ) then
1863         pragma Assert (DIC_Typ = Work_Typ);
1864
1865         Add_Own_DIC
1866           (DIC_Prag => DIC_Prag,
1867            DIC_Typ  => DIC_Typ,
1868            Stmts    => Stmts);
1869
1870         Build_Body := True;
1871
1872      --  Otherwise the working type inherits a DIC pragma from a parent type.
1873      --  This processing is carried out when the type is frozen because the
1874      --  state of all parent discriminants is known at that point. Note that
1875      --  it is semantically sound to delay the creation of the DIC procedure
1876      --  body till the freeze point. If the type has a DIC pragma of its own,
1877      --  then the DIC procedure body would have already been constructed at
1878      --  the end of the visible declarations and all parent DIC pragmas are
1879      --  effectively "hidden" and irrelevant.
1880
1881      elsif For_Freeze then
1882         pragma Assert (Has_Inherited_DIC (Work_Typ));
1883         pragma Assert (DIC_Typ /= Work_Typ);
1884
1885         --  The working type is tagged. The verification of the assertion
1886         --  expression is subject to the same semantics as class-wide pre-
1887         --  and postconditions.
1888
1889         if Is_Tagged_Type (Work_Typ) then
1890            Add_Inherited_Tagged_DIC
1891              (DIC_Prag  => DIC_Prag,
1892               Par_Typ   => DIC_Typ,
1893               Deriv_Typ => Work_Typ,
1894               Stmts     => Stmts);
1895
1896         --  Otherwise the working type is not tagged. Verify the assertion
1897         --  expression of the inherited DIC pragma by directly calling the
1898         --  DIC procedure of the parent type.
1899
1900         else
1901            Add_Inherited_DIC
1902              (DIC_Prag  => DIC_Prag,
1903               Par_Typ   => DIC_Typ,
1904               Deriv_Typ => Work_Typ,
1905               Stmts     => Stmts);
1906         end if;
1907
1908         Build_Body := True;
1909      end if;
1910
1911      End_Scope;
1912
1913      if Build_Body then
1914
1915         --  Produce an empty completing body in the following cases:
1916         --    * Assertions are disabled
1917         --    * The DIC Assertion_Policy is Ignore
1918
1919         if No (Stmts) then
1920            Stmts := New_List (Make_Null_Statement (Loc));
1921         end if;
1922
1923         --  Generate:
1924         --    procedure <Work_Typ>DIC (_object : <Work_Typ>) is
1925         --    begin
1926         --       <Stmts>
1927         --    end <Work_Typ>DIC;
1928
1929         Proc_Body :=
1930           Make_Subprogram_Body (Loc,
1931             Specification                =>
1932               Copy_Subprogram_Spec (Parent (Proc_Id)),
1933             Declarations                 => Empty_List,
1934               Handled_Statement_Sequence =>
1935                 Make_Handled_Sequence_Of_Statements (Loc,
1936                   Statements => Stmts));
1937         Proc_Body_Id := Defining_Entity (Proc_Body);
1938
1939         --  Perform minor decoration in case the body is not analyzed
1940
1941         Set_Ekind        (Proc_Body_Id, E_Subprogram_Body);
1942         Set_Etype        (Proc_Body_Id, Standard_Void_Type);
1943         Set_Scope        (Proc_Body_Id, Current_Scope);
1944         Set_SPARK_Pragma (Proc_Body_Id, SPARK_Pragma (Proc_Id));
1945         Set_SPARK_Pragma_Inherited
1946                          (Proc_Body_Id, SPARK_Pragma_Inherited (Proc_Id));
1947
1948         --  Link both spec and body to avoid generating duplicates
1949
1950         Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
1951         Set_Corresponding_Spec (Proc_Body, Proc_Id);
1952
1953         --  The body should not be inserted into the tree when the context
1954         --  is ASIS or a generic unit because it is not part of the template.
1955         --  Note that the body must still be generated in order to resolve the
1956         --  DIC assertion expression.
1957
1958         if ASIS_Mode or Inside_A_Generic then
1959            null;
1960
1961         --  Semi-insert the body into the tree for GNATprove by setting its
1962         --  Parent field. This allows for proper upstream tree traversals.
1963
1964         elsif GNATprove_Mode then
1965            Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
1966
1967         --  Otherwise the body is part of the freezing actions of the working
1968         --  type.
1969
1970         else
1971            Append_Freeze_Action (Work_Typ, Proc_Body);
1972         end if;
1973      end if;
1974
1975   <<Leave>>
1976      Restore_Ghost_Region (Saved_GM, Saved_IGR);
1977   end Build_DIC_Procedure_Body;
1978
1979   -------------------------------------
1980   -- Build_DIC_Procedure_Declaration --
1981   -------------------------------------
1982
1983   --  WARNING: This routine manages Ghost regions. Return statements must be
1984   --  replaced by gotos which jump to the end of the routine and restore the
1985   --  Ghost mode.
1986
1987   procedure Build_DIC_Procedure_Declaration (Typ : Entity_Id) is
1988      Loc : constant Source_Ptr := Sloc (Typ);
1989
1990      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
1991      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
1992      --  Save the Ghost-related attributes to restore on exit
1993
1994      DIC_Prag  : Node_Id;
1995      DIC_Typ   : Entity_Id;
1996      Proc_Decl : Node_Id;
1997      Proc_Id   : Entity_Id;
1998      Typ_Decl  : Node_Id;
1999
2000      CRec_Typ : Entity_Id;
2001      --  The corresponding record type of Full_Typ
2002
2003      Full_Base : Entity_Id;
2004      --  The base type of Full_Typ
2005
2006      Full_Typ : Entity_Id;
2007      --  The full view of working type
2008
2009      Obj_Id : Entity_Id;
2010      --  The _object formal parameter of the DIC procedure
2011
2012      Priv_Typ : Entity_Id;
2013      --  The partial view of working type
2014
2015      Work_Typ : Entity_Id;
2016      --  The working type
2017
2018   begin
2019      Work_Typ := Base_Type (Typ);
2020
2021      --  Do not process class-wide types as these are Itypes, but lack a first
2022      --  subtype (see below).
2023
2024      if Is_Class_Wide_Type (Work_Typ) then
2025         return;
2026
2027      --  Do not process the underlying full view of a private type. There is
2028      --  no way to get back to the partial view, plus the body will be built
2029      --  by the full view or the base type.
2030
2031      elsif Is_Underlying_Full_View (Work_Typ) then
2032         return;
2033
2034      --  Use the first subtype when dealing with various base types
2035
2036      elsif Is_Itype (Work_Typ) then
2037         Work_Typ := First_Subtype (Work_Typ);
2038
2039      --  The input denotes the corresponding record type of a protected or a
2040      --  task type. Work with the concurrent type because the corresponding
2041      --  record type may not be visible to clients of the type.
2042
2043      elsif Ekind (Work_Typ) = E_Record_Type
2044        and then Is_Concurrent_Record_Type (Work_Typ)
2045      then
2046         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
2047      end if;
2048
2049      --  The working type may be subject to pragma Ghost. Set the mode now to
2050      --  ensure that the DIC procedure is properly marked as Ghost.
2051
2052      Set_Ghost_Mode (Work_Typ);
2053
2054      --  The type must be either subject to a DIC pragma or inherit one from a
2055      --  parent type.
2056
2057      pragma Assert (Has_DIC (Work_Typ));
2058
2059      --  Recover the type which defines the DIC pragma. This is either the
2060      --  working type itself or a parent type when the pragma is inherited.
2061
2062      DIC_Typ := Find_DIC_Type (Work_Typ);
2063      pragma Assert (Present (DIC_Typ));
2064
2065      DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
2066      pragma Assert (Present (DIC_Prag));
2067
2068      --  Nothing to do if pragma DIC appears without an argument or its sole
2069      --  argument is "null".
2070
2071      if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
2072         goto Leave;
2073
2074      --  Nothing to do if the type already has a DIC procedure
2075
2076      elsif Present (DIC_Procedure (Work_Typ)) then
2077         goto Leave;
2078      end if;
2079
2080      Proc_Id :=
2081        Make_Defining_Identifier (Loc,
2082          Chars =>
2083            New_External_Name (Chars (Work_Typ), "Default_Initial_Condition"));
2084
2085      --  Perform minor decoration in case the declaration is not analyzed
2086
2087      Set_Ekind                  (Proc_Id, E_Procedure);
2088      Set_Etype                  (Proc_Id, Standard_Void_Type);
2089      Set_Is_DIC_Procedure       (Proc_Id);
2090      Set_Scope                  (Proc_Id, Current_Scope);
2091      Set_SPARK_Pragma           (Proc_Id, SPARK_Mode_Pragma);
2092      Set_SPARK_Pragma_Inherited (Proc_Id);
2093
2094      Set_DIC_Procedure (Work_Typ, Proc_Id);
2095
2096      --  The DIC procedure requires debug info when the assertion expression
2097      --  is subject to Source Coverage Obligations.
2098
2099      if Generate_SCO then
2100         Set_Debug_Info_Needed (Proc_Id);
2101      end if;
2102
2103      --  Obtain all views of the input type
2104
2105      Get_Views (Work_Typ, Priv_Typ, Full_Typ, Full_Base, CRec_Typ);
2106
2107      --  Associate the DIC procedure and various relevant flags with all views
2108
2109      Propagate_DIC_Attributes (Priv_Typ,  From_Typ => Work_Typ);
2110      Propagate_DIC_Attributes (Full_Typ,  From_Typ => Work_Typ);
2111      Propagate_DIC_Attributes (Full_Base, From_Typ => Work_Typ);
2112      Propagate_DIC_Attributes (CRec_Typ,  From_Typ => Work_Typ);
2113
2114      --  The declaration of the DIC procedure must be inserted after the
2115      --  declaration of the partial view as this allows for proper external
2116      --  visibility.
2117
2118      if Present (Priv_Typ) then
2119         Typ_Decl := Declaration_Node (Priv_Typ);
2120
2121      --  Derived types with the full view as parent do not have a partial
2122      --  view. Insert the DIC procedure after the derived type.
2123
2124      else
2125         Typ_Decl := Declaration_Node (Full_Typ);
2126      end if;
2127
2128      --  The type should have a declarative node
2129
2130      pragma Assert (Present (Typ_Decl));
2131
2132      --  Create the formal parameter which emulates the variable-like behavior
2133      --  of the type's current instance.
2134
2135      Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject);
2136
2137      --  Perform minor decoration in case the declaration is not analyzed
2138
2139      Set_Ekind (Obj_Id, E_In_Parameter);
2140      Set_Etype (Obj_Id, Work_Typ);
2141      Set_Scope (Obj_Id, Proc_Id);
2142
2143      Set_First_Entity (Proc_Id, Obj_Id);
2144      Set_Last_Entity  (Proc_Id, Obj_Id);
2145
2146      --  Generate:
2147      --    procedure <Work_Typ>DIC (_object : <Work_Typ>);
2148
2149      Proc_Decl :=
2150        Make_Subprogram_Declaration (Loc,
2151          Specification =>
2152            Make_Procedure_Specification (Loc,
2153              Defining_Unit_Name       => Proc_Id,
2154              Parameter_Specifications => New_List (
2155                Make_Parameter_Specification (Loc,
2156                  Defining_Identifier => Obj_Id,
2157                  Parameter_Type      =>
2158                    New_Occurrence_Of (Work_Typ, Loc)))));
2159
2160      --  The declaration should not be inserted into the tree when the context
2161      --  is ASIS or a generic unit because it is not part of the template.
2162
2163      if ASIS_Mode or Inside_A_Generic then
2164         null;
2165
2166      --  Semi-insert the declaration into the tree for GNATprove by setting
2167      --  its Parent field. This allows for proper upstream tree traversals.
2168
2169      elsif GNATprove_Mode then
2170         Set_Parent (Proc_Decl, Parent (Typ_Decl));
2171
2172      --  Otherwise insert the declaration
2173
2174      else
2175         Insert_After_And_Analyze (Typ_Decl, Proc_Decl);
2176      end if;
2177
2178   <<Leave>>
2179      Restore_Ghost_Region (Saved_GM, Saved_IGR);
2180   end Build_DIC_Procedure_Declaration;
2181
2182   ------------------------------------
2183   -- Build_Invariant_Procedure_Body --
2184   ------------------------------------
2185
2186   --  WARNING: This routine manages Ghost regions. Return statements must be
2187   --  replaced by gotos which jump to the end of the routine and restore the
2188   --  Ghost mode.
2189
2190   procedure Build_Invariant_Procedure_Body
2191     (Typ               : Entity_Id;
2192      Partial_Invariant : Boolean := False)
2193   is
2194      Loc : constant Source_Ptr := Sloc (Typ);
2195
2196      Pragmas_Seen : Elist_Id := No_Elist;
2197      --  This list contains all invariant pragmas processed so far. The list
2198      --  is used to avoid generating redundant invariant checks.
2199
2200      Produced_Check : Boolean := False;
2201      --  This flag tracks whether the type has produced at least one invariant
2202      --  check. The flag is used as a sanity check at the end of the routine.
2203
2204      --  NOTE: most of the routines in Build_Invariant_Procedure_Body are
2205      --  intentionally unnested to avoid deep indentation of code.
2206
2207      --  NOTE: all Add_xxx_Invariants routines are reactive. In other words
2208      --  they emit checks, loops (for arrays) and case statements (for record
2209      --  variant parts) only when there are invariants to verify. This keeps
2210      --  the body of the invariant procedure free of useless code.
2211
2212      procedure Add_Array_Component_Invariants
2213        (T      : Entity_Id;
2214         Obj_Id : Entity_Id;
2215         Checks : in out List_Id);
2216      --  Generate an invariant check for each component of array type T.
2217      --  Obj_Id denotes the entity of the _object formal parameter of the
2218      --  invariant procedure. All created checks are added to list Checks.
2219
2220      procedure Add_Inherited_Invariants
2221        (T         : Entity_Id;
2222         Priv_Typ  : Entity_Id;
2223         Full_Typ  : Entity_Id;
2224         Obj_Id    : Entity_Id;
2225         Checks    : in out List_Id);
2226      --  Generate an invariant check for each inherited class-wide invariant
2227      --  coming from all parent types of type T. Priv_Typ and Full_Typ denote
2228      --  the partial and full view of the parent type. Obj_Id denotes the
2229      --  entity of the _object formal parameter of the invariant procedure.
2230      --  All created checks are added to list Checks.
2231
2232      procedure Add_Interface_Invariants
2233        (T      : Entity_Id;
2234         Obj_Id : Entity_Id;
2235         Checks : in out List_Id);
2236      --  Generate an invariant check for each inherited class-wide invariant
2237      --  coming from all interfaces implemented by type T. Obj_Id denotes the
2238      --  entity of the _object formal parameter of the invariant procedure.
2239      --  All created checks are added to list Checks.
2240
2241      procedure Add_Invariant_Check
2242        (Prag      : Node_Id;
2243         Expr      : Node_Id;
2244         Checks    : in out List_Id;
2245         Inherited : Boolean := False);
2246      --  Subsidiary to all Add_xxx_Invariant routines. Add a runtime check to
2247      --  verify assertion expression Expr of pragma Prag. All generated code
2248      --  is added to list Checks. Flag Inherited should be set when the pragma
2249      --  is inherited from a parent or interface type.
2250
2251      procedure Add_Own_Invariants
2252        (T         : Entity_Id;
2253         Obj_Id    : Entity_Id;
2254         Checks    : in out List_Id;
2255         Priv_Item : Node_Id := Empty);
2256      --  Generate an invariant check for each invariant found for type T.
2257      --  Obj_Id denotes the entity of the _object formal parameter of the
2258      --  invariant procedure. All created checks are added to list Checks.
2259      --  Priv_Item denotes the first rep item of the private type.
2260
2261      procedure Add_Parent_Invariants
2262        (T      : Entity_Id;
2263         Obj_Id : Entity_Id;
2264         Checks : in out List_Id);
2265      --  Generate an invariant check for each inherited class-wide invariant
2266      --  coming from all parent types of type T. Obj_Id denotes the entity of
2267      --  the _object formal parameter of the invariant procedure. All created
2268      --  checks are added to list Checks.
2269
2270      procedure Add_Record_Component_Invariants
2271        (T      : Entity_Id;
2272         Obj_Id : Entity_Id;
2273         Checks : in out List_Id);
2274      --  Generate an invariant check for each component of record type T.
2275      --  Obj_Id denotes the entity of the _object formal parameter of the
2276      --  invariant procedure. All created checks are added to list Checks.
2277
2278      ------------------------------------
2279      -- Add_Array_Component_Invariants --
2280      ------------------------------------
2281
2282      procedure Add_Array_Component_Invariants
2283        (T      : Entity_Id;
2284         Obj_Id : Entity_Id;
2285         Checks : in out List_Id)
2286      is
2287         Comp_Typ : constant Entity_Id := Component_Type (T);
2288         Dims     : constant Pos       := Number_Dimensions (T);
2289
2290         procedure Process_Array_Component
2291           (Indices     : List_Id;
2292            Comp_Checks : in out List_Id);
2293         --  Generate an invariant check for an array component identified by
2294         --  the indices in list Indices. All created checks are added to list
2295         --  Comp_Checks.
2296
2297         procedure Process_One_Dimension
2298           (Dim        : Pos;
2299            Indices    : List_Id;
2300            Dim_Checks : in out List_Id);
2301         --  Generate a loop over the Nth dimension Dim of an array type. List
2302         --  Indices contains all array indices for the dimension. All created
2303         --  checks are added to list Dim_Checks.
2304
2305         -----------------------------
2306         -- Process_Array_Component --
2307         -----------------------------
2308
2309         procedure Process_Array_Component
2310           (Indices     : List_Id;
2311            Comp_Checks : in out List_Id)
2312         is
2313            Proc_Id : Entity_Id;
2314
2315         begin
2316            if Has_Invariants (Comp_Typ) then
2317
2318               --  In GNATprove mode, the component invariants are checked by
2319               --  other means. They should not be added to the array type
2320               --  invariant procedure, so that the procedure can be used to
2321               --  check the array type invariants if any.
2322
2323               if GNATprove_Mode then
2324                  null;
2325
2326               else
2327                  Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ));
2328
2329                  --  The component type should have an invariant procedure
2330                  --  if it has invariants of its own or inherits class-wide
2331                  --  invariants from parent or interface types.
2332
2333                  pragma Assert (Present (Proc_Id));
2334
2335                  --  Generate:
2336                  --    <Comp_Typ>Invariant (_object (<Indices>));
2337
2338                  --  Note that the invariant procedure may have a null body if
2339                  --  assertions are disabled or Assertion_Policy Ignore is in
2340                  --  effect.
2341
2342                  if not Has_Null_Body (Proc_Id) then
2343                     Append_New_To (Comp_Checks,
2344                       Make_Procedure_Call_Statement (Loc,
2345                         Name                   =>
2346                           New_Occurrence_Of (Proc_Id, Loc),
2347                         Parameter_Associations => New_List (
2348                           Make_Indexed_Component (Loc,
2349                             Prefix      => New_Occurrence_Of (Obj_Id, Loc),
2350                             Expressions => New_Copy_List (Indices)))));
2351                  end if;
2352               end if;
2353
2354               Produced_Check := True;
2355            end if;
2356         end Process_Array_Component;
2357
2358         ---------------------------
2359         -- Process_One_Dimension --
2360         ---------------------------
2361
2362         procedure Process_One_Dimension
2363           (Dim        : Pos;
2364            Indices    : List_Id;
2365            Dim_Checks : in out List_Id)
2366         is
2367            Comp_Checks : List_Id := No_List;
2368            Index       : Entity_Id;
2369
2370         begin
2371            --  Generate the invariant checks for the array component after all
2372            --  dimensions have produced their respective loops.
2373
2374            if Dim > Dims then
2375               Process_Array_Component
2376                 (Indices     => Indices,
2377                  Comp_Checks => Dim_Checks);
2378
2379            --  Otherwise create a loop for the current dimension
2380
2381            else
2382               --  Create a new loop variable for each dimension
2383
2384               Index :=
2385                 Make_Defining_Identifier (Loc,
2386                   Chars => New_External_Name ('I', Dim));
2387               Append_To (Indices, New_Occurrence_Of (Index, Loc));
2388
2389               Process_One_Dimension
2390                 (Dim        => Dim + 1,
2391                  Indices    => Indices,
2392                  Dim_Checks => Comp_Checks);
2393
2394               --  Generate:
2395               --    for I<Dim> in _object'Range (<Dim>) loop
2396               --       <Comp_Checks>
2397               --    end loop;
2398
2399               --  Note that the invariant procedure may have a null body if
2400               --  assertions are disabled or Assertion_Policy Ignore is in
2401               --  effect.
2402
2403               if Present (Comp_Checks) then
2404                  Append_New_To (Dim_Checks,
2405                    Make_Implicit_Loop_Statement (T,
2406                      Identifier       => Empty,
2407                      Iteration_Scheme =>
2408                        Make_Iteration_Scheme (Loc,
2409                          Loop_Parameter_Specification =>
2410                            Make_Loop_Parameter_Specification (Loc,
2411                              Defining_Identifier         => Index,
2412                              Discrete_Subtype_Definition =>
2413                                Make_Attribute_Reference (Loc,
2414                                  Prefix         =>
2415                                    New_Occurrence_Of (Obj_Id, Loc),
2416                                  Attribute_Name => Name_Range,
2417                                  Expressions    => New_List (
2418                                    Make_Integer_Literal (Loc, Dim))))),
2419                      Statements       => Comp_Checks));
2420               end if;
2421            end if;
2422         end Process_One_Dimension;
2423
2424      --  Start of processing for Add_Array_Component_Invariants
2425
2426      begin
2427         Process_One_Dimension
2428           (Dim        => 1,
2429            Indices    => New_List,
2430            Dim_Checks => Checks);
2431      end Add_Array_Component_Invariants;
2432
2433      ------------------------------
2434      -- Add_Inherited_Invariants --
2435      ------------------------------
2436
2437      procedure Add_Inherited_Invariants
2438        (T         : Entity_Id;
2439         Priv_Typ  : Entity_Id;
2440         Full_Typ  : Entity_Id;
2441         Obj_Id    : Entity_Id;
2442         Checks    : in out List_Id)
2443      is
2444         Deriv_Typ     : Entity_Id;
2445         Expr          : Node_Id;
2446         Prag          : Node_Id;
2447         Prag_Expr     : Node_Id;
2448         Prag_Expr_Arg : Node_Id;
2449         Prag_Typ      : Node_Id;
2450         Prag_Typ_Arg  : Node_Id;
2451
2452         Par_Proc : Entity_Id;
2453         --  The "partial" invariant procedure of Par_Typ
2454
2455         Par_Typ : Entity_Id;
2456         --  The suitable view of the parent type used in the substitution of
2457         --  type attributes.
2458
2459      begin
2460         if not Present (Priv_Typ) and then not Present (Full_Typ) then
2461            return;
2462         end if;
2463
2464         --  When the type inheriting the class-wide invariant is a concurrent
2465         --  type, use the corresponding record type because it contains all
2466         --  primitive operations of the concurrent type and allows for proper
2467         --  substitution.
2468
2469         if Is_Concurrent_Type (T) then
2470            Deriv_Typ := Corresponding_Record_Type (T);
2471         else
2472            Deriv_Typ := T;
2473         end if;
2474
2475         pragma Assert (Present (Deriv_Typ));
2476
2477         --  Determine which rep item chain to use. Precedence is given to that
2478         --  of the parent type's partial view since it usually carries all the
2479         --  class-wide invariants.
2480
2481         if Present (Priv_Typ) then
2482            Prag := First_Rep_Item (Priv_Typ);
2483         else
2484            Prag := First_Rep_Item (Full_Typ);
2485         end if;
2486
2487         while Present (Prag) loop
2488            if Nkind (Prag) = N_Pragma
2489              and then Pragma_Name (Prag) = Name_Invariant
2490            then
2491               --  Nothing to do if the pragma was already processed
2492
2493               if Contains (Pragmas_Seen, Prag) then
2494                  return;
2495
2496               --  Nothing to do when the caller requests the processing of all
2497               --  inherited class-wide invariants, but the pragma does not
2498               --  fall in this category.
2499
2500               elsif not Class_Present (Prag) then
2501                  return;
2502               end if;
2503
2504               --  Extract the arguments of the invariant pragma
2505
2506               Prag_Typ_Arg  := First (Pragma_Argument_Associations (Prag));
2507               Prag_Expr_Arg := Next (Prag_Typ_Arg);
2508               Prag_Expr     := Expression_Copy (Prag_Expr_Arg);
2509               Prag_Typ      := Get_Pragma_Arg (Prag_Typ_Arg);
2510
2511               --  The pragma applies to the partial view of the parent type
2512
2513               if Present (Priv_Typ)
2514                 and then Entity (Prag_Typ) = Priv_Typ
2515               then
2516                  Par_Typ := Priv_Typ;
2517
2518               --  The pragma applies to the full view of the parent type
2519
2520               elsif Present (Full_Typ)
2521                 and then Entity (Prag_Typ) = Full_Typ
2522               then
2523                  Par_Typ := Full_Typ;
2524
2525               --  Otherwise the pragma does not belong to the parent type and
2526               --  should not be considered.
2527
2528               else
2529                  return;
2530               end if;
2531
2532               --  Perform the following substitutions:
2533
2534               --    * Replace a reference to the _object parameter of the
2535               --      parent type's partial invariant procedure with a
2536               --      reference to the _object parameter of the derived
2537               --      type's full invariant procedure.
2538
2539               --    * Replace a reference to a discriminant of the parent type
2540               --      with a suitable value from the point of view of the
2541               --      derived type.
2542
2543               --    * Replace a call to an overridden parent primitive with a
2544               --      call to the overriding derived type primitive.
2545
2546               --    * Replace a call to an inherited parent primitive with a
2547               --      call to the internally-generated inherited derived type
2548               --      primitive.
2549
2550               Expr := New_Copy_Tree (Prag_Expr);
2551
2552               --  The parent type must have a "partial" invariant procedure
2553               --  because class-wide invariants are captured exclusively by
2554               --  it.
2555
2556               Par_Proc := Partial_Invariant_Procedure (Par_Typ);
2557               pragma Assert (Present (Par_Proc));
2558
2559               Replace_References
2560                 (Expr      => Expr,
2561                  Par_Typ   => Par_Typ,
2562                  Deriv_Typ => Deriv_Typ,
2563                  Par_Obj   => First_Formal (Par_Proc),
2564                  Deriv_Obj => Obj_Id);
2565
2566               Add_Invariant_Check (Prag, Expr, Checks, Inherited => True);
2567            end if;
2568
2569            Next_Rep_Item (Prag);
2570         end loop;
2571      end Add_Inherited_Invariants;
2572
2573      ------------------------------
2574      -- Add_Interface_Invariants --
2575      ------------------------------
2576
2577      procedure Add_Interface_Invariants
2578        (T      : Entity_Id;
2579         Obj_Id : Entity_Id;
2580         Checks : in out List_Id)
2581      is
2582         Iface_Elmt : Elmt_Id;
2583         Ifaces     : Elist_Id;
2584
2585      begin
2586         --  Generate an invariant check for each class-wide invariant coming
2587         --  from all interfaces implemented by type T.
2588
2589         if Is_Tagged_Type (T) then
2590            Collect_Interfaces (T, Ifaces);
2591
2592            --  Process the class-wide invariants of all implemented interfaces
2593
2594            Iface_Elmt := First_Elmt (Ifaces);
2595            while Present (Iface_Elmt) loop
2596
2597               --  The Full_Typ parameter is intentionally left Empty because
2598               --  interfaces are treated as the partial view of a private type
2599               --  in order to achieve uniformity with the general case.
2600
2601               Add_Inherited_Invariants
2602                 (T         => T,
2603                  Priv_Typ  => Node (Iface_Elmt),
2604                  Full_Typ  => Empty,
2605                  Obj_Id    => Obj_Id,
2606                  Checks    => Checks);
2607
2608               Next_Elmt (Iface_Elmt);
2609            end loop;
2610         end if;
2611      end Add_Interface_Invariants;
2612
2613      -------------------------
2614      -- Add_Invariant_Check --
2615      -------------------------
2616
2617      procedure Add_Invariant_Check
2618        (Prag      : Node_Id;
2619         Expr      : Node_Id;
2620         Checks    : in out List_Id;
2621         Inherited : Boolean := False)
2622      is
2623         Args    : constant List_Id    := Pragma_Argument_Associations (Prag);
2624         Nam     : constant Name_Id    := Original_Aspect_Pragma_Name (Prag);
2625         Ploc    : constant Source_Ptr := Sloc (Prag);
2626         Str_Arg : constant Node_Id    := Next (Next (First (Args)));
2627
2628         Assoc : List_Id;
2629         Str   : String_Id;
2630
2631      begin
2632         --  The invariant is ignored, nothing left to do
2633
2634         if Is_Ignored (Prag) then
2635            null;
2636
2637         --  Otherwise the invariant is checked. Build a pragma Check to verify
2638         --  the expression at run time.
2639
2640         else
2641            Assoc := New_List (
2642              Make_Pragma_Argument_Association (Ploc,
2643                Expression => Make_Identifier (Ploc, Nam)),
2644              Make_Pragma_Argument_Association (Ploc,
2645                Expression => Expr));
2646
2647            --  Handle the String argument (if any)
2648
2649            if Present (Str_Arg) then
2650               Str := Strval (Get_Pragma_Arg (Str_Arg));
2651
2652               --  When inheriting an invariant, modify the message from
2653               --  "failed invariant" to "failed inherited invariant".
2654
2655               if Inherited then
2656                  String_To_Name_Buffer (Str);
2657
2658                  if Name_Buffer (1 .. 16) = "failed invariant" then
2659                     Insert_Str_In_Name_Buffer ("inherited ", 8);
2660                     Str := String_From_Name_Buffer;
2661                  end if;
2662               end if;
2663
2664               Append_To (Assoc,
2665                 Make_Pragma_Argument_Association (Ploc,
2666                   Expression => Make_String_Literal (Ploc, Str)));
2667            end if;
2668
2669            --  Generate:
2670            --    pragma Check (<Nam>, <Expr>, <Str>);
2671
2672            Append_New_To (Checks,
2673              Make_Pragma (Ploc,
2674                Chars                        => Name_Check,
2675                Pragma_Argument_Associations => Assoc));
2676         end if;
2677
2678         --  Output an info message when inheriting an invariant and the
2679         --  listing option is enabled.
2680
2681         if Inherited and Opt.List_Inherited_Aspects then
2682            Error_Msg_Sloc := Sloc (Prag);
2683            Error_Msg_N
2684              ("info: & inherits `Invariant''Class` aspect from #?L?", Typ);
2685         end if;
2686
2687         --  Add the pragma to the list of processed pragmas
2688
2689         Append_New_Elmt (Prag, Pragmas_Seen);
2690         Produced_Check := True;
2691      end Add_Invariant_Check;
2692
2693      ---------------------------
2694      -- Add_Parent_Invariants --
2695      ---------------------------
2696
2697      procedure Add_Parent_Invariants
2698        (T      : Entity_Id;
2699         Obj_Id : Entity_Id;
2700         Checks : in out List_Id)
2701      is
2702         Dummy_1 : Entity_Id;
2703         Dummy_2 : Entity_Id;
2704
2705         Curr_Typ : Entity_Id;
2706         --  The entity of the current type being examined
2707
2708         Full_Typ : Entity_Id;
2709         --  The full view of Par_Typ
2710
2711         Par_Typ : Entity_Id;
2712         --  The entity of the parent type
2713
2714         Priv_Typ : Entity_Id;
2715         --  The partial view of Par_Typ
2716
2717      begin
2718         --  Do not process array types because they cannot have true parent
2719         --  types. This also prevents the generation of a duplicate invariant
2720         --  check when the input type is an array base type because its Etype
2721         --  denotes the first subtype, both of which share the same component
2722         --  type.
2723
2724         if Is_Array_Type (T) then
2725            return;
2726         end if;
2727
2728         --  Climb the parent type chain
2729
2730         Curr_Typ := T;
2731         loop
2732            --  Do not consider subtypes as they inherit the invariants
2733            --  from their base types.
2734
2735            Par_Typ := Base_Type (Etype (Curr_Typ));
2736
2737            --  Stop the climb once the root of the parent chain is
2738            --  reached.
2739
2740            exit when Curr_Typ = Par_Typ;
2741
2742            --  Process the class-wide invariants of the parent type
2743
2744            Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2);
2745
2746            --  Process the elements of an array type
2747
2748            if Is_Array_Type (Full_Typ) then
2749               Add_Array_Component_Invariants (Full_Typ, Obj_Id, Checks);
2750
2751            --  Process the components of a record type
2752
2753            elsif Ekind (Full_Typ) = E_Record_Type then
2754               Add_Record_Component_Invariants (Full_Typ, Obj_Id, Checks);
2755            end if;
2756
2757            Add_Inherited_Invariants
2758              (T         => T,
2759               Priv_Typ  => Priv_Typ,
2760               Full_Typ  => Full_Typ,
2761               Obj_Id    => Obj_Id,
2762               Checks    => Checks);
2763
2764            Curr_Typ := Par_Typ;
2765         end loop;
2766      end Add_Parent_Invariants;
2767
2768      ------------------------
2769      -- Add_Own_Invariants --
2770      ------------------------
2771
2772      procedure Add_Own_Invariants
2773        (T         : Entity_Id;
2774         Obj_Id    : Entity_Id;
2775         Checks    : in out List_Id;
2776         Priv_Item : Node_Id := Empty)
2777      is
2778         ASIS_Expr     : Node_Id;
2779         Expr          : Node_Id;
2780         Prag          : Node_Id;
2781         Prag_Asp      : Node_Id;
2782         Prag_Expr     : Node_Id;
2783         Prag_Expr_Arg : Node_Id;
2784         Prag_Typ      : Node_Id;
2785         Prag_Typ_Arg  : Node_Id;
2786
2787      begin
2788         if not Present (T) then
2789            return;
2790         end if;
2791
2792         Prag := First_Rep_Item (T);
2793         while Present (Prag) loop
2794            if Nkind (Prag) = N_Pragma
2795              and then Pragma_Name (Prag) = Name_Invariant
2796            then
2797               --  Stop the traversal of the rep item chain once a specific
2798               --  item is encountered.
2799
2800               if Present (Priv_Item) and then Prag = Priv_Item then
2801                  exit;
2802               end if;
2803
2804               --  Nothing to do if the pragma was already processed
2805
2806               if Contains (Pragmas_Seen, Prag) then
2807                  return;
2808               end if;
2809
2810               --  Extract the arguments of the invariant pragma
2811
2812               Prag_Typ_Arg  := First (Pragma_Argument_Associations (Prag));
2813               Prag_Expr_Arg := Next (Prag_Typ_Arg);
2814               Prag_Expr     := Get_Pragma_Arg (Prag_Expr_Arg);
2815               Prag_Typ      := Get_Pragma_Arg (Prag_Typ_Arg);
2816               Prag_Asp      := Corresponding_Aspect (Prag);
2817
2818               --  Verify the pragma belongs to T, otherwise the pragma applies
2819               --  to a parent type in which case it will be processed later by
2820               --  Add_Parent_Invariants or Add_Interface_Invariants.
2821
2822               if Entity (Prag_Typ) /= T then
2823                  return;
2824               end if;
2825
2826               Expr := New_Copy_Tree (Prag_Expr);
2827
2828               --  Substitute all references to type T with references to the
2829               --  _object formal parameter.
2830
2831               Replace_Type_References (Expr, T, Obj_Id);
2832
2833               --  Preanalyze the invariant expression to detect errors and at
2834               --  the same time capture the visibility of the proper package
2835               --  part.
2836
2837               Set_Parent (Expr, Parent (Prag_Expr));
2838               Preanalyze_Assert_Expression (Expr, Any_Boolean);
2839
2840               --  Save a copy of the expression when T is tagged to detect
2841               --  errors and capture the visibility of the proper package part
2842               --  for the generation of inherited type invariants.
2843
2844               if Is_Tagged_Type (T) then
2845                  Set_Expression_Copy (Prag_Expr_Arg, New_Copy_Tree (Expr));
2846               end if;
2847
2848               --  If the pragma comes from an aspect specification, replace
2849               --  the saved expression because all type references must be
2850               --  substituted for the call to Preanalyze_Spec_Expression in
2851               --  Check_Aspect_At_xxx routines.
2852
2853               if Present (Prag_Asp) then
2854                  Set_Entity (Identifier (Prag_Asp), New_Copy_Tree (Expr));
2855               end if;
2856
2857               --  Analyze the original invariant expression for ASIS
2858
2859               if ASIS_Mode then
2860                  ASIS_Expr := Empty;
2861
2862                  if Comes_From_Source (Prag) then
2863                     ASIS_Expr := Prag_Expr;
2864                  elsif Present (Prag_Asp) then
2865                     ASIS_Expr := Expression (Prag_Asp);
2866                  end if;
2867
2868                  if Present (ASIS_Expr) then
2869                     Replace_Type_References (ASIS_Expr, T, Obj_Id);
2870                     Preanalyze_Assert_Expression (ASIS_Expr, Any_Boolean);
2871                  end if;
2872               end if;
2873
2874               Add_Invariant_Check (Prag, Expr, Checks);
2875            end if;
2876
2877            Next_Rep_Item (Prag);
2878         end loop;
2879      end Add_Own_Invariants;
2880
2881      -------------------------------------
2882      -- Add_Record_Component_Invariants --
2883      -------------------------------------
2884
2885      procedure Add_Record_Component_Invariants
2886        (T      : Entity_Id;
2887         Obj_Id : Entity_Id;
2888         Checks : in out List_Id)
2889      is
2890         procedure Process_Component_List
2891           (Comp_List : Node_Id;
2892            CL_Checks : in out List_Id);
2893         --  Generate invariant checks for all record components found in
2894         --  component list Comp_List, including variant parts. All created
2895         --  checks are added to list CL_Checks.
2896
2897         procedure Process_Record_Component
2898           (Comp_Id     : Entity_Id;
2899            Comp_Checks : in out List_Id);
2900         --  Generate an invariant check for a record component identified by
2901         --  Comp_Id. All created checks are added to list Comp_Checks.
2902
2903         ----------------------------
2904         -- Process_Component_List --
2905         ----------------------------
2906
2907         procedure Process_Component_List
2908           (Comp_List : Node_Id;
2909            CL_Checks : in out List_Id)
2910         is
2911            Comp       : Node_Id;
2912            Var        : Node_Id;
2913            Var_Alts   : List_Id := No_List;
2914            Var_Checks : List_Id := No_List;
2915            Var_Stmts  : List_Id;
2916
2917            Produced_Variant_Check : Boolean := False;
2918            --  This flag tracks whether the component has produced at least
2919            --  one invariant check.
2920
2921         begin
2922            --  Traverse the component items
2923
2924            Comp := First (Component_Items (Comp_List));
2925            while Present (Comp) loop
2926               if Nkind (Comp) = N_Component_Declaration then
2927
2928                  --  Generate the component invariant check
2929
2930                  Process_Record_Component
2931                    (Comp_Id     => Defining_Entity (Comp),
2932                     Comp_Checks => CL_Checks);
2933               end if;
2934
2935               Next (Comp);
2936            end loop;
2937
2938            --  Traverse the variant part
2939
2940            if Present (Variant_Part (Comp_List)) then
2941               Var := First (Variants (Variant_Part (Comp_List)));
2942               while Present (Var) loop
2943                  Var_Checks := No_List;
2944
2945                  --  Generate invariant checks for all components and variant
2946                  --  parts that qualify.
2947
2948                  Process_Component_List
2949                    (Comp_List => Component_List (Var),
2950                     CL_Checks => Var_Checks);
2951
2952                  --  The components of the current variant produced at least
2953                  --  one invariant check.
2954
2955                  if Present (Var_Checks) then
2956                     Var_Stmts := Var_Checks;
2957                     Produced_Variant_Check := True;
2958
2959                  --  Otherwise there are either no components with invariants,
2960                  --  assertions are disabled, or Assertion_Policy Ignore is in
2961                  --  effect.
2962
2963                  else
2964                     Var_Stmts := New_List (Make_Null_Statement (Loc));
2965                  end if;
2966
2967                  Append_New_To (Var_Alts,
2968                    Make_Case_Statement_Alternative (Loc,
2969                      Discrete_Choices =>
2970                        New_Copy_List (Discrete_Choices (Var)),
2971                      Statements       => Var_Stmts));
2972
2973                  Next (Var);
2974               end loop;
2975
2976               --  Create a case statement which verifies the invariant checks
2977               --  of a particular component list depending on the discriminant
2978               --  values only when there is at least one real invariant check.
2979
2980               if Produced_Variant_Check then
2981                  Append_New_To (CL_Checks,
2982                    Make_Case_Statement (Loc,
2983                      Expression   =>
2984                        Make_Selected_Component (Loc,
2985                          Prefix        => New_Occurrence_Of (Obj_Id, Loc),
2986                          Selector_Name =>
2987                            New_Occurrence_Of
2988                              (Entity (Name (Variant_Part (Comp_List))), Loc)),
2989                      Alternatives => Var_Alts));
2990               end if;
2991            end if;
2992         end Process_Component_List;
2993
2994         ------------------------------
2995         -- Process_Record_Component --
2996         ------------------------------
2997
2998         procedure Process_Record_Component
2999           (Comp_Id     : Entity_Id;
3000            Comp_Checks : in out List_Id)
3001         is
3002            Comp_Typ : constant Entity_Id := Etype (Comp_Id);
3003            Proc_Id  : Entity_Id;
3004
3005            Produced_Component_Check : Boolean := False;
3006            --  This flag tracks whether the component has produced at least
3007            --  one invariant check.
3008
3009         begin
3010            --  Nothing to do for internal component _parent. Note that it is
3011            --  not desirable to check whether the component comes from source
3012            --  because protected type components are relocated to an internal
3013            --  corresponding record, but still need processing.
3014
3015            if Chars (Comp_Id) = Name_uParent then
3016               return;
3017            end if;
3018
3019            --  Verify the invariant of the component. Note that an access
3020            --  type may have an invariant when it acts as the full view of a
3021            --  private type and the invariant appears on the partial view. In
3022            --  this case verify the access value itself.
3023
3024            if Has_Invariants (Comp_Typ) then
3025
3026               --  In GNATprove mode, the component invariants are checked by
3027               --  other means. They should not be added to the record type
3028               --  invariant procedure, so that the procedure can be used to
3029               --  check the record type invariants if any.
3030
3031               if GNATprove_Mode then
3032                  null;
3033
3034               else
3035                  Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ));
3036
3037                  --  The component type should have an invariant procedure
3038                  --  if it has invariants of its own or inherits class-wide
3039                  --  invariants from parent or interface types.
3040
3041                  pragma Assert (Present (Proc_Id));
3042
3043                  --  Generate:
3044                  --    <Comp_Typ>Invariant (T (_object).<Comp_Id>);
3045
3046                  --  Note that the invariant procedure may have a null body if
3047                  --  assertions are disabled or Assertion_Policy Ignore is in
3048                  --  effect.
3049
3050                  if not Has_Null_Body (Proc_Id) then
3051                     Append_New_To (Comp_Checks,
3052                       Make_Procedure_Call_Statement (Loc,
3053                         Name                   =>
3054                           New_Occurrence_Of (Proc_Id, Loc),
3055                         Parameter_Associations => New_List (
3056                           Make_Selected_Component (Loc,
3057                             Prefix        =>
3058                               Unchecked_Convert_To
3059                                 (T, New_Occurrence_Of (Obj_Id, Loc)),
3060                             Selector_Name =>
3061                               New_Occurrence_Of (Comp_Id, Loc)))));
3062                  end if;
3063               end if;
3064
3065               Produced_Check           := True;
3066               Produced_Component_Check := True;
3067            end if;
3068
3069            if Produced_Component_Check and then Has_Unchecked_Union (T) then
3070               Error_Msg_NE
3071                 ("invariants cannot be checked on components of "
3072                  & "unchecked_union type &?", Comp_Id, T);
3073            end if;
3074         end Process_Record_Component;
3075
3076         --  Local variables
3077
3078         Comps : Node_Id;
3079         Def   : Node_Id;
3080
3081      --  Start of processing for Add_Record_Component_Invariants
3082
3083      begin
3084         --  An untagged derived type inherits the components of its parent
3085         --  type. In order to avoid creating redundant invariant checks, do
3086         --  not process the components now. Instead wait until the ultimate
3087         --  parent of the untagged derivation chain is reached.
3088
3089         if not Is_Untagged_Derivation (T) then
3090            Def := Type_Definition (Parent (T));
3091
3092            if Nkind (Def) = N_Derived_Type_Definition then
3093               Def := Record_Extension_Part (Def);
3094            end if;
3095
3096            pragma Assert (Nkind (Def) = N_Record_Definition);
3097            Comps := Component_List (Def);
3098
3099            if Present (Comps) then
3100               Process_Component_List
3101                 (Comp_List => Comps,
3102                  CL_Checks => Checks);
3103            end if;
3104         end if;
3105      end Add_Record_Component_Invariants;
3106
3107      --  Local variables
3108
3109      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
3110      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
3111      --  Save the Ghost-related attributes to restore on exit
3112
3113      Dummy        : Entity_Id;
3114      Priv_Item    : Node_Id;
3115      Proc_Body    : Node_Id;
3116      Proc_Body_Id : Entity_Id;
3117      Proc_Decl    : Node_Id;
3118      Proc_Id      : Entity_Id;
3119      Stmts        : List_Id := No_List;
3120
3121      CRec_Typ : Entity_Id := Empty;
3122      --  The corresponding record type of Full_Typ
3123
3124      Full_Proc : Entity_Id := Empty;
3125      --  The entity of the "full" invariant procedure
3126
3127      Full_Typ : Entity_Id := Empty;
3128      --  The full view of the working type
3129
3130      Obj_Id : Entity_Id := Empty;
3131      --  The _object formal parameter of the invariant procedure
3132
3133      Part_Proc : Entity_Id := Empty;
3134      --  The entity of the "partial" invariant procedure
3135
3136      Priv_Typ : Entity_Id := Empty;
3137      --  The partial view of the working type
3138
3139      Work_Typ : Entity_Id := Empty;
3140      --  The working type
3141
3142   --  Start of processing for Build_Invariant_Procedure_Body
3143
3144   begin
3145      Work_Typ := Typ;
3146
3147      --  The input type denotes the implementation base type of a constrained
3148      --  array type. Work with the first subtype as all invariant pragmas are
3149      --  on its rep item chain.
3150
3151      if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
3152         Work_Typ := First_Subtype (Work_Typ);
3153
3154      --  The input type denotes the corresponding record type of a protected
3155      --  or task type. Work with the concurrent type because the corresponding
3156      --  record type may not be visible to clients of the type.
3157
3158      elsif Ekind (Work_Typ) = E_Record_Type
3159        and then Is_Concurrent_Record_Type (Work_Typ)
3160      then
3161         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
3162      end if;
3163
3164      --  The working type may be subject to pragma Ghost. Set the mode now to
3165      --  ensure that the invariant procedure is properly marked as Ghost.
3166
3167      Set_Ghost_Mode (Work_Typ);
3168
3169      --  The type must either have invariants of its own, inherit class-wide
3170      --  invariants from parent types or interfaces, or be an array or record
3171      --  type whose components have invariants.
3172
3173      pragma Assert (Has_Invariants (Work_Typ));
3174
3175      --  Interfaces are treated as the partial view of a private type in order
3176      --  to achieve uniformity with the general case.
3177
3178      if Is_Interface (Work_Typ) then
3179         Priv_Typ := Work_Typ;
3180
3181      --  Otherwise obtain both views of the type
3182
3183      else
3184         Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy, CRec_Typ);
3185      end if;
3186
3187      --  The caller requests a body for the partial invariant procedure
3188
3189      if Partial_Invariant then
3190         Full_Proc := Invariant_Procedure (Work_Typ);
3191         Proc_Id   := Partial_Invariant_Procedure (Work_Typ);
3192
3193         --  The "full" invariant procedure body was already created
3194
3195         if Present (Full_Proc)
3196           and then Present
3197                      (Corresponding_Body (Unit_Declaration_Node (Full_Proc)))
3198         then
3199            --  This scenario happens only when the type is an untagged
3200            --  derivation from a private parent and the underlying full
3201            --  view was processed before the partial view.
3202
3203            pragma Assert
3204              (Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ));
3205
3206            --  Nothing to do because the processing of the underlying full
3207            --  view already checked the invariants of the partial view.
3208
3209            goto Leave;
3210         end if;
3211
3212         --  Create a declaration for the "partial" invariant procedure if it
3213         --  is not available.
3214
3215         if No (Proc_Id) then
3216            Build_Invariant_Procedure_Declaration
3217              (Typ               => Work_Typ,
3218               Partial_Invariant => True);
3219
3220            Proc_Id := Partial_Invariant_Procedure (Work_Typ);
3221         end if;
3222
3223      --  The caller requests a body for the "full" invariant procedure
3224
3225      else
3226         Proc_Id   := Invariant_Procedure (Work_Typ);
3227         Part_Proc := Partial_Invariant_Procedure (Work_Typ);
3228
3229         --  Create a declaration for the "full" invariant procedure if it is
3230         --  not available.
3231
3232         if No (Proc_Id) then
3233            Build_Invariant_Procedure_Declaration (Work_Typ);
3234            Proc_Id := Invariant_Procedure (Work_Typ);
3235         end if;
3236      end if;
3237
3238      --  At this point there should be an invariant procedure declaration
3239
3240      pragma Assert (Present (Proc_Id));
3241      Proc_Decl := Unit_Declaration_Node (Proc_Id);
3242
3243      --  Nothing to do if the invariant procedure already has a body
3244
3245      if Present (Corresponding_Body (Proc_Decl)) then
3246         goto Leave;
3247      end if;
3248
3249      --  Emulate the environment of the invariant procedure by installing its
3250      --  scope and formal parameters. Note that this is not needed, but having
3251      --  the scope installed helps with the detection of invariant-related
3252      --  errors.
3253
3254      Push_Scope (Proc_Id);
3255      Install_Formals (Proc_Id);
3256
3257      Obj_Id := First_Formal (Proc_Id);
3258      pragma Assert (Present (Obj_Id));
3259
3260      --  The "partial" invariant procedure verifies the invariants of the
3261      --  partial view only.
3262
3263      if Partial_Invariant then
3264         pragma Assert (Present (Priv_Typ));
3265
3266         Add_Own_Invariants
3267           (T      => Priv_Typ,
3268            Obj_Id => Obj_Id,
3269            Checks => Stmts);
3270
3271      --  Otherwise the "full" invariant procedure verifies the invariants of
3272      --  the full view, all array or record components, as well as class-wide
3273      --  invariants inherited from parent types or interfaces. In addition, it
3274      --  indirectly verifies the invariants of the partial view by calling the
3275      --  "partial" invariant procedure.
3276
3277      else
3278         pragma Assert (Present (Full_Typ));
3279
3280         --  Check the invariants of the partial view by calling the "partial"
3281         --  invariant procedure. Generate:
3282
3283         --    <Work_Typ>Partial_Invariant (_object);
3284
3285         if Present (Part_Proc) then
3286            Append_New_To (Stmts,
3287              Make_Procedure_Call_Statement (Loc,
3288                Name                   => New_Occurrence_Of (Part_Proc, Loc),
3289                Parameter_Associations => New_List (
3290                  New_Occurrence_Of (Obj_Id, Loc))));
3291
3292            Produced_Check := True;
3293         end if;
3294
3295         Priv_Item := Empty;
3296
3297         --  Derived subtypes do not have a partial view
3298
3299         if Present (Priv_Typ) then
3300
3301            --  The processing of the "full" invariant procedure intentionally
3302            --  skips the partial view because a) this may result in changes of
3303            --  visibility and b) lead to duplicate checks. However, when the
3304            --  full view is the underlying full view of an untagged derived
3305            --  type whose parent type is private, partial invariants appear on
3306            --  the rep item chain of the partial view only.
3307
3308            --    package Pack_1 is
3309            --       type Root ... is private;
3310            --    private
3311            --       <full view of Root>
3312            --    end Pack_1;
3313
3314            --    with Pack_1;
3315            --    package Pack_2 is
3316            --       type Child is new Pack_1.Root with Type_Invariant => ...;
3317            --       <underlying full view of Child>
3318            --    end Pack_2;
3319
3320            --  As a result, the processing of the full view must also consider
3321            --  all invariants of the partial view.
3322
3323            if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then
3324               null;
3325
3326            --  Otherwise the invariants of the partial view are ignored
3327
3328            else
3329               --  Note that the rep item chain is shared between the partial
3330               --  and full views of a type. To avoid processing the invariants
3331               --  of the partial view, signal the logic to stop when the first
3332               --  rep item of the partial view has been reached.
3333
3334               Priv_Item := First_Rep_Item (Priv_Typ);
3335
3336               --  Ignore the invariants of the partial view by eliminating the
3337               --  view.
3338
3339               Priv_Typ := Empty;
3340            end if;
3341         end if;
3342
3343         --  Process the invariants of the full view and in certain cases those
3344         --  of the partial view. This also handles any invariants on array or
3345         --  record components.
3346
3347         Add_Own_Invariants
3348           (T         => Priv_Typ,
3349            Obj_Id    => Obj_Id,
3350            Checks    => Stmts,
3351            Priv_Item => Priv_Item);
3352
3353         Add_Own_Invariants
3354           (T         => Full_Typ,
3355            Obj_Id    => Obj_Id,
3356            Checks    => Stmts,
3357            Priv_Item => Priv_Item);
3358
3359         --  Process the elements of an array type
3360
3361         if Is_Array_Type (Full_Typ) then
3362            Add_Array_Component_Invariants (Full_Typ, Obj_Id, Stmts);
3363
3364         --  Process the components of a record type
3365
3366         elsif Ekind (Full_Typ) = E_Record_Type then
3367            Add_Record_Component_Invariants (Full_Typ, Obj_Id, Stmts);
3368
3369         --  Process the components of a corresponding record
3370
3371         elsif Present (CRec_Typ) then
3372            Add_Record_Component_Invariants (CRec_Typ, Obj_Id, Stmts);
3373         end if;
3374
3375         --  Process the inherited class-wide invariants of all parent types.
3376         --  This also handles any invariants on record components.
3377
3378         Add_Parent_Invariants (Full_Typ, Obj_Id, Stmts);
3379
3380         --  Process the inherited class-wide invariants of all implemented
3381         --  interface types.
3382
3383         Add_Interface_Invariants (Full_Typ, Obj_Id, Stmts);
3384      end if;
3385
3386      End_Scope;
3387
3388      --  At this point there should be at least one invariant check. If this
3389      --  is not the case, then the invariant-related flags were not properly
3390      --  set, or there is a missing invariant procedure on one of the array
3391      --  or record components.
3392
3393      pragma Assert (Produced_Check);
3394
3395      --  Account for the case where assertions are disabled or all invariant
3396      --  checks are subject to Assertion_Policy Ignore. Produce a completing
3397      --  empty body.
3398
3399      if No (Stmts) then
3400         Stmts := New_List (Make_Null_Statement (Loc));
3401      end if;
3402
3403      --  Generate:
3404      --    procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>) is
3405      --    begin
3406      --       <Stmts>
3407      --    end <Work_Typ>[Partial_]Invariant;
3408
3409      Proc_Body :=
3410        Make_Subprogram_Body (Loc,
3411          Specification                =>
3412            Copy_Subprogram_Spec (Parent (Proc_Id)),
3413          Declarations                 => Empty_List,
3414            Handled_Statement_Sequence =>
3415              Make_Handled_Sequence_Of_Statements (Loc,
3416                Statements => Stmts));
3417      Proc_Body_Id := Defining_Entity (Proc_Body);
3418
3419      --  Perform minor decoration in case the body is not analyzed
3420
3421      Set_Ekind (Proc_Body_Id, E_Subprogram_Body);
3422      Set_Etype (Proc_Body_Id, Standard_Void_Type);
3423      Set_Scope (Proc_Body_Id, Current_Scope);
3424
3425      --  Link both spec and body to avoid generating duplicates
3426
3427      Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
3428      Set_Corresponding_Spec (Proc_Body, Proc_Id);
3429
3430      --  The body should not be inserted into the tree when the context is
3431      --  ASIS or a generic unit because it is not part of the template. Note
3432      --  that the body must still be generated in order to resolve the
3433      --  invariants.
3434
3435      if ASIS_Mode or Inside_A_Generic then
3436         null;
3437
3438      --  Semi-insert the body into the tree for GNATprove by setting its
3439      --  Parent field. This allows for proper upstream tree traversals.
3440
3441      elsif GNATprove_Mode then
3442         Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
3443
3444      --  Otherwise the body is part of the freezing actions of the type
3445
3446      else
3447         Append_Freeze_Action (Work_Typ, Proc_Body);
3448      end if;
3449
3450   <<Leave>>
3451      Restore_Ghost_Region (Saved_GM, Saved_IGR);
3452   end Build_Invariant_Procedure_Body;
3453
3454   -------------------------------------------
3455   -- Build_Invariant_Procedure_Declaration --
3456   -------------------------------------------
3457
3458   --  WARNING: This routine manages Ghost regions. Return statements must be
3459   --  replaced by gotos which jump to the end of the routine and restore the
3460   --  Ghost mode.
3461
3462   procedure Build_Invariant_Procedure_Declaration
3463     (Typ               : Entity_Id;
3464      Partial_Invariant : Boolean := False)
3465   is
3466      Loc : constant Source_Ptr := Sloc (Typ);
3467
3468      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
3469      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
3470      --  Save the Ghost-related attributes to restore on exit
3471
3472      Proc_Decl : Node_Id;
3473      Proc_Id   : Entity_Id;
3474      Proc_Nam  : Name_Id;
3475      Typ_Decl  : Node_Id;
3476
3477      CRec_Typ : Entity_Id;
3478      --  The corresponding record type of Full_Typ
3479
3480      Full_Base : Entity_Id;
3481      --  The base type of Full_Typ
3482
3483      Full_Typ : Entity_Id;
3484      --  The full view of working type
3485
3486      Obj_Id : Entity_Id;
3487      --  The _object formal parameter of the invariant procedure
3488
3489      Obj_Typ : Entity_Id;
3490      --  The type of the _object formal parameter
3491
3492      Priv_Typ : Entity_Id;
3493      --  The partial view of working type
3494
3495      Work_Typ : Entity_Id;
3496      --  The working type
3497
3498   begin
3499      Work_Typ := Typ;
3500
3501      --  The input type denotes the implementation base type of a constrained
3502      --  array type. Work with the first subtype as all invariant pragmas are
3503      --  on its rep item chain.
3504
3505      if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
3506         Work_Typ := First_Subtype (Work_Typ);
3507
3508      --  The input denotes the corresponding record type of a protected or a
3509      --  task type. Work with the concurrent type because the corresponding
3510      --  record type may not be visible to clients of the type.
3511
3512      elsif Ekind (Work_Typ) = E_Record_Type
3513        and then Is_Concurrent_Record_Type (Work_Typ)
3514      then
3515         Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
3516      end if;
3517
3518      --  The working type may be subject to pragma Ghost. Set the mode now to
3519      --  ensure that the invariant procedure is properly marked as Ghost.
3520
3521      Set_Ghost_Mode (Work_Typ);
3522
3523      --  The type must either have invariants of its own, inherit class-wide
3524      --  invariants from parent or interface types, or be an array or record
3525      --  type whose components have invariants.
3526
3527      pragma Assert (Has_Invariants (Work_Typ));
3528
3529      --  Nothing to do if the type already has a "partial" invariant procedure
3530
3531      if Partial_Invariant then
3532         if Present (Partial_Invariant_Procedure (Work_Typ)) then
3533            goto Leave;
3534         end if;
3535
3536      --  Nothing to do if the type already has a "full" invariant procedure
3537
3538      elsif Present (Invariant_Procedure (Work_Typ)) then
3539         goto Leave;
3540      end if;
3541
3542      --  The caller requests the declaration of the "partial" invariant
3543      --  procedure.
3544
3545      if Partial_Invariant then
3546         Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_Invariant");
3547
3548      --  Otherwise the caller requests the declaration of the "full" invariant
3549      --  procedure.
3550
3551      else
3552         Proc_Nam := New_External_Name (Chars (Work_Typ), "Invariant");
3553      end if;
3554
3555      Proc_Id := Make_Defining_Identifier (Loc, Chars => Proc_Nam);
3556
3557      --  Perform minor decoration in case the declaration is not analyzed
3558
3559      Set_Ekind (Proc_Id, E_Procedure);
3560      Set_Etype (Proc_Id, Standard_Void_Type);
3561      Set_Scope (Proc_Id, Current_Scope);
3562
3563      if Partial_Invariant then
3564         Set_Is_Partial_Invariant_Procedure (Proc_Id);
3565         Set_Partial_Invariant_Procedure (Work_Typ, Proc_Id);
3566      else
3567         Set_Is_Invariant_Procedure (Proc_Id);
3568         Set_Invariant_Procedure (Work_Typ, Proc_Id);
3569      end if;
3570
3571      --  The invariant procedure requires debug info when the invariants are
3572      --  subject to Source Coverage Obligations.
3573
3574      if Generate_SCO then
3575         Set_Debug_Info_Needed (Proc_Id);
3576      end if;
3577
3578      --  Obtain all views of the input type
3579
3580      Get_Views (Work_Typ, Priv_Typ, Full_Typ, Full_Base, CRec_Typ);
3581
3582      --  Associate the invariant procedure with all views
3583
3584      Propagate_Invariant_Attributes (Priv_Typ,  From_Typ => Work_Typ);
3585      Propagate_Invariant_Attributes (Full_Typ,  From_Typ => Work_Typ);
3586      Propagate_Invariant_Attributes (Full_Base, From_Typ => Work_Typ);
3587      Propagate_Invariant_Attributes (CRec_Typ,  From_Typ => Work_Typ);
3588
3589      --  The declaration of the invariant procedure is inserted after the
3590      --  declaration of the partial view as this allows for proper external
3591      --  visibility.
3592
3593      if Present (Priv_Typ) then
3594         Typ_Decl := Declaration_Node (Priv_Typ);
3595
3596      --  Anonymous arrays in object declarations have no explicit declaration
3597      --  so use the related object declaration as the insertion point.
3598
3599      elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ)  then
3600         Typ_Decl := Associated_Node_For_Itype (Work_Typ);
3601
3602      --  Derived types with the full view as parent do not have a partial
3603      --  view. Insert the invariant procedure after the derived type.
3604
3605      else
3606         Typ_Decl := Declaration_Node (Full_Typ);
3607      end if;
3608
3609      --  The type should have a declarative node
3610
3611      pragma Assert (Present (Typ_Decl));
3612
3613      --  Create the formal parameter which emulates the variable-like behavior
3614      --  of the current type instance.
3615
3616      Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject);
3617
3618      --  When generating an invariant procedure declaration for an abstract
3619      --  type (including interfaces), use the class-wide type as the _object
3620      --  type. This has several desirable effects:
3621
3622      --    * The invariant procedure does not become a primitive of the type.
3623      --      This eliminates the need to either special case the treatment of
3624      --      invariant procedures, or to make it a predefined primitive and
3625      --      force every derived type to potentially provide an empty body.
3626
3627      --    * The invariant procedure does not need to be declared as abstract.
3628      --      This allows for a proper body, which in turn avoids redundant
3629      --      processing of the same invariants for types with multiple views.
3630
3631      --    * The class-wide type allows for calls to abstract primitives
3632      --      within a nonabstract subprogram. The calls are treated as
3633      --      dispatching and require additional processing when they are
3634      --      remapped to call primitives of derived types. See routine
3635      --      Replace_References for details.
3636
3637      if Is_Abstract_Type (Work_Typ) then
3638         Obj_Typ := Class_Wide_Type (Work_Typ);
3639      else
3640         Obj_Typ := Work_Typ;
3641      end if;
3642
3643      --  Perform minor decoration in case the declaration is not analyzed
3644
3645      Set_Ekind (Obj_Id, E_In_Parameter);
3646      Set_Etype (Obj_Id, Obj_Typ);
3647      Set_Scope (Obj_Id, Proc_Id);
3648
3649      Set_First_Entity (Proc_Id, Obj_Id);
3650      Set_Last_Entity  (Proc_Id, Obj_Id);
3651
3652      --  Generate:
3653      --    procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>);
3654
3655      Proc_Decl :=
3656        Make_Subprogram_Declaration (Loc,
3657          Specification =>
3658            Make_Procedure_Specification (Loc,
3659              Defining_Unit_Name       => Proc_Id,
3660              Parameter_Specifications => New_List (
3661                Make_Parameter_Specification (Loc,
3662                  Defining_Identifier => Obj_Id,
3663                  Parameter_Type      => New_Occurrence_Of (Obj_Typ, Loc)))));
3664
3665      --  The declaration should not be inserted into the tree when the context
3666      --  is ASIS or a generic unit because it is not part of the template.
3667
3668      if ASIS_Mode or Inside_A_Generic then
3669         null;
3670
3671      --  Semi-insert the declaration into the tree for GNATprove by setting
3672      --  its Parent field. This allows for proper upstream tree traversals.
3673
3674      elsif GNATprove_Mode then
3675         Set_Parent (Proc_Decl, Parent (Typ_Decl));
3676
3677      --  Otherwise insert the declaration
3678
3679      else
3680         pragma Assert (Present (Typ_Decl));
3681         Insert_After_And_Analyze (Typ_Decl, Proc_Decl);
3682      end if;
3683
3684   <<Leave>>
3685      Restore_Ghost_Region (Saved_GM, Saved_IGR);
3686   end Build_Invariant_Procedure_Declaration;
3687
3688   --------------------------
3689   -- Build_Procedure_Form --
3690   --------------------------
3691
3692   procedure Build_Procedure_Form (N : Node_Id) is
3693      Loc  : constant Source_Ptr := Sloc (N);
3694      Subp : constant Entity_Id := Defining_Entity (N);
3695
3696      Func_Formal  : Entity_Id;
3697      Proc_Formals : List_Id;
3698      Proc_Decl    : Node_Id;
3699
3700   begin
3701      --  No action needed if this transformation was already done, or in case
3702      --  of subprogram renaming declarations.
3703
3704      if Nkind (Specification (N)) = N_Procedure_Specification
3705        or else Nkind (N) = N_Subprogram_Renaming_Declaration
3706      then
3707         return;
3708      end if;
3709
3710      --  Ditto when dealing with an expression function, where both the
3711      --  original expression and the generated declaration end up being
3712      --  expanded here.
3713
3714      if Rewritten_For_C (Subp) then
3715         return;
3716      end if;
3717
3718      Proc_Formals := New_List;
3719
3720      --  Create a list of formal parameters with the same types as the
3721      --  function.
3722
3723      Func_Formal := First_Formal (Subp);
3724      while Present (Func_Formal) loop
3725         Append_To (Proc_Formals,
3726           Make_Parameter_Specification (Loc,
3727             Defining_Identifier =>
3728               Make_Defining_Identifier (Loc, Chars (Func_Formal)),
3729             Parameter_Type      =>
3730               New_Occurrence_Of (Etype (Func_Formal), Loc)));
3731
3732         Next_Formal (Func_Formal);
3733      end loop;
3734
3735      --  Add an extra out parameter to carry the function result
3736
3737      Name_Len := 6;
3738      Name_Buffer (1 .. Name_Len) := "RESULT";
3739      Append_To (Proc_Formals,
3740        Make_Parameter_Specification (Loc,
3741          Defining_Identifier =>
3742            Make_Defining_Identifier (Loc, Chars => Name_Find),
3743          Out_Present         => True,
3744          Parameter_Type      => New_Occurrence_Of (Etype (Subp), Loc)));
3745
3746      --  The new procedure declaration is inserted immediately after the
3747      --  function declaration. The processing in Build_Procedure_Body_Form
3748      --  relies on this order.
3749
3750      Proc_Decl :=
3751        Make_Subprogram_Declaration (Loc,
3752          Specification =>
3753            Make_Procedure_Specification (Loc,
3754              Defining_Unit_Name       =>
3755                Make_Defining_Identifier (Loc, Chars (Subp)),
3756              Parameter_Specifications => Proc_Formals));
3757
3758      Insert_After_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl);
3759
3760      --  Entity of procedure must remain invisible so that it does not
3761      --  overload subsequent references to the original function.
3762
3763      Set_Is_Immediately_Visible (Defining_Entity (Proc_Decl), False);
3764
3765      --  Mark the function as having a procedure form and link the function
3766      --  and its internally built procedure.
3767
3768      Set_Rewritten_For_C (Subp);
3769      Set_Corresponding_Procedure (Subp, Defining_Entity (Proc_Decl));
3770      Set_Corresponding_Function (Defining_Entity (Proc_Decl), Subp);
3771   end Build_Procedure_Form;
3772
3773   ------------------------
3774   -- Build_Runtime_Call --
3775   ------------------------
3776
3777   function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
3778   begin
3779      --  If entity is not available, we can skip making the call (this avoids
3780      --  junk duplicated error messages in a number of cases).
3781
3782      if not RTE_Available (RE) then
3783         return Make_Null_Statement (Loc);
3784      else
3785         return
3786           Make_Procedure_Call_Statement (Loc,
3787             Name => New_Occurrence_Of (RTE (RE), Loc));
3788      end if;
3789   end Build_Runtime_Call;
3790
3791   ------------------------
3792   -- Build_SS_Mark_Call --
3793   ------------------------
3794
3795   function Build_SS_Mark_Call
3796     (Loc  : Source_Ptr;
3797      Mark : Entity_Id) return Node_Id
3798   is
3799   begin
3800      --  Generate:
3801      --    Mark : constant Mark_Id := SS_Mark;
3802
3803      return
3804        Make_Object_Declaration (Loc,
3805          Defining_Identifier => Mark,
3806          Constant_Present    => True,
3807          Object_Definition   =>
3808            New_Occurrence_Of (RTE (RE_Mark_Id), Loc),
3809          Expression          =>
3810            Make_Function_Call (Loc,
3811              Name => New_Occurrence_Of (RTE (RE_SS_Mark), Loc)));
3812   end Build_SS_Mark_Call;
3813
3814   ---------------------------
3815   -- Build_SS_Release_Call --
3816   ---------------------------
3817
3818   function Build_SS_Release_Call
3819     (Loc  : Source_Ptr;
3820      Mark : Entity_Id) return Node_Id
3821   is
3822   begin
3823      --  Generate:
3824      --    SS_Release (Mark);
3825
3826      return
3827        Make_Procedure_Call_Statement (Loc,
3828          Name                   =>
3829            New_Occurrence_Of (RTE (RE_SS_Release), Loc),
3830          Parameter_Associations => New_List (
3831            New_Occurrence_Of (Mark, Loc)));
3832   end Build_SS_Release_Call;
3833
3834   ----------------------------
3835   -- Build_Task_Array_Image --
3836   ----------------------------
3837
3838   --  This function generates the body for a function that constructs the
3839   --  image string for a task that is an array component. The function is
3840   --  local to the init proc for the array type, and is called for each one
3841   --  of the components. The constructed image has the form of an indexed
3842   --  component, whose prefix is the outer variable of the array type.
3843   --  The n-dimensional array type has known indexes Index, Index2...
3844
3845   --  Id_Ref is an indexed component form created by the enclosing init proc.
3846   --  Its successive indexes are Val1, Val2, ... which are the loop variables
3847   --  in the loops that call the individual task init proc on each component.
3848
3849   --  The generated function has the following structure:
3850
3851   --  function F return String is
3852   --     Pref : string renames Task_Name;
3853   --     T1   : String := Index1'Image (Val1);
3854   --     ...
3855   --     Tn   : String := indexn'image (Valn);
3856   --     Len  : Integer := T1'Length + ... + Tn'Length + n + 1;
3857   --     --  Len includes commas and the end parentheses.
3858   --     Res  : String (1..Len);
3859   --     Pos  : Integer := Pref'Length;
3860   --
3861   --  begin
3862   --     Res (1 .. Pos) := Pref;
3863   --     Pos := Pos + 1;
3864   --     Res (Pos)    := '(';
3865   --     Pos := Pos + 1;
3866   --     Res (Pos .. Pos + T1'Length - 1) := T1;
3867   --     Pos := Pos + T1'Length;
3868   --     Res (Pos) := '.';
3869   --     Pos := Pos + 1;
3870   --     ...
3871   --     Res (Pos .. Pos + Tn'Length - 1) := Tn;
3872   --     Res (Len) := ')';
3873   --
3874   --     return Res;
3875   --  end F;
3876   --
3877   --  Needless to say, multidimensional arrays of tasks are rare enough that
3878   --  the bulkiness of this code is not really a concern.
3879
3880   function Build_Task_Array_Image
3881     (Loc    : Source_Ptr;
3882      Id_Ref : Node_Id;
3883      A_Type : Entity_Id;
3884      Dyn    : Boolean := False) return Node_Id
3885   is
3886      Dims : constant Nat := Number_Dimensions (A_Type);
3887      --  Number of dimensions for array of tasks
3888
3889      Temps : array (1 .. Dims) of Entity_Id;
3890      --  Array of temporaries to hold string for each index
3891
3892      Indx : Node_Id;
3893      --  Index expression
3894
3895      Len : Entity_Id;
3896      --  Total length of generated name
3897
3898      Pos : Entity_Id;
3899      --  Running index for substring assignments
3900
3901      Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
3902      --  Name of enclosing variable, prefix of resulting name
3903
3904      Res : Entity_Id;
3905      --  String to hold result
3906
3907      Val : Node_Id;
3908      --  Value of successive indexes
3909
3910      Sum : Node_Id;
3911      --  Expression to compute total size of string
3912
3913      T : Entity_Id;
3914      --  Entity for name at one index position
3915
3916      Decls : constant List_Id := New_List;
3917      Stats : constant List_Id := New_List;
3918
3919   begin
3920      --  For a dynamic task, the name comes from the target variable. For a
3921      --  static one it is a formal of the enclosing init proc.
3922
3923      if Dyn then
3924         Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
3925         Append_To (Decls,
3926           Make_Object_Declaration (Loc,
3927             Defining_Identifier => Pref,
3928             Object_Definition => New_Occurrence_Of (Standard_String, Loc),
3929             Expression =>
3930               Make_String_Literal (Loc,
3931                 Strval => String_From_Name_Buffer)));
3932
3933      else
3934         Append_To (Decls,
3935           Make_Object_Renaming_Declaration (Loc,
3936             Defining_Identifier => Pref,
3937             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
3938             Name                => Make_Identifier (Loc, Name_uTask_Name)));
3939      end if;
3940
3941      Indx := First_Index (A_Type);
3942      Val  := First (Expressions (Id_Ref));
3943
3944      for J in 1 .. Dims loop
3945         T := Make_Temporary (Loc, 'T');
3946         Temps (J) := T;
3947
3948         Append_To (Decls,
3949           Make_Object_Declaration (Loc,
3950             Defining_Identifier => T,
3951             Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
3952             Expression          =>
3953               Make_Attribute_Reference (Loc,
3954                 Attribute_Name => Name_Image,
3955                 Prefix         => New_Occurrence_Of (Etype (Indx), Loc),
3956                 Expressions    => New_List (New_Copy_Tree (Val)))));
3957
3958         Next_Index (Indx);
3959         Next (Val);
3960      end loop;
3961
3962      Sum := Make_Integer_Literal (Loc, Dims + 1);
3963
3964      Sum :=
3965        Make_Op_Add (Loc,
3966          Left_Opnd => Sum,
3967          Right_Opnd =>
3968            Make_Attribute_Reference (Loc,
3969              Attribute_Name => Name_Length,
3970              Prefix         => New_Occurrence_Of (Pref, Loc),
3971              Expressions    => New_List (Make_Integer_Literal (Loc, 1))));
3972
3973      for J in 1 .. Dims loop
3974         Sum :=
3975           Make_Op_Add (Loc,
3976             Left_Opnd  => Sum,
3977             Right_Opnd =>
3978               Make_Attribute_Reference (Loc,
3979                 Attribute_Name => Name_Length,
3980                 Prefix         =>
3981                  New_Occurrence_Of (Temps (J), Loc),
3982                Expressions     => New_List (Make_Integer_Literal (Loc, 1))));
3983      end loop;
3984
3985      Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
3986
3987      Set_Character_Literal_Name (Char_Code (Character'Pos ('(')));
3988
3989      Append_To (Stats,
3990        Make_Assignment_Statement (Loc,
3991          Name       =>
3992            Make_Indexed_Component (Loc,
3993              Prefix      => New_Occurrence_Of (Res, Loc),
3994              Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
3995          Expression =>
3996            Make_Character_Literal (Loc,
3997              Chars              => Name_Find,
3998              Char_Literal_Value => UI_From_Int (Character'Pos ('(')))));
3999
4000      Append_To (Stats,
4001        Make_Assignment_Statement (Loc,
4002          Name       => New_Occurrence_Of (Pos, Loc),
4003          Expression =>
4004            Make_Op_Add (Loc,
4005              Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4006              Right_Opnd => Make_Integer_Literal (Loc, 1))));
4007
4008      for J in 1 .. Dims loop
4009
4010         Append_To (Stats,
4011           Make_Assignment_Statement (Loc,
4012             Name =>
4013               Make_Slice (Loc,
4014                 Prefix          => New_Occurrence_Of (Res, Loc),
4015                 Discrete_Range  =>
4016                   Make_Range (Loc,
4017                     Low_Bound  => New_Occurrence_Of  (Pos, Loc),
4018                     High_Bound =>
4019                       Make_Op_Subtract (Loc,
4020                         Left_Opnd  =>
4021                           Make_Op_Add (Loc,
4022                             Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4023                             Right_Opnd =>
4024                               Make_Attribute_Reference (Loc,
4025                                 Attribute_Name => Name_Length,
4026                                 Prefix         =>
4027                                   New_Occurrence_Of (Temps (J), Loc),
4028                                 Expressions    =>
4029                                   New_List (Make_Integer_Literal (Loc, 1)))),
4030                         Right_Opnd => Make_Integer_Literal (Loc, 1)))),
4031
4032              Expression => New_Occurrence_Of (Temps (J), Loc)));
4033
4034         if J < Dims then
4035            Append_To (Stats,
4036               Make_Assignment_Statement (Loc,
4037                  Name       => New_Occurrence_Of (Pos, Loc),
4038                  Expression =>
4039                    Make_Op_Add (Loc,
4040                      Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4041                      Right_Opnd =>
4042                        Make_Attribute_Reference (Loc,
4043                          Attribute_Name => Name_Length,
4044                          Prefix         => New_Occurrence_Of (Temps (J), Loc),
4045                          Expressions    =>
4046                            New_List (Make_Integer_Literal (Loc, 1))))));
4047
4048            Set_Character_Literal_Name (Char_Code (Character'Pos (',')));
4049
4050            Append_To (Stats,
4051              Make_Assignment_Statement (Loc,
4052                Name => Make_Indexed_Component (Loc,
4053                   Prefix => New_Occurrence_Of (Res, Loc),
4054                   Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4055                Expression =>
4056                  Make_Character_Literal (Loc,
4057                    Chars              => Name_Find,
4058                    Char_Literal_Value => UI_From_Int (Character'Pos (',')))));
4059
4060            Append_To (Stats,
4061              Make_Assignment_Statement (Loc,
4062                Name         => New_Occurrence_Of (Pos, Loc),
4063                  Expression =>
4064                    Make_Op_Add (Loc,
4065                      Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4066                      Right_Opnd => Make_Integer_Literal (Loc, 1))));
4067         end if;
4068      end loop;
4069
4070      Set_Character_Literal_Name (Char_Code (Character'Pos (')')));
4071
4072      Append_To (Stats,
4073        Make_Assignment_Statement (Loc,
4074          Name        =>
4075            Make_Indexed_Component (Loc,
4076              Prefix      => New_Occurrence_Of (Res, Loc),
4077              Expressions => New_List (New_Occurrence_Of (Len, Loc))),
4078           Expression =>
4079             Make_Character_Literal (Loc,
4080               Chars              => Name_Find,
4081               Char_Literal_Value => UI_From_Int (Character'Pos (')')))));
4082      return Build_Task_Image_Function (Loc, Decls, Stats, Res);
4083   end Build_Task_Array_Image;
4084
4085   ----------------------------
4086   -- Build_Task_Image_Decls --
4087   ----------------------------
4088
4089   function Build_Task_Image_Decls
4090     (Loc          : Source_Ptr;
4091      Id_Ref       : Node_Id;
4092      A_Type       : Entity_Id;
4093      In_Init_Proc : Boolean := False) return List_Id
4094   is
4095      Decls  : constant List_Id   := New_List;
4096      T_Id   : Entity_Id := Empty;
4097      Decl   : Node_Id;
4098      Expr   : Node_Id   := Empty;
4099      Fun    : Node_Id   := Empty;
4100      Is_Dyn : constant Boolean :=
4101                 Nkind (Parent (Id_Ref)) = N_Assignment_Statement
4102                   and then
4103                 Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
4104
4105   begin
4106      --  If Discard_Names or No_Implicit_Heap_Allocations are in effect,
4107      --  generate a dummy declaration only.
4108
4109      if Restriction_Active (No_Implicit_Heap_Allocations)
4110        or else Global_Discard_Names
4111      then
4112         T_Id := Make_Temporary (Loc, 'J');
4113         Name_Len := 0;
4114
4115         return
4116           New_List (
4117             Make_Object_Declaration (Loc,
4118               Defining_Identifier => T_Id,
4119               Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4120               Expression =>
4121                 Make_String_Literal (Loc,
4122                   Strval => String_From_Name_Buffer)));
4123
4124      else
4125         if Nkind (Id_Ref) = N_Identifier
4126           or else Nkind (Id_Ref) = N_Defining_Identifier
4127         then
4128            --  For a simple variable, the image of the task is built from
4129            --  the name of the variable. To avoid possible conflict with the
4130            --  anonymous type created for a single protected object, add a
4131            --  numeric suffix.
4132
4133            T_Id :=
4134              Make_Defining_Identifier (Loc,
4135                New_External_Name (Chars (Id_Ref), 'T', 1));
4136
4137            Get_Name_String (Chars (Id_Ref));
4138
4139            Expr :=
4140              Make_String_Literal (Loc,
4141                Strval => String_From_Name_Buffer);
4142
4143         elsif Nkind (Id_Ref) = N_Selected_Component then
4144            T_Id :=
4145              Make_Defining_Identifier (Loc,
4146                New_External_Name (Chars (Selector_Name (Id_Ref)), 'T'));
4147            Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
4148
4149         elsif Nkind (Id_Ref) = N_Indexed_Component then
4150            T_Id :=
4151              Make_Defining_Identifier (Loc,
4152                New_External_Name (Chars (A_Type), 'N'));
4153
4154            Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
4155         end if;
4156      end if;
4157
4158      if Present (Fun) then
4159         Append (Fun, Decls);
4160         Expr := Make_Function_Call (Loc,
4161           Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
4162
4163         if not In_Init_Proc then
4164            Set_Uses_Sec_Stack (Defining_Entity (Fun));
4165         end if;
4166      end if;
4167
4168      Decl := Make_Object_Declaration (Loc,
4169        Defining_Identifier => T_Id,
4170        Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
4171        Constant_Present    => True,
4172        Expression          => Expr);
4173
4174      Append (Decl, Decls);
4175      return Decls;
4176   end Build_Task_Image_Decls;
4177
4178   -------------------------------
4179   -- Build_Task_Image_Function --
4180   -------------------------------
4181
4182   function Build_Task_Image_Function
4183     (Loc   : Source_Ptr;
4184      Decls : List_Id;
4185      Stats : List_Id;
4186      Res   : Entity_Id) return Node_Id
4187   is
4188      Spec : Node_Id;
4189
4190   begin
4191      Append_To (Stats,
4192        Make_Simple_Return_Statement (Loc,
4193          Expression => New_Occurrence_Of (Res, Loc)));
4194
4195      Spec := Make_Function_Specification (Loc,
4196        Defining_Unit_Name => Make_Temporary (Loc, 'F'),
4197        Result_Definition  => New_Occurrence_Of (Standard_String, Loc));
4198
4199      --  Calls to 'Image use the secondary stack, which must be cleaned up
4200      --  after the task name is built.
4201
4202      return Make_Subprogram_Body (Loc,
4203         Specification => Spec,
4204         Declarations => Decls,
4205         Handled_Statement_Sequence =>
4206           Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats));
4207   end Build_Task_Image_Function;
4208
4209   -----------------------------
4210   -- Build_Task_Image_Prefix --
4211   -----------------------------
4212
4213   procedure Build_Task_Image_Prefix
4214      (Loc    : Source_Ptr;
4215       Len    : out Entity_Id;
4216       Res    : out Entity_Id;
4217       Pos    : out Entity_Id;
4218       Prefix : Entity_Id;
4219       Sum    : Node_Id;
4220       Decls  : List_Id;
4221       Stats  : List_Id)
4222   is
4223   begin
4224      Len := Make_Temporary (Loc, 'L', Sum);
4225
4226      Append_To (Decls,
4227        Make_Object_Declaration (Loc,
4228          Defining_Identifier => Len,
4229          Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc),
4230          Expression          => Sum));
4231
4232      Res := Make_Temporary (Loc, 'R');
4233
4234      Append_To (Decls,
4235         Make_Object_Declaration (Loc,
4236            Defining_Identifier => Res,
4237            Object_Definition =>
4238               Make_Subtype_Indication (Loc,
4239                  Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
4240               Constraint =>
4241                 Make_Index_Or_Discriminant_Constraint (Loc,
4242                   Constraints =>
4243                     New_List (
4244                       Make_Range (Loc,
4245                         Low_Bound => Make_Integer_Literal (Loc, 1),
4246                         High_Bound => New_Occurrence_Of (Len, Loc)))))));
4247
4248      --  Indicate that the result is an internal temporary, so it does not
4249      --  receive a bogus initialization when declaration is expanded. This
4250      --  is both efficient, and prevents anomalies in the handling of
4251      --  dynamic objects on the secondary stack.
4252
4253      Set_Is_Internal (Res);
4254      Pos := Make_Temporary (Loc, 'P');
4255
4256      Append_To (Decls,
4257         Make_Object_Declaration (Loc,
4258            Defining_Identifier => Pos,
4259            Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc)));
4260
4261      --  Pos := Prefix'Length;
4262
4263      Append_To (Stats,
4264         Make_Assignment_Statement (Loc,
4265            Name => New_Occurrence_Of (Pos, Loc),
4266            Expression =>
4267              Make_Attribute_Reference (Loc,
4268                Attribute_Name => Name_Length,
4269                Prefix         => New_Occurrence_Of (Prefix, Loc),
4270                Expressions    => New_List (Make_Integer_Literal (Loc, 1)))));
4271
4272      --  Res (1 .. Pos) := Prefix;
4273
4274      Append_To (Stats,
4275        Make_Assignment_Statement (Loc,
4276          Name =>
4277            Make_Slice (Loc,
4278              Prefix          => New_Occurrence_Of (Res, Loc),
4279              Discrete_Range  =>
4280                Make_Range (Loc,
4281                   Low_Bound  => Make_Integer_Literal (Loc, 1),
4282                   High_Bound => New_Occurrence_Of (Pos, Loc))),
4283
4284          Expression => New_Occurrence_Of (Prefix, Loc)));
4285
4286      Append_To (Stats,
4287         Make_Assignment_Statement (Loc,
4288            Name       => New_Occurrence_Of (Pos, Loc),
4289            Expression =>
4290              Make_Op_Add (Loc,
4291                Left_Opnd  => New_Occurrence_Of (Pos, Loc),
4292                Right_Opnd => Make_Integer_Literal (Loc, 1))));
4293   end Build_Task_Image_Prefix;
4294
4295   -----------------------------
4296   -- Build_Task_Record_Image --
4297   -----------------------------
4298
4299   function Build_Task_Record_Image
4300     (Loc    : Source_Ptr;
4301      Id_Ref : Node_Id;
4302      Dyn    : Boolean := False) return Node_Id
4303   is
4304      Len : Entity_Id;
4305      --  Total length of generated name
4306
4307      Pos : Entity_Id;
4308      --  Index into result
4309
4310      Res : Entity_Id;
4311      --  String to hold result
4312
4313      Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
4314      --  Name of enclosing variable, prefix of resulting name
4315
4316      Sum : Node_Id;
4317      --  Expression to compute total size of string
4318
4319      Sel : Entity_Id;
4320      --  Entity for selector name
4321
4322      Decls : constant List_Id := New_List;
4323      Stats : constant List_Id := New_List;
4324
4325   begin
4326      --  For a dynamic task, the name comes from the target variable. For a
4327      --  static one it is a formal of the enclosing init proc.
4328
4329      if Dyn then
4330         Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
4331         Append_To (Decls,
4332           Make_Object_Declaration (Loc,
4333             Defining_Identifier => Pref,
4334             Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4335             Expression =>
4336               Make_String_Literal (Loc,
4337                 Strval => String_From_Name_Buffer)));
4338
4339      else
4340         Append_To (Decls,
4341           Make_Object_Renaming_Declaration (Loc,
4342             Defining_Identifier => Pref,
4343             Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
4344             Name                => Make_Identifier (Loc, Name_uTask_Name)));
4345      end if;
4346
4347      Sel := Make_Temporary (Loc, 'S');
4348
4349      Get_Name_String (Chars (Selector_Name (Id_Ref)));
4350
4351      Append_To (Decls,
4352         Make_Object_Declaration (Loc,
4353           Defining_Identifier => Sel,
4354           Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
4355           Expression          =>
4356             Make_String_Literal (Loc,
4357               Strval => String_From_Name_Buffer)));
4358
4359      Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
4360
4361      Sum :=
4362        Make_Op_Add (Loc,
4363          Left_Opnd => Sum,
4364          Right_Opnd =>
4365           Make_Attribute_Reference (Loc,
4366             Attribute_Name => Name_Length,
4367             Prefix =>
4368               New_Occurrence_Of (Pref, Loc),
4369             Expressions => New_List (Make_Integer_Literal (Loc, 1))));
4370
4371      Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
4372
4373      Set_Character_Literal_Name (Char_Code (Character'Pos ('.')));
4374
4375      --  Res (Pos) := '.';
4376
4377      Append_To (Stats,
4378         Make_Assignment_Statement (Loc,
4379           Name => Make_Indexed_Component (Loc,
4380              Prefix => New_Occurrence_Of (Res, Loc),
4381              Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4382           Expression =>
4383             Make_Character_Literal (Loc,
4384               Chars => Name_Find,
4385               Char_Literal_Value =>
4386                 UI_From_Int (Character'Pos ('.')))));
4387
4388      Append_To (Stats,
4389        Make_Assignment_Statement (Loc,
4390          Name => New_Occurrence_Of (Pos, Loc),
4391          Expression =>
4392            Make_Op_Add (Loc,
4393              Left_Opnd => New_Occurrence_Of (Pos, Loc),
4394              Right_Opnd => Make_Integer_Literal (Loc, 1))));
4395
4396      --  Res (Pos .. Len) := Selector;
4397
4398      Append_To (Stats,
4399        Make_Assignment_Statement (Loc,
4400          Name => Make_Slice (Loc,
4401             Prefix => New_Occurrence_Of (Res, Loc),
4402             Discrete_Range  =>
4403               Make_Range (Loc,
4404                 Low_Bound  => New_Occurrence_Of (Pos, Loc),
4405                 High_Bound => New_Occurrence_Of (Len, Loc))),
4406          Expression => New_Occurrence_Of (Sel, Loc)));
4407
4408      return Build_Task_Image_Function (Loc, Decls, Stats, Res);
4409   end Build_Task_Record_Image;
4410
4411   ---------------------------------------
4412   -- Build_Transient_Object_Statements --
4413   ---------------------------------------
4414
4415   procedure Build_Transient_Object_Statements
4416     (Obj_Decl     : Node_Id;
4417      Fin_Call     : out Node_Id;
4418      Hook_Assign  : out Node_Id;
4419      Hook_Clear   : out Node_Id;
4420      Hook_Decl    : out Node_Id;
4421      Ptr_Decl     : out Node_Id;
4422      Finalize_Obj : Boolean := True)
4423   is
4424      Loc     : constant Source_Ptr := Sloc (Obj_Decl);
4425      Obj_Id  : constant Entity_Id  := Defining_Entity (Obj_Decl);
4426      Obj_Typ : constant Entity_Id  := Base_Type (Etype (Obj_Id));
4427
4428      Desig_Typ : Entity_Id;
4429      Hook_Expr : Node_Id;
4430      Hook_Id   : Entity_Id;
4431      Obj_Ref   : Node_Id;
4432      Ptr_Typ   : Entity_Id;
4433
4434   begin
4435      --  Recover the type of the object
4436
4437      Desig_Typ := Obj_Typ;
4438
4439      if Is_Access_Type (Desig_Typ) then
4440         Desig_Typ := Available_View (Designated_Type (Desig_Typ));
4441      end if;
4442
4443      --  Create an access type which provides a reference to the transient
4444      --  object. Generate:
4445
4446      --    type Ptr_Typ is access all Desig_Typ;
4447
4448      Ptr_Typ := Make_Temporary (Loc, 'A');
4449      Set_Ekind (Ptr_Typ, E_General_Access_Type);
4450      Set_Directly_Designated_Type (Ptr_Typ, Desig_Typ);
4451
4452      Ptr_Decl :=
4453        Make_Full_Type_Declaration (Loc,
4454          Defining_Identifier => Ptr_Typ,
4455          Type_Definition     =>
4456            Make_Access_To_Object_Definition (Loc,
4457              All_Present        => True,
4458              Subtype_Indication => New_Occurrence_Of (Desig_Typ, Loc)));
4459
4460      --  Create a temporary check which acts as a hook to the transient
4461      --  object. Generate:
4462
4463      --    Hook : Ptr_Typ := null;
4464
4465      Hook_Id := Make_Temporary (Loc, 'T');
4466      Set_Ekind (Hook_Id, E_Variable);
4467      Set_Etype (Hook_Id, Ptr_Typ);
4468
4469      Hook_Decl :=
4470        Make_Object_Declaration (Loc,
4471          Defining_Identifier => Hook_Id,
4472          Object_Definition   => New_Occurrence_Of (Ptr_Typ, Loc),
4473          Expression          => Make_Null (Loc));
4474
4475      --  Mark the temporary as a hook. This signals the machinery in
4476      --  Build_Finalizer to recognize this special case.
4477
4478      Set_Status_Flag_Or_Transient_Decl (Hook_Id, Obj_Decl);
4479
4480      --  Hook the transient object to the temporary. Generate:
4481
4482      --    Hook := Ptr_Typ (Obj_Id);
4483      --      <or>
4484      --    Hool := Obj_Id'Unrestricted_Access;
4485
4486      if Is_Access_Type (Obj_Typ) then
4487         Hook_Expr :=
4488           Unchecked_Convert_To (Ptr_Typ, New_Occurrence_Of (Obj_Id, Loc));
4489      else
4490         Hook_Expr :=
4491           Make_Attribute_Reference (Loc,
4492             Prefix         => New_Occurrence_Of (Obj_Id, Loc),
4493             Attribute_Name => Name_Unrestricted_Access);
4494      end if;
4495
4496      Hook_Assign :=
4497        Make_Assignment_Statement (Loc,
4498          Name       => New_Occurrence_Of (Hook_Id, Loc),
4499          Expression => Hook_Expr);
4500
4501      --  Crear the hook prior to finalizing the object. Generate:
4502
4503      --    Hook := null;
4504
4505      Hook_Clear :=
4506        Make_Assignment_Statement (Loc,
4507          Name       => New_Occurrence_Of (Hook_Id, Loc),
4508          Expression => Make_Null (Loc));
4509
4510      --  Finalize the object. Generate:
4511
4512      --    [Deep_]Finalize (Obj_Ref[.all]);
4513
4514      if Finalize_Obj then
4515         Obj_Ref := New_Occurrence_Of (Obj_Id, Loc);
4516
4517         if Is_Access_Type (Obj_Typ) then
4518            Obj_Ref := Make_Explicit_Dereference (Loc, Obj_Ref);
4519            Set_Etype (Obj_Ref, Desig_Typ);
4520         end if;
4521
4522         Fin_Call :=
4523           Make_Final_Call
4524             (Obj_Ref => Obj_Ref,
4525              Typ     => Desig_Typ);
4526
4527      --  Otherwise finalize the hook. Generate:
4528
4529      --    [Deep_]Finalize (Hook.all);
4530
4531      else
4532         Fin_Call :=
4533           Make_Final_Call (
4534             Obj_Ref =>
4535               Make_Explicit_Dereference (Loc,
4536                 Prefix => New_Occurrence_Of (Hook_Id, Loc)),
4537             Typ     => Desig_Typ);
4538      end if;
4539   end Build_Transient_Object_Statements;
4540
4541   -----------------------------
4542   -- Check_Float_Op_Overflow --
4543   -----------------------------
4544
4545   procedure Check_Float_Op_Overflow (N : Node_Id) is
4546   begin
4547      --  Return if no check needed
4548
4549      if not Is_Floating_Point_Type (Etype (N))
4550        or else not (Do_Overflow_Check (N) and then Check_Float_Overflow)
4551
4552        --  In CodePeer_Mode, rely on the overflow check flag being set instead
4553        --  and do not expand the code for float overflow checking.
4554
4555        or else CodePeer_Mode
4556      then
4557         return;
4558      end if;
4559
4560      --  Otherwise we replace the expression by
4561
4562      --  do Tnn : constant ftype := expression;
4563      --     constraint_error when not Tnn'Valid;
4564      --  in Tnn;
4565
4566      declare
4567         Loc : constant Source_Ptr := Sloc (N);
4568         Tnn : constant Entity_Id  := Make_Temporary (Loc, 'T', N);
4569         Typ : constant Entity_Id  := Etype (N);
4570
4571      begin
4572         --  Turn off the Do_Overflow_Check flag, since we are doing that work
4573         --  right here. We also set the node as analyzed to prevent infinite
4574         --  recursion from repeating the operation in the expansion.
4575
4576         Set_Do_Overflow_Check (N, False);
4577         Set_Analyzed (N, True);
4578
4579         --  Do the rewrite to include the check
4580
4581         Rewrite (N,
4582           Make_Expression_With_Actions (Loc,
4583             Actions    => New_List (
4584               Make_Object_Declaration (Loc,
4585                 Defining_Identifier => Tnn,
4586                 Object_Definition   => New_Occurrence_Of (Typ, Loc),
4587                 Constant_Present    => True,
4588                 Expression          => Relocate_Node (N)),
4589               Make_Raise_Constraint_Error (Loc,
4590                 Condition =>
4591                   Make_Op_Not (Loc,
4592                     Right_Opnd =>
4593                       Make_Attribute_Reference (Loc,
4594                         Prefix         => New_Occurrence_Of (Tnn, Loc),
4595                         Attribute_Name => Name_Valid)),
4596                 Reason    => CE_Overflow_Check_Failed)),
4597             Expression => New_Occurrence_Of (Tnn, Loc)));
4598
4599         Analyze_And_Resolve (N, Typ);
4600      end;
4601   end Check_Float_Op_Overflow;
4602
4603   ----------------------------------
4604   -- Component_May_Be_Bit_Aligned --
4605   ----------------------------------
4606
4607   function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
4608      UT : Entity_Id;
4609
4610   begin
4611      --  If no component clause, then everything is fine, since the back end
4612      --  never misaligns from byte boundaries by default, even if there is a
4613      --  pragma Pack for the record.
4614
4615      if No (Comp) or else No (Component_Clause (Comp)) then
4616         return False;
4617      end if;
4618
4619      UT := Underlying_Type (Etype (Comp));
4620
4621      --  It is only array and record types that cause trouble
4622
4623      if not Is_Record_Type (UT) and then not Is_Array_Type (UT) then
4624         return False;
4625
4626      --  If we know that we have a small (64 bits or less) record or small
4627      --  bit-packed array, then everything is fine, since the back end can
4628      --  handle these cases correctly.
4629
4630      elsif Esize (Comp) <= 64
4631        and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT))
4632      then
4633         return False;
4634
4635      --  Otherwise if the component is not byte aligned, we know we have the
4636      --  nasty unaligned case.
4637
4638      elsif Normalized_First_Bit (Comp) /= Uint_0
4639        or else Esize (Comp) mod System_Storage_Unit /= Uint_0
4640      then
4641         return True;
4642
4643      --  If we are large and byte aligned, then OK at this level
4644
4645      else
4646         return False;
4647      end if;
4648   end Component_May_Be_Bit_Aligned;
4649
4650   ----------------------------------------
4651   -- Containing_Package_With_Ext_Axioms --
4652   ----------------------------------------
4653
4654   function Containing_Package_With_Ext_Axioms
4655     (E : Entity_Id) return Entity_Id
4656   is
4657   begin
4658      --  E is the package or generic package which is externally axiomatized
4659
4660      if Is_Package_Or_Generic_Package (E)
4661        and then Has_Annotate_Pragma_For_External_Axiomatization (E)
4662      then
4663         return E;
4664      end if;
4665
4666      --  If E's scope is axiomatized, E is axiomatized
4667
4668      if Present (Scope (E)) then
4669         declare
4670            First_Ax_Parent_Scope : constant Entity_Id :=
4671              Containing_Package_With_Ext_Axioms (Scope (E));
4672         begin
4673            if Present (First_Ax_Parent_Scope) then
4674               return First_Ax_Parent_Scope;
4675            end if;
4676         end;
4677      end if;
4678
4679      --  Otherwise, if E is a package instance, it is axiomatized if the
4680      --  corresponding generic package is axiomatized.
4681
4682      if Ekind (E) = E_Package then
4683         declare
4684            Par  : constant Node_Id := Parent (E);
4685            Decl : Node_Id;
4686
4687         begin
4688            if Nkind (Par) = N_Defining_Program_Unit_Name then
4689               Decl := Parent (Par);
4690            else
4691               Decl := Par;
4692            end if;
4693
4694            if Present (Generic_Parent (Decl)) then
4695               return
4696                 Containing_Package_With_Ext_Axioms (Generic_Parent (Decl));
4697            end if;
4698         end;
4699      end if;
4700
4701      return Empty;
4702   end Containing_Package_With_Ext_Axioms;
4703
4704   -------------------------------
4705   -- Convert_To_Actual_Subtype --
4706   -------------------------------
4707
4708   procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is
4709      Act_ST : Entity_Id;
4710
4711   begin
4712      Act_ST := Get_Actual_Subtype (Exp);
4713
4714      if Act_ST = Etype (Exp) then
4715         return;
4716      else
4717         Rewrite (Exp, Convert_To (Act_ST, Relocate_Node (Exp)));
4718         Analyze_And_Resolve (Exp, Act_ST);
4719      end if;
4720   end Convert_To_Actual_Subtype;
4721
4722   -----------------------------------
4723   -- Corresponding_Runtime_Package --
4724   -----------------------------------
4725
4726   function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is
4727      function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean;
4728      --  Return True if protected type T has one entry and the maximum queue
4729      --  length is one.
4730
4731      --------------------------------
4732      -- Has_One_Entry_And_No_Queue --
4733      --------------------------------
4734
4735      function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean is
4736         Item     : Entity_Id;
4737         Is_First : Boolean := True;
4738
4739      begin
4740         Item := First_Entity (T);
4741         while Present (Item) loop
4742            if Is_Entry (Item) then
4743
4744               --  The protected type has more than one entry
4745
4746               if not Is_First then
4747                  return False;
4748               end if;
4749
4750               --  The queue length is not one
4751
4752               if not Restriction_Active (No_Entry_Queue)
4753                 and then Get_Max_Queue_Length (Item) /= Uint_1
4754               then
4755                  return False;
4756               end if;
4757
4758               Is_First := False;
4759            end if;
4760
4761            Next_Entity (Item);
4762         end loop;
4763
4764         return True;
4765      end Has_One_Entry_And_No_Queue;
4766
4767      --  Local variables
4768
4769      Pkg_Id : RTU_Id := RTU_Null;
4770
4771   --  Start of processing for Corresponding_Runtime_Package
4772
4773   begin
4774      pragma Assert (Is_Concurrent_Type (Typ));
4775
4776      if Is_Protected_Type (Typ) then
4777         if Has_Entries (Typ)
4778
4779            --  A protected type without entries that covers an interface and
4780            --  overrides the abstract routines with protected procedures is
4781            --  considered equivalent to a protected type with entries in the
4782            --  context of dispatching select statements. It is sufficient to
4783            --  check for the presence of an interface list in the declaration
4784            --  node to recognize this case.
4785
4786           or else Present (Interface_List (Parent (Typ)))
4787
4788            --  Protected types with interrupt handlers (when not using a
4789            --  restricted profile) are also considered equivalent to
4790            --  protected types with entries. The types which are used
4791            --  (Static_Interrupt_Protection and Dynamic_Interrupt_Protection)
4792            --  are derived from Protection_Entries.
4793
4794           or else (Has_Attach_Handler (Typ) and then not Restricted_Profile)
4795           or else Has_Interrupt_Handler (Typ)
4796         then
4797            if Abort_Allowed
4798              or else Restriction_Active (No_Select_Statements) = False
4799              or else not Has_One_Entry_And_No_Queue (Typ)
4800              or else (Has_Attach_Handler (Typ)
4801                        and then not Restricted_Profile)
4802            then
4803               Pkg_Id := System_Tasking_Protected_Objects_Entries;
4804            else
4805               Pkg_Id := System_Tasking_Protected_Objects_Single_Entry;
4806            end if;
4807
4808         else
4809            Pkg_Id := System_Tasking_Protected_Objects;
4810         end if;
4811      end if;
4812
4813      return Pkg_Id;
4814   end Corresponding_Runtime_Package;
4815
4816   -----------------------------------
4817   -- Current_Sem_Unit_Declarations --
4818   -----------------------------------
4819
4820   function Current_Sem_Unit_Declarations return List_Id is
4821      U     : Node_Id := Unit (Cunit (Current_Sem_Unit));
4822      Decls : List_Id;
4823
4824   begin
4825      --  If the current unit is a package body, locate the visible
4826      --  declarations of the package spec.
4827
4828      if Nkind (U) = N_Package_Body then
4829         U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
4830      end if;
4831
4832      if Nkind (U) = N_Package_Declaration then
4833         U := Specification (U);
4834         Decls := Visible_Declarations (U);
4835
4836         if No (Decls) then
4837            Decls := New_List;
4838            Set_Visible_Declarations (U, Decls);
4839         end if;
4840
4841      else
4842         Decls := Declarations (U);
4843
4844         if No (Decls) then
4845            Decls := New_List;
4846            Set_Declarations (U, Decls);
4847         end if;
4848      end if;
4849
4850      return Decls;
4851   end Current_Sem_Unit_Declarations;
4852
4853   -----------------------
4854   -- Duplicate_Subexpr --
4855   -----------------------
4856
4857   function Duplicate_Subexpr
4858     (Exp          : Node_Id;
4859      Name_Req     : Boolean := False;
4860      Renaming_Req : Boolean := False) return Node_Id
4861   is
4862   begin
4863      Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
4864      return New_Copy_Tree (Exp);
4865   end Duplicate_Subexpr;
4866
4867   ---------------------------------
4868   -- Duplicate_Subexpr_No_Checks --
4869   ---------------------------------
4870
4871   function Duplicate_Subexpr_No_Checks
4872     (Exp           : Node_Id;
4873      Name_Req      : Boolean   := False;
4874      Renaming_Req  : Boolean   := False;
4875      Related_Id    : Entity_Id := Empty;
4876      Is_Low_Bound  : Boolean   := False;
4877      Is_High_Bound : Boolean   := False) return Node_Id
4878   is
4879      New_Exp : Node_Id;
4880
4881   begin
4882      Remove_Side_Effects
4883        (Exp           => Exp,
4884         Name_Req      => Name_Req,
4885         Renaming_Req  => Renaming_Req,
4886         Related_Id    => Related_Id,
4887         Is_Low_Bound  => Is_Low_Bound,
4888         Is_High_Bound => Is_High_Bound);
4889
4890      New_Exp := New_Copy_Tree (Exp);
4891      Remove_Checks (New_Exp);
4892      return New_Exp;
4893   end Duplicate_Subexpr_No_Checks;
4894
4895   -----------------------------------
4896   -- Duplicate_Subexpr_Move_Checks --
4897   -----------------------------------
4898
4899   function Duplicate_Subexpr_Move_Checks
4900     (Exp          : Node_Id;
4901      Name_Req     : Boolean := False;
4902      Renaming_Req : Boolean := False) return Node_Id
4903   is
4904      New_Exp : Node_Id;
4905
4906   begin
4907      Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
4908      New_Exp := New_Copy_Tree (Exp);
4909      Remove_Checks (Exp);
4910      return New_Exp;
4911   end Duplicate_Subexpr_Move_Checks;
4912
4913   -------------------------
4914   -- Enclosing_Init_Proc --
4915   -------------------------
4916
4917   function Enclosing_Init_Proc return Entity_Id is
4918      S : Entity_Id;
4919
4920   begin
4921      S := Current_Scope;
4922      while Present (S) and then S /= Standard_Standard loop
4923         if Is_Init_Proc (S) then
4924            return S;
4925         else
4926            S := Scope (S);
4927         end if;
4928      end loop;
4929
4930      return Empty;
4931   end Enclosing_Init_Proc;
4932
4933   --------------------
4934   -- Ensure_Defined --
4935   --------------------
4936
4937   procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
4938      IR : Node_Id;
4939
4940   begin
4941      --  An itype reference must only be created if this is a local itype, so
4942      --  that gigi can elaborate it on the proper objstack.
4943
4944      if Is_Itype (Typ) and then Scope (Typ) = Current_Scope then
4945         IR := Make_Itype_Reference (Sloc (N));
4946         Set_Itype (IR, Typ);
4947         Insert_Action (N, IR);
4948      end if;
4949   end Ensure_Defined;
4950
4951   --------------------
4952   -- Entry_Names_OK --
4953   --------------------
4954
4955   function Entry_Names_OK return Boolean is
4956   begin
4957      return
4958        not Restricted_Profile
4959          and then not Global_Discard_Names
4960          and then not Restriction_Active (No_Implicit_Heap_Allocations)
4961          and then not Restriction_Active (No_Local_Allocators);
4962   end Entry_Names_OK;
4963
4964   -------------------
4965   -- Evaluate_Name --
4966   -------------------
4967
4968   procedure Evaluate_Name (Nam : Node_Id) is
4969   begin
4970      --  For an attribute reference or an indexed component, evaluate the
4971      --  prefix, which is itself a name, recursively, and then force the
4972      --  evaluation of all the subscripts (or attribute expressions).
4973
4974      case Nkind (Nam) is
4975         when N_Attribute_Reference
4976            | N_Indexed_Component
4977         =>
4978            Evaluate_Name (Prefix (Nam));
4979
4980            declare
4981               E : Node_Id;
4982
4983            begin
4984               E := First (Expressions (Nam));
4985               while Present (E) loop
4986                  Force_Evaluation (E);
4987
4988                  if Is_Rewrite_Substitution (E) then
4989                     Set_Do_Range_Check
4990                       (E, Do_Range_Check (Original_Node (E)));
4991                  end if;
4992
4993                  Next (E);
4994               end loop;
4995            end;
4996
4997         --  For an explicit dereference, we simply force the evaluation of
4998         --  the name expression. The dereference provides a value that is the
4999         --  address for the renamed object, and it is precisely this value
5000         --  that we want to preserve.
5001
5002         when N_Explicit_Dereference =>
5003            Force_Evaluation (Prefix (Nam));
5004
5005         --  For a function call, we evaluate the call
5006
5007         when N_Function_Call =>
5008            Force_Evaluation (Nam);
5009
5010         --  For a qualified expression, we evaluate the underlying object
5011         --  name if any, otherwise we force the evaluation of the underlying
5012         --  expression.
5013
5014         when N_Qualified_Expression =>
5015            if Is_Object_Reference (Expression (Nam)) then
5016               Evaluate_Name (Expression (Nam));
5017            else
5018               Force_Evaluation (Expression (Nam));
5019            end if;
5020
5021         --  For a selected component, we simply evaluate the prefix
5022
5023         when N_Selected_Component =>
5024            Evaluate_Name (Prefix (Nam));
5025
5026         --  For a slice, we evaluate the prefix, as for the indexed component
5027         --  case and then, if there is a range present, either directly or as
5028         --  the constraint of a discrete subtype indication, we evaluate the
5029         --  two bounds of this range.
5030
5031         when N_Slice =>
5032            Evaluate_Name (Prefix (Nam));
5033            Evaluate_Slice_Bounds (Nam);
5034
5035         --  For a type conversion, the expression of the conversion must be
5036         --  the name of an object, and we simply need to evaluate this name.
5037
5038         when N_Type_Conversion =>
5039            Evaluate_Name (Expression (Nam));
5040
5041         --  The remaining cases are direct name, operator symbol and character
5042         --  literal. In all these cases, we do nothing, since we want to
5043         --  reevaluate each time the renamed object is used.
5044
5045         when others =>
5046            null;
5047      end case;
5048   end Evaluate_Name;
5049
5050   ---------------------------
5051   -- Evaluate_Slice_Bounds --
5052   ---------------------------
5053
5054   procedure Evaluate_Slice_Bounds (Slice : Node_Id) is
5055      DR     : constant Node_Id := Discrete_Range (Slice);
5056      Constr : Node_Id;
5057      Rexpr  : Node_Id;
5058
5059   begin
5060      if Nkind (DR) = N_Range then
5061         Force_Evaluation (Low_Bound (DR));
5062         Force_Evaluation (High_Bound (DR));
5063
5064      elsif Nkind (DR) = N_Subtype_Indication then
5065         Constr := Constraint (DR);
5066
5067         if Nkind (Constr) = N_Range_Constraint then
5068            Rexpr := Range_Expression (Constr);
5069
5070            Force_Evaluation (Low_Bound (Rexpr));
5071            Force_Evaluation (High_Bound (Rexpr));
5072         end if;
5073      end if;
5074   end Evaluate_Slice_Bounds;
5075
5076   ---------------------
5077   -- Evolve_And_Then --
5078   ---------------------
5079
5080   procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
5081   begin
5082      if No (Cond) then
5083         Cond := Cond1;
5084      else
5085         Cond :=
5086           Make_And_Then (Sloc (Cond1),
5087             Left_Opnd  => Cond,
5088             Right_Opnd => Cond1);
5089      end if;
5090   end Evolve_And_Then;
5091
5092   --------------------
5093   -- Evolve_Or_Else --
5094   --------------------
5095
5096   procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
5097   begin
5098      if No (Cond) then
5099         Cond := Cond1;
5100      else
5101         Cond :=
5102           Make_Or_Else (Sloc (Cond1),
5103             Left_Opnd  => Cond,
5104             Right_Opnd => Cond1);
5105      end if;
5106   end Evolve_Or_Else;
5107
5108   -----------------------------------------
5109   -- Expand_Static_Predicates_In_Choices --
5110   -----------------------------------------
5111
5112   procedure Expand_Static_Predicates_In_Choices (N : Node_Id) is
5113      pragma Assert (Nkind_In (N, N_Case_Statement_Alternative, N_Variant));
5114
5115      Choices : constant List_Id := Discrete_Choices (N);
5116
5117      Choice : Node_Id;
5118      Next_C : Node_Id;
5119      P      : Node_Id;
5120      C      : Node_Id;
5121
5122   begin
5123      Choice := First (Choices);
5124      while Present (Choice) loop
5125         Next_C := Next (Choice);
5126
5127         --  Check for name of subtype with static predicate
5128
5129         if Is_Entity_Name (Choice)
5130           and then Is_Type (Entity (Choice))
5131           and then Has_Predicates (Entity (Choice))
5132         then
5133            --  Loop through entries in predicate list, converting to choices
5134            --  and inserting in the list before the current choice. Note that
5135            --  if the list is empty, corresponding to a False predicate, then
5136            --  no choices are inserted.
5137
5138            P := First (Static_Discrete_Predicate (Entity (Choice)));
5139            while Present (P) loop
5140
5141               --  If low bound and high bounds are equal, copy simple choice
5142
5143               if Expr_Value (Low_Bound (P)) = Expr_Value (High_Bound (P)) then
5144                  C := New_Copy (Low_Bound (P));
5145
5146               --  Otherwise copy a range
5147
5148               else
5149                  C := New_Copy (P);
5150               end if;
5151
5152               --  Change Sloc to referencing choice (rather than the Sloc of
5153               --  the predicate declaration element itself).
5154
5155               Set_Sloc (C, Sloc (Choice));
5156               Insert_Before (Choice, C);
5157               Next (P);
5158            end loop;
5159
5160            --  Delete the predicated entry
5161
5162            Remove (Choice);
5163         end if;
5164
5165         --  Move to next choice to check
5166
5167         Choice := Next_C;
5168      end loop;
5169
5170      Set_Has_SP_Choice (N, False);
5171   end Expand_Static_Predicates_In_Choices;
5172
5173   ------------------------------
5174   -- Expand_Subtype_From_Expr --
5175   ------------------------------
5176
5177   --  This function is applicable for both static and dynamic allocation of
5178   --  objects which are constrained by an initial expression. Basically it
5179   --  transforms an unconstrained subtype indication into a constrained one.
5180
5181   --  The expression may also be transformed in certain cases in order to
5182   --  avoid multiple evaluation. In the static allocation case, the general
5183   --  scheme is:
5184
5185   --     Val : T := Expr;
5186
5187   --        is transformed into
5188
5189   --     Val : Constrained_Subtype_Of_T := Maybe_Modified_Expr;
5190   --
5191   --  Here are the main cases :
5192   --
5193   --  <if Expr is a Slice>
5194   --    Val : T ([Index_Subtype (Expr)]) := Expr;
5195   --
5196   --  <elsif Expr is a String Literal>
5197   --    Val : T (T'First .. T'First + Length (string literal) - 1) := Expr;
5198   --
5199   --  <elsif Expr is Constrained>
5200   --    subtype T is Type_Of_Expr
5201   --    Val : T := Expr;
5202   --
5203   --  <elsif Expr is an entity_name>
5204   --    Val : T (constraints taken from Expr) := Expr;
5205   --
5206   --  <else>
5207   --    type Axxx is access all T;
5208   --    Rval : Axxx := Expr'ref;
5209   --    Val  : T (constraints taken from Rval) := Rval.all;
5210
5211   --    ??? note: when the Expression is allocated in the secondary stack
5212   --              we could use it directly instead of copying it by declaring
5213   --              Val : T (...) renames Rval.all
5214
5215   procedure Expand_Subtype_From_Expr
5216     (N             : Node_Id;
5217      Unc_Type      : Entity_Id;
5218      Subtype_Indic : Node_Id;
5219      Exp           : Node_Id;
5220      Related_Id    : Entity_Id := Empty)
5221   is
5222      Loc     : constant Source_Ptr := Sloc (N);
5223      Exp_Typ : constant Entity_Id  := Etype (Exp);
5224      T       : Entity_Id;
5225
5226   begin
5227      --  In general we cannot build the subtype if expansion is disabled,
5228      --  because internal entities may not have been defined. However, to
5229      --  avoid some cascaded errors, we try to continue when the expression is
5230      --  an array (or string), because it is safe to compute the bounds. It is
5231      --  in fact required to do so even in a generic context, because there
5232      --  may be constants that depend on the bounds of a string literal, both
5233      --  standard string types and more generally arrays of characters.
5234
5235      --  In GNATprove mode, these extra subtypes are not needed, unless Exp is
5236      --  a static expression. In that case, the subtype will be constrained
5237      --  while the original type might be unconstrained, so expanding the type
5238      --  is necessary both for passing legality checks in GNAT and for precise
5239      --  analysis in GNATprove.
5240
5241      if GNATprove_Mode and then not Is_Static_Expression (Exp) then
5242         return;
5243      end if;
5244
5245      if not Expander_Active
5246        and then (No (Etype (Exp)) or else not Is_String_Type (Etype (Exp)))
5247      then
5248         return;
5249      end if;
5250
5251      if Nkind (Exp) = N_Slice then
5252         declare
5253            Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
5254
5255         begin
5256            Rewrite (Subtype_Indic,
5257              Make_Subtype_Indication (Loc,
5258                Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
5259                Constraint =>
5260                  Make_Index_Or_Discriminant_Constraint (Loc,
5261                    Constraints => New_List
5262                      (New_Occurrence_Of (Slice_Type, Loc)))));
5263
5264            --  This subtype indication may be used later for constraint checks
5265            --  we better make sure that if a variable was used as a bound of
5266            --  the original slice, its value is frozen.
5267
5268            Evaluate_Slice_Bounds (Exp);
5269         end;
5270
5271      elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
5272         Rewrite (Subtype_Indic,
5273           Make_Subtype_Indication (Loc,
5274             Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
5275             Constraint =>
5276               Make_Index_Or_Discriminant_Constraint (Loc,
5277                 Constraints => New_List (
5278                   Make_Literal_Range (Loc,
5279                     Literal_Typ => Exp_Typ)))));
5280
5281      --  If the type of the expression is an internally generated type it
5282      --  may not be necessary to create a new subtype. However there are two
5283      --  exceptions: references to the current instances, and aliased array
5284      --  object declarations for which the back end has to create a template.
5285
5286      elsif Is_Constrained (Exp_Typ)
5287        and then not Is_Class_Wide_Type (Unc_Type)
5288        and then
5289          (Nkind (N) /= N_Object_Declaration
5290            or else not Is_Entity_Name (Expression (N))
5291            or else not Comes_From_Source (Entity (Expression (N)))
5292            or else not Is_Array_Type (Exp_Typ)
5293            or else not Aliased_Present (N))
5294      then
5295         if Is_Itype (Exp_Typ) then
5296
5297            --  Within an initialization procedure, a selected component
5298            --  denotes a component of the enclosing record, and it appears as
5299            --  an actual in a call to its own initialization procedure. If
5300            --  this component depends on the outer discriminant, we must
5301            --  generate the proper actual subtype for it.
5302
5303            if Nkind (Exp) = N_Selected_Component
5304              and then Within_Init_Proc
5305            then
5306               declare
5307                  Decl : constant Node_Id :=
5308                           Build_Actual_Subtype_Of_Component (Exp_Typ, Exp);
5309               begin
5310                  if Present (Decl) then
5311                     Insert_Action (N, Decl);
5312                     T := Defining_Identifier (Decl);
5313                  else
5314                     T := Exp_Typ;
5315                  end if;
5316               end;
5317
5318            --  No need to generate a new subtype
5319
5320            else
5321               T := Exp_Typ;
5322            end if;
5323
5324         else
5325            T := Make_Temporary (Loc, 'T');
5326
5327            Insert_Action (N,
5328              Make_Subtype_Declaration (Loc,
5329                Defining_Identifier => T,
5330                Subtype_Indication  => New_Occurrence_Of (Exp_Typ, Loc)));
5331
5332            --  This type is marked as an itype even though it has an explicit
5333            --  declaration since otherwise Is_Generic_Actual_Type can get
5334            --  set, resulting in the generation of spurious errors. (See
5335            --  sem_ch8.Analyze_Package_Renaming and sem_type.covers)
5336
5337            Set_Is_Itype (T);
5338            Set_Associated_Node_For_Itype (T, Exp);
5339         end if;
5340
5341         Rewrite (Subtype_Indic, New_Occurrence_Of (T, Loc));
5342
5343      --  Nothing needs to be done for private types with unknown discriminants
5344      --  if the underlying type is not an unconstrained composite type or it
5345      --  is an unchecked union.
5346
5347      elsif Is_Private_Type (Unc_Type)
5348        and then Has_Unknown_Discriminants (Unc_Type)
5349        and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
5350                   or else Is_Constrained (Underlying_Type (Unc_Type))
5351                   or else Is_Unchecked_Union (Underlying_Type (Unc_Type)))
5352      then
5353         null;
5354
5355      --  Case of derived type with unknown discriminants where the parent type
5356      --  also has unknown discriminants.
5357
5358      elsif Is_Record_Type (Unc_Type)
5359        and then not Is_Class_Wide_Type (Unc_Type)
5360        and then Has_Unknown_Discriminants (Unc_Type)
5361        and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type))
5362      then
5363         --  Nothing to be done if no underlying record view available
5364
5365         --  If this is a limited type derived from a type with unknown
5366         --  discriminants, do not expand either, so that subsequent expansion
5367         --  of the call can add build-in-place parameters to call.
5368
5369         if No (Underlying_Record_View (Unc_Type))
5370           or else Is_Limited_Type (Unc_Type)
5371         then
5372            null;
5373
5374         --  Otherwise use the Underlying_Record_View to create the proper
5375         --  constrained subtype for an object of a derived type with unknown
5376         --  discriminants.
5377
5378         else
5379            Remove_Side_Effects (Exp);
5380            Rewrite (Subtype_Indic,
5381              Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type)));
5382         end if;
5383
5384      --  Renamings of class-wide interface types require no equivalent
5385      --  constrained type declarations because we only need to reference
5386      --  the tag component associated with the interface. The same is
5387      --  presumably true for class-wide types in general, so this test
5388      --  is broadened to include all class-wide renamings, which also
5389      --  avoids cases of unbounded recursion in Remove_Side_Effects.
5390      --  (Is this really correct, or are there some cases of class-wide
5391      --  renamings that require action in this procedure???)
5392
5393      elsif Present (N)
5394        and then Nkind (N) = N_Object_Renaming_Declaration
5395        and then Is_Class_Wide_Type (Unc_Type)
5396      then
5397         null;
5398
5399      --  In Ada 95 nothing to be done if the type of the expression is limited
5400      --  because in this case the expression cannot be copied, and its use can
5401      --  only be by reference.
5402
5403      --  In Ada 2005 the context can be an object declaration whose expression
5404      --  is a function that returns in place. If the nominal subtype has
5405      --  unknown discriminants, the call still provides constraints on the
5406      --  object, and we have to create an actual subtype from it.
5407
5408      --  If the type is class-wide, the expression is dynamically tagged and
5409      --  we do not create an actual subtype either. Ditto for an interface.
5410      --  For now this applies only if the type is immutably limited, and the
5411      --  function being called is build-in-place. This will have to be revised
5412      --  when build-in-place functions are generalized to other types.
5413
5414      elsif Is_Limited_View (Exp_Typ)
5415        and then
5416         (Is_Class_Wide_Type (Exp_Typ)
5417           or else Is_Interface (Exp_Typ)
5418           or else not Has_Unknown_Discriminants (Exp_Typ)
5419           or else not Is_Composite_Type (Unc_Type))
5420      then
5421         null;
5422
5423      --  For limited objects initialized with build in place function calls,
5424      --  nothing to be done; otherwise we prematurely introduce an N_Reference
5425      --  node in the expression initializing the object, which breaks the
5426      --  circuitry that detects and adds the additional arguments to the
5427      --  called function.
5428
5429      elsif Is_Build_In_Place_Function_Call (Exp) then
5430         null;
5431
5432      else
5433         Remove_Side_Effects (Exp);
5434         Rewrite (Subtype_Indic,
5435           Make_Subtype_From_Expr (Exp, Unc_Type, Related_Id));
5436      end if;
5437   end Expand_Subtype_From_Expr;
5438
5439   ---------------------------------------------
5440   -- Expression_Contains_Primitives_Calls_Of --
5441   ---------------------------------------------
5442
5443   function Expression_Contains_Primitives_Calls_Of
5444     (Expr : Node_Id;
5445      Typ  : Entity_Id) return Boolean
5446   is
5447      U_Typ : constant Entity_Id := Unique_Entity (Typ);
5448
5449      Calls_OK : Boolean := False;
5450      --  This flag is set to True when expression Expr contains at least one
5451      --  call to a nondispatching primitive function of Typ.
5452
5453      function Search_Primitive_Calls (N : Node_Id) return Traverse_Result;
5454      --  Search for nondispatching calls to primitive functions of type Typ
5455
5456      ----------------------------
5457      -- Search_Primitive_Calls --
5458      ----------------------------
5459
5460      function Search_Primitive_Calls (N : Node_Id) return Traverse_Result is
5461         Disp_Typ : Entity_Id;
5462         Subp     : Entity_Id;
5463
5464      begin
5465         --  Detect a function call that could denote a nondispatching
5466         --  primitive of the input type.
5467
5468         if Nkind (N) = N_Function_Call
5469           and then Is_Entity_Name (Name (N))
5470         then
5471            Subp := Entity (Name (N));
5472
5473            --  Do not consider function calls with a controlling argument, as
5474            --  those are always dispatching calls.
5475
5476            if Is_Dispatching_Operation (Subp)
5477              and then No (Controlling_Argument (N))
5478            then
5479               Disp_Typ := Find_Dispatching_Type (Subp);
5480
5481               --  To qualify as a suitable primitive, the dispatching type of
5482               --  the function must be the input type.
5483
5484               if Present (Disp_Typ)
5485                 and then Unique_Entity (Disp_Typ) = U_Typ
5486               then
5487                  Calls_OK := True;
5488
5489                  --  There is no need to continue the traversal, as one such
5490                  --  call suffices.
5491
5492                  return Abandon;
5493               end if;
5494            end if;
5495         end if;
5496
5497         return OK;
5498      end Search_Primitive_Calls;
5499
5500      procedure Search_Calls is new Traverse_Proc (Search_Primitive_Calls);
5501
5502   --  Start of processing for Expression_Contains_Primitives_Calls_Of_Type
5503
5504   begin
5505      Search_Calls (Expr);
5506      return Calls_OK;
5507   end Expression_Contains_Primitives_Calls_Of;
5508
5509   ----------------------
5510   -- Finalize_Address --
5511   ----------------------
5512
5513   function Finalize_Address (Typ : Entity_Id) return Entity_Id is
5514      Btyp : constant Entity_Id := Base_Type (Typ);
5515      Utyp : Entity_Id := Typ;
5516
5517   begin
5518      --  Handle protected class-wide or task class-wide types
5519
5520      if Is_Class_Wide_Type (Utyp) then
5521         if Is_Concurrent_Type (Root_Type (Utyp)) then
5522            Utyp := Root_Type (Utyp);
5523
5524         elsif Is_Private_Type (Root_Type (Utyp))
5525           and then Present (Full_View (Root_Type (Utyp)))
5526           and then Is_Concurrent_Type (Full_View (Root_Type (Utyp)))
5527         then
5528            Utyp := Full_View (Root_Type (Utyp));
5529         end if;
5530      end if;
5531
5532      --  Handle private types
5533
5534      if Is_Private_Type (Utyp) and then Present (Full_View (Utyp)) then
5535         Utyp := Full_View (Utyp);
5536      end if;
5537
5538      --  Handle protected and task types
5539
5540      if Is_Concurrent_Type (Utyp)
5541        and then Present (Corresponding_Record_Type (Utyp))
5542      then
5543         Utyp := Corresponding_Record_Type (Utyp);
5544      end if;
5545
5546      Utyp := Underlying_Type (Base_Type (Utyp));
5547
5548      --  Deal with untagged derivation of private views. If the parent is
5549      --  now known to be protected, the finalization routine is the one
5550      --  defined on the corresponding record of the ancestor (corresponding
5551      --  records do not automatically inherit operations, but maybe they
5552      --  should???)
5553
5554      if Is_Untagged_Derivation (Btyp) then
5555         if Is_Protected_Type (Btyp) then
5556            Utyp := Corresponding_Record_Type (Root_Type (Btyp));
5557
5558         else
5559            Utyp := Underlying_Type (Root_Type (Btyp));
5560
5561            if Is_Protected_Type (Utyp) then
5562               Utyp := Corresponding_Record_Type (Utyp);
5563            end if;
5564         end if;
5565      end if;
5566
5567      --  If the underlying_type is a subtype, we are dealing with the
5568      --  completion of a private type. We need to access the base type and
5569      --  generate a conversion to it.
5570
5571      if Utyp /= Base_Type (Utyp) then
5572         pragma Assert (Is_Private_Type (Typ));
5573
5574         Utyp := Base_Type (Utyp);
5575      end if;
5576
5577      --  When dealing with an internally built full view for a type with
5578      --  unknown discriminants, use the original record type.
5579
5580      if Is_Underlying_Record_View (Utyp) then
5581         Utyp := Etype (Utyp);
5582      end if;
5583
5584      return TSS (Utyp, TSS_Finalize_Address);
5585   end Finalize_Address;
5586
5587   ------------------------
5588   -- Find_Interface_ADT --
5589   ------------------------
5590
5591   function Find_Interface_ADT
5592     (T     : Entity_Id;
5593      Iface : Entity_Id) return Elmt_Id
5594   is
5595      ADT : Elmt_Id;
5596      Typ : Entity_Id := T;
5597
5598   begin
5599      pragma Assert (Is_Interface (Iface));
5600
5601      --  Handle private types
5602
5603      if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
5604         Typ := Full_View (Typ);
5605      end if;
5606
5607      --  Handle access types
5608
5609      if Is_Access_Type (Typ) then
5610         Typ := Designated_Type (Typ);
5611      end if;
5612
5613      --  Handle task and protected types implementing interfaces
5614
5615      if Is_Concurrent_Type (Typ) then
5616         Typ := Corresponding_Record_Type (Typ);
5617      end if;
5618
5619      pragma Assert
5620        (not Is_Class_Wide_Type (Typ)
5621          and then Ekind (Typ) /= E_Incomplete_Type);
5622
5623      if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
5624         return First_Elmt (Access_Disp_Table (Typ));
5625
5626      else
5627         ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
5628         while Present (ADT)
5629           and then Present (Related_Type (Node (ADT)))
5630           and then Related_Type (Node (ADT)) /= Iface
5631           and then not Is_Ancestor (Iface, Related_Type (Node (ADT)),
5632                                     Use_Full_View => True)
5633         loop
5634            Next_Elmt (ADT);
5635         end loop;
5636
5637         pragma Assert (Present (Related_Type (Node (ADT))));
5638         return ADT;
5639      end if;
5640   end Find_Interface_ADT;
5641
5642   ------------------------
5643   -- Find_Interface_Tag --
5644   ------------------------
5645
5646   function Find_Interface_Tag
5647     (T     : Entity_Id;
5648      Iface : Entity_Id) return Entity_Id
5649   is
5650      AI_Tag : Entity_Id := Empty;
5651      Found  : Boolean   := False;
5652      Typ    : Entity_Id := T;
5653
5654      procedure Find_Tag (Typ : Entity_Id);
5655      --  Internal subprogram used to recursively climb to the ancestors
5656
5657      --------------
5658      -- Find_Tag --
5659      --------------
5660
5661      procedure Find_Tag (Typ : Entity_Id) is
5662         AI_Elmt : Elmt_Id;
5663         AI      : Node_Id;
5664
5665      begin
5666         --  This routine does not handle the case in which the interface is an
5667         --  ancestor of Typ. That case is handled by the enclosing subprogram.
5668
5669         pragma Assert (Typ /= Iface);
5670
5671         --  Climb to the root type handling private types
5672
5673         if Present (Full_View (Etype (Typ))) then
5674            if Full_View (Etype (Typ)) /= Typ then
5675               Find_Tag (Full_View (Etype (Typ)));
5676            end if;
5677
5678         elsif Etype (Typ) /= Typ then
5679            Find_Tag (Etype (Typ));
5680         end if;
5681
5682         --  Traverse the list of interfaces implemented by the type
5683
5684         if not Found
5685           and then Present (Interfaces (Typ))
5686           and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
5687         then
5688            --  Skip the tag associated with the primary table
5689
5690            AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
5691            pragma Assert (Present (AI_Tag));
5692
5693            AI_Elmt := First_Elmt (Interfaces (Typ));
5694            while Present (AI_Elmt) loop
5695               AI := Node (AI_Elmt);
5696
5697               if AI = Iface
5698                 or else Is_Ancestor (Iface, AI, Use_Full_View => True)
5699               then
5700                  Found := True;
5701                  return;
5702               end if;
5703
5704               AI_Tag := Next_Tag_Component (AI_Tag);
5705               Next_Elmt (AI_Elmt);
5706            end loop;
5707         end if;
5708      end Find_Tag;
5709
5710   --  Start of processing for Find_Interface_Tag
5711
5712   begin
5713      pragma Assert (Is_Interface (Iface));
5714
5715      --  Handle access types
5716
5717      if Is_Access_Type (Typ) then
5718         Typ := Designated_Type (Typ);
5719      end if;
5720
5721      --  Handle class-wide types
5722
5723      if Is_Class_Wide_Type (Typ) then
5724         Typ := Root_Type (Typ);
5725      end if;
5726
5727      --  Handle private types
5728
5729      if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
5730         Typ := Full_View (Typ);
5731      end if;
5732
5733      --  Handle entities from the limited view
5734
5735      if Ekind (Typ) = E_Incomplete_Type then
5736         pragma Assert (Present (Non_Limited_View (Typ)));
5737         Typ := Non_Limited_View (Typ);
5738      end if;
5739
5740      --  Handle task and protected types implementing interfaces
5741
5742      if Is_Concurrent_Type (Typ) then
5743         Typ := Corresponding_Record_Type (Typ);
5744      end if;
5745
5746      --  If the interface is an ancestor of the type, then it shared the
5747      --  primary dispatch table.
5748
5749      if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
5750         return First_Tag_Component (Typ);
5751
5752      --  Otherwise we need to search for its associated tag component
5753
5754      else
5755         Find_Tag (Typ);
5756         return AI_Tag;
5757      end if;
5758   end Find_Interface_Tag;
5759
5760   ---------------------------
5761   -- Find_Optional_Prim_Op --
5762   ---------------------------
5763
5764   function Find_Optional_Prim_Op
5765     (T : Entity_Id; Name : Name_Id) return Entity_Id
5766   is
5767      Prim : Elmt_Id;
5768      Typ  : Entity_Id := T;
5769      Op   : Entity_Id;
5770
5771   begin
5772      if Is_Class_Wide_Type (Typ) then
5773         Typ := Root_Type (Typ);
5774      end if;
5775
5776      Typ := Underlying_Type (Typ);
5777
5778      --  Loop through primitive operations
5779
5780      Prim := First_Elmt (Primitive_Operations (Typ));
5781      while Present (Prim) loop
5782         Op := Node (Prim);
5783
5784         --  We can retrieve primitive operations by name if it is an internal
5785         --  name. For equality we must check that both of its operands have
5786         --  the same type, to avoid confusion with user-defined equalities
5787         --  than may have a asymmetric signature.
5788
5789         exit when Chars (Op) = Name
5790           and then
5791             (Name /= Name_Op_Eq
5792               or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op)));
5793
5794         Next_Elmt (Prim);
5795      end loop;
5796
5797      return Node (Prim); -- Empty if not found
5798   end Find_Optional_Prim_Op;
5799
5800   ---------------------------
5801   -- Find_Optional_Prim_Op --
5802   ---------------------------
5803
5804   function Find_Optional_Prim_Op
5805     (T    : Entity_Id;
5806      Name : TSS_Name_Type) return Entity_Id
5807   is
5808      Inher_Op  : Entity_Id := Empty;
5809      Own_Op    : Entity_Id := Empty;
5810      Prim_Elmt : Elmt_Id;
5811      Prim_Id   : Entity_Id;
5812      Typ       : Entity_Id := T;
5813
5814   begin
5815      if Is_Class_Wide_Type (Typ) then
5816         Typ := Root_Type (Typ);
5817      end if;
5818
5819      Typ := Underlying_Type (Typ);
5820
5821      --  This search is based on the assertion that the dispatching version
5822      --  of the TSS routine always precedes the real primitive.
5823
5824      Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
5825      while Present (Prim_Elmt) loop
5826         Prim_Id := Node (Prim_Elmt);
5827
5828         if Is_TSS (Prim_Id, Name) then
5829            if Present (Alias (Prim_Id)) then
5830               Inher_Op := Prim_Id;
5831            else
5832               Own_Op := Prim_Id;
5833            end if;
5834         end if;
5835
5836         Next_Elmt (Prim_Elmt);
5837      end loop;
5838
5839      if Present (Own_Op) then
5840         return Own_Op;
5841      elsif Present (Inher_Op) then
5842         return Inher_Op;
5843      else
5844         return Empty;
5845      end if;
5846   end Find_Optional_Prim_Op;
5847
5848   ------------------
5849   -- Find_Prim_Op --
5850   ------------------
5851
5852   function Find_Prim_Op
5853     (T : Entity_Id; Name : Name_Id) return Entity_Id
5854   is
5855      Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
5856   begin
5857      if No (Result) then
5858         raise Program_Error;
5859      end if;
5860
5861      return Result;
5862   end Find_Prim_Op;
5863
5864   ------------------
5865   -- Find_Prim_Op --
5866   ------------------
5867
5868   function Find_Prim_Op
5869     (T    : Entity_Id;
5870      Name : TSS_Name_Type) return Entity_Id
5871   is
5872      Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
5873   begin
5874      if No (Result) then
5875         raise Program_Error;
5876      end if;
5877
5878      return Result;
5879   end Find_Prim_Op;
5880
5881   ----------------------------
5882   -- Find_Protection_Object --
5883   ----------------------------
5884
5885   function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
5886      S : Entity_Id;
5887
5888   begin
5889      S := Scop;
5890      while Present (S) loop
5891         if Ekind_In (S, E_Entry, E_Entry_Family, E_Function, E_Procedure)
5892           and then Present (Protection_Object (S))
5893         then
5894            return Protection_Object (S);
5895         end if;
5896
5897         S := Scope (S);
5898      end loop;
5899
5900      --  If we do not find a Protection object in the scope chain, then
5901      --  something has gone wrong, most likely the object was never created.
5902
5903      raise Program_Error;
5904   end Find_Protection_Object;
5905
5906   --------------------------
5907   -- Find_Protection_Type --
5908   --------------------------
5909
5910   function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is
5911      Comp : Entity_Id;
5912      Typ  : Entity_Id := Conc_Typ;
5913
5914   begin
5915      if Is_Concurrent_Type (Typ) then
5916         Typ := Corresponding_Record_Type (Typ);
5917      end if;
5918
5919      --  Since restriction violations are not considered serious errors, the
5920      --  expander remains active, but may leave the corresponding record type
5921      --  malformed. In such cases, component _object is not available so do
5922      --  not look for it.
5923
5924      if not Analyzed (Typ) then
5925         return Empty;
5926      end if;
5927
5928      Comp := First_Component (Typ);
5929      while Present (Comp) loop
5930         if Chars (Comp) = Name_uObject then
5931            return Base_Type (Etype (Comp));
5932         end if;
5933
5934         Next_Component (Comp);
5935      end loop;
5936
5937      --  The corresponding record of a protected type should always have an
5938      --  _object field.
5939
5940      raise Program_Error;
5941   end Find_Protection_Type;
5942
5943   -----------------------
5944   -- Find_Hook_Context --
5945   -----------------------
5946
5947   function Find_Hook_Context (N : Node_Id) return Node_Id is
5948      Par : Node_Id;
5949      Top : Node_Id;
5950
5951      Wrapped_Node : Node_Id;
5952      --  Note: if we are in a transient scope, we want to reuse it as
5953      --  the context for actions insertion, if possible. But if N is itself
5954      --  part of the stored actions for the current transient scope,
5955      --  then we need to insert at the appropriate (inner) location in
5956      --  the not as an action on Node_To_Be_Wrapped.
5957
5958      In_Cond_Expr : constant Boolean := Within_Case_Or_If_Expression (N);
5959
5960   begin
5961      --  When the node is inside a case/if expression, the lifetime of any
5962      --  temporary controlled object is extended. Find a suitable insertion
5963      --  node by locating the topmost case or if expressions.
5964
5965      if In_Cond_Expr then
5966         Par := N;
5967         Top := N;
5968         while Present (Par) loop
5969            if Nkind_In (Original_Node (Par), N_Case_Expression,
5970                                              N_If_Expression)
5971            then
5972               Top := Par;
5973
5974            --  Prevent the search from going too far
5975
5976            elsif Is_Body_Or_Package_Declaration (Par) then
5977               exit;
5978            end if;
5979
5980            Par := Parent (Par);
5981         end loop;
5982
5983         --  The topmost case or if expression is now recovered, but it may
5984         --  still not be the correct place to add generated code. Climb to
5985         --  find a parent that is part of a declarative or statement list,
5986         --  and is not a list of actuals in a call.
5987
5988         Par := Top;
5989         while Present (Par) loop
5990            if Is_List_Member (Par)
5991              and then not Nkind_In (Par, N_Component_Association,
5992                                          N_Discriminant_Association,
5993                                          N_Parameter_Association,
5994                                          N_Pragma_Argument_Association)
5995              and then not Nkind_In (Parent (Par), N_Function_Call,
5996                                                   N_Procedure_Call_Statement,
5997                                                   N_Entry_Call_Statement)
5998
5999            then
6000               return Par;
6001
6002            --  Prevent the search from going too far
6003
6004            elsif Is_Body_Or_Package_Declaration (Par) then
6005               exit;
6006            end if;
6007
6008            Par := Parent (Par);
6009         end loop;
6010
6011         return Par;
6012
6013      else
6014         Par := N;
6015         while Present (Par) loop
6016
6017            --  Keep climbing past various operators
6018
6019            if Nkind (Parent (Par)) in N_Op
6020              or else Nkind_In (Parent (Par), N_And_Then, N_Or_Else)
6021            then
6022               Par := Parent (Par);
6023            else
6024               exit;
6025            end if;
6026         end loop;
6027
6028         Top := Par;
6029
6030         --  The node may be located in a pragma in which case return the
6031         --  pragma itself:
6032
6033         --    pragma Precondition (... and then Ctrl_Func_Call ...);
6034
6035         --  Similar case occurs when the node is related to an object
6036         --  declaration or assignment:
6037
6038         --    Obj [: Some_Typ] := ... and then Ctrl_Func_Call ...;
6039
6040         --  Another case to consider is when the node is part of a return
6041         --  statement:
6042
6043         --    return ... and then Ctrl_Func_Call ...;
6044
6045         --  Another case is when the node acts as a formal in a procedure
6046         --  call statement:
6047
6048         --    Proc (... and then Ctrl_Func_Call ...);
6049
6050         if Scope_Is_Transient then
6051            Wrapped_Node := Node_To_Be_Wrapped;
6052         else
6053            Wrapped_Node := Empty;
6054         end if;
6055
6056         while Present (Par) loop
6057            if Par = Wrapped_Node
6058              or else Nkind_In (Par, N_Assignment_Statement,
6059                                     N_Object_Declaration,
6060                                     N_Pragma,
6061                                     N_Procedure_Call_Statement,
6062                                     N_Simple_Return_Statement)
6063            then
6064               return Par;
6065
6066            --  Prevent the search from going too far
6067
6068            elsif Is_Body_Or_Package_Declaration (Par) then
6069               exit;
6070            end if;
6071
6072            Par := Parent (Par);
6073         end loop;
6074
6075         --  Return the topmost short circuit operator
6076
6077         return Top;
6078      end if;
6079   end Find_Hook_Context;
6080
6081   ------------------------------
6082   -- Following_Address_Clause --
6083   ------------------------------
6084
6085   function Following_Address_Clause (D : Node_Id) return Node_Id is
6086      Id     : constant Entity_Id := Defining_Identifier (D);
6087      Result : Node_Id;
6088      Par    : Node_Id;
6089
6090      function Check_Decls (D : Node_Id) return Node_Id;
6091      --  This internal function differs from the main function in that it
6092      --  gets called to deal with a following package private part, and
6093      --  it checks declarations starting with D (the main function checks
6094      --  declarations following D). If D is Empty, then Empty is returned.
6095
6096      -----------------
6097      -- Check_Decls --
6098      -----------------
6099
6100      function Check_Decls (D : Node_Id) return Node_Id is
6101         Decl : Node_Id;
6102
6103      begin
6104         Decl := D;
6105         while Present (Decl) loop
6106            if Nkind (Decl) = N_At_Clause
6107              and then Chars (Identifier (Decl)) = Chars (Id)
6108            then
6109               return Decl;
6110
6111            elsif Nkind (Decl) = N_Attribute_Definition_Clause
6112              and then Chars (Decl) = Name_Address
6113              and then Chars (Name (Decl)) = Chars (Id)
6114            then
6115               return Decl;
6116            end if;
6117
6118            Next (Decl);
6119         end loop;
6120
6121         --  Otherwise not found, return Empty
6122
6123         return Empty;
6124      end Check_Decls;
6125
6126      --  Start of processing for Following_Address_Clause
6127
6128   begin
6129      --  If parser detected no address clause for the identifier in question,
6130      --  then the answer is a quick NO, without the need for a search.
6131
6132      if not Get_Name_Table_Boolean1 (Chars (Id)) then
6133         return Empty;
6134      end if;
6135
6136      --  Otherwise search current declarative unit
6137
6138      Result := Check_Decls (Next (D));
6139
6140      if Present (Result) then
6141         return Result;
6142      end if;
6143
6144      --  Check for possible package private part following
6145
6146      Par := Parent (D);
6147
6148      if Nkind (Par) = N_Package_Specification
6149        and then Visible_Declarations (Par) = List_Containing (D)
6150        and then Present (Private_Declarations (Par))
6151      then
6152         --  Private part present, check declarations there
6153
6154         return Check_Decls (First (Private_Declarations (Par)));
6155
6156      else
6157         --  No private part, clause not found, return Empty
6158
6159         return Empty;
6160      end if;
6161   end Following_Address_Clause;
6162
6163   ----------------------
6164   -- Force_Evaluation --
6165   ----------------------
6166
6167   procedure Force_Evaluation
6168     (Exp           : Node_Id;
6169      Name_Req      : Boolean   := False;
6170      Related_Id    : Entity_Id := Empty;
6171      Is_Low_Bound  : Boolean   := False;
6172      Is_High_Bound : Boolean   := False;
6173      Mode          : Force_Evaluation_Mode := Relaxed)
6174   is
6175   begin
6176      Remove_Side_Effects
6177        (Exp                => Exp,
6178         Name_Req           => Name_Req,
6179         Variable_Ref       => True,
6180         Renaming_Req       => False,
6181         Related_Id         => Related_Id,
6182         Is_Low_Bound       => Is_Low_Bound,
6183         Is_High_Bound      => Is_High_Bound,
6184         Check_Side_Effects =>
6185           Is_Static_Expression (Exp)
6186             or else Mode = Relaxed);
6187   end Force_Evaluation;
6188
6189   ---------------------------------
6190   -- Fully_Qualified_Name_String --
6191   ---------------------------------
6192
6193   function Fully_Qualified_Name_String
6194     (E          : Entity_Id;
6195      Append_NUL : Boolean := True) return String_Id
6196   is
6197      procedure Internal_Full_Qualified_Name (E : Entity_Id);
6198      --  Compute recursively the qualified name without NUL at the end, adding
6199      --  it to the currently started string being generated
6200
6201      ----------------------------------
6202      -- Internal_Full_Qualified_Name --
6203      ----------------------------------
6204
6205      procedure Internal_Full_Qualified_Name (E : Entity_Id) is
6206         Ent : Entity_Id;
6207
6208      begin
6209         --  Deal properly with child units
6210
6211         if Nkind (E) = N_Defining_Program_Unit_Name then
6212            Ent := Defining_Identifier (E);
6213         else
6214            Ent := E;
6215         end if;
6216
6217         --  Compute qualification recursively (only "Standard" has no scope)
6218
6219         if Present (Scope (Scope (Ent))) then
6220            Internal_Full_Qualified_Name (Scope (Ent));
6221            Store_String_Char (Get_Char_Code ('.'));
6222         end if;
6223
6224         --  Every entity should have a name except some expanded blocks
6225         --  don't bother about those.
6226
6227         if Chars (Ent) = No_Name then
6228            return;
6229         end if;
6230
6231         --  Generates the entity name in upper case
6232
6233         Get_Decoded_Name_String (Chars (Ent));
6234         Set_All_Upper_Case;
6235         Store_String_Chars (Name_Buffer (1 .. Name_Len));
6236         return;
6237      end Internal_Full_Qualified_Name;
6238
6239   --  Start of processing for Full_Qualified_Name
6240
6241   begin
6242      Start_String;
6243      Internal_Full_Qualified_Name (E);
6244
6245      if Append_NUL then
6246         Store_String_Char (Get_Char_Code (ASCII.NUL));
6247      end if;
6248
6249      return End_String;
6250   end Fully_Qualified_Name_String;
6251
6252   ------------------------
6253   -- Generate_Poll_Call --
6254   ------------------------
6255
6256   procedure Generate_Poll_Call (N : Node_Id) is
6257   begin
6258      --  No poll call if polling not active
6259
6260      if not Polling_Required then
6261         return;
6262
6263      --  Otherwise generate require poll call
6264
6265      else
6266         Insert_Before_And_Analyze (N,
6267           Make_Procedure_Call_Statement (Sloc (N),
6268             Name => New_Occurrence_Of (RTE (RE_Poll), Sloc (N))));
6269      end if;
6270   end Generate_Poll_Call;
6271
6272   ---------------------------------
6273   -- Get_Current_Value_Condition --
6274   ---------------------------------
6275
6276   --  Note: the implementation of this procedure is very closely tied to the
6277   --  implementation of Set_Current_Value_Condition. In the Get procedure, we
6278   --  interpret Current_Value fields set by the Set procedure, so the two
6279   --  procedures need to be closely coordinated.
6280
6281   procedure Get_Current_Value_Condition
6282     (Var : Node_Id;
6283      Op  : out Node_Kind;
6284      Val : out Node_Id)
6285   is
6286      Loc : constant Source_Ptr := Sloc (Var);
6287      Ent : constant Entity_Id  := Entity (Var);
6288
6289      procedure Process_Current_Value_Condition
6290        (N : Node_Id;
6291         S : Boolean);
6292      --  N is an expression which holds either True (S = True) or False (S =
6293      --  False) in the condition. This procedure digs out the expression and
6294      --  if it refers to Ent, sets Op and Val appropriately.
6295
6296      -------------------------------------
6297      -- Process_Current_Value_Condition --
6298      -------------------------------------
6299
6300      procedure Process_Current_Value_Condition
6301        (N : Node_Id;
6302         S : Boolean)
6303      is
6304         Cond      : Node_Id;
6305         Prev_Cond : Node_Id;
6306         Sens      : Boolean;
6307
6308      begin
6309         Cond := N;
6310         Sens := S;
6311
6312         loop
6313            Prev_Cond := Cond;
6314
6315            --  Deal with NOT operators, inverting sense
6316
6317            while Nkind (Cond) = N_Op_Not loop
6318               Cond := Right_Opnd (Cond);
6319               Sens := not Sens;
6320            end loop;
6321
6322            --  Deal with conversions, qualifications, and expressions with
6323            --  actions.
6324
6325            while Nkind_In (Cond,
6326                    N_Type_Conversion,
6327                    N_Qualified_Expression,
6328                    N_Expression_With_Actions)
6329            loop
6330               Cond := Expression (Cond);
6331            end loop;
6332
6333            exit when Cond = Prev_Cond;
6334         end loop;
6335
6336         --  Deal with AND THEN and AND cases
6337
6338         if Nkind_In (Cond, N_And_Then, N_Op_And) then
6339
6340            --  Don't ever try to invert a condition that is of the form of an
6341            --  AND or AND THEN (since we are not doing sufficiently general
6342            --  processing to allow this).
6343
6344            if Sens = False then
6345               Op  := N_Empty;
6346               Val := Empty;
6347               return;
6348            end if;
6349
6350            --  Recursively process AND and AND THEN branches
6351
6352            Process_Current_Value_Condition (Left_Opnd (Cond), True);
6353
6354            if Op /= N_Empty then
6355               return;
6356            end if;
6357
6358            Process_Current_Value_Condition (Right_Opnd (Cond), True);
6359            return;
6360
6361         --  Case of relational operator
6362
6363         elsif Nkind (Cond) in N_Op_Compare then
6364            Op := Nkind (Cond);
6365
6366            --  Invert sense of test if inverted test
6367
6368            if Sens = False then
6369               case Op is
6370                  when N_Op_Eq => Op := N_Op_Ne;
6371                  when N_Op_Ne => Op := N_Op_Eq;
6372                  when N_Op_Lt => Op := N_Op_Ge;
6373                  when N_Op_Gt => Op := N_Op_Le;
6374                  when N_Op_Le => Op := N_Op_Gt;
6375                  when N_Op_Ge => Op := N_Op_Lt;
6376                  when others  => raise Program_Error;
6377               end case;
6378            end if;
6379
6380            --  Case of entity op value
6381
6382            if Is_Entity_Name (Left_Opnd (Cond))
6383              and then Ent = Entity (Left_Opnd (Cond))
6384              and then Compile_Time_Known_Value (Right_Opnd (Cond))
6385            then
6386               Val := Right_Opnd (Cond);
6387
6388            --  Case of value op entity
6389
6390            elsif Is_Entity_Name (Right_Opnd (Cond))
6391              and then Ent = Entity (Right_Opnd (Cond))
6392              and then Compile_Time_Known_Value (Left_Opnd (Cond))
6393            then
6394               Val := Left_Opnd (Cond);
6395
6396               --  We are effectively swapping operands
6397
6398               case Op is
6399                  when N_Op_Eq => null;
6400                  when N_Op_Ne => null;
6401                  when N_Op_Lt => Op := N_Op_Gt;
6402                  when N_Op_Gt => Op := N_Op_Lt;
6403                  when N_Op_Le => Op := N_Op_Ge;
6404                  when N_Op_Ge => Op := N_Op_Le;
6405                  when others  => raise Program_Error;
6406               end case;
6407
6408            else
6409               Op := N_Empty;
6410            end if;
6411
6412            return;
6413
6414         elsif Nkind_In (Cond,
6415                 N_Type_Conversion,
6416                 N_Qualified_Expression,
6417                 N_Expression_With_Actions)
6418         then
6419            Cond := Expression (Cond);
6420
6421         --  Case of Boolean variable reference, return as though the
6422         --  reference had said var = True.
6423
6424         else
6425            if Is_Entity_Name (Cond) and then Ent = Entity (Cond) then
6426               Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
6427
6428               if Sens = False then
6429                  Op := N_Op_Ne;
6430               else
6431                  Op := N_Op_Eq;
6432               end if;
6433            end if;
6434         end if;
6435      end Process_Current_Value_Condition;
6436
6437   --  Start of processing for Get_Current_Value_Condition
6438
6439   begin
6440      Op  := N_Empty;
6441      Val := Empty;
6442
6443      --  Immediate return, nothing doing, if this is not an object
6444
6445      if Ekind (Ent) not in Object_Kind then
6446         return;
6447      end if;
6448
6449      --  Otherwise examine current value
6450
6451      declare
6452         CV   : constant Node_Id := Current_Value (Ent);
6453         Sens : Boolean;
6454         Stm  : Node_Id;
6455
6456      begin
6457         --  If statement. Condition is known true in THEN section, known False
6458         --  in any ELSIF or ELSE part, and unknown outside the IF statement.
6459
6460         if Nkind (CV) = N_If_Statement then
6461
6462            --  Before start of IF statement
6463
6464            if Loc < Sloc (CV) then
6465               return;
6466
6467               --  After end of IF statement
6468
6469            elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
6470               return;
6471            end if;
6472
6473            --  At this stage we know that we are within the IF statement, but
6474            --  unfortunately, the tree does not record the SLOC of the ELSE so
6475            --  we cannot use a simple SLOC comparison to distinguish between
6476            --  the then/else statements, so we have to climb the tree.
6477
6478            declare
6479               N : Node_Id;
6480
6481            begin
6482               N := Parent (Var);
6483               while Parent (N) /= CV loop
6484                  N := Parent (N);
6485
6486                  --  If we fall off the top of the tree, then that's odd, but
6487                  --  perhaps it could occur in some error situation, and the
6488                  --  safest response is simply to assume that the outcome of
6489                  --  the condition is unknown. No point in bombing during an
6490                  --  attempt to optimize things.
6491
6492                  if No (N) then
6493                     return;
6494                  end if;
6495               end loop;
6496
6497               --  Now we have N pointing to a node whose parent is the IF
6498               --  statement in question, so now we can tell if we are within
6499               --  the THEN statements.
6500
6501               if Is_List_Member (N)
6502                 and then List_Containing (N) = Then_Statements (CV)
6503               then
6504                  Sens := True;
6505
6506               --  If the variable reference does not come from source, we
6507               --  cannot reliably tell whether it appears in the else part.
6508               --  In particular, if it appears in generated code for a node
6509               --  that requires finalization, it may be attached to a list
6510               --  that has not been yet inserted into the code. For now,
6511               --  treat it as unknown.
6512
6513               elsif not Comes_From_Source (N) then
6514                  return;
6515
6516               --  Otherwise we must be in ELSIF or ELSE part
6517
6518               else
6519                  Sens := False;
6520               end if;
6521            end;
6522
6523            --  ELSIF part. Condition is known true within the referenced
6524            --  ELSIF, known False in any subsequent ELSIF or ELSE part,
6525            --  and unknown before the ELSE part or after the IF statement.
6526
6527         elsif Nkind (CV) = N_Elsif_Part then
6528
6529            --  if the Elsif_Part had condition_actions, the elsif has been
6530            --  rewritten as a nested if, and the original elsif_part is
6531            --  detached from the tree, so there is no way to obtain useful
6532            --  information on the current value of the variable.
6533            --  Can this be improved ???
6534
6535            if No (Parent (CV)) then
6536               return;
6537            end if;
6538
6539            Stm := Parent (CV);
6540
6541            --  If the tree has been otherwise rewritten there is nothing
6542            --  else to be done either.
6543
6544            if Nkind (Stm) /= N_If_Statement then
6545               return;
6546            end if;
6547
6548            --  Before start of ELSIF part
6549
6550            if Loc < Sloc (CV) then
6551               return;
6552
6553               --  After end of IF statement
6554
6555            elsif Loc >= Sloc (Stm) +
6556              Text_Ptr (UI_To_Int (End_Span (Stm)))
6557            then
6558               return;
6559            end if;
6560
6561            --  Again we lack the SLOC of the ELSE, so we need to climb the
6562            --  tree to see if we are within the ELSIF part in question.
6563
6564            declare
6565               N : Node_Id;
6566
6567            begin
6568               N := Parent (Var);
6569               while Parent (N) /= Stm loop
6570                  N := Parent (N);
6571
6572                  --  If we fall off the top of the tree, then that's odd, but
6573                  --  perhaps it could occur in some error situation, and the
6574                  --  safest response is simply to assume that the outcome of
6575                  --  the condition is unknown. No point in bombing during an
6576                  --  attempt to optimize things.
6577
6578                  if No (N) then
6579                     return;
6580                  end if;
6581               end loop;
6582
6583               --  Now we have N pointing to a node whose parent is the IF
6584               --  statement in question, so see if is the ELSIF part we want.
6585               --  the THEN statements.
6586
6587               if N = CV then
6588                  Sens := True;
6589
6590                  --  Otherwise we must be in subsequent ELSIF or ELSE part
6591
6592               else
6593                  Sens := False;
6594               end if;
6595            end;
6596
6597         --  Iteration scheme of while loop. The condition is known to be
6598         --  true within the body of the loop.
6599
6600         elsif Nkind (CV) = N_Iteration_Scheme then
6601            declare
6602               Loop_Stmt : constant Node_Id := Parent (CV);
6603
6604            begin
6605               --  Before start of body of loop
6606
6607               if Loc < Sloc (Loop_Stmt) then
6608                  return;
6609
6610               --  After end of LOOP statement
6611
6612               elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
6613                  return;
6614
6615               --  We are within the body of the loop
6616
6617               else
6618                  Sens := True;
6619               end if;
6620            end;
6621
6622         --  All other cases of Current_Value settings
6623
6624         else
6625            return;
6626         end if;
6627
6628         --  If we fall through here, then we have a reportable condition, Sens
6629         --  is True if the condition is true and False if it needs inverting.
6630
6631         Process_Current_Value_Condition (Condition (CV), Sens);
6632      end;
6633   end Get_Current_Value_Condition;
6634
6635   ---------------------
6636   -- Get_Stream_Size --
6637   ---------------------
6638
6639   function Get_Stream_Size (E : Entity_Id) return Uint is
6640   begin
6641      --  If we have a Stream_Size clause for this type use it
6642
6643      if Has_Stream_Size_Clause (E) then
6644         return Static_Integer (Expression (Stream_Size_Clause (E)));
6645
6646      --  Otherwise the Stream_Size if the size of the type
6647
6648      else
6649         return Esize (E);
6650      end if;
6651   end Get_Stream_Size;
6652
6653   ---------------------------
6654   -- Has_Access_Constraint --
6655   ---------------------------
6656
6657   function Has_Access_Constraint (E : Entity_Id) return Boolean is
6658      Disc : Entity_Id;
6659      T    : constant Entity_Id := Etype (E);
6660
6661   begin
6662      if Has_Per_Object_Constraint (E) and then Has_Discriminants (T) then
6663         Disc := First_Discriminant (T);
6664         while Present (Disc) loop
6665            if Is_Access_Type (Etype (Disc)) then
6666               return True;
6667            end if;
6668
6669            Next_Discriminant (Disc);
6670         end loop;
6671
6672         return False;
6673      else
6674         return False;
6675      end if;
6676   end Has_Access_Constraint;
6677
6678   -----------------------------------------------------
6679   -- Has_Annotate_Pragma_For_External_Axiomatization --
6680   -----------------------------------------------------
6681
6682   function Has_Annotate_Pragma_For_External_Axiomatization
6683     (E : Entity_Id) return Boolean
6684   is
6685      function Is_Annotate_Pragma_For_External_Axiomatization
6686        (N : Node_Id) return Boolean;
6687      --  Returns whether N is
6688      --    pragma Annotate (GNATprove, External_Axiomatization);
6689
6690      ----------------------------------------------------
6691      -- Is_Annotate_Pragma_For_External_Axiomatization --
6692      ----------------------------------------------------
6693
6694      --  The general form of pragma Annotate is
6695
6696      --    pragma Annotate (IDENTIFIER [, IDENTIFIER {, ARG}]);
6697      --    ARG ::= NAME | EXPRESSION
6698
6699      --  The first two arguments are by convention intended to refer to an
6700      --  external tool and a tool-specific function. These arguments are
6701      --  not analyzed.
6702
6703      --  The following is used to annotate a package specification which
6704      --  GNATprove should treat specially, because the axiomatization of
6705      --  this unit is given by the user instead of being automatically
6706      --  generated.
6707
6708      --    pragma Annotate (GNATprove, External_Axiomatization);
6709
6710      function Is_Annotate_Pragma_For_External_Axiomatization
6711        (N : Node_Id) return Boolean
6712      is
6713         Name_GNATprove               : constant String :=
6714                                          "gnatprove";
6715         Name_External_Axiomatization : constant String :=
6716                                          "external_axiomatization";
6717         --  Special names
6718
6719      begin
6720         if Nkind (N) = N_Pragma
6721           and then Get_Pragma_Id (N) = Pragma_Annotate
6722           and then List_Length (Pragma_Argument_Associations (N)) = 2
6723         then
6724            declare
6725               Arg1 : constant Node_Id :=
6726                        First (Pragma_Argument_Associations (N));
6727               Arg2 : constant Node_Id := Next (Arg1);
6728               Nam1 : Name_Id;
6729               Nam2 : Name_Id;
6730
6731            begin
6732               --  Fill in Name_Buffer with Name_GNATprove first, and then with
6733               --  Name_External_Axiomatization so that Name_Find returns the
6734               --  corresponding name. This takes care of all possible casings.
6735
6736               Name_Len := 0;
6737               Add_Str_To_Name_Buffer (Name_GNATprove);
6738               Nam1 := Name_Find;
6739
6740               Name_Len := 0;
6741               Add_Str_To_Name_Buffer (Name_External_Axiomatization);
6742               Nam2 := Name_Find;
6743
6744               return Chars (Get_Pragma_Arg (Arg1)) = Nam1
6745                         and then
6746                      Chars (Get_Pragma_Arg (Arg2)) = Nam2;
6747            end;
6748
6749         else
6750            return False;
6751         end if;
6752      end Is_Annotate_Pragma_For_External_Axiomatization;
6753
6754      --  Local variables
6755
6756      Decl      : Node_Id;
6757      Vis_Decls : List_Id;
6758      N         : Node_Id;
6759
6760   --  Start of processing for Has_Annotate_Pragma_For_External_Axiomatization
6761
6762   begin
6763      if Nkind (Parent (E)) = N_Defining_Program_Unit_Name then
6764         Decl := Parent (Parent (E));
6765      else
6766         Decl := Parent (E);
6767      end if;
6768
6769      Vis_Decls := Visible_Declarations (Decl);
6770
6771      N := First (Vis_Decls);
6772      while Present (N) loop
6773
6774         --  Skip declarations generated by the frontend. Skip all pragmas
6775         --  that are not the desired Annotate pragma. Stop the search on
6776         --  the first non-pragma source declaration.
6777
6778         if Comes_From_Source (N) then
6779            if Nkind (N) = N_Pragma then
6780               if Is_Annotate_Pragma_For_External_Axiomatization (N) then
6781                  return True;
6782               end if;
6783            else
6784               return False;
6785            end if;
6786         end if;
6787
6788         Next (N);
6789      end loop;
6790
6791      return False;
6792   end Has_Annotate_Pragma_For_External_Axiomatization;
6793
6794   --------------------
6795   -- Homonym_Number --
6796   --------------------
6797
6798   function Homonym_Number (Subp : Entity_Id) return Pos is
6799      Hom   : Entity_Id := Homonym (Subp);
6800      Count : Pos := 1;
6801
6802   begin
6803      while Present (Hom) loop
6804         if Scope (Hom) = Scope (Subp) then
6805            Count := Count + 1;
6806         end if;
6807
6808         Hom := Homonym (Hom);
6809      end loop;
6810
6811      return Count;
6812   end Homonym_Number;
6813
6814   -----------------------------------
6815   -- In_Library_Level_Package_Body --
6816   -----------------------------------
6817
6818   function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is
6819   begin
6820      --  First determine whether the entity appears at the library level, then
6821      --  look at the containing unit.
6822
6823      if Is_Library_Level_Entity (Id) then
6824         declare
6825            Container : constant Node_Id := Cunit (Get_Source_Unit (Id));
6826
6827         begin
6828            return Nkind (Unit (Container)) = N_Package_Body;
6829         end;
6830      end if;
6831
6832      return False;
6833   end In_Library_Level_Package_Body;
6834
6835   ------------------------------
6836   -- In_Unconditional_Context --
6837   ------------------------------
6838
6839   function In_Unconditional_Context (Node : Node_Id) return Boolean is
6840      P : Node_Id;
6841
6842   begin
6843      P := Node;
6844      while Present (P) loop
6845         case Nkind (P) is
6846            when N_Subprogram_Body => return True;
6847            when N_If_Statement    => return False;
6848            when N_Loop_Statement  => return False;
6849            when N_Case_Statement  => return False;
6850            when others            => P := Parent (P);
6851         end case;
6852      end loop;
6853
6854      return False;
6855   end In_Unconditional_Context;
6856
6857   -------------------
6858   -- Insert_Action --
6859   -------------------
6860
6861   procedure Insert_Action
6862     (Assoc_Node   : Node_Id;
6863      Ins_Action   : Node_Id;
6864      Spec_Expr_OK : Boolean := False)
6865   is
6866   begin
6867      if Present (Ins_Action) then
6868         Insert_Actions
6869           (Assoc_Node   => Assoc_Node,
6870            Ins_Actions  => New_List (Ins_Action),
6871            Spec_Expr_OK => Spec_Expr_OK);
6872      end if;
6873   end Insert_Action;
6874
6875   --  Version with check(s) suppressed
6876
6877   procedure Insert_Action
6878     (Assoc_Node   : Node_Id;
6879      Ins_Action   : Node_Id;
6880      Suppress     : Check_Id;
6881      Spec_Expr_OK : Boolean := False)
6882   is
6883   begin
6884      Insert_Actions
6885        (Assoc_Node   => Assoc_Node,
6886         Ins_Actions  => New_List (Ins_Action),
6887         Suppress     => Suppress,
6888         Spec_Expr_OK => Spec_Expr_OK);
6889   end Insert_Action;
6890
6891   -------------------------
6892   -- Insert_Action_After --
6893   -------------------------
6894
6895   procedure Insert_Action_After
6896     (Assoc_Node : Node_Id;
6897      Ins_Action : Node_Id)
6898   is
6899   begin
6900      Insert_Actions_After (Assoc_Node, New_List (Ins_Action));
6901   end Insert_Action_After;
6902
6903   --------------------
6904   -- Insert_Actions --
6905   --------------------
6906
6907   procedure Insert_Actions
6908     (Assoc_Node   : Node_Id;
6909      Ins_Actions  : List_Id;
6910      Spec_Expr_OK : Boolean := False)
6911   is
6912      N : Node_Id;
6913      P : Node_Id;
6914
6915      Wrapped_Node : Node_Id := Empty;
6916
6917   begin
6918      if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
6919         return;
6920      end if;
6921
6922      --  Insert the action when the context is "Handling of Default and Per-
6923      --  Object Expressions" only when requested by the caller.
6924
6925      if Spec_Expr_OK then
6926         null;
6927
6928      --  Ignore insert of actions from inside default expression (or other
6929      --  similar "spec expression") in the special spec-expression analyze
6930      --  mode. Any insertions at this point have no relevance, since we are
6931      --  only doing the analyze to freeze the types of any static expressions.
6932      --  See section "Handling of Default and Per-Object Expressions" in the
6933      --  spec of package Sem for further details.
6934
6935      elsif In_Spec_Expression then
6936         return;
6937      end if;
6938
6939      --  If the action derives from stuff inside a record, then the actions
6940      --  are attached to the current scope, to be inserted and analyzed on
6941      --  exit from the scope. The reason for this is that we may also be
6942      --  generating freeze actions at the same time, and they must eventually
6943      --  be elaborated in the correct order.
6944
6945      if Is_Record_Type (Current_Scope)
6946        and then not Is_Frozen (Current_Scope)
6947      then
6948         if No (Scope_Stack.Table
6949                  (Scope_Stack.Last).Pending_Freeze_Actions)
6950         then
6951            Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
6952              Ins_Actions;
6953         else
6954            Append_List
6955              (Ins_Actions,
6956               Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
6957         end if;
6958
6959         return;
6960      end if;
6961
6962      --  We now intend to climb up the tree to find the right point to
6963      --  insert the actions. We start at Assoc_Node, unless this node is a
6964      --  subexpression in which case we start with its parent. We do this for
6965      --  two reasons. First it speeds things up. Second, if Assoc_Node is
6966      --  itself one of the special nodes like N_And_Then, then we assume that
6967      --  an initial request to insert actions for such a node does not expect
6968      --  the actions to get deposited in the node for later handling when the
6969      --  node is expanded, since clearly the node is being dealt with by the
6970      --  caller. Note that in the subexpression case, N is always the child we
6971      --  came from.
6972
6973      --  N_Raise_xxx_Error is an annoying special case, it is a statement
6974      --  if it has type Standard_Void_Type, and a subexpression otherwise.
6975      --  Procedure calls, and similarly procedure attribute references, are
6976      --  also statements.
6977
6978      if Nkind (Assoc_Node) in N_Subexpr
6979        and then (Nkind (Assoc_Node) not in N_Raise_xxx_Error
6980                   or else Etype (Assoc_Node) /= Standard_Void_Type)
6981        and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement
6982        and then (Nkind (Assoc_Node) /= N_Attribute_Reference
6983                   or else not Is_Procedure_Attribute_Name
6984                                 (Attribute_Name (Assoc_Node)))
6985      then
6986         N := Assoc_Node;
6987         P := Parent (Assoc_Node);
6988
6989      --  Nonsubexpression case. Note that N is initially Empty in this case
6990      --  (N is only guaranteed non-Empty in the subexpr case).
6991
6992      else
6993         N := Empty;
6994         P := Assoc_Node;
6995      end if;
6996
6997      --  Capture root of the transient scope
6998
6999      if Scope_Is_Transient then
7000         Wrapped_Node := Node_To_Be_Wrapped;
7001      end if;
7002
7003      loop
7004         pragma Assert (Present (P));
7005
7006         --  Make sure that inserted actions stay in the transient scope
7007
7008         if Present (Wrapped_Node) and then N = Wrapped_Node then
7009            Store_Before_Actions_In_Scope (Ins_Actions);
7010            return;
7011         end if;
7012
7013         case Nkind (P) is
7014
7015            --  Case of right operand of AND THEN or OR ELSE. Put the actions
7016            --  in the Actions field of the right operand. They will be moved
7017            --  out further when the AND THEN or OR ELSE operator is expanded.
7018            --  Nothing special needs to be done for the left operand since
7019            --  in that case the actions are executed unconditionally.
7020
7021            when N_Short_Circuit =>
7022               if N = Right_Opnd (P) then
7023
7024                  --  We are now going to either append the actions to the
7025                  --  actions field of the short-circuit operation. We will
7026                  --  also analyze the actions now.
7027
7028                  --  This analysis is really too early, the proper thing would
7029                  --  be to just park them there now, and only analyze them if
7030                  --  we find we really need them, and to it at the proper
7031                  --  final insertion point. However attempting to this proved
7032                  --  tricky, so for now we just kill current values before and
7033                  --  after the analyze call to make sure we avoid peculiar
7034                  --  optimizations from this out of order insertion.
7035
7036                  Kill_Current_Values;
7037
7038                  --  If P has already been expanded, we can't park new actions
7039                  --  on it, so we need to expand them immediately, introducing
7040                  --  an Expression_With_Actions. N can't be an expression
7041                  --  with actions, or else then the actions would have been
7042                  --  inserted at an inner level.
7043
7044                  if Analyzed (P) then
7045                     pragma Assert (Nkind (N) /= N_Expression_With_Actions);
7046                     Rewrite (N,
7047                       Make_Expression_With_Actions (Sloc (N),
7048                         Actions    => Ins_Actions,
7049                         Expression => Relocate_Node (N)));
7050                     Analyze_And_Resolve (N);
7051
7052                  elsif Present (Actions (P)) then
7053                     Insert_List_After_And_Analyze
7054                       (Last (Actions (P)), Ins_Actions);
7055                  else
7056                     Set_Actions (P, Ins_Actions);
7057                     Analyze_List (Actions (P));
7058                  end if;
7059
7060                  Kill_Current_Values;
7061
7062                  return;
7063               end if;
7064
7065            --  Then or Else dependent expression of an if expression. Add
7066            --  actions to Then_Actions or Else_Actions field as appropriate.
7067            --  The actions will be moved further out when the if is expanded.
7068
7069            when N_If_Expression =>
7070               declare
7071                  ThenX : constant Node_Id := Next (First (Expressions (P)));
7072                  ElseX : constant Node_Id := Next (ThenX);
7073
7074               begin
7075                  --  If the enclosing expression is already analyzed, as
7076                  --  is the case for nested elaboration checks, insert the
7077                  --  conditional further out.
7078
7079                  if Analyzed (P) then
7080                     null;
7081
7082                  --  Actions belong to the then expression, temporarily place
7083                  --  them as Then_Actions of the if expression. They will be
7084                  --  moved to the proper place later when the if expression
7085                  --  is expanded.
7086
7087                  elsif N = ThenX then
7088                     if Present (Then_Actions (P)) then
7089                        Insert_List_After_And_Analyze
7090                          (Last (Then_Actions (P)), Ins_Actions);
7091                     else
7092                        Set_Then_Actions (P, Ins_Actions);
7093                        Analyze_List (Then_Actions (P));
7094                     end if;
7095
7096                     return;
7097
7098                  --  Actions belong to the else expression, temporarily place
7099                  --  them as Else_Actions of the if expression. They will be
7100                  --  moved to the proper place later when the if expression
7101                  --  is expanded.
7102
7103                  elsif N = ElseX then
7104                     if Present (Else_Actions (P)) then
7105                        Insert_List_After_And_Analyze
7106                          (Last (Else_Actions (P)), Ins_Actions);
7107                     else
7108                        Set_Else_Actions (P, Ins_Actions);
7109                        Analyze_List (Else_Actions (P));
7110                     end if;
7111
7112                     return;
7113
7114                  --  Actions belong to the condition. In this case they are
7115                  --  unconditionally executed, and so we can continue the
7116                  --  search for the proper insert point.
7117
7118                  else
7119                     null;
7120                  end if;
7121               end;
7122
7123            --  Alternative of case expression, we place the action in the
7124            --  Actions field of the case expression alternative, this will
7125            --  be handled when the case expression is expanded.
7126
7127            when N_Case_Expression_Alternative =>
7128               if Present (Actions (P)) then
7129                  Insert_List_After_And_Analyze
7130                    (Last (Actions (P)), Ins_Actions);
7131               else
7132                  Set_Actions (P, Ins_Actions);
7133                  Analyze_List (Actions (P));
7134               end if;
7135
7136               return;
7137
7138            --  Case of appearing within an Expressions_With_Actions node. When
7139            --  the new actions come from the expression of the expression with
7140            --  actions, they must be added to the existing actions. The other
7141            --  alternative is when the new actions are related to one of the
7142            --  existing actions of the expression with actions, and should
7143            --  never reach here: if actions are inserted on a statement
7144            --  within the Actions of an expression with actions, or on some
7145            --  subexpression of such a statement, then the outermost proper
7146            --  insertion point is right before the statement, and we should
7147            --  never climb up as far as the N_Expression_With_Actions itself.
7148
7149            when N_Expression_With_Actions =>
7150               if N = Expression (P) then
7151                  if Is_Empty_List (Actions (P)) then
7152                     Append_List_To (Actions (P), Ins_Actions);
7153                     Analyze_List (Actions (P));
7154                  else
7155                     Insert_List_After_And_Analyze
7156                       (Last (Actions (P)), Ins_Actions);
7157                  end if;
7158
7159                  return;
7160
7161               else
7162                  raise Program_Error;
7163               end if;
7164
7165            --  Case of appearing in the condition of a while expression or
7166            --  elsif. We insert the actions into the Condition_Actions field.
7167            --  They will be moved further out when the while loop or elsif
7168            --  is analyzed.
7169
7170            when N_Elsif_Part
7171               | N_Iteration_Scheme
7172            =>
7173               if N = Condition (P) then
7174                  if Present (Condition_Actions (P)) then
7175                     Insert_List_After_And_Analyze
7176                       (Last (Condition_Actions (P)), Ins_Actions);
7177                  else
7178                     Set_Condition_Actions (P, Ins_Actions);
7179
7180                     --  Set the parent of the insert actions explicitly. This
7181                     --  is not a syntactic field, but we need the parent field
7182                     --  set, in particular so that freeze can understand that
7183                     --  it is dealing with condition actions, and properly
7184                     --  insert the freezing actions.
7185
7186                     Set_Parent (Ins_Actions, P);
7187                     Analyze_List (Condition_Actions (P));
7188                  end if;
7189
7190                  return;
7191               end if;
7192
7193            --  Statements, declarations, pragmas, representation clauses
7194
7195            when
7196               --  Statements
7197
7198                 N_Procedure_Call_Statement
7199               | N_Statement_Other_Than_Procedure_Call
7200
7201               --  Pragmas
7202
7203               | N_Pragma
7204
7205               --  Representation_Clause
7206
7207               | N_At_Clause
7208               | N_Attribute_Definition_Clause
7209               | N_Enumeration_Representation_Clause
7210               | N_Record_Representation_Clause
7211
7212               --  Declarations
7213
7214               | N_Abstract_Subprogram_Declaration
7215               | N_Entry_Body
7216               | N_Exception_Declaration
7217               | N_Exception_Renaming_Declaration
7218               | N_Expression_Function
7219               | N_Formal_Abstract_Subprogram_Declaration
7220               | N_Formal_Concrete_Subprogram_Declaration
7221               | N_Formal_Object_Declaration
7222               | N_Formal_Type_Declaration
7223               | N_Full_Type_Declaration
7224               | N_Function_Instantiation
7225               | N_Generic_Function_Renaming_Declaration
7226               | N_Generic_Package_Declaration
7227               | N_Generic_Package_Renaming_Declaration
7228               | N_Generic_Procedure_Renaming_Declaration
7229               | N_Generic_Subprogram_Declaration
7230               | N_Implicit_Label_Declaration
7231               | N_Incomplete_Type_Declaration
7232               | N_Number_Declaration
7233               | N_Object_Declaration
7234               | N_Object_Renaming_Declaration
7235               | N_Package_Body
7236               | N_Package_Body_Stub
7237               | N_Package_Declaration
7238               | N_Package_Instantiation
7239               | N_Package_Renaming_Declaration
7240               | N_Private_Extension_Declaration
7241               | N_Private_Type_Declaration
7242               | N_Procedure_Instantiation
7243               | N_Protected_Body
7244               | N_Protected_Body_Stub
7245               | N_Single_Task_Declaration
7246               | N_Subprogram_Body
7247               | N_Subprogram_Body_Stub
7248               | N_Subprogram_Declaration
7249               | N_Subprogram_Renaming_Declaration
7250               | N_Subtype_Declaration
7251               | N_Task_Body
7252               | N_Task_Body_Stub
7253
7254               --  Use clauses can appear in lists of declarations
7255
7256               | N_Use_Package_Clause
7257               | N_Use_Type_Clause
7258
7259               --  Freeze entity behaves like a declaration or statement
7260
7261               | N_Freeze_Entity
7262               | N_Freeze_Generic_Entity
7263            =>
7264               --  Do not insert here if the item is not a list member (this
7265               --  happens for example with a triggering statement, and the
7266               --  proper approach is to insert before the entire select).
7267
7268               if not Is_List_Member (P) then
7269                  null;
7270
7271               --  Do not insert if parent of P is an N_Component_Association
7272               --  node (i.e. we are in the context of an N_Aggregate or
7273               --  N_Extension_Aggregate node. In this case we want to insert
7274               --  before the entire aggregate.
7275
7276               elsif Nkind (Parent (P)) = N_Component_Association then
7277                  null;
7278
7279               --  Do not insert if the parent of P is either an N_Variant node
7280               --  or an N_Record_Definition node, meaning in either case that
7281               --  P is a member of a component list, and that therefore the
7282               --  actions should be inserted outside the complete record
7283               --  declaration.
7284
7285               elsif Nkind_In (Parent (P), N_Variant, N_Record_Definition) then
7286                  null;
7287
7288               --  Do not insert freeze nodes within the loop generated for
7289               --  an aggregate, because they may be elaborated too late for
7290               --  subsequent use in the back end: within a package spec the
7291               --  loop is part of the elaboration procedure and is only
7292               --  elaborated during the second pass.
7293
7294               --  If the loop comes from source, or the entity is local to the
7295               --  loop itself it must remain within.
7296
7297               elsif Nkind (Parent (P)) = N_Loop_Statement
7298                 and then not Comes_From_Source (Parent (P))
7299                 and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
7300                 and then
7301                   Scope (Entity (First (Ins_Actions))) /= Current_Scope
7302               then
7303                  null;
7304
7305               --  Otherwise we can go ahead and do the insertion
7306
7307               elsif P = Wrapped_Node then
7308                  Store_Before_Actions_In_Scope (Ins_Actions);
7309                  return;
7310
7311               else
7312                  Insert_List_Before_And_Analyze (P, Ins_Actions);
7313                  return;
7314               end if;
7315
7316            --  the expansion of Task and protected type declarations can
7317            --  create declarations for temporaries which, like other actions
7318            --  are inserted and analyzed before the current declaraation.
7319            --  However, the current scope is the synchronized type, and
7320            --  for unnesting it is critical that the proper scope for these
7321            --  generated entities be the enclosing one.
7322
7323            when N_Task_Type_Declaration
7324               | N_Protected_Type_Declaration =>
7325
7326               Push_Scope (Scope (Current_Scope));
7327               Insert_List_Before_And_Analyze (P, Ins_Actions);
7328               Pop_Scope;
7329               return;
7330
7331            --  A special case, N_Raise_xxx_Error can act either as a statement
7332            --  or a subexpression. We tell the difference by looking at the
7333            --  Etype. It is set to Standard_Void_Type in the statement case.
7334
7335            when N_Raise_xxx_Error =>
7336               if Etype (P) = Standard_Void_Type then
7337                  if P = Wrapped_Node then
7338                     Store_Before_Actions_In_Scope (Ins_Actions);
7339                  else
7340                     Insert_List_Before_And_Analyze (P, Ins_Actions);
7341                  end if;
7342
7343                  return;
7344
7345               --  In the subexpression case, keep climbing
7346
7347               else
7348                  null;
7349               end if;
7350
7351            --  If a component association appears within a loop created for
7352            --  an array aggregate, attach the actions to the association so
7353            --  they can be subsequently inserted within the loop. For other
7354            --  component associations insert outside of the aggregate. For
7355            --  an association that will generate a loop, its Loop_Actions
7356            --  attribute is already initialized (see exp_aggr.adb).
7357
7358            --  The list of Loop_Actions can in turn generate additional ones,
7359            --  that are inserted before the associated node. If the associated
7360            --  node is outside the aggregate, the new actions are collected
7361            --  at the end of the Loop_Actions, to respect the order in which
7362            --  they are to be elaborated.
7363
7364            when N_Component_Association
7365               | N_Iterated_Component_Association
7366            =>
7367               if Nkind (Parent (P)) = N_Aggregate
7368                 and then Present (Loop_Actions (P))
7369               then
7370                  if Is_Empty_List (Loop_Actions (P)) then
7371                     Set_Loop_Actions (P, Ins_Actions);
7372                     Analyze_List (Ins_Actions);
7373                  else
7374                     declare
7375                        Decl : Node_Id;
7376
7377                     begin
7378                        --  Check whether these actions were generated by a
7379                        --  declaration that is part of the Loop_Actions for
7380                        --  the component_association.
7381
7382                        Decl := Assoc_Node;
7383                        while Present (Decl) loop
7384                           exit when Parent (Decl) = P
7385                             and then Is_List_Member (Decl)
7386                             and then
7387                               List_Containing (Decl) = Loop_Actions (P);
7388                           Decl := Parent (Decl);
7389                        end loop;
7390
7391                        if Present (Decl) then
7392                           Insert_List_Before_And_Analyze
7393                             (Decl, Ins_Actions);
7394                        else
7395                           Insert_List_After_And_Analyze
7396                             (Last (Loop_Actions (P)), Ins_Actions);
7397                        end if;
7398                     end;
7399                  end if;
7400
7401                  return;
7402
7403               else
7404                  null;
7405               end if;
7406
7407            --  Special case: an attribute denoting a procedure call
7408
7409            when N_Attribute_Reference =>
7410               if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
7411                  if P = Wrapped_Node then
7412                     Store_Before_Actions_In_Scope (Ins_Actions);
7413                  else
7414                     Insert_List_Before_And_Analyze (P, Ins_Actions);
7415                  end if;
7416
7417                  return;
7418
7419               --  In the subexpression case, keep climbing
7420
7421               else
7422                  null;
7423               end if;
7424
7425            --  Special case: a marker
7426
7427            when N_Call_Marker
7428               | N_Variable_Reference_Marker
7429            =>
7430               if Is_List_Member (P) then
7431                  Insert_List_Before_And_Analyze (P, Ins_Actions);
7432                  return;
7433               end if;
7434
7435            --  A contract node should not belong to the tree
7436
7437            when N_Contract =>
7438               raise Program_Error;
7439
7440            --  For all other node types, keep climbing tree
7441
7442            when N_Abortable_Part
7443               | N_Accept_Alternative
7444               | N_Access_Definition
7445               | N_Access_Function_Definition
7446               | N_Access_Procedure_Definition
7447               | N_Access_To_Object_Definition
7448               | N_Aggregate
7449               | N_Allocator
7450               | N_Aspect_Specification
7451               | N_Case_Expression
7452               | N_Case_Statement_Alternative
7453               | N_Character_Literal
7454               | N_Compilation_Unit
7455               | N_Compilation_Unit_Aux
7456               | N_Component_Clause
7457               | N_Component_Declaration
7458               | N_Component_Definition
7459               | N_Component_List
7460               | N_Constrained_Array_Definition
7461               | N_Decimal_Fixed_Point_Definition
7462               | N_Defining_Character_Literal
7463               | N_Defining_Identifier
7464               | N_Defining_Operator_Symbol
7465               | N_Defining_Program_Unit_Name
7466               | N_Delay_Alternative
7467               | N_Delta_Aggregate
7468               | N_Delta_Constraint
7469               | N_Derived_Type_Definition
7470               | N_Designator
7471               | N_Digits_Constraint
7472               | N_Discriminant_Association
7473               | N_Discriminant_Specification
7474               | N_Empty
7475               | N_Entry_Body_Formal_Part
7476               | N_Entry_Call_Alternative
7477               | N_Entry_Declaration
7478               | N_Entry_Index_Specification
7479               | N_Enumeration_Type_Definition
7480               | N_Error
7481               | N_Exception_Handler
7482               | N_Expanded_Name
7483               | N_Explicit_Dereference
7484               | N_Extension_Aggregate
7485               | N_Floating_Point_Definition
7486               | N_Formal_Decimal_Fixed_Point_Definition
7487               | N_Formal_Derived_Type_Definition
7488               | N_Formal_Discrete_Type_Definition
7489               | N_Formal_Floating_Point_Definition
7490               | N_Formal_Modular_Type_Definition
7491               | N_Formal_Ordinary_Fixed_Point_Definition
7492               | N_Formal_Package_Declaration
7493               | N_Formal_Private_Type_Definition
7494               | N_Formal_Incomplete_Type_Definition
7495               | N_Formal_Signed_Integer_Type_Definition
7496               | N_Function_Call
7497               | N_Function_Specification
7498               | N_Generic_Association
7499               | N_Handled_Sequence_Of_Statements
7500               | N_Identifier
7501               | N_In
7502               | N_Index_Or_Discriminant_Constraint
7503               | N_Indexed_Component
7504               | N_Integer_Literal
7505               | N_Iterator_Specification
7506               | N_Itype_Reference
7507               | N_Label
7508               | N_Loop_Parameter_Specification
7509               | N_Mod_Clause
7510               | N_Modular_Type_Definition
7511               | N_Not_In
7512               | N_Null
7513               | N_Op_Abs
7514               | N_Op_Add
7515               | N_Op_And
7516               | N_Op_Concat
7517               | N_Op_Divide
7518               | N_Op_Eq
7519               | N_Op_Expon
7520               | N_Op_Ge
7521               | N_Op_Gt
7522               | N_Op_Le
7523               | N_Op_Lt
7524               | N_Op_Minus
7525               | N_Op_Mod
7526               | N_Op_Multiply
7527               | N_Op_Ne
7528               | N_Op_Not
7529               | N_Op_Or
7530               | N_Op_Plus
7531               | N_Op_Rem
7532               | N_Op_Rotate_Left
7533               | N_Op_Rotate_Right
7534               | N_Op_Shift_Left
7535               | N_Op_Shift_Right
7536               | N_Op_Shift_Right_Arithmetic
7537               | N_Op_Subtract
7538               | N_Op_Xor
7539               | N_Operator_Symbol
7540               | N_Ordinary_Fixed_Point_Definition
7541               | N_Others_Choice
7542               | N_Package_Specification
7543               | N_Parameter_Association
7544               | N_Parameter_Specification
7545               | N_Pop_Constraint_Error_Label
7546               | N_Pop_Program_Error_Label
7547               | N_Pop_Storage_Error_Label
7548               | N_Pragma_Argument_Association
7549               | N_Procedure_Specification
7550               | N_Protected_Definition
7551               | N_Push_Constraint_Error_Label
7552               | N_Push_Program_Error_Label
7553               | N_Push_Storage_Error_Label
7554               | N_Qualified_Expression
7555               | N_Quantified_Expression
7556               | N_Raise_Expression
7557               | N_Range
7558               | N_Range_Constraint
7559               | N_Real_Literal
7560               | N_Real_Range_Specification
7561               | N_Record_Definition
7562               | N_Reference
7563               | N_SCIL_Dispatch_Table_Tag_Init
7564               | N_SCIL_Dispatching_Call
7565               | N_SCIL_Membership_Test
7566               | N_Selected_Component
7567               | N_Signed_Integer_Type_Definition
7568               | N_Single_Protected_Declaration
7569               | N_Slice
7570               | N_String_Literal
7571               | N_Subtype_Indication
7572               | N_Subunit
7573               | N_Target_Name
7574               | N_Task_Definition
7575               | N_Terminate_Alternative
7576               | N_Triggering_Alternative
7577               | N_Type_Conversion
7578               | N_Unchecked_Expression
7579               | N_Unchecked_Type_Conversion
7580               | N_Unconstrained_Array_Definition
7581               | N_Unused_At_End
7582               | N_Unused_At_Start
7583               | N_Variant
7584               | N_Variant_Part
7585               | N_Validate_Unchecked_Conversion
7586               | N_With_Clause
7587            =>
7588               null;
7589         end case;
7590
7591         --  If we fall through above tests, keep climbing tree
7592
7593         N := P;
7594
7595         if Nkind (Parent (N)) = N_Subunit then
7596
7597            --  This is the proper body corresponding to a stub. Insertion must
7598            --  be done at the point of the stub, which is in the declarative
7599            --  part of the parent unit.
7600
7601            P := Corresponding_Stub (Parent (N));
7602
7603         else
7604            P := Parent (N);
7605         end if;
7606      end loop;
7607   end Insert_Actions;
7608
7609   --  Version with check(s) suppressed
7610
7611   procedure Insert_Actions
7612     (Assoc_Node   : Node_Id;
7613      Ins_Actions  : List_Id;
7614      Suppress     : Check_Id;
7615      Spec_Expr_OK : Boolean := False)
7616   is
7617   begin
7618      if Suppress = All_Checks then
7619         declare
7620            Sva : constant Suppress_Array := Scope_Suppress.Suppress;
7621         begin
7622            Scope_Suppress.Suppress := (others => True);
7623            Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK);
7624            Scope_Suppress.Suppress := Sva;
7625         end;
7626
7627      else
7628         declare
7629            Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
7630         begin
7631            Scope_Suppress.Suppress (Suppress) := True;
7632            Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK);
7633            Scope_Suppress.Suppress (Suppress) := Svg;
7634         end;
7635      end if;
7636   end Insert_Actions;
7637
7638   --------------------------
7639   -- Insert_Actions_After --
7640   --------------------------
7641
7642   procedure Insert_Actions_After
7643     (Assoc_Node  : Node_Id;
7644      Ins_Actions : List_Id)
7645   is
7646   begin
7647      if Scope_Is_Transient and then Assoc_Node = Node_To_Be_Wrapped then
7648         Store_After_Actions_In_Scope (Ins_Actions);
7649      else
7650         Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
7651      end if;
7652   end Insert_Actions_After;
7653
7654   ------------------------
7655   -- Insert_Declaration --
7656   ------------------------
7657
7658   procedure Insert_Declaration (N : Node_Id; Decl : Node_Id) is
7659      P : Node_Id;
7660
7661   begin
7662      pragma Assert (Nkind (N) in N_Subexpr);
7663
7664      --  Climb until we find a procedure or a package
7665
7666      P := N;
7667      loop
7668         pragma Assert (Present (Parent (P)));
7669         P := Parent (P);
7670
7671         if Is_List_Member (P) then
7672            exit when Nkind_In (Parent (P), N_Package_Specification,
7673                                            N_Subprogram_Body);
7674
7675            --  Special handling for handled sequence of statements, we must
7676            --  insert in the statements not the exception handlers!
7677
7678            if Nkind (Parent (P)) = N_Handled_Sequence_Of_Statements then
7679               P := First (Statements (Parent (P)));
7680               exit;
7681            end if;
7682         end if;
7683      end loop;
7684
7685      --  Now do the insertion
7686
7687      Insert_Before (P, Decl);
7688      Analyze (Decl);
7689   end Insert_Declaration;
7690
7691   ---------------------------------
7692   -- Insert_Library_Level_Action --
7693   ---------------------------------
7694
7695   procedure Insert_Library_Level_Action (N : Node_Id) is
7696      Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
7697
7698   begin
7699      Push_Scope (Cunit_Entity (Current_Sem_Unit));
7700      --  And not Main_Unit as previously. If the main unit is a body,
7701      --  the scope needed to analyze the actions is the entity of the
7702      --  corresponding declaration.
7703
7704      if No (Actions (Aux)) then
7705         Set_Actions (Aux, New_List (N));
7706      else
7707         Append (N, Actions (Aux));
7708      end if;
7709
7710      Analyze (N);
7711      Pop_Scope;
7712   end Insert_Library_Level_Action;
7713
7714   ----------------------------------
7715   -- Insert_Library_Level_Actions --
7716   ----------------------------------
7717
7718   procedure Insert_Library_Level_Actions (L : List_Id) is
7719      Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
7720
7721   begin
7722      if Is_Non_Empty_List (L) then
7723         Push_Scope (Cunit_Entity (Main_Unit));
7724         --  ??? should this be Current_Sem_Unit instead of Main_Unit?
7725
7726         if No (Actions (Aux)) then
7727            Set_Actions (Aux, L);
7728            Analyze_List (L);
7729         else
7730            Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
7731         end if;
7732
7733         Pop_Scope;
7734      end if;
7735   end Insert_Library_Level_Actions;
7736
7737   ----------------------
7738   -- Inside_Init_Proc --
7739   ----------------------
7740
7741   function Inside_Init_Proc return Boolean is
7742      Proc : constant Entity_Id := Enclosing_Init_Proc;
7743
7744   begin
7745      return Proc /= Empty;
7746   end Inside_Init_Proc;
7747
7748   ----------------------------
7749   -- Is_All_Null_Statements --
7750   ----------------------------
7751
7752   function Is_All_Null_Statements (L : List_Id) return Boolean is
7753      Stm : Node_Id;
7754
7755   begin
7756      Stm := First (L);
7757      while Present (Stm) loop
7758         if Nkind (Stm) /= N_Null_Statement then
7759            return False;
7760         end if;
7761
7762         Next (Stm);
7763      end loop;
7764
7765      return True;
7766   end Is_All_Null_Statements;
7767
7768   --------------------------------------------------
7769   -- Is_Displacement_Of_Object_Or_Function_Result --
7770   --------------------------------------------------
7771
7772   function Is_Displacement_Of_Object_Or_Function_Result
7773     (Obj_Id : Entity_Id) return Boolean
7774   is
7775      function Is_Controlled_Function_Call (N : Node_Id) return Boolean;
7776      --  Determine whether node N denotes a controlled function call
7777
7778      function Is_Controlled_Indexing (N : Node_Id) return Boolean;
7779      --  Determine whether node N denotes a generalized indexing form which
7780      --  involves a controlled result.
7781
7782      function Is_Displace_Call (N : Node_Id) return Boolean;
7783      --  Determine whether node N denotes a call to Ada.Tags.Displace
7784
7785      function Is_Source_Object (N : Node_Id) return Boolean;
7786      --  Determine whether a particular node denotes a source object
7787
7788      function Strip (N : Node_Id) return Node_Id;
7789      --  Examine arbitrary node N by stripping various indirections and return
7790      --  the "real" node.
7791
7792      ---------------------------------
7793      -- Is_Controlled_Function_Call --
7794      ---------------------------------
7795
7796      function Is_Controlled_Function_Call (N : Node_Id) return Boolean is
7797         Expr : Node_Id;
7798
7799      begin
7800         --  When a function call appears in Object.Operation format, the
7801         --  original representation has several possible forms depending on
7802         --  the availability and form of actual parameters:
7803
7804         --    Obj.Func                    N_Selected_Component
7805         --    Obj.Func (Actual)           N_Indexed_Component
7806         --    Obj.Func (Formal => Actual) N_Function_Call, whose Name is an
7807         --                                N_Selected_Component
7808
7809         Expr := Original_Node (N);
7810         loop
7811            if Nkind (Expr) = N_Function_Call then
7812               Expr := Name (Expr);
7813
7814            --  "Obj.Func (Actual)" case
7815
7816            elsif Nkind (Expr) = N_Indexed_Component then
7817               Expr := Prefix (Expr);
7818
7819            --  "Obj.Func" or "Obj.Func (Formal => Actual) case
7820
7821            elsif Nkind (Expr) = N_Selected_Component then
7822               Expr := Selector_Name (Expr);
7823
7824            else
7825               exit;
7826            end if;
7827         end loop;
7828
7829         return
7830           Nkind (Expr) in N_Has_Entity
7831             and then Present (Entity (Expr))
7832             and then Ekind (Entity (Expr)) = E_Function
7833             and then Needs_Finalization (Etype (Entity (Expr)));
7834      end Is_Controlled_Function_Call;
7835
7836      ----------------------------
7837      -- Is_Controlled_Indexing --
7838      ----------------------------
7839
7840      function Is_Controlled_Indexing (N : Node_Id) return Boolean is
7841         Expr : constant Node_Id := Original_Node (N);
7842
7843      begin
7844         return
7845           Nkind (Expr) = N_Indexed_Component
7846             and then Present (Generalized_Indexing (Expr))
7847             and then Needs_Finalization (Etype (Expr));
7848      end Is_Controlled_Indexing;
7849
7850      ----------------------
7851      -- Is_Displace_Call --
7852      ----------------------
7853
7854      function Is_Displace_Call (N : Node_Id) return Boolean is
7855         Call : constant Node_Id := Strip (N);
7856
7857      begin
7858         return
7859           Present (Call)
7860             and then Nkind (Call) = N_Function_Call
7861             and then Nkind (Name (Call)) in N_Has_Entity
7862             and then Is_RTE (Entity (Name (Call)), RE_Displace);
7863      end Is_Displace_Call;
7864
7865      ----------------------
7866      -- Is_Source_Object --
7867      ----------------------
7868
7869      function Is_Source_Object (N : Node_Id) return Boolean is
7870         Obj : constant Node_Id := Strip (N);
7871
7872      begin
7873         return
7874           Present (Obj)
7875             and then Comes_From_Source (Obj)
7876             and then Nkind (Obj) in N_Has_Entity
7877             and then Is_Object (Entity (Obj));
7878      end Is_Source_Object;
7879
7880      -----------
7881      -- Strip --
7882      -----------
7883
7884      function Strip (N : Node_Id) return Node_Id is
7885         Result : Node_Id;
7886
7887      begin
7888         Result := N;
7889         loop
7890            if Nkind (Result) = N_Explicit_Dereference then
7891               Result := Prefix (Result);
7892
7893            elsif Nkind_In (Result, N_Type_Conversion,
7894                                    N_Unchecked_Type_Conversion)
7895            then
7896               Result := Expression (Result);
7897
7898            else
7899               exit;
7900            end if;
7901         end loop;
7902
7903         return Result;
7904      end Strip;
7905
7906      --  Local variables
7907
7908      Obj_Decl  : constant Node_Id   := Declaration_Node (Obj_Id);
7909      Obj_Typ   : constant Entity_Id := Base_Type (Etype (Obj_Id));
7910      Orig_Decl : constant Node_Id   := Original_Node (Obj_Decl);
7911      Orig_Expr : Node_Id;
7912
7913   --  Start of processing for Is_Displacement_Of_Object_Or_Function_Result
7914
7915   begin
7916      --  Case 1:
7917
7918      --     Obj : CW_Type := Function_Call (...);
7919
7920      --  is rewritten into:
7921
7922      --     Temp : ... := Function_Call (...)'reference;
7923      --     Obj  : CW_Type renames (... Ada.Tags.Displace (Temp));
7924
7925      --  where the return type of the function and the class-wide type require
7926      --  dispatch table pointer displacement.
7927
7928      --  Case 2:
7929
7930      --     Obj : CW_Type := Container (...);
7931
7932      --  is rewritten into:
7933
7934      --     Temp : ... := Function_Call (Container, ...)'reference;
7935      --     Obj  : CW_Type renames (... Ada.Tags.Displace (Temp));
7936
7937      --  where the container element type and the class-wide type require
7938      --  dispatch table pointer dispacement.
7939
7940      --  Case 3:
7941
7942      --     Obj : CW_Type := Src_Obj;
7943
7944      --  is rewritten into:
7945
7946      --     Obj : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
7947
7948      --  where the type of the source object and the class-wide type require
7949      --  dispatch table pointer displacement.
7950
7951      if Nkind (Obj_Decl) = N_Object_Renaming_Declaration
7952        and then Is_Class_Wide_Type (Obj_Typ)
7953        and then Is_Displace_Call (Renamed_Object (Obj_Id))
7954        and then Nkind (Orig_Decl) = N_Object_Declaration
7955        and then Comes_From_Source (Orig_Decl)
7956      then
7957         Orig_Expr := Expression (Orig_Decl);
7958
7959         return
7960           Is_Controlled_Function_Call (Orig_Expr)
7961             or else Is_Controlled_Indexing (Orig_Expr)
7962             or else Is_Source_Object (Orig_Expr);
7963      end if;
7964
7965      return False;
7966   end Is_Displacement_Of_Object_Or_Function_Result;
7967
7968   ------------------------------
7969   -- Is_Finalizable_Transient --
7970   ------------------------------
7971
7972   function Is_Finalizable_Transient
7973     (Decl     : Node_Id;
7974      Rel_Node : Node_Id) return Boolean
7975   is
7976      Obj_Id  : constant Entity_Id := Defining_Identifier (Decl);
7977      Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
7978
7979      function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean;
7980      --  Determine whether transient object Trans_Id is initialized either
7981      --  by a function call which returns an access type or simply renames
7982      --  another pointer.
7983
7984      function Initialized_By_Aliased_BIP_Func_Call
7985        (Trans_Id : Entity_Id) return Boolean;
7986      --  Determine whether transient object Trans_Id is initialized by a
7987      --  build-in-place function call where the BIPalloc parameter is of
7988      --  value 1 and BIPaccess is not null. This case creates an aliasing
7989      --  between the returned value and the value denoted by BIPaccess.
7990
7991      function Is_Aliased
7992        (Trans_Id   : Entity_Id;
7993         First_Stmt : Node_Id) return Boolean;
7994      --  Determine whether transient object Trans_Id has been renamed or
7995      --  aliased through 'reference in the statement list starting from
7996      --  First_Stmt.
7997
7998      function Is_Allocated (Trans_Id : Entity_Id) return Boolean;
7999      --  Determine whether transient object Trans_Id is allocated on the heap
8000
8001      function Is_Iterated_Container
8002        (Trans_Id   : Entity_Id;
8003         First_Stmt : Node_Id) return Boolean;
8004      --  Determine whether transient object Trans_Id denotes a container which
8005      --  is in the process of being iterated in the statement list starting
8006      --  from First_Stmt.
8007
8008      ---------------------------
8009      -- Initialized_By_Access --
8010      ---------------------------
8011
8012      function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is
8013         Expr : constant Node_Id := Expression (Parent (Trans_Id));
8014
8015      begin
8016         return
8017           Present (Expr)
8018             and then Nkind (Expr) /= N_Reference
8019             and then Is_Access_Type (Etype (Expr));
8020      end Initialized_By_Access;
8021
8022      ------------------------------------------
8023      -- Initialized_By_Aliased_BIP_Func_Call --
8024      ------------------------------------------
8025
8026      function Initialized_By_Aliased_BIP_Func_Call
8027        (Trans_Id : Entity_Id) return Boolean
8028      is
8029         Call : Node_Id := Expression (Parent (Trans_Id));
8030
8031      begin
8032         --  Build-in-place calls usually appear in 'reference format
8033
8034         if Nkind (Call) = N_Reference then
8035            Call := Prefix (Call);
8036         end if;
8037
8038         Call := Unqual_Conv (Call);
8039
8040         if Is_Build_In_Place_Function_Call (Call) then
8041            declare
8042               Access_Nam : Name_Id := No_Name;
8043               Access_OK  : Boolean := False;
8044               Actual     : Node_Id;
8045               Alloc_Nam  : Name_Id := No_Name;
8046               Alloc_OK   : Boolean := False;
8047               Formal     : Node_Id;
8048               Func_Id    : Entity_Id;
8049               Param      : Node_Id;
8050
8051            begin
8052               --  Examine all parameter associations of the function call
8053
8054               Param := First (Parameter_Associations (Call));
8055               while Present (Param) loop
8056                  if Nkind (Param) = N_Parameter_Association
8057                    and then Nkind (Selector_Name (Param)) = N_Identifier
8058                  then
8059                     Actual := Explicit_Actual_Parameter (Param);
8060                     Formal := Selector_Name (Param);
8061
8062                     --  Construct the names of formals BIPaccess and BIPalloc
8063                     --  using the function name retrieved from an arbitrary
8064                     --  formal.
8065
8066                     if Access_Nam = No_Name
8067                       and then Alloc_Nam = No_Name
8068                       and then Present (Entity (Formal))
8069                     then
8070                        Func_Id := Scope (Entity (Formal));
8071
8072                        Access_Nam :=
8073                          New_External_Name (Chars (Func_Id),
8074                            BIP_Formal_Suffix (BIP_Object_Access));
8075
8076                        Alloc_Nam :=
8077                          New_External_Name (Chars (Func_Id),
8078                            BIP_Formal_Suffix (BIP_Alloc_Form));
8079                     end if;
8080
8081                     --  A match for BIPaccess => Temp has been found
8082
8083                     if Chars (Formal) = Access_Nam
8084                       and then Nkind (Actual) /= N_Null
8085                     then
8086                        Access_OK := True;
8087                     end if;
8088
8089                     --  A match for BIPalloc => 1 has been found
8090
8091                     if Chars (Formal) = Alloc_Nam
8092                       and then Nkind (Actual) = N_Integer_Literal
8093                       and then Intval (Actual) = Uint_1
8094                     then
8095                        Alloc_OK := True;
8096                     end if;
8097                  end if;
8098
8099                  Next (Param);
8100               end loop;
8101
8102               return Access_OK and Alloc_OK;
8103            end;
8104         end if;
8105
8106         return False;
8107      end Initialized_By_Aliased_BIP_Func_Call;
8108
8109      ----------------
8110      -- Is_Aliased --
8111      ----------------
8112
8113      function Is_Aliased
8114        (Trans_Id   : Entity_Id;
8115         First_Stmt : Node_Id) return Boolean
8116      is
8117         function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id;
8118         --  Given an object renaming declaration, retrieve the entity of the
8119         --  renamed name. Return Empty if the renamed name is anything other
8120         --  than a variable or a constant.
8121
8122         -------------------------
8123         -- Find_Renamed_Object --
8124         -------------------------
8125
8126         function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id is
8127            Ren_Obj : Node_Id := Empty;
8128
8129            function Find_Object (N : Node_Id) return Traverse_Result;
8130            --  Try to detect an object which is either a constant or a
8131            --  variable.
8132
8133            -----------------
8134            -- Find_Object --
8135            -----------------
8136
8137            function Find_Object (N : Node_Id) return Traverse_Result is
8138            begin
8139               --  Stop the search once a constant or a variable has been
8140               --  detected.
8141
8142               if Nkind (N) = N_Identifier
8143                 and then Present (Entity (N))
8144                 and then Ekind_In (Entity (N), E_Constant, E_Variable)
8145               then
8146                  Ren_Obj := Entity (N);
8147                  return Abandon;
8148               end if;
8149
8150               return OK;
8151            end Find_Object;
8152
8153            procedure Search is new Traverse_Proc (Find_Object);
8154
8155            --  Local variables
8156
8157            Typ : constant Entity_Id := Etype (Defining_Identifier (Ren_Decl));
8158
8159         --  Start of processing for Find_Renamed_Object
8160
8161         begin
8162            --  Actions related to dispatching calls may appear as renamings of
8163            --  tags. Do not process this type of renaming because it does not
8164            --  use the actual value of the object.
8165
8166            if not Is_RTE (Typ, RE_Tag_Ptr) then
8167               Search (Name (Ren_Decl));
8168            end if;
8169
8170            return Ren_Obj;
8171         end Find_Renamed_Object;
8172
8173         --  Local variables
8174
8175         Expr    : Node_Id;
8176         Ren_Obj : Entity_Id;
8177         Stmt    : Node_Id;
8178
8179      --  Start of processing for Is_Aliased
8180
8181      begin
8182         --  A controlled transient object is not considered aliased when it
8183         --  appears inside an expression_with_actions node even when there are
8184         --  explicit aliases of it:
8185
8186         --    do
8187         --       Trans_Id : Ctrl_Typ ...;  --  transient object
8188         --       Alias : ... := Trans_Id;  --  object is aliased
8189         --       Val : constant Boolean :=
8190         --               ... Alias ...;    --  aliasing ends
8191         --       <finalize Trans_Id>       --  object safe to finalize
8192         --    in Val end;
8193
8194         --  Expansion ensures that all aliases are encapsulated in the actions
8195         --  list and do not leak to the expression by forcing the evaluation
8196         --  of the expression.
8197
8198         if Nkind (Rel_Node) = N_Expression_With_Actions then
8199            return False;
8200
8201         --  Otherwise examine the statements after the controlled transient
8202         --  object and look for various forms of aliasing.
8203
8204         else
8205            Stmt := First_Stmt;
8206            while Present (Stmt) loop
8207               if Nkind (Stmt) = N_Object_Declaration then
8208                  Expr := Expression (Stmt);
8209
8210                  --  Aliasing of the form:
8211                  --    Obj : ... := Trans_Id'reference;
8212
8213                  if Present (Expr)
8214                    and then Nkind (Expr) = N_Reference
8215                    and then Nkind (Prefix (Expr)) = N_Identifier
8216                    and then Entity (Prefix (Expr)) = Trans_Id
8217                  then
8218                     return True;
8219                  end if;
8220
8221               elsif Nkind (Stmt) = N_Object_Renaming_Declaration then
8222                  Ren_Obj := Find_Renamed_Object (Stmt);
8223
8224                  --  Aliasing of the form:
8225                  --    Obj : ... renames ... Trans_Id ...;
8226
8227                  if Present (Ren_Obj) and then Ren_Obj = Trans_Id then
8228                     return True;
8229                  end if;
8230               end if;
8231
8232               Next (Stmt);
8233            end loop;
8234
8235            return False;
8236         end if;
8237      end Is_Aliased;
8238
8239      ------------------
8240      -- Is_Allocated --
8241      ------------------
8242
8243      function Is_Allocated (Trans_Id : Entity_Id) return Boolean is
8244         Expr : constant Node_Id := Expression (Parent (Trans_Id));
8245      begin
8246         return
8247           Is_Access_Type (Etype (Trans_Id))
8248             and then Present (Expr)
8249             and then Nkind (Expr) = N_Allocator;
8250      end Is_Allocated;
8251
8252      ---------------------------
8253      -- Is_Iterated_Container --
8254      ---------------------------
8255
8256      function Is_Iterated_Container
8257        (Trans_Id   : Entity_Id;
8258         First_Stmt : Node_Id) return Boolean
8259      is
8260         Aspect : Node_Id;
8261         Call   : Node_Id;
8262         Iter   : Entity_Id;
8263         Param  : Node_Id;
8264         Stmt   : Node_Id;
8265         Typ    : Entity_Id;
8266
8267      begin
8268         --  It is not possible to iterate over containers in non-Ada 2012 code
8269
8270         if Ada_Version < Ada_2012 then
8271            return False;
8272         end if;
8273
8274         Typ := Etype (Trans_Id);
8275
8276         --  Handle access type created for secondary stack use
8277
8278         if Is_Access_Type (Typ) then
8279            Typ := Designated_Type (Typ);
8280         end if;
8281
8282         --  Look for aspect Default_Iterator. It may be part of a type
8283         --  declaration for a container, or inherited from a base type
8284         --  or parent type.
8285
8286         Aspect := Find_Value_Of_Aspect (Typ, Aspect_Default_Iterator);
8287
8288         if Present (Aspect) then
8289            Iter := Entity (Aspect);
8290
8291            --  Examine the statements following the container object and
8292            --  look for a call to the default iterate routine where the
8293            --  first parameter is the transient. Such a call appears as:
8294
8295            --     It : Access_To_CW_Iterator :=
8296            --            Iterate (Tran_Id.all, ...)'reference;
8297
8298            Stmt := First_Stmt;
8299            while Present (Stmt) loop
8300
8301               --  Detect an object declaration which is initialized by a
8302               --  secondary stack function call.
8303
8304               if Nkind (Stmt) = N_Object_Declaration
8305                 and then Present (Expression (Stmt))
8306                 and then Nkind (Expression (Stmt)) = N_Reference
8307                 and then Nkind (Prefix (Expression (Stmt))) = N_Function_Call
8308               then
8309                  Call := Prefix (Expression (Stmt));
8310
8311                  --  The call must invoke the default iterate routine of
8312                  --  the container and the transient object must appear as
8313                  --  the first actual parameter. Skip any calls whose names
8314                  --  are not entities.
8315
8316                  if Is_Entity_Name (Name (Call))
8317                    and then Entity (Name (Call)) = Iter
8318                    and then Present (Parameter_Associations (Call))
8319                  then
8320                     Param := First (Parameter_Associations (Call));
8321
8322                     if Nkind (Param) = N_Explicit_Dereference
8323                       and then Entity (Prefix (Param)) = Trans_Id
8324                     then
8325                        return True;
8326                     end if;
8327                  end if;
8328               end if;
8329
8330               Next (Stmt);
8331            end loop;
8332         end if;
8333
8334         return False;
8335      end Is_Iterated_Container;
8336
8337      --  Local variables
8338
8339      Desig : Entity_Id := Obj_Typ;
8340
8341   --  Start of processing for Is_Finalizable_Transient
8342
8343   begin
8344      --  Handle access types
8345
8346      if Is_Access_Type (Desig) then
8347         Desig := Available_View (Designated_Type (Desig));
8348      end if;
8349
8350      return
8351        Ekind_In (Obj_Id, E_Constant, E_Variable)
8352          and then Needs_Finalization (Desig)
8353          and then Requires_Transient_Scope (Desig)
8354          and then Nkind (Rel_Node) /= N_Simple_Return_Statement
8355
8356          --  Do not consider a transient object that was already processed
8357
8358          and then not Is_Finalized_Transient (Obj_Id)
8359
8360          --  Do not consider renamed or 'reference-d transient objects because
8361          --  the act of renaming extends the object's lifetime.
8362
8363          and then not Is_Aliased (Obj_Id, Decl)
8364
8365          --  Do not consider transient objects allocated on the heap since
8366          --  they are attached to a finalization master.
8367
8368          and then not Is_Allocated (Obj_Id)
8369
8370          --  If the transient object is a pointer, check that it is not
8371          --  initialized by a function that returns a pointer or acts as a
8372          --  renaming of another pointer.
8373
8374          and then
8375            (not Is_Access_Type (Obj_Typ)
8376               or else not Initialized_By_Access (Obj_Id))
8377
8378          --  Do not consider transient objects which act as indirect aliases
8379          --  of build-in-place function results.
8380
8381          and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id)
8382
8383          --  Do not consider conversions of tags to class-wide types
8384
8385          and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
8386
8387          --  Do not consider iterators because those are treated as normal
8388          --  controlled objects and are processed by the usual finalization
8389          --  machinery. This avoids the double finalization of an iterator.
8390
8391          and then not Is_Iterator (Desig)
8392
8393          --  Do not consider containers in the context of iterator loops. Such
8394          --  transient objects must exist for as long as the loop is around,
8395          --  otherwise any operation carried out by the iterator will fail.
8396
8397          and then not Is_Iterated_Container (Obj_Id, Decl);
8398   end Is_Finalizable_Transient;
8399
8400   ---------------------------------
8401   -- Is_Fully_Repped_Tagged_Type --
8402   ---------------------------------
8403
8404   function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is
8405      U    : constant Entity_Id := Underlying_Type (T);
8406      Comp : Entity_Id;
8407
8408   begin
8409      if No (U) or else not Is_Tagged_Type (U) then
8410         return False;
8411      elsif Has_Discriminants (U) then
8412         return False;
8413      elsif not Has_Specified_Layout (U) then
8414         return False;
8415      end if;
8416
8417      --  Here we have a tagged type, see if it has any component (other than
8418      --  tag and parent) with no component_clause. If so, we return False.
8419
8420      Comp := First_Component (U);
8421      while Present (Comp) loop
8422         if not Is_Tag (Comp)
8423           and then Chars (Comp) /= Name_uParent
8424           and then No (Component_Clause (Comp))
8425         then
8426            return False;
8427         else
8428            Next_Component (Comp);
8429         end if;
8430      end loop;
8431
8432      --  All components have clauses
8433
8434      return True;
8435   end Is_Fully_Repped_Tagged_Type;
8436
8437   ----------------------------------
8438   -- Is_Library_Level_Tagged_Type --
8439   ----------------------------------
8440
8441   function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
8442   begin
8443      return Is_Tagged_Type (Typ) and then Is_Library_Level_Entity (Typ);
8444   end Is_Library_Level_Tagged_Type;
8445
8446   --------------------------
8447   -- Is_Non_BIP_Func_Call --
8448   --------------------------
8449
8450   function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is
8451   begin
8452      --  The expected call is of the format
8453      --
8454      --    Func_Call'reference
8455
8456      return
8457        Nkind (Expr) = N_Reference
8458          and then Nkind (Prefix (Expr)) = N_Function_Call
8459          and then not Is_Build_In_Place_Function_Call (Prefix (Expr));
8460   end Is_Non_BIP_Func_Call;
8461
8462   ----------------------------------
8463   -- Is_Possibly_Unaligned_Object --
8464   ----------------------------------
8465
8466   function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
8467      T  : constant Entity_Id := Etype (N);
8468
8469   begin
8470      --  If renamed object, apply test to underlying object
8471
8472      if Is_Entity_Name (N)
8473        and then Is_Object (Entity (N))
8474        and then Present (Renamed_Object (Entity (N)))
8475      then
8476         return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
8477      end if;
8478
8479      --  Tagged and controlled types and aliased types are always aligned, as
8480      --  are concurrent types.
8481
8482      if Is_Aliased (T)
8483        or else Has_Controlled_Component (T)
8484        or else Is_Concurrent_Type (T)
8485        or else Is_Tagged_Type (T)
8486        or else Is_Controlled (T)
8487      then
8488         return False;
8489      end if;
8490
8491      --  If this is an element of a packed array, may be unaligned
8492
8493      if Is_Ref_To_Bit_Packed_Array (N) then
8494         return True;
8495      end if;
8496
8497      --  Case of indexed component reference: test whether prefix is unaligned
8498
8499      if Nkind (N) = N_Indexed_Component then
8500         return Is_Possibly_Unaligned_Object (Prefix (N));
8501
8502      --  Case of selected component reference
8503
8504      elsif Nkind (N) = N_Selected_Component then
8505         declare
8506            P : constant Node_Id   := Prefix (N);
8507            C : constant Entity_Id := Entity (Selector_Name (N));
8508            M : Nat;
8509            S : Nat;
8510
8511         begin
8512            --  If component reference is for an array with nonstatic bounds,
8513            --  then it is always aligned: we can only process unaligned arrays
8514            --  with static bounds (more precisely compile time known bounds).
8515
8516            if Is_Array_Type (T)
8517              and then not Compile_Time_Known_Bounds (T)
8518            then
8519               return False;
8520            end if;
8521
8522            --  If component is aliased, it is definitely properly aligned
8523
8524            if Is_Aliased (C) then
8525               return False;
8526            end if;
8527
8528            --  If component is for a type implemented as a scalar, and the
8529            --  record is packed, and the component is other than the first
8530            --  component of the record, then the component may be unaligned.
8531
8532            if Is_Packed (Etype (P))
8533              and then Represented_As_Scalar (Etype (C))
8534              and then First_Entity (Scope (C)) /= C
8535            then
8536               return True;
8537            end if;
8538
8539            --  Compute maximum possible alignment for T
8540
8541            --  If alignment is known, then that settles things
8542
8543            if Known_Alignment (T) then
8544               M := UI_To_Int (Alignment (T));
8545
8546            --  If alignment is not known, tentatively set max alignment
8547
8548            else
8549               M := Ttypes.Maximum_Alignment;
8550
8551               --  We can reduce this if the Esize is known since the default
8552               --  alignment will never be more than the smallest power of 2
8553               --  that does not exceed this Esize value.
8554
8555               if Known_Esize (T) then
8556                  S := UI_To_Int (Esize (T));
8557
8558                  while (M / 2) >= S loop
8559                     M := M / 2;
8560                  end loop;
8561               end if;
8562            end if;
8563
8564            --  The following code is historical, it used to be present but it
8565            --  is too cautious, because the front-end does not know the proper
8566            --  default alignments for the target. Also, if the alignment is
8567            --  not known, the front end can't know in any case. If a copy is
8568            --  needed, the back-end will take care of it. This whole section
8569            --  including this comment can be removed later ???
8570
8571            --  If the component reference is for a record that has a specified
8572            --  alignment, and we either know it is too small, or cannot tell,
8573            --  then the component may be unaligned.
8574
8575            --  What is the following commented out code ???
8576
8577            --  if Known_Alignment (Etype (P))
8578            --    and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment
8579            --    and then M > Alignment (Etype (P))
8580            --  then
8581            --     return True;
8582            --  end if;
8583
8584            --  Case of component clause present which may specify an
8585            --  unaligned position.
8586
8587            if Present (Component_Clause (C)) then
8588
8589               --  Otherwise we can do a test to make sure that the actual
8590               --  start position in the record, and the length, are both
8591               --  consistent with the required alignment. If not, we know
8592               --  that we are unaligned.
8593
8594               declare
8595                  Align_In_Bits : constant Nat := M * System_Storage_Unit;
8596                  Comp : Entity_Id;
8597
8598               begin
8599                  Comp := C;
8600
8601                  --  For a component inherited in a record extension, the
8602                  --  clause is inherited but position and size are not set.
8603
8604                  if Is_Base_Type (Etype (P))
8605                    and then Is_Tagged_Type (Etype (P))
8606                    and then Present (Original_Record_Component (Comp))
8607                  then
8608                     Comp := Original_Record_Component (Comp);
8609                  end if;
8610
8611                  if Component_Bit_Offset (Comp) mod Align_In_Bits /= 0
8612                    or else Esize (Comp) mod Align_In_Bits /= 0
8613                  then
8614                     return True;
8615                  end if;
8616               end;
8617            end if;
8618
8619            --  Otherwise, for a component reference, test prefix
8620
8621            return Is_Possibly_Unaligned_Object (P);
8622         end;
8623
8624      --  If not a component reference, must be aligned
8625
8626      else
8627         return False;
8628      end if;
8629   end Is_Possibly_Unaligned_Object;
8630
8631   ---------------------------------
8632   -- Is_Possibly_Unaligned_Slice --
8633   ---------------------------------
8634
8635   function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
8636   begin
8637      --  Go to renamed object
8638
8639      if Is_Entity_Name (N)
8640        and then Is_Object (Entity (N))
8641        and then Present (Renamed_Object (Entity (N)))
8642      then
8643         return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
8644      end if;
8645
8646      --  The reference must be a slice
8647
8648      if Nkind (N) /= N_Slice then
8649         return False;
8650      end if;
8651
8652      --  If it is a slice, then look at the array type being sliced
8653
8654      declare
8655         Sarr : constant Node_Id := Prefix (N);
8656         --  Prefix of the slice, i.e. the array being sliced
8657
8658         Styp : constant Entity_Id := Etype (Prefix (N));
8659         --  Type of the array being sliced
8660
8661         Pref : Node_Id;
8662         Ptyp : Entity_Id;
8663
8664      begin
8665         --  The problems arise if the array object that is being sliced
8666         --  is a component of a record or array, and we cannot guarantee
8667         --  the alignment of the array within its containing object.
8668
8669         --  To investigate this, we look at successive prefixes to see
8670         --  if we have a worrisome indexed or selected component.
8671
8672         Pref := Sarr;
8673         loop
8674            --  Case of array is part of an indexed component reference
8675
8676            if Nkind (Pref) = N_Indexed_Component then
8677               Ptyp := Etype (Prefix (Pref));
8678
8679               --  The only problematic case is when the array is packed, in
8680               --  which case we really know nothing about the alignment of
8681               --  individual components.
8682
8683               if Is_Bit_Packed_Array (Ptyp) then
8684                  return True;
8685               end if;
8686
8687            --  Case of array is part of a selected component reference
8688
8689            elsif Nkind (Pref) = N_Selected_Component then
8690               Ptyp := Etype (Prefix (Pref));
8691
8692               --  We are definitely in trouble if the record in question
8693               --  has an alignment, and either we know this alignment is
8694               --  inconsistent with the alignment of the slice, or we don't
8695               --  know what the alignment of the slice should be. But this
8696               --  really matters only if the target has strict alignment.
8697
8698               if Target_Strict_Alignment
8699                 and then Known_Alignment (Ptyp)
8700                 and then (Unknown_Alignment (Styp)
8701                            or else Alignment (Styp) > Alignment (Ptyp))
8702               then
8703                  return True;
8704               end if;
8705
8706               --  We are in potential trouble if the record type is packed.
8707               --  We could special case when we know that the array is the
8708               --  first component, but that's not such a simple case ???
8709
8710               if Is_Packed (Ptyp) then
8711                  return True;
8712               end if;
8713
8714               --  We are in trouble if there is a component clause, and
8715               --  either we do not know the alignment of the slice, or
8716               --  the alignment of the slice is inconsistent with the
8717               --  bit position specified by the component clause.
8718
8719               declare
8720                  Field : constant Entity_Id := Entity (Selector_Name (Pref));
8721               begin
8722                  if Present (Component_Clause (Field))
8723                    and then
8724                      (Unknown_Alignment (Styp)
8725                        or else
8726                         (Component_Bit_Offset (Field) mod
8727                           (System_Storage_Unit * Alignment (Styp))) /= 0)
8728                  then
8729                     return True;
8730                  end if;
8731               end;
8732
8733            --  For cases other than selected or indexed components we know we
8734            --  are OK, since no issues arise over alignment.
8735
8736            else
8737               return False;
8738            end if;
8739
8740            --  We processed an indexed component or selected component
8741            --  reference that looked safe, so keep checking prefixes.
8742
8743            Pref := Prefix (Pref);
8744         end loop;
8745      end;
8746   end Is_Possibly_Unaligned_Slice;
8747
8748   -------------------------------
8749   -- Is_Related_To_Func_Return --
8750   -------------------------------
8751
8752   function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is
8753      Expr : constant Node_Id := Related_Expression (Id);
8754   begin
8755      return
8756        Present (Expr)
8757          and then Nkind (Expr) = N_Explicit_Dereference
8758          and then Nkind (Parent (Expr)) = N_Simple_Return_Statement;
8759   end Is_Related_To_Func_Return;
8760
8761   --------------------------------
8762   -- Is_Ref_To_Bit_Packed_Array --
8763   --------------------------------
8764
8765   function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
8766      Result : Boolean;
8767      Expr   : Node_Id;
8768
8769   begin
8770      if Is_Entity_Name (N)
8771        and then Is_Object (Entity (N))
8772        and then Present (Renamed_Object (Entity (N)))
8773      then
8774         return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
8775      end if;
8776
8777      if Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
8778         if Is_Bit_Packed_Array (Etype (Prefix (N))) then
8779            Result := True;
8780         else
8781            Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
8782         end if;
8783
8784         if Result and then Nkind (N) = N_Indexed_Component then
8785            Expr := First (Expressions (N));
8786            while Present (Expr) loop
8787               Force_Evaluation (Expr);
8788               Next (Expr);
8789            end loop;
8790         end if;
8791
8792         return Result;
8793
8794      else
8795         return False;
8796      end if;
8797   end Is_Ref_To_Bit_Packed_Array;
8798
8799   --------------------------------
8800   -- Is_Ref_To_Bit_Packed_Slice --
8801   --------------------------------
8802
8803   function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
8804   begin
8805      if Nkind (N) = N_Type_Conversion then
8806         return Is_Ref_To_Bit_Packed_Slice (Expression (N));
8807
8808      elsif Is_Entity_Name (N)
8809        and then Is_Object (Entity (N))
8810        and then Present (Renamed_Object (Entity (N)))
8811      then
8812         return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
8813
8814      elsif Nkind (N) = N_Slice
8815        and then Is_Bit_Packed_Array (Etype (Prefix (N)))
8816      then
8817         return True;
8818
8819      elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
8820         return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
8821
8822      else
8823         return False;
8824      end if;
8825   end Is_Ref_To_Bit_Packed_Slice;
8826
8827   -----------------------
8828   -- Is_Renamed_Object --
8829   -----------------------
8830
8831   function Is_Renamed_Object (N : Node_Id) return Boolean is
8832      Pnod : constant Node_Id   := Parent (N);
8833      Kind : constant Node_Kind := Nkind (Pnod);
8834   begin
8835      if Kind = N_Object_Renaming_Declaration then
8836         return True;
8837      elsif Nkind_In (Kind, N_Indexed_Component, N_Selected_Component) then
8838         return Is_Renamed_Object (Pnod);
8839      else
8840         return False;
8841      end if;
8842   end Is_Renamed_Object;
8843
8844   --------------------------------------
8845   -- Is_Secondary_Stack_BIP_Func_Call --
8846   --------------------------------------
8847
8848   function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is
8849      Alloc_Nam : Name_Id := No_Name;
8850      Actual    : Node_Id;
8851      Call      : Node_Id := Expr;
8852      Formal    : Node_Id;
8853      Param     : Node_Id;
8854
8855   begin
8856      --  Build-in-place calls usually appear in 'reference format. Note that
8857      --  the accessibility check machinery may add an extra 'reference due to
8858      --  side effect removal.
8859
8860      while Nkind (Call) = N_Reference loop
8861         Call := Prefix (Call);
8862      end loop;
8863
8864      Call := Unqual_Conv (Call);
8865
8866      if Is_Build_In_Place_Function_Call (Call) then
8867
8868         --  Examine all parameter associations of the function call
8869
8870         Param := First (Parameter_Associations (Call));
8871         while Present (Param) loop
8872            if Nkind (Param) = N_Parameter_Association then
8873               Formal := Selector_Name (Param);
8874               Actual := Explicit_Actual_Parameter (Param);
8875
8876               --  Construct the name of formal BIPalloc. It is much easier to
8877               --  extract the name of the function using an arbitrary formal's
8878               --  scope rather than the Name field of Call.
8879
8880               if Alloc_Nam = No_Name and then Present (Entity (Formal)) then
8881                  Alloc_Nam :=
8882                    New_External_Name
8883                      (Chars (Scope (Entity (Formal))),
8884                       BIP_Formal_Suffix (BIP_Alloc_Form));
8885               end if;
8886
8887               --  A match for BIPalloc => 2 has been found
8888
8889               if Chars (Formal) = Alloc_Nam
8890                 and then Nkind (Actual) = N_Integer_Literal
8891                 and then Intval (Actual) = Uint_2
8892               then
8893                  return True;
8894               end if;
8895            end if;
8896
8897            Next (Param);
8898         end loop;
8899      end if;
8900
8901      return False;
8902   end Is_Secondary_Stack_BIP_Func_Call;
8903
8904   -------------------------------------
8905   -- Is_Tag_To_Class_Wide_Conversion --
8906   -------------------------------------
8907
8908   function Is_Tag_To_Class_Wide_Conversion
8909     (Obj_Id : Entity_Id) return Boolean
8910   is
8911      Expr : constant Node_Id := Expression (Parent (Obj_Id));
8912
8913   begin
8914      return
8915        Is_Class_Wide_Type (Etype (Obj_Id))
8916          and then Present (Expr)
8917          and then Nkind (Expr) = N_Unchecked_Type_Conversion
8918          and then Etype (Expression (Expr)) = RTE (RE_Tag);
8919   end Is_Tag_To_Class_Wide_Conversion;
8920
8921   ----------------------------
8922   -- Is_Untagged_Derivation --
8923   ----------------------------
8924
8925   function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
8926   begin
8927      return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
8928               or else
8929                 (Is_Private_Type (T) and then Present (Full_View (T))
8930                   and then not Is_Tagged_Type (Full_View (T))
8931                   and then Is_Derived_Type (Full_View (T))
8932                   and then Etype (Full_View (T)) /= T);
8933   end Is_Untagged_Derivation;
8934
8935   ------------------------------------
8936   -- Is_Untagged_Private_Derivation --
8937   ------------------------------------
8938
8939   function Is_Untagged_Private_Derivation
8940     (Priv_Typ : Entity_Id;
8941      Full_Typ : Entity_Id) return Boolean
8942   is
8943   begin
8944      return
8945        Present (Priv_Typ)
8946          and then Is_Untagged_Derivation (Priv_Typ)
8947          and then Is_Private_Type (Etype (Priv_Typ))
8948          and then Present (Full_Typ)
8949          and then Is_Itype (Full_Typ);
8950   end Is_Untagged_Private_Derivation;
8951
8952   ------------------------------
8953   -- Is_Verifiable_DIC_Pragma --
8954   ------------------------------
8955
8956   function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean is
8957      Args : constant List_Id := Pragma_Argument_Associations (Prag);
8958
8959   begin
8960      --  To qualify as verifiable, a DIC pragma must have a non-null argument
8961
8962      return
8963        Present (Args)
8964          and then Nkind (Get_Pragma_Arg (First (Args))) /= N_Null;
8965   end Is_Verifiable_DIC_Pragma;
8966
8967   ---------------------------
8968   -- Is_Volatile_Reference --
8969   ---------------------------
8970
8971   function Is_Volatile_Reference (N : Node_Id) return Boolean is
8972   begin
8973      --  Only source references are to be treated as volatile, internally
8974      --  generated stuff cannot have volatile external effects.
8975
8976      if not Comes_From_Source (N) then
8977         return False;
8978
8979      --  Never true for reference to a type
8980
8981      elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then
8982         return False;
8983
8984      --  Never true for a compile time known constant
8985
8986      elsif Compile_Time_Known_Value (N) then
8987         return False;
8988
8989      --  True if object reference with volatile type
8990
8991      elsif Is_Volatile_Object (N) then
8992         return True;
8993
8994      --  True if reference to volatile entity
8995
8996      elsif Is_Entity_Name (N) then
8997         return Treat_As_Volatile (Entity (N));
8998
8999      --  True for slice of volatile array
9000
9001      elsif Nkind (N) = N_Slice then
9002         return Is_Volatile_Reference (Prefix (N));
9003
9004      --  True if volatile component
9005
9006      elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
9007         if (Is_Entity_Name (Prefix (N))
9008              and then Has_Volatile_Components (Entity (Prefix (N))))
9009           or else (Present (Etype (Prefix (N)))
9010                     and then Has_Volatile_Components (Etype (Prefix (N))))
9011         then
9012            return True;
9013         else
9014            return Is_Volatile_Reference (Prefix (N));
9015         end if;
9016
9017      --  Otherwise false
9018
9019      else
9020         return False;
9021      end if;
9022   end Is_Volatile_Reference;
9023
9024   --------------------
9025   -- Kill_Dead_Code --
9026   --------------------
9027
9028   procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
9029      W : Boolean := Warn;
9030      --  Set False if warnings suppressed
9031
9032   begin
9033      if Present (N) then
9034         Remove_Warning_Messages (N);
9035
9036         --  Update the internal structures of the ABE mechanism in case the
9037         --  dead node is an elaboration scenario.
9038
9039         Kill_Elaboration_Scenario (N);
9040
9041         --  Generate warning if appropriate
9042
9043         if W then
9044
9045            --  We suppress the warning if this code is under control of an
9046            --  if statement, whose condition is a simple identifier, and
9047            --  either we are in an instance, or warnings off is set for this
9048            --  identifier. The reason for killing it in the instance case is
9049            --  that it is common and reasonable for code to be deleted in
9050            --  instances for various reasons.
9051
9052            --  Could we use Is_Statically_Unevaluated here???
9053
9054            if Nkind (Parent (N)) = N_If_Statement then
9055               declare
9056                  C : constant Node_Id := Condition (Parent (N));
9057               begin
9058                  if Nkind (C) = N_Identifier
9059                    and then
9060                      (In_Instance
9061                        or else (Present (Entity (C))
9062                                  and then Has_Warnings_Off (Entity (C))))
9063                  then
9064                     W := False;
9065                  end if;
9066               end;
9067            end if;
9068
9069            --  Generate warning if not suppressed
9070
9071            if W then
9072               Error_Msg_F
9073                 ("?t?this code can never be executed and has been deleted!",
9074                  N);
9075            end if;
9076         end if;
9077
9078         --  Recurse into block statements and bodies to process declarations
9079         --  and statements.
9080
9081         if Nkind (N) = N_Block_Statement
9082           or else Nkind (N) = N_Subprogram_Body
9083           or else Nkind (N) = N_Package_Body
9084         then
9085            Kill_Dead_Code (Declarations (N), False);
9086            Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
9087
9088            if Nkind (N) = N_Subprogram_Body then
9089               Set_Is_Eliminated (Defining_Entity (N));
9090            end if;
9091
9092         elsif Nkind (N) = N_Package_Declaration then
9093            Kill_Dead_Code (Visible_Declarations (Specification (N)));
9094            Kill_Dead_Code (Private_Declarations (Specification (N)));
9095
9096            --  ??? After this point, Delete_Tree has been called on all
9097            --  declarations in Specification (N), so references to entities
9098            --  therein look suspicious.
9099
9100            declare
9101               E : Entity_Id := First_Entity (Defining_Entity (N));
9102
9103            begin
9104               while Present (E) loop
9105                  if Ekind (E) = E_Operator then
9106                     Set_Is_Eliminated (E);
9107                  end if;
9108
9109                  Next_Entity (E);
9110               end loop;
9111            end;
9112
9113         --  Recurse into composite statement to kill individual statements in
9114         --  particular instantiations.
9115
9116         elsif Nkind (N) = N_If_Statement then
9117            Kill_Dead_Code (Then_Statements (N));
9118            Kill_Dead_Code (Elsif_Parts     (N));
9119            Kill_Dead_Code (Else_Statements (N));
9120
9121         elsif Nkind (N) = N_Loop_Statement then
9122            Kill_Dead_Code (Statements (N));
9123
9124         elsif Nkind (N) = N_Case_Statement then
9125            declare
9126               Alt : Node_Id;
9127            begin
9128               Alt := First (Alternatives (N));
9129               while Present (Alt) loop
9130                  Kill_Dead_Code (Statements (Alt));
9131                  Next (Alt);
9132               end loop;
9133            end;
9134
9135         elsif Nkind (N) = N_Case_Statement_Alternative then
9136            Kill_Dead_Code (Statements (N));
9137
9138         --  Deal with dead instances caused by deleting instantiations
9139
9140         elsif Nkind (N) in N_Generic_Instantiation then
9141            Remove_Dead_Instance (N);
9142         end if;
9143      end if;
9144   end Kill_Dead_Code;
9145
9146   --  Case where argument is a list of nodes to be killed
9147
9148   procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
9149      N : Node_Id;
9150      W : Boolean;
9151
9152   begin
9153      W := Warn;
9154
9155      if Is_Non_Empty_List (L) then
9156         N := First (L);
9157         while Present (N) loop
9158            Kill_Dead_Code (N, W);
9159            W := False;
9160            Next (N);
9161         end loop;
9162      end if;
9163   end Kill_Dead_Code;
9164
9165   ------------------------
9166   -- Known_Non_Negative --
9167   ------------------------
9168
9169   function Known_Non_Negative (Opnd : Node_Id) return Boolean is
9170   begin
9171      if Is_OK_Static_Expression (Opnd) and then Expr_Value (Opnd) >= 0 then
9172         return True;
9173
9174      else
9175         declare
9176            Lo : constant Node_Id := Type_Low_Bound (Etype (Opnd));
9177         begin
9178            return
9179              Is_OK_Static_Expression (Lo) and then Expr_Value (Lo) >= 0;
9180         end;
9181      end if;
9182   end Known_Non_Negative;
9183
9184   -----------------------------
9185   -- Make_CW_Equivalent_Type --
9186   -----------------------------
9187
9188   --  Create a record type used as an equivalent of any member of the class
9189   --  which takes its size from exp.
9190
9191   --  Generate the following code:
9192
9193   --   type Equiv_T is record
9194   --     _parent : T (List of discriminant constraints taken from Exp);
9195   --     Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8);
9196   --   end Equiv_T;
9197   --
9198   --  ??? Note that this type does not guarantee same alignment as all
9199   --  derived types
9200   --
9201   --  Note: for the freezing circuitry, this looks like a record extension,
9202   --  and so we need to make sure that the scalar storage order is the same
9203   --  as that of the parent type. (This does not change anything for the
9204   --  representation of the extension part.)
9205
9206   function Make_CW_Equivalent_Type
9207     (T : Entity_Id;
9208      E : Node_Id) return Entity_Id
9209   is
9210      Loc         : constant Source_Ptr := Sloc (E);
9211      Root_Typ    : constant Entity_Id  := Root_Type (T);
9212      Root_Utyp   : constant Entity_Id  := Underlying_Type (Root_Typ);
9213      List_Def    : constant List_Id    := Empty_List;
9214      Comp_List   : constant List_Id    := New_List;
9215      Equiv_Type  : Entity_Id;
9216      Range_Type  : Entity_Id;
9217      Str_Type    : Entity_Id;
9218      Constr_Root : Entity_Id;
9219      Sizexpr     : Node_Id;
9220
9221   begin
9222      --  If the root type is already constrained, there are no discriminants
9223      --  in the expression.
9224
9225      if not Has_Discriminants (Root_Typ)
9226        or else Is_Constrained (Root_Typ)
9227      then
9228         Constr_Root := Root_Typ;
9229
9230         --  At this point in the expansion, nonlimited view of the type
9231         --  must be available, otherwise the error will be reported later.
9232
9233         if From_Limited_With (Constr_Root)
9234           and then Present (Non_Limited_View (Constr_Root))
9235         then
9236            Constr_Root := Non_Limited_View (Constr_Root);
9237         end if;
9238
9239      else
9240         Constr_Root := Make_Temporary (Loc, 'R');
9241
9242         --  subtype cstr__n is T (List of discr constraints taken from Exp)
9243
9244         Append_To (List_Def,
9245           Make_Subtype_Declaration (Loc,
9246             Defining_Identifier => Constr_Root,
9247             Subtype_Indication  => Make_Subtype_From_Expr (E, Root_Typ)));
9248      end if;
9249
9250      --  Generate the range subtype declaration
9251
9252      Range_Type := Make_Temporary (Loc, 'G');
9253
9254      if not Is_Interface (Root_Typ) then
9255
9256         --  subtype rg__xx is
9257         --    Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit
9258
9259         Sizexpr :=
9260           Make_Op_Subtract (Loc,
9261             Left_Opnd =>
9262               Make_Attribute_Reference (Loc,
9263                 Prefix =>
9264                   OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
9265                 Attribute_Name => Name_Size),
9266             Right_Opnd =>
9267               Make_Attribute_Reference (Loc,
9268                 Prefix => New_Occurrence_Of (Constr_Root, Loc),
9269                 Attribute_Name => Name_Object_Size));
9270      else
9271         --  subtype rg__xx is
9272         --    Storage_Offset range 1 .. Expr'size / Storage_Unit
9273
9274         Sizexpr :=
9275           Make_Attribute_Reference (Loc,
9276             Prefix =>
9277               OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
9278             Attribute_Name => Name_Size);
9279      end if;
9280
9281      Set_Paren_Count (Sizexpr, 1);
9282
9283      Append_To (List_Def,
9284        Make_Subtype_Declaration (Loc,
9285          Defining_Identifier => Range_Type,
9286          Subtype_Indication =>
9287            Make_Subtype_Indication (Loc,
9288              Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
9289              Constraint => Make_Range_Constraint (Loc,
9290                Range_Expression =>
9291                  Make_Range (Loc,
9292                    Low_Bound => Make_Integer_Literal (Loc, 1),
9293                    High_Bound =>
9294                      Make_Op_Divide (Loc,
9295                        Left_Opnd => Sizexpr,
9296                        Right_Opnd => Make_Integer_Literal (Loc,
9297                            Intval => System_Storage_Unit)))))));
9298
9299      --  subtype str__nn is Storage_Array (rg__x);
9300
9301      Str_Type := Make_Temporary (Loc, 'S');
9302      Append_To (List_Def,
9303        Make_Subtype_Declaration (Loc,
9304          Defining_Identifier => Str_Type,
9305          Subtype_Indication =>
9306            Make_Subtype_Indication (Loc,
9307              Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Array), Loc),
9308              Constraint =>
9309                Make_Index_Or_Discriminant_Constraint (Loc,
9310                  Constraints =>
9311                    New_List (New_Occurrence_Of (Range_Type, Loc))))));
9312
9313      --  type Equiv_T is record
9314      --    [ _parent : Tnn; ]
9315      --    E : Str_Type;
9316      --  end Equiv_T;
9317
9318      Equiv_Type := Make_Temporary (Loc, 'T');
9319      Set_Ekind (Equiv_Type, E_Record_Type);
9320      Set_Parent_Subtype (Equiv_Type, Constr_Root);
9321
9322      --  Set Is_Class_Wide_Equivalent_Type very early to trigger the special
9323      --  treatment for this type. In particular, even though _parent's type
9324      --  is a controlled type or contains controlled components, we do not
9325      --  want to set Has_Controlled_Component on it to avoid making it gain
9326      --  an unwanted _controller component.
9327
9328      Set_Is_Class_Wide_Equivalent_Type (Equiv_Type);
9329
9330      --  A class-wide equivalent type does not require initialization
9331
9332      Set_Suppress_Initialization (Equiv_Type);
9333
9334      if not Is_Interface (Root_Typ) then
9335         Append_To (Comp_List,
9336           Make_Component_Declaration (Loc,
9337             Defining_Identifier  =>
9338               Make_Defining_Identifier (Loc, Name_uParent),
9339             Component_Definition =>
9340               Make_Component_Definition (Loc,
9341                 Aliased_Present    => False,
9342                 Subtype_Indication => New_Occurrence_Of (Constr_Root, Loc))));
9343
9344         Set_Reverse_Storage_Order
9345           (Equiv_Type, Reverse_Storage_Order (Base_Type (Root_Utyp)));
9346         Set_Reverse_Bit_Order
9347           (Equiv_Type, Reverse_Bit_Order (Base_Type (Root_Utyp)));
9348      end if;
9349
9350      Append_To (Comp_List,
9351        Make_Component_Declaration (Loc,
9352          Defining_Identifier  => Make_Temporary (Loc, 'C'),
9353          Component_Definition =>
9354            Make_Component_Definition (Loc,
9355              Aliased_Present    => False,
9356              Subtype_Indication => New_Occurrence_Of (Str_Type, Loc))));
9357
9358      Append_To (List_Def,
9359        Make_Full_Type_Declaration (Loc,
9360          Defining_Identifier => Equiv_Type,
9361          Type_Definition     =>
9362            Make_Record_Definition (Loc,
9363              Component_List  =>
9364                Make_Component_List (Loc,
9365                  Component_Items => Comp_List,
9366                  Variant_Part    => Empty))));
9367
9368      --  Suppress all checks during the analysis of the expanded code to avoid
9369      --  the generation of spurious warnings under ZFP run-time.
9370
9371      Insert_Actions (E, List_Def, Suppress => All_Checks);
9372      return Equiv_Type;
9373   end Make_CW_Equivalent_Type;
9374
9375   -------------------------
9376   -- Make_Invariant_Call --
9377   -------------------------
9378
9379   function Make_Invariant_Call (Expr : Node_Id) return Node_Id is
9380      Loc : constant Source_Ptr := Sloc (Expr);
9381      Typ : constant Entity_Id  := Base_Type (Etype (Expr));
9382
9383      Proc_Id : Entity_Id;
9384
9385   begin
9386      pragma Assert (Has_Invariants (Typ));
9387
9388      Proc_Id := Invariant_Procedure (Typ);
9389      pragma Assert (Present (Proc_Id));
9390
9391      --  Ignore the invariant if that policy is in effect
9392
9393      if Invariants_Ignored (Typ) then
9394         return Make_Null_Statement (Loc);
9395      else
9396         return
9397           Make_Procedure_Call_Statement (Loc,
9398             Name                   => New_Occurrence_Of (Proc_Id, Loc),
9399             Parameter_Associations => New_List (Relocate_Node (Expr)));
9400      end if;
9401   end Make_Invariant_Call;
9402
9403   ------------------------
9404   -- Make_Literal_Range --
9405   ------------------------
9406
9407   function Make_Literal_Range
9408     (Loc         : Source_Ptr;
9409      Literal_Typ : Entity_Id) return Node_Id
9410   is
9411      Lo          : constant Node_Id :=
9412                      New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
9413      Index       : constant Entity_Id := Etype (Lo);
9414      Length_Expr : constant Node_Id :=
9415                      Make_Op_Subtract (Loc,
9416                        Left_Opnd  =>
9417                          Make_Integer_Literal (Loc,
9418                            Intval => String_Literal_Length (Literal_Typ)),
9419                        Right_Opnd => Make_Integer_Literal (Loc, 1));
9420
9421      Hi : Node_Id;
9422
9423   begin
9424      Set_Analyzed (Lo, False);
9425
9426      if Is_Integer_Type (Index) then
9427         Hi :=
9428           Make_Op_Add (Loc,
9429             Left_Opnd  => New_Copy_Tree (Lo),
9430             Right_Opnd => Length_Expr);
9431      else
9432         Hi :=
9433           Make_Attribute_Reference (Loc,
9434             Attribute_Name => Name_Val,
9435             Prefix         => New_Occurrence_Of (Index, Loc),
9436             Expressions    => New_List (
9437               Make_Op_Add (Loc,
9438                 Left_Opnd  =>
9439                   Make_Attribute_Reference (Loc,
9440                     Attribute_Name => Name_Pos,
9441                     Prefix         => New_Occurrence_Of (Index, Loc),
9442                     Expressions    => New_List (New_Copy_Tree (Lo))),
9443                 Right_Opnd => Length_Expr)));
9444      end if;
9445
9446      return
9447        Make_Range (Loc,
9448          Low_Bound  => Lo,
9449          High_Bound => Hi);
9450   end Make_Literal_Range;
9451
9452   --------------------------
9453   -- Make_Non_Empty_Check --
9454   --------------------------
9455
9456   function Make_Non_Empty_Check
9457     (Loc : Source_Ptr;
9458      N   : Node_Id) return Node_Id
9459   is
9460   begin
9461      return
9462        Make_Op_Ne (Loc,
9463          Left_Opnd =>
9464            Make_Attribute_Reference (Loc,
9465              Attribute_Name => Name_Length,
9466              Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
9467          Right_Opnd =>
9468            Make_Integer_Literal (Loc, 0));
9469   end Make_Non_Empty_Check;
9470
9471   -------------------------
9472   -- Make_Predicate_Call --
9473   -------------------------
9474
9475   --  WARNING: This routine manages Ghost regions. Return statements must be
9476   --  replaced by gotos which jump to the end of the routine and restore the
9477   --  Ghost mode.
9478
9479   function Make_Predicate_Call
9480     (Typ  : Entity_Id;
9481      Expr : Node_Id;
9482      Mem  : Boolean := False) return Node_Id
9483   is
9484      Loc : constant Source_Ptr := Sloc (Expr);
9485
9486      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
9487      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
9488      --  Save the Ghost-related attributes to restore on exit
9489
9490      Call    : Node_Id;
9491      Func_Id : Entity_Id;
9492
9493   begin
9494      Func_Id := Predicate_Function (Typ);
9495      pragma Assert (Present (Func_Id));
9496
9497      --  The related type may be subject to pragma Ghost. Set the mode now to
9498      --  ensure that the call is properly marked as Ghost.
9499
9500      Set_Ghost_Mode (Typ);
9501
9502      --  Call special membership version if requested and available
9503
9504      if Mem and then Present (Predicate_Function_M (Typ)) then
9505         Func_Id := Predicate_Function_M (Typ);
9506      end if;
9507
9508      --  Case of calling normal predicate function
9509
9510      --  If the type is tagged, the expression may be class-wide, in which
9511      --  case it has to be converted to its root type, given that the
9512      --  generated predicate function is not dispatching. The conversion is
9513      --  type-safe and does not need validation, which matters when private
9514      --  extensions are involved.
9515
9516      if Is_Tagged_Type (Typ) then
9517         Call :=
9518           Make_Function_Call (Loc,
9519             Name                   => New_Occurrence_Of (Func_Id, Loc),
9520             Parameter_Associations =>
9521               New_List (OK_Convert_To (Typ, Relocate_Node (Expr))));
9522      else
9523         Call :=
9524           Make_Function_Call (Loc,
9525             Name                   => New_Occurrence_Of (Func_Id, Loc),
9526             Parameter_Associations => New_List (Relocate_Node (Expr)));
9527      end if;
9528
9529      Restore_Ghost_Region (Saved_GM, Saved_IGR);
9530
9531      return Call;
9532   end Make_Predicate_Call;
9533
9534   --------------------------
9535   -- Make_Predicate_Check --
9536   --------------------------
9537
9538   function Make_Predicate_Check
9539     (Typ  : Entity_Id;
9540      Expr : Node_Id) return Node_Id
9541   is
9542      Loc : constant Source_Ptr := Sloc (Expr);
9543
9544      procedure Add_Failure_Expression (Args : List_Id);
9545      --  Add the failure expression of pragma Predicate_Failure (if any) to
9546      --  list Args.
9547
9548      ----------------------------
9549      -- Add_Failure_Expression --
9550      ----------------------------
9551
9552      procedure Add_Failure_Expression (Args : List_Id) is
9553         function Failure_Expression return Node_Id;
9554         pragma Inline (Failure_Expression);
9555         --  Find aspect or pragma Predicate_Failure that applies to type Typ
9556         --  and return its expression. Return Empty if no such annotation is
9557         --  available.
9558
9559         function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean;
9560         pragma Inline (Is_OK_PF_Aspect);
9561         --  Determine whether aspect Asp is a suitable Predicate_Failure
9562         --  aspect that applies to type Typ.
9563
9564         function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean;
9565         pragma Inline (Is_OK_PF_Pragma);
9566         --  Determine whether pragma Prag is a suitable Predicate_Failure
9567         --  pragma that applies to type Typ.
9568
9569         procedure Replace_Subtype_Reference (N : Node_Id);
9570         --  Replace the current instance of type Typ denoted by N with
9571         --  expression Expr.
9572
9573         ------------------------
9574         -- Failure_Expression --
9575         ------------------------
9576
9577         function Failure_Expression return Node_Id is
9578            Item : Node_Id;
9579
9580         begin
9581            --  The management of the rep item chain involves "inheritance" of
9582            --  parent type chains. If a parent [sub]type is already subject to
9583            --  pragma Predicate_Failure, then the pragma will also appear in
9584            --  the chain of the child [sub]type, which in turn may possess a
9585            --  pragma of its own. Avoid order-dependent issues by inspecting
9586            --  the rep item chain directly. Note that routine Get_Pragma may
9587            --  return a parent pragma.
9588
9589            Item := First_Rep_Item (Typ);
9590            while Present (Item) loop
9591
9592               --  Predicate_Failure appears as an aspect
9593
9594               if Nkind (Item) = N_Aspect_Specification
9595                 and then Is_OK_PF_Aspect (Item)
9596               then
9597                  return Expression (Item);
9598
9599               --  Predicate_Failure appears as a pragma
9600
9601               elsif Nkind (Item) = N_Pragma
9602                 and then Is_OK_PF_Pragma (Item)
9603               then
9604                  return
9605                    Get_Pragma_Arg
9606                      (Next (First (Pragma_Argument_Associations (Item))));
9607               end if;
9608
9609               Item := Next_Rep_Item (Item);
9610            end loop;
9611
9612            return Empty;
9613         end Failure_Expression;
9614
9615         ---------------------
9616         -- Is_OK_PF_Aspect --
9617         ---------------------
9618
9619         function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean is
9620         begin
9621            --  To qualify, the aspect must apply to the type subjected to the
9622            --  predicate check.
9623
9624            return
9625              Chars (Identifier (Asp)) = Name_Predicate_Failure
9626                and then Present (Entity (Asp))
9627                and then Entity (Asp) = Typ;
9628         end Is_OK_PF_Aspect;
9629
9630         ---------------------
9631         -- Is_OK_PF_Pragma --
9632         ---------------------
9633
9634         function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean is
9635            Args    : constant List_Id := Pragma_Argument_Associations (Prag);
9636            Typ_Arg : Node_Id;
9637
9638         begin
9639            --  Nothing to do when the pragma does not denote Predicate_Failure
9640
9641            if Pragma_Name (Prag) /= Name_Predicate_Failure then
9642               return False;
9643
9644            --  Nothing to do when the pragma lacks arguments, in which case it
9645            --  is illegal.
9646
9647            elsif No (Args) or else Is_Empty_List (Args) then
9648               return False;
9649            end if;
9650
9651            Typ_Arg := Get_Pragma_Arg (First (Args));
9652
9653            --  To qualify, the local name argument of the pragma must denote
9654            --  the type subjected to the predicate check.
9655
9656            return
9657              Is_Entity_Name (Typ_Arg)
9658                and then Present (Entity (Typ_Arg))
9659                and then Entity (Typ_Arg) = Typ;
9660         end Is_OK_PF_Pragma;
9661
9662         --------------------------------
9663         --  Replace_Subtype_Reference --
9664         --------------------------------
9665
9666         procedure Replace_Subtype_Reference (N : Node_Id) is
9667         begin
9668            Rewrite (N, New_Copy_Tree (Expr));
9669
9670            --  We want to treat the node as if it comes from source, so that
9671            --  ASIS will not ignore it.
9672
9673            Set_Comes_From_Source (N, True);
9674         end Replace_Subtype_Reference;
9675
9676         procedure Replace_Subtype_References is
9677           new Replace_Type_References_Generic (Replace_Subtype_Reference);
9678
9679         --  Local variables
9680
9681         PF_Expr : constant Node_Id := Failure_Expression;
9682         Expr    : Node_Id;
9683
9684      --  Start of processing for Add_Failure_Expression
9685
9686      begin
9687         if Present (PF_Expr) then
9688
9689            --  Replace any occurrences of the current instance of the type
9690            --  with the object subjected to the predicate check.
9691
9692            Expr := New_Copy_Tree (PF_Expr);
9693            Replace_Subtype_References (Expr, Typ);
9694
9695            --  The failure expression appears as the third argument of the
9696            --  Check pragma.
9697
9698            Append_To (Args,
9699              Make_Pragma_Argument_Association (Loc,
9700                Expression => Expr));
9701         end if;
9702      end Add_Failure_Expression;
9703
9704      --  Local variables
9705
9706      Args : List_Id;
9707      Nam  : Name_Id;
9708
9709   --  Start of processing for Make_Predicate_Check
9710
9711   begin
9712      --  If predicate checks are suppressed, then return a null statement. For
9713      --  this call, we check only the scope setting. If the caller wants to
9714      --  check a specific entity's setting, they must do it manually.
9715
9716      if Predicate_Checks_Suppressed (Empty) then
9717         return Make_Null_Statement (Loc);
9718      end if;
9719
9720      --  Do not generate a check within an internal subprogram (stream
9721      --  functions and the like, including predicate functions).
9722
9723      if Within_Internal_Subprogram then
9724         return Make_Null_Statement (Loc);
9725      end if;
9726
9727      --  Compute proper name to use, we need to get this right so that the
9728      --  right set of check policies apply to the Check pragma we are making.
9729
9730      if Has_Dynamic_Predicate_Aspect (Typ) then
9731         Nam := Name_Dynamic_Predicate;
9732      elsif Has_Static_Predicate_Aspect (Typ) then
9733         Nam := Name_Static_Predicate;
9734      else
9735         Nam := Name_Predicate;
9736      end if;
9737
9738      Args := New_List (
9739        Make_Pragma_Argument_Association (Loc,
9740          Expression => Make_Identifier (Loc, Nam)),
9741        Make_Pragma_Argument_Association (Loc,
9742          Expression => Make_Predicate_Call (Typ, Expr)));
9743
9744      --  If the subtype is subject to pragma Predicate_Failure, add the
9745      --  failure expression as an additional parameter.
9746
9747      Add_Failure_Expression (Args);
9748
9749      return
9750        Make_Pragma (Loc,
9751          Chars                        => Name_Check,
9752          Pragma_Argument_Associations => Args);
9753   end Make_Predicate_Check;
9754
9755   ----------------------------
9756   -- Make_Subtype_From_Expr --
9757   ----------------------------
9758
9759   --  1. If Expr is an unconstrained array expression, creates
9760   --    Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
9761
9762   --  2. If Expr is a unconstrained discriminated type expression, creates
9763   --    Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
9764
9765   --  3. If Expr is class-wide, creates an implicit class-wide subtype
9766
9767   function Make_Subtype_From_Expr
9768     (E          : Node_Id;
9769      Unc_Typ    : Entity_Id;
9770      Related_Id : Entity_Id := Empty) return Node_Id
9771   is
9772      List_Constr : constant List_Id    := New_List;
9773      Loc         : constant Source_Ptr := Sloc (E);
9774      D           : Entity_Id;
9775      Full_Exp    : Node_Id;
9776      Full_Subtyp : Entity_Id;
9777      High_Bound  : Entity_Id;
9778      Index_Typ   : Entity_Id;
9779      Low_Bound   : Entity_Id;
9780      Priv_Subtyp : Entity_Id;
9781      Utyp        : Entity_Id;
9782
9783   begin
9784      if Is_Private_Type (Unc_Typ)
9785        and then Has_Unknown_Discriminants (Unc_Typ)
9786      then
9787         --  The caller requests a unique external name for both the private
9788         --  and the full subtype.
9789
9790         if Present (Related_Id) then
9791            Full_Subtyp :=
9792              Make_Defining_Identifier (Loc,
9793                Chars => New_External_Name (Chars (Related_Id), 'C'));
9794            Priv_Subtyp :=
9795              Make_Defining_Identifier (Loc,
9796                Chars => New_External_Name (Chars (Related_Id), 'P'));
9797
9798         else
9799            Full_Subtyp := Make_Temporary (Loc, 'C');
9800            Priv_Subtyp := Make_Temporary (Loc, 'P');
9801         end if;
9802
9803         --  Prepare the subtype completion. Use the base type to find the
9804         --  underlying type because the type may be a generic actual or an
9805         --  explicit subtype.
9806
9807         Utyp := Underlying_Type (Base_Type (Unc_Typ));
9808
9809         Full_Exp :=
9810           Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E));
9811         Set_Parent (Full_Exp, Parent (E));
9812
9813         Insert_Action (E,
9814           Make_Subtype_Declaration (Loc,
9815             Defining_Identifier => Full_Subtyp,
9816             Subtype_Indication  => Make_Subtype_From_Expr (Full_Exp, Utyp)));
9817
9818         --  Define the dummy private subtype
9819
9820         Set_Ekind          (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
9821         Set_Etype          (Priv_Subtyp, Base_Type (Unc_Typ));
9822         Set_Scope          (Priv_Subtyp, Full_Subtyp);
9823         Set_Is_Constrained (Priv_Subtyp);
9824         Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
9825         Set_Is_Itype       (Priv_Subtyp);
9826         Set_Associated_Node_For_Itype (Priv_Subtyp, E);
9827
9828         if Is_Tagged_Type  (Priv_Subtyp) then
9829            Set_Class_Wide_Type
9830              (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
9831            Set_Direct_Primitive_Operations (Priv_Subtyp,
9832              Direct_Primitive_Operations (Unc_Typ));
9833         end if;
9834
9835         Set_Full_View (Priv_Subtyp, Full_Subtyp);
9836
9837         return New_Occurrence_Of (Priv_Subtyp, Loc);
9838
9839      elsif Is_Array_Type (Unc_Typ) then
9840         Index_Typ := First_Index (Unc_Typ);
9841         for J in 1 .. Number_Dimensions (Unc_Typ) loop
9842
9843            --  Capture the bounds of each index constraint in case the context
9844            --  is an object declaration of an unconstrained type initialized
9845            --  by a function call:
9846
9847            --    Obj : Unconstr_Typ := Func_Call;
9848
9849            --  This scenario requires secondary scope management and the index
9850            --  constraint cannot depend on the temporary used to capture the
9851            --  result of the function call.
9852
9853            --    SS_Mark;
9854            --    Temp : Unconstr_Typ_Ptr := Func_Call'reference;
9855            --    subtype S is Unconstr_Typ (Temp.all'First .. Temp.all'Last);
9856            --    Obj : S := Temp.all;
9857            --    SS_Release;  --  Temp is gone at this point, bounds of S are
9858            --                 --  non existent.
9859
9860            --  Generate:
9861            --    Low_Bound : constant Base_Type (Index_Typ) := E'First (J);
9862
9863            Low_Bound := Make_Temporary (Loc, 'B');
9864            Insert_Action (E,
9865              Make_Object_Declaration (Loc,
9866                Defining_Identifier => Low_Bound,
9867                Object_Definition   =>
9868                  New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
9869                Constant_Present    => True,
9870                Expression          =>
9871                  Make_Attribute_Reference (Loc,
9872                    Prefix         => Duplicate_Subexpr_No_Checks (E),
9873                    Attribute_Name => Name_First,
9874                    Expressions    => New_List (
9875                      Make_Integer_Literal (Loc, J)))));
9876
9877            --  Generate:
9878            --    High_Bound : constant Base_Type (Index_Typ) := E'Last (J);
9879
9880            High_Bound := Make_Temporary (Loc, 'B');
9881            Insert_Action (E,
9882              Make_Object_Declaration (Loc,
9883                Defining_Identifier => High_Bound,
9884                Object_Definition   =>
9885                  New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
9886                Constant_Present    => True,
9887                Expression          =>
9888                  Make_Attribute_Reference (Loc,
9889                    Prefix         => Duplicate_Subexpr_No_Checks (E),
9890                    Attribute_Name => Name_Last,
9891                    Expressions    => New_List (
9892                      Make_Integer_Literal (Loc, J)))));
9893
9894            Append_To (List_Constr,
9895              Make_Range (Loc,
9896                Low_Bound  => New_Occurrence_Of (Low_Bound,  Loc),
9897                High_Bound => New_Occurrence_Of (High_Bound, Loc)));
9898
9899            Index_Typ := Next_Index (Index_Typ);
9900         end loop;
9901
9902      elsif Is_Class_Wide_Type (Unc_Typ) then
9903         declare
9904            CW_Subtype : Entity_Id;
9905            EQ_Typ     : Entity_Id := Empty;
9906
9907         begin
9908            --  A class-wide equivalent type is not needed on VM targets
9909            --  because the VM back-ends handle the class-wide object
9910            --  initialization itself (and doesn't need or want the
9911            --  additional intermediate type to handle the assignment).
9912
9913            if Expander_Active and then Tagged_Type_Expansion then
9914
9915               --  If this is the class-wide type of a completion that is a
9916               --  record subtype, set the type of the class-wide type to be
9917               --  the full base type, for use in the expanded code for the
9918               --  equivalent type. Should this be done earlier when the
9919               --  completion is analyzed ???
9920
9921               if Is_Private_Type (Etype (Unc_Typ))
9922                 and then
9923                   Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype
9924               then
9925                  Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ))));
9926               end if;
9927
9928               EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
9929            end if;
9930
9931            CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
9932            Set_Equivalent_Type (CW_Subtype, EQ_Typ);
9933            Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
9934
9935            return New_Occurrence_Of (CW_Subtype, Loc);
9936         end;
9937
9938      --  Indefinite record type with discriminants
9939
9940      else
9941         D := First_Discriminant (Unc_Typ);
9942         while Present (D) loop
9943            Append_To (List_Constr,
9944              Make_Selected_Component (Loc,
9945                Prefix        => Duplicate_Subexpr_No_Checks (E),
9946                Selector_Name => New_Occurrence_Of (D, Loc)));
9947
9948            Next_Discriminant (D);
9949         end loop;
9950      end if;
9951
9952      return
9953        Make_Subtype_Indication (Loc,
9954          Subtype_Mark => New_Occurrence_Of (Unc_Typ, Loc),
9955          Constraint   =>
9956            Make_Index_Or_Discriminant_Constraint (Loc,
9957              Constraints => List_Constr));
9958   end Make_Subtype_From_Expr;
9959
9960   ---------------
9961   -- Map_Types --
9962   ---------------
9963
9964   procedure Map_Types (Parent_Type : Entity_Id; Derived_Type : Entity_Id) is
9965
9966      --  NOTE: Most of the routines in Map_Types are intentionally unnested to
9967      --  avoid deep indentation of code.
9968
9969      --  NOTE: Routines which deal with discriminant mapping operate on the
9970      --  [underlying/record] full view of various types because those views
9971      --  contain all discriminants and stored constraints.
9972
9973      procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id);
9974      --  Subsidiary to Map_Primitives. Find a primitive in the inheritance or
9975      --  overriding chain starting from Prim whose dispatching type is parent
9976      --  type Par_Typ and add a mapping between the result and primitive Prim.
9977
9978      function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id;
9979      --  Subsidiary to Map_Primitives. Return the next ancestor primitive in
9980      --  the inheritance or overriding chain of subprogram Subp. Return Empty
9981      --  if no such primitive is available.
9982
9983      function Build_Chain
9984        (Par_Typ   : Entity_Id;
9985         Deriv_Typ : Entity_Id) return Elist_Id;
9986      --  Subsidiary to Map_Discriminants. Recreate the derivation chain from
9987      --  parent type Par_Typ leading down towards derived type Deriv_Typ. The
9988      --  list has the form:
9989      --
9990      --    head                                              tail
9991      --    v                                                 v
9992      --    <Ancestor_N> -> <Ancestor_N-1> -> <Ancestor_1> -> Deriv_Typ
9993      --
9994      --  Note that Par_Typ is not part of the resulting derivation chain
9995
9996      function Discriminated_View (Typ : Entity_Id) return Entity_Id;
9997      --  Return the view of type Typ which could potentially contains either
9998      --  the discriminants or stored constraints of the type.
9999
10000      function Find_Discriminant_Value
10001        (Discr     : Entity_Id;
10002         Par_Typ   : Entity_Id;
10003         Deriv_Typ : Entity_Id;
10004         Typ_Elmt  : Elmt_Id) return Node_Or_Entity_Id;
10005      --  Subsidiary to Map_Discriminants. Find the value of discriminant Discr
10006      --  in the derivation chain starting from parent type Par_Typ leading to
10007      --  derived type Deriv_Typ. The returned value is one of the following:
10008      --
10009      --    * An entity which is either a discriminant or a nondiscriminant
10010      --      name, and renames/constraints Discr.
10011      --
10012      --    * An expression which constraints Discr
10013      --
10014      --  Typ_Elmt is an element of the derivation chain created by routine
10015      --  Build_Chain and denotes the current ancestor being examined.
10016
10017      procedure Map_Discriminants
10018        (Par_Typ   : Entity_Id;
10019         Deriv_Typ : Entity_Id);
10020      --  Map each discriminant of type Par_Typ to a meaningful constraint
10021      --  from the point of view of type Deriv_Typ.
10022
10023      procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id);
10024      --  Map each primitive of type Par_Typ to a corresponding primitive of
10025      --  type Deriv_Typ.
10026
10027      -------------------
10028      -- Add_Primitive --
10029      -------------------
10030
10031      procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id) is
10032         Par_Prim : Entity_Id;
10033
10034      begin
10035         --  Inspect the inheritance chain through the Alias attribute and the
10036         --  overriding chain through the Overridden_Operation looking for an
10037         --  ancestor primitive with the appropriate dispatching type.
10038
10039         Par_Prim := Prim;
10040         while Present (Par_Prim) loop
10041            exit when Find_Dispatching_Type (Par_Prim) = Par_Typ;
10042            Par_Prim := Ancestor_Primitive (Par_Prim);
10043         end loop;
10044
10045         --  Create a mapping of the form:
10046
10047         --    parent type primitive -> derived type primitive
10048
10049         if Present (Par_Prim) then
10050            Type_Map.Set (Par_Prim, Prim);
10051         end if;
10052      end Add_Primitive;
10053
10054      ------------------------
10055      -- Ancestor_Primitive --
10056      ------------------------
10057
10058      function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id is
10059         Inher_Prim : constant Entity_Id := Alias (Subp);
10060         Over_Prim  : constant Entity_Id := Overridden_Operation (Subp);
10061
10062      begin
10063         --  The current subprogram overrides an ancestor primitive
10064
10065         if Present (Over_Prim) then
10066            return Over_Prim;
10067
10068         --  The current subprogram is an internally generated alias of an
10069         --  inherited ancestor primitive.
10070
10071         elsif Present (Inher_Prim) then
10072            return Inher_Prim;
10073
10074         --  Otherwise the current subprogram is the root of the inheritance or
10075         --  overriding chain.
10076
10077         else
10078            return Empty;
10079         end if;
10080      end Ancestor_Primitive;
10081
10082      -----------------
10083      -- Build_Chain --
10084      -----------------
10085
10086      function Build_Chain
10087        (Par_Typ   : Entity_Id;
10088         Deriv_Typ : Entity_Id) return Elist_Id
10089      is
10090         Anc_Typ  : Entity_Id;
10091         Chain    : Elist_Id;
10092         Curr_Typ : Entity_Id;
10093
10094      begin
10095         Chain := New_Elmt_List;
10096
10097         --  Add the derived type to the derivation chain
10098
10099         Prepend_Elmt (Deriv_Typ, Chain);
10100
10101         --  Examine all ancestors starting from the derived type climbing
10102         --  towards parent type Par_Typ.
10103
10104         Curr_Typ := Deriv_Typ;
10105         loop
10106            --  Handle the case where the current type is a record which
10107            --  derives from a subtype.
10108
10109            --    subtype Sub_Typ is Par_Typ ...
10110            --    type Deriv_Typ is Sub_Typ ...
10111
10112            if Ekind (Curr_Typ) = E_Record_Type
10113              and then Present (Parent_Subtype (Curr_Typ))
10114            then
10115               Anc_Typ := Parent_Subtype (Curr_Typ);
10116
10117            --  Handle the case where the current type is a record subtype of
10118            --  another subtype.
10119
10120            --    subtype Sub_Typ1 is Par_Typ ...
10121            --    subtype Sub_Typ2 is Sub_Typ1 ...
10122
10123            elsif Ekind (Curr_Typ) = E_Record_Subtype
10124              and then Present (Cloned_Subtype (Curr_Typ))
10125            then
10126               Anc_Typ := Cloned_Subtype (Curr_Typ);
10127
10128            --  Otherwise use the direct parent type
10129
10130            else
10131               Anc_Typ := Etype (Curr_Typ);
10132            end if;
10133
10134            --  Use the first subtype when dealing with itypes
10135
10136            if Is_Itype (Anc_Typ) then
10137               Anc_Typ := First_Subtype (Anc_Typ);
10138            end if;
10139
10140            --  Work with the view which contains the discriminants and stored
10141            --  constraints.
10142
10143            Anc_Typ := Discriminated_View (Anc_Typ);
10144
10145            --  Stop the climb when either the parent type has been reached or
10146            --  there are no more ancestors left to examine.
10147
10148            exit when Anc_Typ = Curr_Typ or else Anc_Typ = Par_Typ;
10149
10150            Prepend_Unique_Elmt (Anc_Typ, Chain);
10151            Curr_Typ := Anc_Typ;
10152         end loop;
10153
10154         return Chain;
10155      end Build_Chain;
10156
10157      ------------------------
10158      -- Discriminated_View --
10159      ------------------------
10160
10161      function Discriminated_View (Typ : Entity_Id) return Entity_Id is
10162         T : Entity_Id;
10163
10164      begin
10165         T := Typ;
10166
10167         --  Use the [underlying] full view when dealing with private types
10168         --  because the view contains all inherited discriminants or stored
10169         --  constraints.
10170
10171         if Is_Private_Type (T) then
10172            if Present (Underlying_Full_View (T)) then
10173               T := Underlying_Full_View (T);
10174
10175            elsif Present (Full_View (T)) then
10176               T := Full_View (T);
10177            end if;
10178         end if;
10179
10180         --  Use the underlying record view when the type is an extenstion of
10181         --  a parent type with unknown discriminants because the view contains
10182         --  all inherited discriminants or stored constraints.
10183
10184         if Ekind (T) = E_Record_Type
10185           and then Present (Underlying_Record_View (T))
10186         then
10187            T := Underlying_Record_View (T);
10188         end if;
10189
10190         return T;
10191      end Discriminated_View;
10192
10193      -----------------------------
10194      -- Find_Discriminant_Value --
10195      -----------------------------
10196
10197      function Find_Discriminant_Value
10198        (Discr     : Entity_Id;
10199         Par_Typ   : Entity_Id;
10200         Deriv_Typ : Entity_Id;
10201         Typ_Elmt  : Elmt_Id) return Node_Or_Entity_Id
10202      is
10203         Discr_Pos : constant Uint      := Discriminant_Number (Discr);
10204         Typ       : constant Entity_Id := Node (Typ_Elmt);
10205
10206         function Find_Constraint_Value
10207           (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id;
10208         --  Given constraint Constr, find what it denotes. This is either:
10209         --
10210         --    * An entity which is either a discriminant or a name
10211         --
10212         --    * An expression
10213
10214         ---------------------------
10215         -- Find_Constraint_Value --
10216         ---------------------------
10217
10218         function Find_Constraint_Value
10219           (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id
10220         is
10221         begin
10222            if Nkind (Constr) in N_Entity then
10223
10224               --  The constraint denotes a discriminant of the curren type
10225               --  which renames the ancestor discriminant:
10226
10227               --              vv
10228               --    type Typ (D1 : ...; DN : ...) is
10229               --      new Anc (Discr => D1) with ...
10230               --                        ^^
10231
10232               if Ekind (Constr) = E_Discriminant then
10233
10234                  --  The discriminant belongs to derived type Deriv_Typ. This
10235                  --  is the final value for the ancestor discriminant as the
10236                  --  derivations chain has been fully exhausted.
10237
10238                  if Typ = Deriv_Typ then
10239                     return Constr;
10240
10241                  --  Otherwise the discriminant may be renamed or constrained
10242                  --  at a lower level. Continue looking down the derivation
10243                  --  chain.
10244
10245                  else
10246                     return
10247                       Find_Discriminant_Value
10248                         (Discr     => Constr,
10249                          Par_Typ   => Par_Typ,
10250                          Deriv_Typ => Deriv_Typ,
10251                          Typ_Elmt  => Next_Elmt (Typ_Elmt));
10252                  end if;
10253
10254               --  Otherwise the constraint denotes a reference to some name
10255               --  which results in a Girder discriminant:
10256
10257               --    vvvv
10258               --    Name : ...;
10259               --    type Typ (D1 : ...; DN : ...) is
10260               --      new Anc (Discr => Name) with ...
10261               --                        ^^^^
10262
10263               --  Return the name as this is the proper constraint of the
10264               --  discriminant.
10265
10266               else
10267                  return Constr;
10268               end if;
10269
10270            --  The constraint denotes a reference to a name
10271
10272            elsif Is_Entity_Name (Constr) then
10273               return Find_Constraint_Value (Entity (Constr));
10274
10275            --  Otherwise the current constraint is an expression which yields
10276            --  a Girder discriminant:
10277
10278            --    type Typ (D1 : ...; DN : ...) is
10279            --      new Anc (Discr => <expression>) with ...
10280            --                         ^^^^^^^^^^
10281
10282            --  Return the expression as this is the proper constraint of the
10283            --  discriminant.
10284
10285            else
10286               return Constr;
10287            end if;
10288         end Find_Constraint_Value;
10289
10290         --  Local variables
10291
10292         Constrs : constant Elist_Id := Stored_Constraint (Typ);
10293
10294         Constr_Elmt : Elmt_Id;
10295         Pos         : Uint;
10296         Typ_Discr   : Entity_Id;
10297
10298      --  Start of processing for Find_Discriminant_Value
10299
10300      begin
10301         --  The algorithm for finding the value of a discriminant works as
10302         --  follows. First, it recreates the derivation chain from Par_Typ
10303         --  to Deriv_Typ as a list:
10304
10305         --     Par_Typ      (shown for completeness)
10306         --        v
10307         --    Ancestor_N  <-- head of chain
10308         --        v
10309         --    Ancestor_1
10310         --        v
10311         --    Deriv_Typ   <--  tail of chain
10312
10313         --  The algorithm then traces the fate of a parent discriminant down
10314         --  the derivation chain. At each derivation level, the discriminant
10315         --  may be either inherited or constrained.
10316
10317         --    1) Discriminant is inherited: there are two cases, depending on
10318         --    which type is inheriting.
10319
10320         --    1.1) Deriv_Typ is inheriting:
10321
10322         --      type Ancestor (D_1 : ...) is tagged ...
10323         --      type Deriv_Typ is new Ancestor ...
10324
10325         --    In this case the inherited discriminant is the final value of
10326         --    the parent discriminant because the end of the derivation chain
10327         --    has been reached.
10328
10329         --    1.2) Some other type is inheriting:
10330
10331         --      type Ancestor_1 (D_1 : ...) is tagged ...
10332         --      type Ancestor_2 is new Ancestor_1 ...
10333
10334         --    In this case the algorithm continues to trace the fate of the
10335         --    inherited discriminant down the derivation chain because it may
10336         --    be further inherited or constrained.
10337
10338         --    2) Discriminant is constrained: there are three cases, depending
10339         --    on what the constraint is.
10340
10341         --    2.1) The constraint is another discriminant (aka renaming):
10342
10343         --      type Ancestor_1 (D_1 : ...) is tagged ...
10344         --      type Ancestor_2 (D_2 : ...) is new Ancestor_1 (D_1 => D_2) ...
10345
10346         --    In this case the constraining discriminant becomes the one to
10347         --    track down the derivation chain. The algorithm already knows
10348         --    that D_2 constrains D_1, therefore if the algorithm finds the
10349         --    value of D_2, then this would also be the value for D_1.
10350
10351         --    2.2) The constraint is a name (aka Girder):
10352
10353         --      Name : ...
10354         --      type Ancestor_1 (D_1 : ...) is tagged ...
10355         --      type Ancestor_2 is new Ancestor_1 (D_1 => Name) ...
10356
10357         --    In this case the name is the final value of D_1 because the
10358         --    discriminant cannot be further constrained.
10359
10360         --    2.3) The constraint is an expression (aka Girder):
10361
10362         --      type Ancestor_1 (D_1 : ...) is tagged ...
10363         --      type Ancestor_2 is new Ancestor_1 (D_1 => 1 + 2) ...
10364
10365         --    Similar to 2.2, the expression is the final value of D_1
10366
10367         Pos := Uint_1;
10368
10369         --  When a derived type constrains its parent type, all constaints
10370         --  appear in the Stored_Constraint list. Examine the list looking
10371         --  for a positional match.
10372
10373         if Present (Constrs) then
10374            Constr_Elmt := First_Elmt (Constrs);
10375            while Present (Constr_Elmt) loop
10376
10377               --  The position of the current constraint matches that of the
10378               --  ancestor discriminant.
10379
10380               if Pos = Discr_Pos then
10381                  return Find_Constraint_Value (Node (Constr_Elmt));
10382               end if;
10383
10384               Next_Elmt (Constr_Elmt);
10385               Pos := Pos + 1;
10386            end loop;
10387
10388         --  Otherwise the derived type does not constraint its parent type in
10389         --  which case it inherits the parent discriminants.
10390
10391         else
10392            Typ_Discr := First_Discriminant (Typ);
10393            while Present (Typ_Discr) loop
10394
10395               --  The position of the current discriminant matches that of the
10396               --  ancestor discriminant.
10397
10398               if Pos = Discr_Pos then
10399                  return Find_Constraint_Value (Typ_Discr);
10400               end if;
10401
10402               Next_Discriminant (Typ_Discr);
10403               Pos := Pos + 1;
10404            end loop;
10405         end if;
10406
10407         --  A discriminant must always have a corresponding value. This is
10408         --  either another discriminant, a name, or an expression. If this
10409         --  point is reached, them most likely the derivation chain employs
10410         --  the wrong views of types.
10411
10412         pragma Assert (False);
10413
10414         return Empty;
10415      end Find_Discriminant_Value;
10416
10417      -----------------------
10418      -- Map_Discriminants --
10419      -----------------------
10420
10421      procedure Map_Discriminants
10422        (Par_Typ   : Entity_Id;
10423         Deriv_Typ : Entity_Id)
10424      is
10425         Deriv_Chain : constant Elist_Id := Build_Chain (Par_Typ, Deriv_Typ);
10426
10427         Discr     : Entity_Id;
10428         Discr_Val : Node_Or_Entity_Id;
10429
10430      begin
10431         --  Examine each discriminant of parent type Par_Typ and find a
10432         --  suitable value for it from the point of view of derived type
10433         --  Deriv_Typ.
10434
10435         if Has_Discriminants (Par_Typ) then
10436            Discr := First_Discriminant (Par_Typ);
10437            while Present (Discr) loop
10438               Discr_Val :=
10439                 Find_Discriminant_Value
10440                   (Discr     => Discr,
10441                    Par_Typ   => Par_Typ,
10442                    Deriv_Typ => Deriv_Typ,
10443                    Typ_Elmt  => First_Elmt (Deriv_Chain));
10444
10445               --  Create a mapping of the form:
10446
10447               --    parent type discriminant -> value
10448
10449               Type_Map.Set (Discr, Discr_Val);
10450
10451               Next_Discriminant (Discr);
10452            end loop;
10453         end if;
10454      end Map_Discriminants;
10455
10456      --------------------
10457      -- Map_Primitives --
10458      --------------------
10459
10460      procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id) is
10461         Deriv_Prim : Entity_Id;
10462         Par_Prim   : Entity_Id;
10463         Par_Prims  : Elist_Id;
10464         Prim_Elmt  : Elmt_Id;
10465
10466      begin
10467         --  Inspect the primitives of the derived type and determine whether
10468         --  they relate to the primitives of the parent type. If there is a
10469         --  meaningful relation, create a mapping of the form:
10470
10471         --    parent type primitive -> perived type primitive
10472
10473         if Present (Direct_Primitive_Operations (Deriv_Typ)) then
10474            Prim_Elmt := First_Elmt (Direct_Primitive_Operations (Deriv_Typ));
10475            while Present (Prim_Elmt) loop
10476               Deriv_Prim := Node (Prim_Elmt);
10477
10478               if Is_Subprogram (Deriv_Prim)
10479                 and then Find_Dispatching_Type (Deriv_Prim) = Deriv_Typ
10480               then
10481                  Add_Primitive (Deriv_Prim, Par_Typ);
10482               end if;
10483
10484               Next_Elmt (Prim_Elmt);
10485            end loop;
10486         end if;
10487
10488         --  If the parent operation is an interface operation, the overriding
10489         --  indicator is not present. Instead, we get from the interface
10490         --  operation the primitive of the current type that implements it.
10491
10492         if Is_Interface (Par_Typ) then
10493            Par_Prims := Collect_Primitive_Operations (Par_Typ);
10494
10495            if Present (Par_Prims) then
10496               Prim_Elmt := First_Elmt (Par_Prims);
10497
10498               while Present (Prim_Elmt) loop
10499                  Par_Prim   := Node (Prim_Elmt);
10500                  Deriv_Prim :=
10501                    Find_Primitive_Covering_Interface (Deriv_Typ, Par_Prim);
10502
10503                  if Present (Deriv_Prim) then
10504                     Type_Map.Set (Par_Prim, Deriv_Prim);
10505                  end if;
10506
10507                  Next_Elmt (Prim_Elmt);
10508               end loop;
10509            end if;
10510         end if;
10511      end Map_Primitives;
10512
10513   --  Start of processing for Map_Types
10514
10515   begin
10516      --  Nothing to do if there are no types to work with
10517
10518      if No (Parent_Type) or else No (Derived_Type) then
10519         return;
10520
10521      --  Nothing to do if the mapping already exists
10522
10523      elsif Type_Map.Get (Parent_Type) = Derived_Type then
10524         return;
10525
10526      --  Nothing to do if both types are not tagged. Note that untagged types
10527      --  do not have primitive operations and their discriminants are already
10528      --  handled by gigi.
10529
10530      elsif not Is_Tagged_Type (Parent_Type)
10531        or else not Is_Tagged_Type (Derived_Type)
10532      then
10533         return;
10534      end if;
10535
10536      --  Create a mapping of the form
10537
10538      --    parent type -> derived type
10539
10540      --  to prevent any subsequent attempts to produce the same relations
10541
10542      Type_Map.Set (Parent_Type, Derived_Type);
10543
10544      --  Create mappings of the form
10545
10546      --    parent type discriminant -> derived type discriminant
10547      --      <or>
10548      --    parent type discriminant -> constraint
10549
10550      --  Note that mapping of discriminants breaks privacy because it needs to
10551      --  work with those views which contains the discriminants and any stored
10552      --  constraints.
10553
10554      Map_Discriminants
10555        (Par_Typ   => Discriminated_View (Parent_Type),
10556         Deriv_Typ => Discriminated_View (Derived_Type));
10557
10558      --  Create mappings of the form
10559
10560      --    parent type primitive -> derived type primitive
10561
10562      Map_Primitives
10563        (Par_Typ   => Parent_Type,
10564         Deriv_Typ => Derived_Type);
10565   end Map_Types;
10566
10567   ----------------------------
10568   -- Matching_Standard_Type --
10569   ----------------------------
10570
10571   function Matching_Standard_Type (Typ : Entity_Id) return Entity_Id is
10572      pragma Assert (Is_Scalar_Type (Typ));
10573      Siz : constant Uint := Esize (Typ);
10574
10575   begin
10576      --  Floating-point cases
10577
10578      if Is_Floating_Point_Type (Typ) then
10579         if Siz <= Esize (Standard_Short_Float) then
10580            return Standard_Short_Float;
10581         elsif Siz <= Esize (Standard_Float) then
10582            return Standard_Float;
10583         elsif Siz <= Esize (Standard_Long_Float) then
10584            return Standard_Long_Float;
10585         elsif Siz <= Esize (Standard_Long_Long_Float) then
10586            return Standard_Long_Long_Float;
10587         else
10588            raise Program_Error;
10589         end if;
10590
10591      --  Integer cases (includes fixed-point types)
10592
10593      --  Unsigned integer cases (includes normal enumeration types)
10594
10595      elsif Is_Unsigned_Type (Typ) then
10596         if Siz <= Esize (Standard_Short_Short_Unsigned) then
10597            return Standard_Short_Short_Unsigned;
10598         elsif Siz <= Esize (Standard_Short_Unsigned) then
10599            return Standard_Short_Unsigned;
10600         elsif Siz <= Esize (Standard_Unsigned) then
10601            return Standard_Unsigned;
10602         elsif Siz <= Esize (Standard_Long_Unsigned) then
10603            return Standard_Long_Unsigned;
10604         elsif Siz <= Esize (Standard_Long_Long_Unsigned) then
10605            return Standard_Long_Long_Unsigned;
10606         else
10607            raise Program_Error;
10608         end if;
10609
10610      --  Signed integer cases
10611
10612      else
10613         if Siz <= Esize (Standard_Short_Short_Integer) then
10614            return Standard_Short_Short_Integer;
10615         elsif Siz <= Esize (Standard_Short_Integer) then
10616            return Standard_Short_Integer;
10617         elsif Siz <= Esize (Standard_Integer) then
10618            return Standard_Integer;
10619         elsif Siz <= Esize (Standard_Long_Integer) then
10620            return Standard_Long_Integer;
10621         elsif Siz <= Esize (Standard_Long_Long_Integer) then
10622            return Standard_Long_Long_Integer;
10623         else
10624            raise Program_Error;
10625         end if;
10626      end if;
10627   end Matching_Standard_Type;
10628
10629   -----------------------------
10630   -- May_Generate_Large_Temp --
10631   -----------------------------
10632
10633   --  At the current time, the only types that we return False for (i.e. where
10634   --  we decide we know they cannot generate large temps) are ones where we
10635   --  know the size is 256 bits or less at compile time, and we are still not
10636   --  doing a thorough job on arrays and records ???
10637
10638   function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
10639   begin
10640      if not Size_Known_At_Compile_Time (Typ) then
10641         return False;
10642
10643      elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
10644         return False;
10645
10646      elsif Is_Array_Type (Typ)
10647        and then Present (Packed_Array_Impl_Type (Typ))
10648      then
10649         return May_Generate_Large_Temp (Packed_Array_Impl_Type (Typ));
10650
10651      --  We could do more here to find other small types ???
10652
10653      else
10654         return True;
10655      end if;
10656   end May_Generate_Large_Temp;
10657
10658   --------------------------------------------
10659   -- Needs_Conditional_Null_Excluding_Check --
10660   --------------------------------------------
10661
10662   function Needs_Conditional_Null_Excluding_Check
10663     (Typ : Entity_Id) return Boolean
10664   is
10665   begin
10666      return
10667        Is_Array_Type (Typ) and then Can_Never_Be_Null (Component_Type (Typ));
10668   end Needs_Conditional_Null_Excluding_Check;
10669
10670   ----------------------------
10671   -- Needs_Constant_Address --
10672   ----------------------------
10673
10674   function Needs_Constant_Address
10675     (Decl : Node_Id;
10676      Typ  : Entity_Id) return Boolean
10677   is
10678   begin
10679      --  If we have no initialization of any kind, then we don't need to place
10680      --  any restrictions on the address clause, because the object will be
10681      --  elaborated after the address clause is evaluated. This happens if the
10682      --  declaration has no initial expression, or the type has no implicit
10683      --  initialization, or the object is imported.
10684
10685      --  The same holds for all initialized scalar types and all access types.
10686      --  Packed bit arrays of size up to 64 are represented using a modular
10687      --  type with an initialization (to zero) and can be processed like other
10688      --  initialized scalar types.
10689
10690      --  If the type is controlled, code to attach the object to a
10691      --  finalization chain is generated at the point of declaration, and
10692      --  therefore the elaboration of the object cannot be delayed: the
10693      --  address expression must be a constant.
10694
10695      if No (Expression (Decl))
10696        and then not Needs_Finalization (Typ)
10697        and then
10698          (not Has_Non_Null_Base_Init_Proc (Typ)
10699            or else Is_Imported (Defining_Identifier (Decl)))
10700      then
10701         return False;
10702
10703      elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ))
10704        or else Is_Access_Type (Typ)
10705        or else
10706          (Is_Bit_Packed_Array (Typ)
10707            and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ)))
10708      then
10709         return False;
10710
10711      else
10712         --  Otherwise, we require the address clause to be constant because
10713         --  the call to the initialization procedure (or the attach code) has
10714         --  to happen at the point of the declaration.
10715
10716         --  Actually the IP call has been moved to the freeze actions anyway,
10717         --  so maybe we can relax this restriction???
10718
10719         return True;
10720      end if;
10721   end Needs_Constant_Address;
10722
10723   ----------------------------
10724   -- New_Class_Wide_Subtype --
10725   ----------------------------
10726
10727   function New_Class_Wide_Subtype
10728     (CW_Typ : Entity_Id;
10729      N      : Node_Id) return Entity_Id
10730   is
10731      Res : constant Entity_Id := Create_Itype (E_Void, N);
10732
10733      --  Capture relevant attributes of the class-wide subtype which must be
10734      --  restored after the copy.
10735
10736      Res_Chars  : constant Name_Id   := Chars (Res);
10737      Res_Is_CGE : constant Boolean   := Is_Checked_Ghost_Entity (Res);
10738      Res_Is_IGE : constant Boolean   := Is_Ignored_Ghost_Entity (Res);
10739      Res_Is_IGN : constant Boolean   := Is_Ignored_Ghost_Node   (Res);
10740      Res_Scope  : constant Entity_Id := Scope (Res);
10741
10742   begin
10743      Copy_Node (CW_Typ, Res);
10744
10745      --  Restore the relevant attributes of the class-wide subtype
10746
10747      Set_Chars                   (Res, Res_Chars);
10748      Set_Is_Checked_Ghost_Entity (Res, Res_Is_CGE);
10749      Set_Is_Ignored_Ghost_Entity (Res, Res_Is_IGE);
10750      Set_Is_Ignored_Ghost_Node   (Res, Res_Is_IGN);
10751      Set_Scope                   (Res, Res_Scope);
10752
10753      --  Decorate the class-wide subtype
10754
10755      Set_Associated_Node_For_Itype (Res, N);
10756      Set_Comes_From_Source         (Res, False);
10757      Set_Ekind                     (Res, E_Class_Wide_Subtype);
10758      Set_Etype                     (Res, Base_Type (CW_Typ));
10759      Set_Freeze_Node               (Res, Empty);
10760      Set_Is_Frozen                 (Res, False);
10761      Set_Is_Itype                  (Res);
10762      Set_Is_Public                 (Res, False);
10763      Set_Next_Entity               (Res, Empty);
10764      Set_Prev_Entity               (Res, Empty);
10765      Set_Sloc                      (Res, Sloc (N));
10766
10767      Set_Public_Status (Res);
10768
10769      return Res;
10770   end New_Class_Wide_Subtype;
10771
10772   --------------------------------
10773   -- Non_Limited_Designated_Type --
10774   ---------------------------------
10775
10776   function Non_Limited_Designated_Type (T : Entity_Id) return Entity_Id is
10777      Desig : constant Entity_Id := Designated_Type (T);
10778   begin
10779      if Has_Non_Limited_View (Desig) then
10780         return Non_Limited_View (Desig);
10781      else
10782         return Desig;
10783      end if;
10784   end Non_Limited_Designated_Type;
10785
10786   -----------------------------------
10787   -- OK_To_Do_Constant_Replacement --
10788   -----------------------------------
10789
10790   function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
10791      ES : constant Entity_Id := Scope (E);
10792      CS : Entity_Id;
10793
10794   begin
10795      --  Do not replace statically allocated objects, because they may be
10796      --  modified outside the current scope.
10797
10798      if Is_Statically_Allocated (E) then
10799         return False;
10800
10801      --  Do not replace aliased or volatile objects, since we don't know what
10802      --  else might change the value.
10803
10804      elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
10805         return False;
10806
10807      --  Debug flag -gnatdM disconnects this optimization
10808
10809      elsif Debug_Flag_MM then
10810         return False;
10811
10812      --  Otherwise check scopes
10813
10814      else
10815         CS := Current_Scope;
10816
10817         loop
10818            --  If we are in right scope, replacement is safe
10819
10820            if CS = ES then
10821               return True;
10822
10823            --  Packages do not affect the determination of safety
10824
10825            elsif Ekind (CS) = E_Package then
10826               exit when CS = Standard_Standard;
10827               CS := Scope (CS);
10828
10829            --  Blocks do not affect the determination of safety
10830
10831            elsif Ekind (CS) = E_Block then
10832               CS := Scope (CS);
10833
10834            --  Loops do not affect the determination of safety. Note that we
10835            --  kill all current values on entry to a loop, so we are just
10836            --  talking about processing within a loop here.
10837
10838            elsif Ekind (CS) = E_Loop then
10839               CS := Scope (CS);
10840
10841            --  Otherwise, the reference is dubious, and we cannot be sure that
10842            --  it is safe to do the replacement.
10843
10844            else
10845               exit;
10846            end if;
10847         end loop;
10848
10849         return False;
10850      end if;
10851   end OK_To_Do_Constant_Replacement;
10852
10853   ------------------------------------
10854   -- Possible_Bit_Aligned_Component --
10855   ------------------------------------
10856
10857   function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
10858   begin
10859      --  Do not process an unanalyzed node because it is not yet decorated and
10860      --  most checks performed below will fail.
10861
10862      if not Analyzed (N) then
10863         return False;
10864      end if;
10865
10866      --  There are never alignment issues in CodePeer mode
10867
10868      if CodePeer_Mode then
10869         return False;
10870      end if;
10871
10872      case Nkind (N) is
10873
10874         --  Case of indexed component
10875
10876         when N_Indexed_Component =>
10877            declare
10878               P    : constant Node_Id   := Prefix (N);
10879               Ptyp : constant Entity_Id := Etype (P);
10880
10881            begin
10882               --  If we know the component size and it is not larger than 64,
10883               --  then we are definitely OK. The back end does the assignment
10884               --  of misaligned small objects correctly.
10885
10886               if Known_Static_Component_Size (Ptyp)
10887                 and then Component_Size (Ptyp) <= 64
10888               then
10889                  return False;
10890
10891               --  Otherwise, we need to test the prefix, to see if we are
10892               --  indexing from a possibly unaligned component.
10893
10894               else
10895                  return Possible_Bit_Aligned_Component (P);
10896               end if;
10897            end;
10898
10899         --  Case of selected component
10900
10901         when N_Selected_Component =>
10902            declare
10903               P    : constant Node_Id   := Prefix (N);
10904               Comp : constant Entity_Id := Entity (Selector_Name (N));
10905
10906            begin
10907               --  This is the crucial test: if the component itself causes
10908               --  trouble, then we can stop and return True.
10909
10910               if Component_May_Be_Bit_Aligned (Comp) then
10911                  return True;
10912
10913               --  Otherwise, we need to test the prefix, to see if we are
10914               --  selecting from a possibly unaligned component.
10915
10916               else
10917                  return Possible_Bit_Aligned_Component (P);
10918               end if;
10919            end;
10920
10921         --  For a slice, test the prefix, if that is possibly misaligned,
10922         --  then for sure the slice is.
10923
10924         when N_Slice =>
10925            return Possible_Bit_Aligned_Component (Prefix (N));
10926
10927         --  For an unchecked conversion, check whether the expression may
10928         --  be bit aligned.
10929
10930         when N_Unchecked_Type_Conversion =>
10931            return Possible_Bit_Aligned_Component (Expression (N));
10932
10933         --  If we have none of the above, it means that we have fallen off the
10934         --  top testing prefixes recursively, and we now have a stand alone
10935         --  object, where we don't have a problem, unless this is a renaming,
10936         --  in which case we need to look into the renamed object.
10937
10938         when others =>
10939            if Is_Entity_Name (N)
10940              and then Present (Renamed_Object (Entity (N)))
10941            then
10942               return
10943                 Possible_Bit_Aligned_Component (Renamed_Object (Entity (N)));
10944            else
10945               return False;
10946            end if;
10947      end case;
10948   end Possible_Bit_Aligned_Component;
10949
10950   -----------------------------------------------
10951   -- Process_Statements_For_Controlled_Objects --
10952   -----------------------------------------------
10953
10954   procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is
10955      Loc : constant Source_Ptr := Sloc (N);
10956
10957      function Are_Wrapped (L : List_Id) return Boolean;
10958      --  Determine whether list L contains only one statement which is a block
10959
10960      function Wrap_Statements_In_Block
10961        (L    : List_Id;
10962         Scop : Entity_Id := Current_Scope) return Node_Id;
10963      --  Given a list of statements L, wrap it in a block statement and return
10964      --  the generated node. Scop is either the current scope or the scope of
10965      --  the context (if applicable).
10966
10967      -----------------
10968      -- Are_Wrapped --
10969      -----------------
10970
10971      function Are_Wrapped (L : List_Id) return Boolean is
10972         Stmt : constant Node_Id := First (L);
10973      begin
10974         return
10975           Present (Stmt)
10976             and then No (Next (Stmt))
10977             and then Nkind (Stmt) = N_Block_Statement;
10978      end Are_Wrapped;
10979
10980      ------------------------------
10981      -- Wrap_Statements_In_Block --
10982      ------------------------------
10983
10984      function Wrap_Statements_In_Block
10985        (L    : List_Id;
10986         Scop : Entity_Id := Current_Scope) return Node_Id
10987      is
10988         Block_Id  : Entity_Id;
10989         Block_Nod : Node_Id;
10990         Iter_Loop : Entity_Id;
10991
10992      begin
10993         Block_Nod :=
10994           Make_Block_Statement (Loc,
10995             Declarations               => No_List,
10996             Handled_Statement_Sequence =>
10997               Make_Handled_Sequence_Of_Statements (Loc,
10998                 Statements => L));
10999
11000         --  Create a label for the block in case the block needs to manage the
11001         --  secondary stack. A label allows for flag Uses_Sec_Stack to be set.
11002
11003         Add_Block_Identifier (Block_Nod, Block_Id);
11004
11005         --  When wrapping the statements of an iterator loop, check whether
11006         --  the loop requires secondary stack management and if so, propagate
11007         --  the appropriate flags to the block. This ensures that the cursor
11008         --  is properly cleaned up at each iteration of the loop.
11009
11010         Iter_Loop := Find_Enclosing_Iterator_Loop (Scop);
11011
11012         if Present (Iter_Loop) then
11013            Set_Uses_Sec_Stack (Block_Id, Uses_Sec_Stack (Iter_Loop));
11014
11015            --  Secondary stack reclamation is suppressed when the associated
11016            --  iterator loop contains a return statement which uses the stack.
11017
11018            Set_Sec_Stack_Needed_For_Return
11019              (Block_Id, Sec_Stack_Needed_For_Return (Iter_Loop));
11020         end if;
11021
11022         return Block_Nod;
11023      end Wrap_Statements_In_Block;
11024
11025      --  Local variables
11026
11027      Block : Node_Id;
11028
11029   --  Start of processing for Process_Statements_For_Controlled_Objects
11030
11031   begin
11032      --  Whenever a non-handled statement list is wrapped in a block, the
11033      --  block must be explicitly analyzed to redecorate all entities in the
11034      --  list and ensure that a finalizer is properly built.
11035
11036      case Nkind (N) is
11037         when N_Conditional_Entry_Call
11038            | N_Elsif_Part
11039            | N_If_Statement
11040            | N_Selective_Accept
11041         =>
11042            --  Check the "then statements" for elsif parts and if statements
11043
11044            if Nkind_In (N, N_Elsif_Part, N_If_Statement)
11045              and then not Is_Empty_List (Then_Statements (N))
11046              and then not Are_Wrapped (Then_Statements (N))
11047              and then Requires_Cleanup_Actions
11048                         (L                 => Then_Statements (N),
11049                          Lib_Level         => False,
11050                          Nested_Constructs => False)
11051            then
11052               Block := Wrap_Statements_In_Block (Then_Statements (N));
11053               Set_Then_Statements (N, New_List (Block));
11054
11055               Analyze (Block);
11056            end if;
11057
11058            --  Check the "else statements" for conditional entry calls, if
11059            --  statements and selective accepts.
11060
11061            if Nkind_In (N, N_Conditional_Entry_Call,
11062                            N_If_Statement,
11063                            N_Selective_Accept)
11064              and then not Is_Empty_List (Else_Statements (N))
11065              and then not Are_Wrapped (Else_Statements (N))
11066              and then Requires_Cleanup_Actions
11067                         (L                 => Else_Statements (N),
11068                          Lib_Level         => False,
11069                          Nested_Constructs => False)
11070            then
11071               Block := Wrap_Statements_In_Block (Else_Statements (N));
11072               Set_Else_Statements (N, New_List (Block));
11073
11074               Analyze (Block);
11075            end if;
11076
11077         when N_Abortable_Part
11078            | N_Accept_Alternative
11079            | N_Case_Statement_Alternative
11080            | N_Delay_Alternative
11081            | N_Entry_Call_Alternative
11082            | N_Exception_Handler
11083            | N_Loop_Statement
11084            | N_Triggering_Alternative
11085         =>
11086            if not Is_Empty_List (Statements (N))
11087              and then not Are_Wrapped (Statements (N))
11088              and then Requires_Cleanup_Actions
11089                         (L                 => Statements (N),
11090                          Lib_Level         => False,
11091                          Nested_Constructs => False)
11092            then
11093               if Nkind (N) = N_Loop_Statement
11094                 and then Present (Identifier (N))
11095               then
11096                  Block :=
11097                    Wrap_Statements_In_Block
11098                      (L    => Statements (N),
11099                       Scop => Entity (Identifier (N)));
11100               else
11101                  Block := Wrap_Statements_In_Block (Statements (N));
11102               end if;
11103
11104               Set_Statements (N, New_List (Block));
11105               Analyze (Block);
11106            end if;
11107
11108         --  Could be e.g. a loop that was transformed into a block or null
11109         --  statement. Do nothing for terminate alternatives.
11110
11111         when N_Block_Statement
11112            | N_Null_Statement
11113            | N_Terminate_Alternative
11114         =>
11115            null;
11116
11117         when others =>
11118            raise Program_Error;
11119      end case;
11120   end Process_Statements_For_Controlled_Objects;
11121
11122   ------------------
11123   -- Power_Of_Two --
11124   ------------------
11125
11126   function Power_Of_Two (N : Node_Id) return Nat is
11127      Typ : constant Entity_Id := Etype (N);
11128      pragma Assert (Is_Integer_Type (Typ));
11129
11130      Siz : constant Nat := UI_To_Int (Esize (Typ));
11131      Val : Uint;
11132
11133   begin
11134      if not Compile_Time_Known_Value (N) then
11135         return 0;
11136
11137      else
11138         Val := Expr_Value (N);
11139         for J in 1 .. Siz - 1 loop
11140            if Val = Uint_2 ** J then
11141               return J;
11142            end if;
11143         end loop;
11144
11145         return 0;
11146      end if;
11147   end Power_Of_Two;
11148
11149   ----------------------
11150   -- Remove_Init_Call --
11151   ----------------------
11152
11153   function Remove_Init_Call
11154     (Var        : Entity_Id;
11155      Rep_Clause : Node_Id) return Node_Id
11156   is
11157      Par : constant Node_Id   := Parent (Var);
11158      Typ : constant Entity_Id := Etype (Var);
11159
11160      Init_Proc : Entity_Id;
11161      --  Initialization procedure for Typ
11162
11163      function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
11164      --  Look for init call for Var starting at From and scanning the
11165      --  enclosing list until Rep_Clause or the end of the list is reached.
11166
11167      ----------------------------
11168      -- Find_Init_Call_In_List --
11169      ----------------------------
11170
11171      function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
11172         Init_Call : Node_Id;
11173
11174      begin
11175         Init_Call := From;
11176         while Present (Init_Call) and then Init_Call /= Rep_Clause loop
11177            if Nkind (Init_Call) = N_Procedure_Call_Statement
11178              and then Is_Entity_Name (Name (Init_Call))
11179              and then Entity (Name (Init_Call)) = Init_Proc
11180            then
11181               return Init_Call;
11182            end if;
11183
11184            Next (Init_Call);
11185         end loop;
11186
11187         return Empty;
11188      end Find_Init_Call_In_List;
11189
11190      Init_Call : Node_Id;
11191
11192   --  Start of processing for Find_Init_Call
11193
11194   begin
11195      if Present (Initialization_Statements (Var)) then
11196         Init_Call := Initialization_Statements (Var);
11197         Set_Initialization_Statements (Var, Empty);
11198
11199      elsif not Has_Non_Null_Base_Init_Proc (Typ) then
11200
11201         --  No init proc for the type, so obviously no call to be found
11202
11203         return Empty;
11204
11205      else
11206         --  We might be able to handle other cases below by just properly
11207         --  setting Initialization_Statements at the point where the init proc
11208         --  call is generated???
11209
11210         Init_Proc := Base_Init_Proc (Typ);
11211
11212         --  First scan the list containing the declaration of Var
11213
11214         Init_Call := Find_Init_Call_In_List (From => Next (Par));
11215
11216         --  If not found, also look on Var's freeze actions list, if any,
11217         --  since the init call may have been moved there (case of an address
11218         --  clause applying to Var).
11219
11220         if No (Init_Call) and then Present (Freeze_Node (Var)) then
11221            Init_Call :=
11222              Find_Init_Call_In_List (First (Actions (Freeze_Node (Var))));
11223         end if;
11224
11225         --  If the initialization call has actuals that use the secondary
11226         --  stack, the call may have been wrapped into a temporary block, in
11227         --  which case the block itself has to be removed.
11228
11229         if No (Init_Call) and then Nkind (Next (Par)) = N_Block_Statement then
11230            declare
11231               Blk : constant Node_Id := Next (Par);
11232            begin
11233               if Present
11234                    (Find_Init_Call_In_List
11235                      (First (Statements (Handled_Statement_Sequence (Blk)))))
11236               then
11237                  Init_Call := Blk;
11238               end if;
11239            end;
11240         end if;
11241      end if;
11242
11243      if Present (Init_Call) then
11244         Remove (Init_Call);
11245      end if;
11246      return Init_Call;
11247   end Remove_Init_Call;
11248
11249   -------------------------
11250   -- Remove_Side_Effects --
11251   -------------------------
11252
11253   procedure Remove_Side_Effects
11254     (Exp                : Node_Id;
11255      Name_Req           : Boolean   := False;
11256      Renaming_Req       : Boolean   := False;
11257      Variable_Ref       : Boolean   := False;
11258      Related_Id         : Entity_Id := Empty;
11259      Is_Low_Bound       : Boolean   := False;
11260      Is_High_Bound      : Boolean   := False;
11261      Check_Side_Effects : Boolean   := True)
11262   is
11263      function Build_Temporary
11264        (Loc         : Source_Ptr;
11265         Id          : Character;
11266         Related_Nod : Node_Id := Empty) return Entity_Id;
11267      --  Create an external symbol of the form xxx_FIRST/_LAST if Related_Nod
11268      --  is present (xxx is taken from the Chars field of Related_Nod),
11269      --  otherwise it generates an internal temporary. The created temporary
11270      --  entity is marked as internal.
11271
11272      ---------------------
11273      -- Build_Temporary --
11274      ---------------------
11275
11276      function Build_Temporary
11277        (Loc         : Source_Ptr;
11278         Id          : Character;
11279         Related_Nod : Node_Id := Empty) return Entity_Id
11280      is
11281         Temp_Id  : Entity_Id;
11282         Temp_Nam : Name_Id;
11283
11284      begin
11285         --  The context requires an external symbol
11286
11287         if Present (Related_Id) then
11288            if Is_Low_Bound then
11289               Temp_Nam := New_External_Name (Chars (Related_Id), "_FIRST");
11290            else pragma Assert (Is_High_Bound);
11291               Temp_Nam := New_External_Name (Chars (Related_Id), "_LAST");
11292            end if;
11293
11294            Temp_Id := Make_Defining_Identifier (Loc, Temp_Nam);
11295
11296         --  Otherwise generate an internal temporary
11297
11298         else
11299            Temp_Id := Make_Temporary (Loc, Id, Related_Nod);
11300         end if;
11301
11302         Set_Is_Internal (Temp_Id);
11303
11304         return Temp_Id;
11305      end Build_Temporary;
11306
11307      --  Local variables
11308
11309      Loc          : constant Source_Ptr      := Sloc (Exp);
11310      Exp_Type     : constant Entity_Id       := Etype (Exp);
11311      Svg_Suppress : constant Suppress_Record := Scope_Suppress;
11312      Def_Id       : Entity_Id;
11313      E            : Node_Id;
11314      New_Exp      : Node_Id;
11315      Ptr_Typ_Decl : Node_Id;
11316      Ref_Type     : Entity_Id;
11317      Res          : Node_Id;
11318
11319   --  Start of processing for Remove_Side_Effects
11320
11321   begin
11322      --  Handle cases in which there is nothing to do. In GNATprove mode,
11323      --  removal of side effects is useful for the light expansion of
11324      --  renamings. This removal should only occur when not inside a
11325      --  generic and not doing a preanalysis.
11326
11327      if not Expander_Active
11328        and (Inside_A_Generic or not Full_Analysis or not GNATprove_Mode)
11329      then
11330         return;
11331
11332      --  Cannot generate temporaries if the invocation to remove side effects
11333      --  was issued too early and the type of the expression is not resolved
11334      --  (this happens because routines Duplicate_Subexpr_XX implicitly invoke
11335      --  Remove_Side_Effects).
11336
11337      elsif No (Exp_Type)
11338        or else Ekind (Exp_Type) = E_Access_Attribute_Type
11339      then
11340         return;
11341
11342      --  Nothing to do if prior expansion determined that a function call does
11343      --  not require side effect removal.
11344
11345      elsif Nkind (Exp) = N_Function_Call
11346        and then No_Side_Effect_Removal (Exp)
11347      then
11348         return;
11349
11350      --  No action needed for side-effect free expressions
11351
11352      elsif Check_Side_Effects
11353        and then Side_Effect_Free (Exp, Name_Req, Variable_Ref)
11354      then
11355         return;
11356
11357      --  Generating C code we cannot remove side effect of function returning
11358      --  class-wide types since there is no secondary stack (required to use
11359      --  'reference).
11360
11361      elsif Modify_Tree_For_C
11362        and then Nkind (Exp) = N_Function_Call
11363        and then Is_Class_Wide_Type (Etype (Exp))
11364      then
11365         return;
11366      end if;
11367
11368      --  The remaining processing is done with all checks suppressed
11369
11370      --  Note: from now on, don't use return statements, instead do a goto
11371      --  Leave, to ensure that we properly restore Scope_Suppress.Suppress.
11372
11373      Scope_Suppress.Suppress := (others => True);
11374
11375      --  If this is an elementary or a small not-by-reference record type, and
11376      --  we need to capture the value, just make a constant; this is cheap and
11377      --  objects of both kinds of types can be bit aligned, so it might not be
11378      --  possible to generate a reference to them. Likewise if this is not a
11379      --  name reference, except for a type conversion, because we would enter
11380      --  an infinite recursion with Checks.Apply_Predicate_Check if the target
11381      --  type has predicates (and type conversions need a specific treatment
11382      --  anyway, see below). Also do it if we have a volatile reference and
11383      --  Name_Req is not set (see comments for Side_Effect_Free).
11384
11385      if (Is_Elementary_Type (Exp_Type)
11386           or else (Is_Record_Type (Exp_Type)
11387                     and then Known_Static_RM_Size (Exp_Type)
11388                     and then RM_Size (Exp_Type) <= 64
11389                     and then not Has_Discriminants (Exp_Type)
11390                     and then not Is_By_Reference_Type (Exp_Type)))
11391        and then (Variable_Ref
11392                   or else (not Is_Name_Reference (Exp)
11393                             and then Nkind (Exp) /= N_Type_Conversion)
11394                   or else (not Name_Req
11395                             and then Is_Volatile_Reference (Exp)))
11396      then
11397         Def_Id := Build_Temporary (Loc, 'R', Exp);
11398         Set_Etype (Def_Id, Exp_Type);
11399         Res := New_Occurrence_Of (Def_Id, Loc);
11400
11401         --  If the expression is a packed reference, it must be reanalyzed and
11402         --  expanded, depending on context. This is the case for actuals where
11403         --  a constraint check may capture the actual before expansion of the
11404         --  call is complete.
11405
11406         if Nkind (Exp) = N_Indexed_Component
11407           and then Is_Packed (Etype (Prefix (Exp)))
11408         then
11409            Set_Analyzed (Exp, False);
11410            Set_Analyzed (Prefix (Exp), False);
11411         end if;
11412
11413         --  Generate:
11414         --    Rnn : Exp_Type renames Expr;
11415
11416         --  In GNATprove mode, we prefer to use renamings for intermediate
11417         --  variables to definition of constants, due to the implicit move
11418         --  operation that such a constant definition causes as part of the
11419         --  support in GNATprove for ownership pointers. Hence, we generate
11420         --  a renaming for a reference to an object of a nonscalar type.
11421
11422         if Renaming_Req
11423           or else (GNATprove_Mode
11424                     and then Is_Object_Reference (Exp)
11425                     and then not Is_Scalar_Type (Exp_Type))
11426         then
11427            E :=
11428              Make_Object_Renaming_Declaration (Loc,
11429                Defining_Identifier => Def_Id,
11430                Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
11431                Name                => Relocate_Node (Exp));
11432
11433         --  Generate:
11434         --    Rnn : constant Exp_Type := Expr;
11435
11436         else
11437            E :=
11438              Make_Object_Declaration (Loc,
11439                Defining_Identifier => Def_Id,
11440                Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
11441                Constant_Present    => True,
11442                Expression          => Relocate_Node (Exp));
11443
11444            Set_Assignment_OK (E);
11445         end if;
11446
11447         Insert_Action (Exp, E);
11448
11449      --  If the expression has the form v.all then we can just capture the
11450      --  pointer, and then do an explicit dereference on the result, but
11451      --  this is not right if this is a volatile reference.
11452
11453      elsif Nkind (Exp) = N_Explicit_Dereference
11454        and then not Is_Volatile_Reference (Exp)
11455      then
11456         Def_Id := Build_Temporary (Loc, 'R', Exp);
11457         Res :=
11458           Make_Explicit_Dereference (Loc, New_Occurrence_Of (Def_Id, Loc));
11459
11460         Insert_Action (Exp,
11461           Make_Object_Declaration (Loc,
11462             Defining_Identifier => Def_Id,
11463             Object_Definition   =>
11464               New_Occurrence_Of (Etype (Prefix (Exp)), Loc),
11465             Constant_Present    => True,
11466             Expression          => Relocate_Node (Prefix (Exp))));
11467
11468      --  Similar processing for an unchecked conversion of an expression of
11469      --  the form v.all, where we want the same kind of treatment.
11470
11471      elsif Nkind (Exp) = N_Unchecked_Type_Conversion
11472        and then Nkind (Expression (Exp)) = N_Explicit_Dereference
11473      then
11474         Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
11475         goto Leave;
11476
11477      --  If this is a type conversion, leave the type conversion and remove
11478      --  the side effects in the expression. This is important in several
11479      --  circumstances: for change of representations, and also when this is a
11480      --  view conversion to a smaller object, where gigi can end up creating
11481      --  its own temporary of the wrong size.
11482
11483      elsif Nkind (Exp) = N_Type_Conversion then
11484         Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
11485
11486         --  Generating C code the type conversion of an access to constrained
11487         --  array type into an access to unconstrained array type involves
11488         --  initializing a fat pointer and the expression must be free of
11489         --  side effects to safely compute its bounds.
11490
11491         if Modify_Tree_For_C
11492           and then Is_Access_Type (Etype (Exp))
11493           and then Is_Array_Type (Designated_Type (Etype (Exp)))
11494           and then not Is_Constrained (Designated_Type (Etype (Exp)))
11495         then
11496            Def_Id := Build_Temporary (Loc, 'R', Exp);
11497            Set_Etype (Def_Id, Exp_Type);
11498            Res := New_Occurrence_Of (Def_Id, Loc);
11499
11500            Insert_Action (Exp,
11501              Make_Object_Declaration (Loc,
11502                Defining_Identifier => Def_Id,
11503                Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
11504                Constant_Present    => True,
11505                Expression          => Relocate_Node (Exp)));
11506         else
11507            goto Leave;
11508         end if;
11509
11510      --  If this is an unchecked conversion that Gigi can't handle, make
11511      --  a copy or a use a renaming to capture the value.
11512
11513      elsif Nkind (Exp) = N_Unchecked_Type_Conversion
11514        and then not Safe_Unchecked_Type_Conversion (Exp)
11515      then
11516         if CW_Or_Has_Controlled_Part (Exp_Type) then
11517
11518            --  Use a renaming to capture the expression, rather than create
11519            --  a controlled temporary.
11520
11521            Def_Id := Build_Temporary (Loc, 'R', Exp);
11522            Res    := New_Occurrence_Of (Def_Id, Loc);
11523
11524            Insert_Action (Exp,
11525              Make_Object_Renaming_Declaration (Loc,
11526                Defining_Identifier => Def_Id,
11527                Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
11528                Name                => Relocate_Node (Exp)));
11529
11530         else
11531            Def_Id := Build_Temporary (Loc, 'R', Exp);
11532            Set_Etype (Def_Id, Exp_Type);
11533            Res    := New_Occurrence_Of (Def_Id, Loc);
11534
11535            E :=
11536              Make_Object_Declaration (Loc,
11537                Defining_Identifier => Def_Id,
11538                Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
11539                Constant_Present    => not Is_Variable (Exp),
11540                Expression          => Relocate_Node (Exp));
11541
11542            Set_Assignment_OK (E);
11543            Insert_Action (Exp, E);
11544         end if;
11545
11546      --  For expressions that denote names, we can use a renaming scheme.
11547      --  This is needed for correctness in the case of a volatile object of
11548      --  a nonvolatile type because the Make_Reference call of the "default"
11549      --  approach would generate an illegal access value (an access value
11550      --  cannot designate such an object - see Analyze_Reference).
11551
11552      elsif Is_Name_Reference (Exp)
11553
11554        --  We skip using this scheme if we have an object of a volatile
11555        --  type and we do not have Name_Req set true (see comments for
11556        --  Side_Effect_Free).
11557
11558        and then (Name_Req or else not Treat_As_Volatile (Exp_Type))
11559      then
11560         Def_Id := Build_Temporary (Loc, 'R', Exp);
11561         Res := New_Occurrence_Of (Def_Id, Loc);
11562
11563         Insert_Action (Exp,
11564           Make_Object_Renaming_Declaration (Loc,
11565             Defining_Identifier => Def_Id,
11566             Subtype_Mark        => New_Occurrence_Of (Exp_Type, Loc),
11567             Name                => Relocate_Node (Exp)));
11568
11569         --  If this is a packed reference, or a selected component with
11570         --  a nonstandard representation, a reference to the temporary
11571         --  will be replaced by a copy of the original expression (see
11572         --  Exp_Ch2.Expand_Renaming). Otherwise the temporary must be
11573         --  elaborated by gigi, and is of course not to be replaced in-line
11574         --  by the expression it renames, which would defeat the purpose of
11575         --  removing the side effect.
11576
11577         if Nkind_In (Exp, N_Selected_Component, N_Indexed_Component)
11578           and then Has_Non_Standard_Rep (Etype (Prefix (Exp)))
11579         then
11580            null;
11581         else
11582            Set_Is_Renaming_Of_Object (Def_Id, False);
11583         end if;
11584
11585      --  Avoid generating a variable-sized temporary, by generating the
11586      --  reference just for the function call. The transformation could be
11587      --  refined to apply only when the array component is constrained by a
11588      --  discriminant???
11589
11590      elsif Nkind (Exp) = N_Selected_Component
11591        and then Nkind (Prefix (Exp)) = N_Function_Call
11592        and then Is_Array_Type (Exp_Type)
11593      then
11594         Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref);
11595         goto Leave;
11596
11597      --  Otherwise we generate a reference to the expression
11598
11599      else
11600         --  An expression which is in SPARK mode is considered side effect
11601         --  free if the resulting value is captured by a variable or a
11602         --  constant.
11603
11604         if GNATprove_Mode
11605           and then Nkind (Parent (Exp)) = N_Object_Declaration
11606         then
11607            goto Leave;
11608
11609         --  When generating C code we cannot consider side effect free object
11610         --  declarations that have discriminants and are initialized by means
11611         --  of a function call since on this target there is no secondary
11612         --  stack to store the return value and the expander may generate an
11613         --  extra call to the function to compute the discriminant value. In
11614         --  addition, for targets that have secondary stack, the expansion of
11615         --  functions with side effects involves the generation of an access
11616         --  type to capture the return value stored in the secondary stack;
11617         --  by contrast when generating C code such expansion generates an
11618         --  internal object declaration (no access type involved) which must
11619         --  be identified here to avoid entering into a never-ending loop
11620         --  generating internal object declarations.
11621
11622         elsif Modify_Tree_For_C
11623           and then Nkind (Parent (Exp)) = N_Object_Declaration
11624           and then
11625             (Nkind (Exp) /= N_Function_Call
11626                or else not Has_Discriminants (Exp_Type)
11627                or else Is_Internal_Name
11628                          (Chars (Defining_Identifier (Parent (Exp)))))
11629         then
11630            goto Leave;
11631         end if;
11632
11633         --  Special processing for function calls that return a limited type.
11634         --  We need to build a declaration that will enable build-in-place
11635         --  expansion of the call. This is not done if the context is already
11636         --  an object declaration, to prevent infinite recursion.
11637
11638         --  This is relevant only in Ada 2005 mode. In Ada 95 programs we have
11639         --  to accommodate functions returning limited objects by reference.
11640
11641         if Ada_Version >= Ada_2005
11642           and then Nkind (Exp) = N_Function_Call
11643           and then Is_Limited_View (Etype (Exp))
11644           and then Nkind (Parent (Exp)) /= N_Object_Declaration
11645         then
11646            declare
11647               Obj  : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
11648               Decl : Node_Id;
11649
11650            begin
11651               Decl :=
11652                 Make_Object_Declaration (Loc,
11653                   Defining_Identifier => Obj,
11654                   Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
11655                   Expression          => Relocate_Node (Exp));
11656
11657               Insert_Action (Exp, Decl);
11658               Set_Etype (Obj, Exp_Type);
11659               Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
11660               goto Leave;
11661            end;
11662         end if;
11663
11664         Def_Id := Build_Temporary (Loc, 'R', Exp);
11665
11666         --  The regular expansion of functions with side effects involves the
11667         --  generation of an access type to capture the return value found on
11668         --  the secondary stack. Since SPARK (and why) cannot process access
11669         --  types, use a different approach which ignores the secondary stack
11670         --  and "copies" the returned object.
11671         --  When generating C code, no need for a 'reference since the
11672         --  secondary stack is not supported.
11673
11674         if GNATprove_Mode or Modify_Tree_For_C then
11675            Res := New_Occurrence_Of (Def_Id, Loc);
11676            Ref_Type := Exp_Type;
11677
11678         --  Regular expansion utilizing an access type and 'reference
11679
11680         else
11681            Res :=
11682              Make_Explicit_Dereference (Loc,
11683                Prefix => New_Occurrence_Of (Def_Id, Loc));
11684
11685            --  Generate:
11686            --    type Ann is access all <Exp_Type>;
11687
11688            Ref_Type := Make_Temporary (Loc, 'A');
11689
11690            Ptr_Typ_Decl :=
11691              Make_Full_Type_Declaration (Loc,
11692                Defining_Identifier => Ref_Type,
11693                Type_Definition     =>
11694                  Make_Access_To_Object_Definition (Loc,
11695                    All_Present        => True,
11696                    Subtype_Indication =>
11697                      New_Occurrence_Of (Exp_Type, Loc)));
11698
11699            Insert_Action (Exp, Ptr_Typ_Decl);
11700         end if;
11701
11702         E := Exp;
11703         if Nkind (E) = N_Explicit_Dereference then
11704            New_Exp := Relocate_Node (Prefix (E));
11705
11706         else
11707            E := Relocate_Node (E);
11708
11709            --  Do not generate a 'reference in SPARK mode or C generation
11710            --  since the access type is not created in the first place.
11711
11712            if GNATprove_Mode or Modify_Tree_For_C then
11713               New_Exp := E;
11714
11715            --  Otherwise generate reference, marking the value as non-null
11716            --  since we know it cannot be null and we don't want a check.
11717
11718            else
11719               New_Exp := Make_Reference (Loc, E);
11720               Set_Is_Known_Non_Null (Def_Id);
11721            end if;
11722         end if;
11723
11724         if Is_Delayed_Aggregate (E) then
11725
11726            --  The expansion of nested aggregates is delayed until the
11727            --  enclosing aggregate is expanded. As aggregates are often
11728            --  qualified, the predicate applies to qualified expressions as
11729            --  well, indicating that the enclosing aggregate has not been
11730            --  expanded yet. At this point the aggregate is part of a
11731            --  stand-alone declaration, and must be fully expanded.
11732
11733            if Nkind (E) = N_Qualified_Expression then
11734               Set_Expansion_Delayed (Expression (E), False);
11735               Set_Analyzed (Expression (E), False);
11736            else
11737               Set_Expansion_Delayed (E, False);
11738            end if;
11739
11740            Set_Analyzed (E, False);
11741         end if;
11742
11743         --  Generating C code of object declarations that have discriminants
11744         --  and are initialized by means of a function call we propagate the
11745         --  discriminants of the parent type to the internally built object.
11746         --  This is needed to avoid generating an extra call to the called
11747         --  function.
11748
11749         --  For example, if we generate here the following declaration, it
11750         --  will be expanded later adding an extra call to evaluate the value
11751         --  of the discriminant (needed to compute the size of the object).
11752         --
11753         --     type Rec (D : Integer) is ...
11754         --     Obj : constant Rec := SomeFunc;
11755
11756         if Modify_Tree_For_C
11757           and then Nkind (Parent (Exp)) = N_Object_Declaration
11758           and then Has_Discriminants (Exp_Type)
11759           and then Nkind (Exp) = N_Function_Call
11760         then
11761            Insert_Action (Exp,
11762              Make_Object_Declaration (Loc,
11763                Defining_Identifier => Def_Id,
11764                Object_Definition   => New_Copy_Tree
11765                                         (Object_Definition (Parent (Exp))),
11766                Constant_Present    => True,
11767                Expression          => New_Exp));
11768         else
11769            Insert_Action (Exp,
11770              Make_Object_Declaration (Loc,
11771                Defining_Identifier => Def_Id,
11772                Object_Definition   => New_Occurrence_Of (Ref_Type, Loc),
11773                Constant_Present    => True,
11774                Expression          => New_Exp));
11775         end if;
11776      end if;
11777
11778      --  Preserve the Assignment_OK flag in all copies, since at least one
11779      --  copy may be used in a context where this flag must be set (otherwise
11780      --  why would the flag be set in the first place).
11781
11782      Set_Assignment_OK (Res, Assignment_OK (Exp));
11783
11784      --  Preserve the Do_Range_Check flag in all copies
11785
11786      Set_Do_Range_Check (Res, Do_Range_Check (Exp));
11787
11788      --  Finally rewrite the original expression and we are done
11789
11790      Rewrite (Exp, Res);
11791      Analyze_And_Resolve (Exp, Exp_Type);
11792
11793   <<Leave>>
11794      Scope_Suppress := Svg_Suppress;
11795   end Remove_Side_Effects;
11796
11797   ------------------------
11798   -- Replace_References --
11799   ------------------------
11800
11801   procedure Replace_References
11802     (Expr      : Node_Id;
11803      Par_Typ   : Entity_Id;
11804      Deriv_Typ : Entity_Id;
11805      Par_Obj   : Entity_Id := Empty;
11806      Deriv_Obj : Entity_Id := Empty)
11807   is
11808      function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean;
11809      --  Determine whether node Ref denotes some component of Deriv_Obj
11810
11811      function Replace_Ref (Ref : Node_Id) return Traverse_Result;
11812      --  Substitute a reference to an entity with the corresponding value
11813      --  stored in table Type_Map.
11814
11815      function Type_Of_Formal
11816        (Call   : Node_Id;
11817         Actual : Node_Id) return Entity_Id;
11818      --  Find the type of the formal parameter which corresponds to actual
11819      --  parameter Actual in subprogram call Call.
11820
11821      ----------------------
11822      -- Is_Deriv_Obj_Ref --
11823      ----------------------
11824
11825      function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean is
11826         Par : constant Node_Id := Parent (Ref);
11827
11828      begin
11829         --  Detect the folowing selected component form:
11830
11831         --    Deriv_Obj.(something)
11832
11833         return
11834           Nkind (Par) = N_Selected_Component
11835             and then Is_Entity_Name (Prefix (Par))
11836             and then Entity (Prefix (Par)) = Deriv_Obj;
11837      end Is_Deriv_Obj_Ref;
11838
11839      -----------------
11840      -- Replace_Ref --
11841      -----------------
11842
11843      function Replace_Ref (Ref : Node_Id) return Traverse_Result is
11844         procedure Remove_Controlling_Arguments (From_Arg : Node_Id);
11845         --  Reset the Controlling_Argument of all function calls that
11846         --  encapsulate node From_Arg.
11847
11848         ----------------------------------
11849         -- Remove_Controlling_Arguments --
11850         ----------------------------------
11851
11852         procedure Remove_Controlling_Arguments (From_Arg : Node_Id) is
11853            Par : Node_Id;
11854
11855         begin
11856            Par := From_Arg;
11857            while Present (Par) loop
11858               if Nkind (Par) = N_Function_Call
11859                 and then Present (Controlling_Argument (Par))
11860               then
11861                  Set_Controlling_Argument (Par, Empty);
11862
11863               --  Prevent the search from going too far
11864
11865               elsif Is_Body_Or_Package_Declaration (Par) then
11866                  exit;
11867               end if;
11868
11869               Par := Parent (Par);
11870            end loop;
11871         end Remove_Controlling_Arguments;
11872
11873         --  Local variables
11874
11875         Context : constant Node_Id    := Parent (Ref);
11876         Loc     : constant Source_Ptr := Sloc (Ref);
11877         Ref_Id  : Entity_Id;
11878         Result  : Traverse_Result;
11879
11880         New_Ref : Node_Id;
11881         --  The new reference which is intended to substitute the old one
11882
11883         Old_Ref : Node_Id;
11884         --  The reference designated for replacement. In certain cases this
11885         --  may be a node other than Ref.
11886
11887         Val : Node_Or_Entity_Id;
11888         --  The corresponding value of Ref from the type map
11889
11890      --  Start of processing for Replace_Ref
11891
11892      begin
11893         --  Assume that the input reference is to be replaced and that the
11894         --  traversal should examine the children of the reference.
11895
11896         Old_Ref := Ref;
11897         Result  := OK;
11898
11899         --  The input denotes a meaningful reference
11900
11901         if Nkind (Ref) in N_Has_Entity and then Present (Entity (Ref)) then
11902            Ref_Id := Entity (Ref);
11903            Val    := Type_Map.Get (Ref_Id);
11904
11905            --  The reference has a corresponding value in the type map, a
11906            --  substitution is possible.
11907
11908            if Present (Val) then
11909
11910               --  The reference denotes a discriminant
11911
11912               if Ekind (Ref_Id) = E_Discriminant then
11913                  if Nkind (Val) in N_Entity then
11914
11915                     --  The value denotes another discriminant. Replace as
11916                     --  follows:
11917
11918                     --    _object.Discr -> _object.Val
11919
11920                     if Ekind (Val) = E_Discriminant then
11921                        New_Ref := New_Occurrence_Of (Val, Loc);
11922
11923                     --  Otherwise the value denotes the entity of a name which
11924                     --  constraints the discriminant. Replace as follows:
11925
11926                     --    _object.Discr -> Val
11927
11928                     else
11929                        pragma Assert (Is_Deriv_Obj_Ref (Old_Ref));
11930
11931                        New_Ref := New_Occurrence_Of (Val, Loc);
11932                        Old_Ref := Parent (Old_Ref);
11933                     end if;
11934
11935                  --  Otherwise the value denotes an arbitrary expression which
11936                  --  constraints the discriminant. Replace as follows:
11937
11938                  --    _object.Discr -> Val
11939
11940                  else
11941                     pragma Assert (Is_Deriv_Obj_Ref (Old_Ref));
11942
11943                     New_Ref := New_Copy_Tree (Val);
11944                     Old_Ref := Parent (Old_Ref);
11945                  end if;
11946
11947               --  Otherwise the reference denotes a primitive. Replace as
11948               --  follows:
11949
11950               --    Primitive -> Val
11951
11952               else
11953                  pragma Assert (Nkind (Val) in N_Entity);
11954                  New_Ref := New_Occurrence_Of (Val, Loc);
11955               end if;
11956
11957            --  The reference mentions the _object parameter of the parent
11958            --  type's DIC or type invariant procedure. Replace as follows:
11959
11960            --    _object -> _object
11961
11962            elsif Present (Par_Obj)
11963              and then Present (Deriv_Obj)
11964              and then Ref_Id = Par_Obj
11965            then
11966               New_Ref := New_Occurrence_Of (Deriv_Obj, Loc);
11967
11968               --  The type of the _object parameter is class-wide when the
11969               --  expression comes from an assertion pragma that applies to
11970               --  an abstract parent type or an interface. The class-wide type
11971               --  facilitates the preanalysis of the expression by treating
11972               --  calls to abstract primitives that mention the current
11973               --  instance of the type as dispatching. Once the calls are
11974               --  remapped to invoke overriding or inherited primitives, the
11975               --  calls no longer need to be dispatching. Examine all function
11976               --  calls that encapsulate the _object parameter and reset their
11977               --  Controlling_Argument attribute.
11978
11979               if Is_Class_Wide_Type (Etype (Par_Obj))
11980                 and then Is_Abstract_Type (Root_Type (Etype (Par_Obj)))
11981               then
11982                  Remove_Controlling_Arguments (Old_Ref);
11983               end if;
11984
11985               --  The reference to _object acts as an actual parameter in a
11986               --  subprogram call which may be invoking a primitive of the
11987               --  parent type:
11988
11989               --    Primitive (... _object ...);
11990
11991               --  The parent type primitive may not be overridden nor
11992               --  inherited when it is declared after the derived type
11993               --  definition:
11994
11995               --    type Parent is tagged private;
11996               --    type Child is new Parent with private;
11997               --    procedure Primitive (Obj : Parent);
11998
11999               --  In this scenario the _object parameter is converted to the
12000               --  parent type. Due to complications with partial/full views
12001               --  and view swaps, the parent type is taken from the formal
12002               --  parameter of the subprogram being called.
12003
12004               if Nkind_In (Context, N_Function_Call,
12005                                     N_Procedure_Call_Statement)
12006                 and then No (Type_Map.Get (Entity (Name (Context))))
12007               then
12008                  New_Ref :=
12009                    Convert_To (Type_Of_Formal (Context, Old_Ref), New_Ref);
12010
12011                  --  Do not process the generated type conversion because
12012                  --  both the parent type and the derived type are in the
12013                  --  Type_Map table. This will clobber the type conversion
12014                  --  by resetting its subtype mark.
12015
12016                  Result := Skip;
12017               end if;
12018
12019            --  Otherwise there is nothing to replace
12020
12021            else
12022               New_Ref := Empty;
12023            end if;
12024
12025            if Present (New_Ref) then
12026               Rewrite (Old_Ref, New_Ref);
12027
12028               --  Update the return type when the context of the reference
12029               --  acts as the name of a function call. Note that the update
12030               --  should not be performed when the reference appears as an
12031               --  actual in the call.
12032
12033               if Nkind (Context) = N_Function_Call
12034                 and then Name (Context) = Old_Ref
12035               then
12036                  Set_Etype (Context, Etype (Val));
12037               end if;
12038            end if;
12039         end if;
12040
12041         --  Reanalyze the reference due to potential replacements
12042
12043         if Nkind (Old_Ref) in N_Has_Etype then
12044            Set_Analyzed (Old_Ref, False);
12045         end if;
12046
12047         return Result;
12048      end Replace_Ref;
12049
12050      procedure Replace_Refs is new Traverse_Proc (Replace_Ref);
12051
12052      --------------------
12053      -- Type_Of_Formal --
12054      --------------------
12055
12056      function Type_Of_Formal
12057        (Call   : Node_Id;
12058         Actual : Node_Id) return Entity_Id
12059      is
12060         A : Node_Id;
12061         F : Entity_Id;
12062
12063      begin
12064         --  Examine the list of actual and formal parameters in parallel
12065
12066         A := First (Parameter_Associations (Call));
12067         F := First_Formal (Entity (Name (Call)));
12068         while Present (A) and then Present (F) loop
12069            if A = Actual then
12070               return Etype (F);
12071            end if;
12072
12073            Next (A);
12074            Next_Formal (F);
12075         end loop;
12076
12077         --  The actual parameter must always have a corresponding formal
12078
12079         pragma Assert (False);
12080
12081         return Empty;
12082      end Type_Of_Formal;
12083
12084   --  Start of processing for Replace_References
12085
12086   begin
12087      --  Map the attributes of the parent type to the proper corresponding
12088      --  attributes of the derived type.
12089
12090      Map_Types
12091        (Parent_Type  => Par_Typ,
12092         Derived_Type => Deriv_Typ);
12093
12094      --  Inspect the input expression and perform substitutions where
12095      --  necessary.
12096
12097      Replace_Refs (Expr);
12098   end Replace_References;
12099
12100   -----------------------------
12101   -- Replace_Type_References --
12102   -----------------------------
12103
12104   procedure Replace_Type_References
12105     (Expr   : Node_Id;
12106      Typ    : Entity_Id;
12107      Obj_Id : Entity_Id)
12108   is
12109      procedure Replace_Type_Ref (N : Node_Id);
12110      --  Substitute a single reference of the current instance of type Typ
12111      --  with a reference to Obj_Id.
12112
12113      ----------------------
12114      -- Replace_Type_Ref --
12115      ----------------------
12116
12117      procedure Replace_Type_Ref (N : Node_Id) is
12118      begin
12119         --  Decorate the reference to Typ even though it may be rewritten
12120         --  further down. This is done for two reasons:
12121
12122         --    * ASIS has all necessary semantic information in the original
12123         --      tree.
12124
12125         --    * Routines which examine properties of the Original_Node have
12126         --      some semantic information.
12127
12128         if Nkind (N) = N_Identifier then
12129            Set_Entity (N, Typ);
12130            Set_Etype  (N, Typ);
12131
12132         elsif Nkind (N) = N_Selected_Component then
12133            Analyze (Prefix (N));
12134            Set_Entity (Selector_Name (N), Typ);
12135            Set_Etype  (Selector_Name (N), Typ);
12136         end if;
12137
12138         --  Perform the following substitution:
12139
12140         --    Typ --> _object
12141
12142         Rewrite (N, New_Occurrence_Of (Obj_Id, Sloc (N)));
12143         Set_Comes_From_Source (N, True);
12144      end Replace_Type_Ref;
12145
12146      procedure Replace_Type_Refs is
12147        new Replace_Type_References_Generic (Replace_Type_Ref);
12148
12149   --  Start of processing for Replace_Type_References
12150
12151   begin
12152      Replace_Type_Refs (Expr, Typ);
12153   end Replace_Type_References;
12154
12155   ---------------------------
12156   -- Represented_As_Scalar --
12157   ---------------------------
12158
12159   function Represented_As_Scalar (T : Entity_Id) return Boolean is
12160      UT : constant Entity_Id := Underlying_Type (T);
12161   begin
12162      return Is_Scalar_Type (UT)
12163        or else (Is_Bit_Packed_Array (UT)
12164                  and then Is_Scalar_Type (Packed_Array_Impl_Type (UT)));
12165   end Represented_As_Scalar;
12166
12167   ------------------------------
12168   -- Requires_Cleanup_Actions --
12169   ------------------------------
12170
12171   function Requires_Cleanup_Actions
12172     (N         : Node_Id;
12173      Lib_Level : Boolean) return Boolean
12174   is
12175      At_Lib_Level : constant Boolean :=
12176                       Lib_Level
12177                         and then Nkind_In (N, N_Package_Body,
12178                                               N_Package_Specification);
12179      --  N is at the library level if the top-most context is a package and
12180      --  the path taken to reach N does not include nonpackage constructs.
12181
12182   begin
12183      case Nkind (N) is
12184         when N_Accept_Statement
12185            | N_Block_Statement
12186            | N_Entry_Body
12187            | N_Package_Body
12188            | N_Protected_Body
12189            | N_Subprogram_Body
12190            | N_Task_Body
12191         =>
12192            return
12193                Requires_Cleanup_Actions
12194                  (L                 => Declarations (N),
12195                   Lib_Level         => At_Lib_Level,
12196                   Nested_Constructs => True)
12197              or else
12198                (Present (Handled_Statement_Sequence (N))
12199                  and then
12200                    Requires_Cleanup_Actions
12201                      (L                 =>
12202                         Statements (Handled_Statement_Sequence (N)),
12203                       Lib_Level         => At_Lib_Level,
12204                       Nested_Constructs => True));
12205
12206         --  Extended return statements are the same as the above, except that
12207         --  there is no Declarations field. We do not want to clean up the
12208         --  Return_Object_Declarations.
12209
12210         when N_Extended_Return_Statement =>
12211            return
12212              Present (Handled_Statement_Sequence (N))
12213                and then Requires_Cleanup_Actions
12214                           (L                 =>
12215                              Statements (Handled_Statement_Sequence (N)),
12216                            Lib_Level         => At_Lib_Level,
12217                            Nested_Constructs => True);
12218
12219         when N_Package_Specification =>
12220            return
12221                Requires_Cleanup_Actions
12222                  (L                 => Visible_Declarations (N),
12223                   Lib_Level         => At_Lib_Level,
12224                   Nested_Constructs => True)
12225              or else
12226                Requires_Cleanup_Actions
12227                  (L                 => Private_Declarations (N),
12228                   Lib_Level         => At_Lib_Level,
12229                   Nested_Constructs => True);
12230
12231         when others =>
12232            raise Program_Error;
12233      end case;
12234   end Requires_Cleanup_Actions;
12235
12236   ------------------------------
12237   -- Requires_Cleanup_Actions --
12238   ------------------------------
12239
12240   function Requires_Cleanup_Actions
12241     (L                 : List_Id;
12242      Lib_Level         : Boolean;
12243      Nested_Constructs : Boolean) return Boolean
12244   is
12245      Decl    : Node_Id;
12246      Expr    : Node_Id;
12247      Obj_Id  : Entity_Id;
12248      Obj_Typ : Entity_Id;
12249      Pack_Id : Entity_Id;
12250      Typ     : Entity_Id;
12251
12252   begin
12253      if No (L) or else Is_Empty_List (L) then
12254         return False;
12255      end if;
12256
12257      Decl := First (L);
12258      while Present (Decl) loop
12259
12260         --  Library-level tagged types
12261
12262         if Nkind (Decl) = N_Full_Type_Declaration then
12263            Typ := Defining_Identifier (Decl);
12264
12265            --  Ignored Ghost types do not need any cleanup actions because
12266            --  they will not appear in the final tree.
12267
12268            if Is_Ignored_Ghost_Entity (Typ) then
12269               null;
12270
12271            elsif Is_Tagged_Type (Typ)
12272              and then Is_Library_Level_Entity (Typ)
12273              and then Convention (Typ) = Convention_Ada
12274              and then Present (Access_Disp_Table (Typ))
12275              and then RTE_Available (RE_Unregister_Tag)
12276              and then not Is_Abstract_Type (Typ)
12277              and then not No_Run_Time_Mode
12278            then
12279               return True;
12280            end if;
12281
12282         --  Regular object declarations
12283
12284         elsif Nkind (Decl) = N_Object_Declaration then
12285            Obj_Id  := Defining_Identifier (Decl);
12286            Obj_Typ := Base_Type (Etype (Obj_Id));
12287            Expr    := Expression (Decl);
12288
12289            --  Bypass any form of processing for objects which have their
12290            --  finalization disabled. This applies only to objects at the
12291            --  library level.
12292
12293            if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
12294               null;
12295
12296            --  Finalization of transient objects are treated separately in
12297            --  order to handle sensitive cases. These include:
12298
12299            --    * Aggregate expansion
12300            --    * If, case, and expression with actions expansion
12301            --    * Transient scopes
12302
12303            --  If one of those contexts has marked the transient object as
12304            --  ignored, do not generate finalization actions for it.
12305
12306            elsif Is_Finalized_Transient (Obj_Id)
12307              or else Is_Ignored_Transient (Obj_Id)
12308            then
12309               null;
12310
12311            --  Ignored Ghost objects do not need any cleanup actions because
12312            --  they will not appear in the final tree.
12313
12314            elsif Is_Ignored_Ghost_Entity (Obj_Id) then
12315               null;
12316
12317            --  The object is of the form:
12318            --    Obj : [constant] Typ [:= Expr];
12319            --
12320            --  Do not process tag-to-class-wide conversions because they do
12321            --  not yield an object. Do not process the incomplete view of a
12322            --  deferred constant. Note that an object initialized by means
12323            --  of a build-in-place function call may appear as a deferred
12324            --  constant after expansion activities. These kinds of objects
12325            --  must be finalized.
12326
12327            elsif not Is_Imported (Obj_Id)
12328              and then Needs_Finalization (Obj_Typ)
12329              and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
12330              and then not (Ekind (Obj_Id) = E_Constant
12331                             and then not Has_Completion (Obj_Id)
12332                             and then No (BIP_Initialization_Call (Obj_Id)))
12333            then
12334               return True;
12335
12336            --  The object is of the form:
12337            --    Obj : Access_Typ := Non_BIP_Function_Call'reference;
12338            --
12339            --    Obj : Access_Typ :=
12340            --            BIP_Function_Call (BIPalloc => 2, ...)'reference;
12341
12342            elsif Is_Access_Type (Obj_Typ)
12343              and then Needs_Finalization
12344                         (Available_View (Designated_Type (Obj_Typ)))
12345              and then Present (Expr)
12346              and then
12347                (Is_Secondary_Stack_BIP_Func_Call (Expr)
12348                  or else
12349                    (Is_Non_BIP_Func_Call (Expr)
12350                      and then not Is_Related_To_Func_Return (Obj_Id)))
12351            then
12352               return True;
12353
12354            --  Processing for "hook" objects generated for transient objects
12355            --  declared inside an Expression_With_Actions.
12356
12357            elsif Is_Access_Type (Obj_Typ)
12358              and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
12359              and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
12360                                                        N_Object_Declaration
12361            then
12362               return True;
12363
12364            --  Processing for intermediate results of if expressions where
12365            --  one of the alternatives uses a controlled function call.
12366
12367            elsif Is_Access_Type (Obj_Typ)
12368              and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
12369              and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
12370                                                        N_Defining_Identifier
12371              and then Present (Expr)
12372              and then Nkind (Expr) = N_Null
12373            then
12374               return True;
12375
12376            --  Simple protected objects which use type System.Tasking.
12377            --  Protected_Objects.Protection to manage their locks should be
12378            --  treated as controlled since they require manual cleanup.
12379
12380            elsif Ekind (Obj_Id) = E_Variable
12381              and then (Is_Simple_Protected_Type (Obj_Typ)
12382                         or else Has_Simple_Protected_Object (Obj_Typ))
12383            then
12384               return True;
12385            end if;
12386
12387         --  Specific cases of object renamings
12388
12389         elsif Nkind (Decl) = N_Object_Renaming_Declaration then
12390            Obj_Id  := Defining_Identifier (Decl);
12391            Obj_Typ := Base_Type (Etype (Obj_Id));
12392
12393            --  Bypass any form of processing for objects which have their
12394            --  finalization disabled. This applies only to objects at the
12395            --  library level.
12396
12397            if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
12398               null;
12399
12400            --  Ignored Ghost object renamings do not need any cleanup actions
12401            --  because they will not appear in the final tree.
12402
12403            elsif Is_Ignored_Ghost_Entity (Obj_Id) then
12404               null;
12405
12406            --  Return object of a build-in-place function. This case is
12407            --  recognized and marked by the expansion of an extended return
12408            --  statement (see Expand_N_Extended_Return_Statement).
12409
12410            elsif Needs_Finalization (Obj_Typ)
12411              and then Is_Return_Object (Obj_Id)
12412              and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
12413            then
12414               return True;
12415
12416            --  Detect a case where a source object has been initialized by
12417            --  a controlled function call or another object which was later
12418            --  rewritten as a class-wide conversion of Ada.Tags.Displace.
12419
12420            --     Obj1 : CW_Type := Src_Obj;
12421            --     Obj2 : CW_Type := Function_Call (...);
12422
12423            --     Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
12424            --     Tmp  : ... := Function_Call (...)'reference;
12425            --     Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
12426
12427            elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
12428               return True;
12429            end if;
12430
12431         --  Inspect the freeze node of an access-to-controlled type and look
12432         --  for a delayed finalization master. This case arises when the
12433         --  freeze actions are inserted at a later time than the expansion of
12434         --  the context. Since Build_Finalizer is never called on a single
12435         --  construct twice, the master will be ultimately left out and never
12436         --  finalized. This is also needed for freeze actions of designated
12437         --  types themselves, since in some cases the finalization master is
12438         --  associated with a designated type's freeze node rather than that
12439         --  of the access type (see handling for freeze actions in
12440         --  Build_Finalization_Master).
12441
12442         elsif Nkind (Decl) = N_Freeze_Entity
12443           and then Present (Actions (Decl))
12444         then
12445            Typ := Entity (Decl);
12446
12447            --  Freeze nodes for ignored Ghost types do not need cleanup
12448            --  actions because they will never appear in the final tree.
12449
12450            if Is_Ignored_Ghost_Entity (Typ) then
12451               null;
12452
12453            elsif ((Is_Access_Type (Typ)
12454                      and then not Is_Access_Subprogram_Type (Typ)
12455                      and then Needs_Finalization
12456                                 (Available_View (Designated_Type (Typ))))
12457                    or else (Is_Type (Typ) and then Needs_Finalization (Typ)))
12458              and then Requires_Cleanup_Actions
12459                         (Actions (Decl), Lib_Level, Nested_Constructs)
12460            then
12461               return True;
12462            end if;
12463
12464         --  Nested package declarations
12465
12466         elsif Nested_Constructs
12467           and then Nkind (Decl) = N_Package_Declaration
12468         then
12469            Pack_Id := Defining_Entity (Decl);
12470
12471            --  Do not inspect an ignored Ghost package because all code found
12472            --  within will not appear in the final tree.
12473
12474            if Is_Ignored_Ghost_Entity (Pack_Id) then
12475               null;
12476
12477            elsif Ekind (Pack_Id) /= E_Generic_Package
12478              and then Requires_Cleanup_Actions
12479                         (Specification (Decl), Lib_Level)
12480            then
12481               return True;
12482            end if;
12483
12484         --  Nested package bodies
12485
12486         elsif Nested_Constructs and then Nkind (Decl) = N_Package_Body then
12487
12488            --  Do not inspect an ignored Ghost package body because all code
12489            --  found within will not appear in the final tree.
12490
12491            if Is_Ignored_Ghost_Entity (Defining_Entity (Decl)) then
12492               null;
12493
12494            elsif Ekind (Corresponding_Spec (Decl)) /= E_Generic_Package
12495              and then Requires_Cleanup_Actions (Decl, Lib_Level)
12496            then
12497               return True;
12498            end if;
12499
12500         elsif Nkind (Decl) = N_Block_Statement
12501           and then
12502
12503           --  Handle a rare case caused by a controlled transient object
12504           --  created as part of a record init proc. The variable is wrapped
12505           --  in a block, but the block is not associated with a transient
12506           --  scope.
12507
12508           (Inside_Init_Proc
12509
12510           --  Handle the case where the original context has been wrapped in
12511           --  a block to avoid interference between exception handlers and
12512           --  At_End handlers. Treat the block as transparent and process its
12513           --  contents.
12514
12515             or else Is_Finalization_Wrapper (Decl))
12516         then
12517            if Requires_Cleanup_Actions (Decl, Lib_Level) then
12518               return True;
12519            end if;
12520         end if;
12521
12522         Next (Decl);
12523      end loop;
12524
12525      return False;
12526   end Requires_Cleanup_Actions;
12527
12528   ------------------------------------
12529   -- Safe_Unchecked_Type_Conversion --
12530   ------------------------------------
12531
12532   --  Note: this function knows quite a bit about the exact requirements of
12533   --  Gigi with respect to unchecked type conversions, and its code must be
12534   --  coordinated with any changes in Gigi in this area.
12535
12536   --  The above requirements should be documented in Sinfo ???
12537
12538   function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
12539      Otyp   : Entity_Id;
12540      Ityp   : Entity_Id;
12541      Oalign : Uint;
12542      Ialign : Uint;
12543      Pexp   : constant Node_Id := Parent (Exp);
12544
12545   begin
12546      --  If the expression is the RHS of an assignment or object declaration
12547      --  we are always OK because there will always be a target.
12548
12549      --  Object renaming declarations, (generated for view conversions of
12550      --  actuals in inlined calls), like object declarations, provide an
12551      --  explicit type, and are safe as well.
12552
12553      if (Nkind (Pexp) = N_Assignment_Statement
12554           and then Expression (Pexp) = Exp)
12555        or else Nkind_In (Pexp, N_Object_Declaration,
12556                                N_Object_Renaming_Declaration)
12557      then
12558         return True;
12559
12560      --  If the expression is the prefix of an N_Selected_Component we should
12561      --  also be OK because GCC knows to look inside the conversion except if
12562      --  the type is discriminated. We assume that we are OK anyway if the
12563      --  type is not set yet or if it is controlled since we can't afford to
12564      --  introduce a temporary in this case.
12565
12566      elsif Nkind (Pexp) = N_Selected_Component
12567        and then Prefix (Pexp) = Exp
12568      then
12569         if No (Etype (Pexp)) then
12570            return True;
12571         else
12572            return
12573              not Has_Discriminants (Etype (Pexp))
12574                or else Is_Constrained (Etype (Pexp));
12575         end if;
12576      end if;
12577
12578      --  Set the output type, this comes from Etype if it is set, otherwise we
12579      --  take it from the subtype mark, which we assume was already fully
12580      --  analyzed.
12581
12582      if Present (Etype (Exp)) then
12583         Otyp := Etype (Exp);
12584      else
12585         Otyp := Entity (Subtype_Mark (Exp));
12586      end if;
12587
12588      --  The input type always comes from the expression, and we assume this
12589      --  is indeed always analyzed, so we can simply get the Etype.
12590
12591      Ityp := Etype (Expression (Exp));
12592
12593      --  Initialize alignments to unknown so far
12594
12595      Oalign := No_Uint;
12596      Ialign := No_Uint;
12597
12598      --  Replace a concurrent type by its corresponding record type and each
12599      --  type by its underlying type and do the tests on those. The original
12600      --  type may be a private type whose completion is a concurrent type, so
12601      --  find the underlying type first.
12602
12603      if Present (Underlying_Type (Otyp)) then
12604         Otyp := Underlying_Type (Otyp);
12605      end if;
12606
12607      if Present (Underlying_Type (Ityp)) then
12608         Ityp := Underlying_Type (Ityp);
12609      end if;
12610
12611      if Is_Concurrent_Type (Otyp) then
12612         Otyp := Corresponding_Record_Type (Otyp);
12613      end if;
12614
12615      if Is_Concurrent_Type (Ityp) then
12616         Ityp := Corresponding_Record_Type (Ityp);
12617      end if;
12618
12619      --  If the base types are the same, we know there is no problem since
12620      --  this conversion will be a noop.
12621
12622      if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
12623         return True;
12624
12625      --  Same if this is an upwards conversion of an untagged type, and there
12626      --  are no constraints involved (could be more general???)
12627
12628      elsif Etype (Ityp) = Otyp
12629        and then not Is_Tagged_Type (Ityp)
12630        and then not Has_Discriminants (Ityp)
12631        and then No (First_Rep_Item (Base_Type (Ityp)))
12632      then
12633         return True;
12634
12635      --  If the expression has an access type (object or subprogram) we assume
12636      --  that the conversion is safe, because the size of the target is safe,
12637      --  even if it is a record (which might be treated as having unknown size
12638      --  at this point).
12639
12640      elsif Is_Access_Type (Ityp) then
12641         return True;
12642
12643      --  If the size of output type is known at compile time, there is never
12644      --  a problem. Note that unconstrained records are considered to be of
12645      --  known size, but we can't consider them that way here, because we are
12646      --  talking about the actual size of the object.
12647
12648      --  We also make sure that in addition to the size being known, we do not
12649      --  have a case which might generate an embarrassingly large temp in
12650      --  stack checking mode.
12651
12652      elsif Size_Known_At_Compile_Time (Otyp)
12653        and then
12654          (not Stack_Checking_Enabled
12655            or else not May_Generate_Large_Temp (Otyp))
12656        and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
12657      then
12658         return True;
12659
12660      --  If either type is tagged, then we know the alignment is OK so Gigi
12661      --  will be able to use pointer punning.
12662
12663      elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
12664         return True;
12665
12666      --  If either type is a limited record type, we cannot do a copy, so say
12667      --  safe since there's nothing else we can do.
12668
12669      elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
12670         return True;
12671
12672      --  Conversions to and from packed array types are always ignored and
12673      --  hence are safe.
12674
12675      elsif Is_Packed_Array_Impl_Type (Otyp)
12676        or else Is_Packed_Array_Impl_Type (Ityp)
12677      then
12678         return True;
12679      end if;
12680
12681      --  The only other cases known to be safe is if the input type's
12682      --  alignment is known to be at least the maximum alignment for the
12683      --  target or if both alignments are known and the output type's
12684      --  alignment is no stricter than the input's. We can use the component
12685      --  type alignment for an array if a type is an unpacked array type.
12686
12687      if Present (Alignment_Clause (Otyp)) then
12688         Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
12689
12690      elsif Is_Array_Type (Otyp)
12691        and then Present (Alignment_Clause (Component_Type (Otyp)))
12692      then
12693         Oalign := Expr_Value (Expression (Alignment_Clause
12694                                           (Component_Type (Otyp))));
12695      end if;
12696
12697      if Present (Alignment_Clause (Ityp)) then
12698         Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
12699
12700      elsif Is_Array_Type (Ityp)
12701        and then Present (Alignment_Clause (Component_Type (Ityp)))
12702      then
12703         Ialign := Expr_Value (Expression (Alignment_Clause
12704                                           (Component_Type (Ityp))));
12705      end if;
12706
12707      if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
12708         return True;
12709
12710      elsif Ialign /= No_Uint
12711        and then Oalign /= No_Uint
12712        and then Ialign <= Oalign
12713      then
12714         return True;
12715
12716      --   Otherwise, Gigi cannot handle this and we must make a temporary
12717
12718      else
12719         return False;
12720      end if;
12721   end Safe_Unchecked_Type_Conversion;
12722
12723   ---------------------------------
12724   -- Set_Current_Value_Condition --
12725   ---------------------------------
12726
12727   --  Note: the implementation of this procedure is very closely tied to the
12728   --  implementation of Get_Current_Value_Condition. Here we set required
12729   --  Current_Value fields, and in Get_Current_Value_Condition, we interpret
12730   --  them, so they must have a consistent view.
12731
12732   procedure Set_Current_Value_Condition (Cnode : Node_Id) is
12733
12734      procedure Set_Entity_Current_Value (N : Node_Id);
12735      --  If N is an entity reference, where the entity is of an appropriate
12736      --  kind, then set the current value of this entity to Cnode, unless
12737      --  there is already a definite value set there.
12738
12739      procedure Set_Expression_Current_Value (N : Node_Id);
12740      --  If N is of an appropriate form, sets an appropriate entry in current
12741      --  value fields of relevant entities. Multiple entities can be affected
12742      --  in the case of an AND or AND THEN.
12743
12744      ------------------------------
12745      -- Set_Entity_Current_Value --
12746      ------------------------------
12747
12748      procedure Set_Entity_Current_Value (N : Node_Id) is
12749      begin
12750         if Is_Entity_Name (N) then
12751            declare
12752               Ent : constant Entity_Id := Entity (N);
12753
12754            begin
12755               --  Don't capture if not safe to do so
12756
12757               if not Safe_To_Capture_Value (N, Ent, Cond => True) then
12758                  return;
12759               end if;
12760
12761               --  Here we have a case where the Current_Value field may need
12762               --  to be set. We set it if it is not already set to a compile
12763               --  time expression value.
12764
12765               --  Note that this represents a decision that one condition
12766               --  blots out another previous one. That's certainly right if
12767               --  they occur at the same level. If the second one is nested,
12768               --  then the decision is neither right nor wrong (it would be
12769               --  equally OK to leave the outer one in place, or take the new
12770               --  inner one. Really we should record both, but our data
12771               --  structures are not that elaborate.
12772
12773               if Nkind (Current_Value (Ent)) not in N_Subexpr then
12774                  Set_Current_Value (Ent, Cnode);
12775               end if;
12776            end;
12777         end if;
12778      end Set_Entity_Current_Value;
12779
12780      ----------------------------------
12781      -- Set_Expression_Current_Value --
12782      ----------------------------------
12783
12784      procedure Set_Expression_Current_Value (N : Node_Id) is
12785         Cond : Node_Id;
12786
12787      begin
12788         Cond := N;
12789
12790         --  Loop to deal with (ignore for now) any NOT operators present. The
12791         --  presence of NOT operators will be handled properly when we call
12792         --  Get_Current_Value_Condition.
12793
12794         while Nkind (Cond) = N_Op_Not loop
12795            Cond := Right_Opnd (Cond);
12796         end loop;
12797
12798         --  For an AND or AND THEN, recursively process operands
12799
12800         if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
12801            Set_Expression_Current_Value (Left_Opnd (Cond));
12802            Set_Expression_Current_Value (Right_Opnd (Cond));
12803            return;
12804         end if;
12805
12806         --  Check possible relational operator
12807
12808         if Nkind (Cond) in N_Op_Compare then
12809            if Compile_Time_Known_Value (Right_Opnd (Cond)) then
12810               Set_Entity_Current_Value (Left_Opnd (Cond));
12811            elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
12812               Set_Entity_Current_Value (Right_Opnd (Cond));
12813            end if;
12814
12815         elsif Nkind_In (Cond,
12816                 N_Type_Conversion,
12817                 N_Qualified_Expression,
12818                 N_Expression_With_Actions)
12819         then
12820            Set_Expression_Current_Value (Expression (Cond));
12821
12822         --  Check possible boolean variable reference
12823
12824         else
12825            Set_Entity_Current_Value (Cond);
12826         end if;
12827      end Set_Expression_Current_Value;
12828
12829   --  Start of processing for Set_Current_Value_Condition
12830
12831   begin
12832      Set_Expression_Current_Value (Condition (Cnode));
12833   end Set_Current_Value_Condition;
12834
12835   --------------------------
12836   -- Set_Elaboration_Flag --
12837   --------------------------
12838
12839   procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
12840      Loc : constant Source_Ptr := Sloc (N);
12841      Ent : constant Entity_Id  := Elaboration_Entity (Spec_Id);
12842      Asn : Node_Id;
12843
12844   begin
12845      if Present (Ent) then
12846
12847         --  Nothing to do if at the compilation unit level, because in this
12848         --  case the flag is set by the binder generated elaboration routine.
12849
12850         if Nkind (Parent (N)) = N_Compilation_Unit then
12851            null;
12852
12853         --  Here we do need to generate an assignment statement
12854
12855         else
12856            Check_Restriction (No_Elaboration_Code, N);
12857
12858            Asn :=
12859              Make_Assignment_Statement (Loc,
12860                Name       => New_Occurrence_Of (Ent, Loc),
12861                Expression => Make_Integer_Literal (Loc, Uint_1));
12862
12863            --  Mark the assignment statement as elaboration code. This allows
12864            --  the early call region mechanism (see Sem_Elab) to properly
12865            --  ignore such assignments even though they are nonpreelaborable
12866            --  code.
12867
12868            Set_Is_Elaboration_Code (Asn);
12869
12870            if Nkind (Parent (N)) = N_Subunit then
12871               Insert_After (Corresponding_Stub (Parent (N)), Asn);
12872            else
12873               Insert_After (N, Asn);
12874            end if;
12875
12876            Analyze (Asn);
12877
12878            --  Kill current value indication. This is necessary because the
12879            --  tests of this flag are inserted out of sequence and must not
12880            --  pick up bogus indications of the wrong constant value.
12881
12882            Set_Current_Value (Ent, Empty);
12883
12884            --  If the subprogram is in the current declarative part and
12885            --  'access has been applied to it, generate an elaboration
12886            --  check at the beginning of the declarations of the body.
12887
12888            if Nkind (N) = N_Subprogram_Body
12889              and then Address_Taken (Spec_Id)
12890              and then
12891                Ekind_In (Scope (Spec_Id), E_Block, E_Procedure, E_Function)
12892            then
12893               declare
12894                  Loc   : constant Source_Ptr := Sloc (N);
12895                  Decls : constant List_Id    := Declarations (N);
12896                  Chk   : Node_Id;
12897
12898               begin
12899                  --  No need to generate this check if first entry in the
12900                  --  declaration list is a raise of Program_Error now.
12901
12902                  if Present (Decls)
12903                    and then Nkind (First (Decls)) = N_Raise_Program_Error
12904                  then
12905                     return;
12906                  end if;
12907
12908                  --  Otherwise generate the check
12909
12910                  Chk :=
12911                    Make_Raise_Program_Error (Loc,
12912                      Condition =>
12913                        Make_Op_Eq (Loc,
12914                          Left_Opnd  => New_Occurrence_Of (Ent, Loc),
12915                          Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
12916                      Reason    => PE_Access_Before_Elaboration);
12917
12918                  if No (Decls) then
12919                     Set_Declarations (N, New_List (Chk));
12920                  else
12921                     Prepend (Chk, Decls);
12922                  end if;
12923
12924                  Analyze (Chk);
12925               end;
12926            end if;
12927         end if;
12928      end if;
12929   end Set_Elaboration_Flag;
12930
12931   ----------------------------
12932   -- Set_Renamed_Subprogram --
12933   ----------------------------
12934
12935   procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
12936   begin
12937      --  If input node is an identifier, we can just reset it
12938
12939      if Nkind (N) = N_Identifier then
12940         Set_Chars  (N, Chars (E));
12941         Set_Entity (N, E);
12942
12943         --  Otherwise we have to do a rewrite, preserving Comes_From_Source
12944
12945      else
12946         declare
12947            CS : constant Boolean := Comes_From_Source (N);
12948         begin
12949            Rewrite (N, Make_Identifier (Sloc (N), Chars (E)));
12950            Set_Entity (N, E);
12951            Set_Comes_From_Source (N, CS);
12952            Set_Analyzed (N, True);
12953         end;
12954      end if;
12955   end Set_Renamed_Subprogram;
12956
12957   ----------------------
12958   -- Side_Effect_Free --
12959   ----------------------
12960
12961   function Side_Effect_Free
12962     (N            : Node_Id;
12963      Name_Req     : Boolean := False;
12964      Variable_Ref : Boolean := False) return Boolean
12965   is
12966      Typ : constant Entity_Id := Etype (N);
12967      --  Result type of the expression
12968
12969      function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
12970      --  The argument N is a construct where the Prefix is dereferenced if it
12971      --  is an access type and the result is a variable. The call returns True
12972      --  if the construct is side effect free (not considering side effects in
12973      --  other than the prefix which are to be tested by the caller).
12974
12975      function Within_In_Parameter (N : Node_Id) return Boolean;
12976      --  Determines if N is a subcomponent of a composite in-parameter. If so,
12977      --  N is not side-effect free when the actual is global and modifiable
12978      --  indirectly from within a subprogram, because it may be passed by
12979      --  reference. The front-end must be conservative here and assume that
12980      --  this may happen with any array or record type. On the other hand, we
12981      --  cannot create temporaries for all expressions for which this
12982      --  condition is true, for various reasons that might require clearing up
12983      --  ??? For example, discriminant references that appear out of place, or
12984      --  spurious type errors with class-wide expressions. As a result, we
12985      --  limit the transformation to loop bounds, which is so far the only
12986      --  case that requires it.
12987
12988      -----------------------------
12989      -- Safe_Prefixed_Reference --
12990      -----------------------------
12991
12992      function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
12993      begin
12994         --  If prefix is not side effect free, definitely not safe
12995
12996         if not Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref) then
12997            return False;
12998
12999         --  If the prefix is of an access type that is not access-to-constant,
13000         --  then this construct is a variable reference, which means it is to
13001         --  be considered to have side effects if Variable_Ref is set True.
13002
13003         elsif Is_Access_Type (Etype (Prefix (N)))
13004           and then not Is_Access_Constant (Etype (Prefix (N)))
13005           and then Variable_Ref
13006         then
13007            --  Exception is a prefix that is the result of a previous removal
13008            --  of side effects.
13009
13010            return Is_Entity_Name (Prefix (N))
13011              and then not Comes_From_Source (Prefix (N))
13012              and then Ekind (Entity (Prefix (N))) = E_Constant
13013              and then Is_Internal_Name (Chars (Entity (Prefix (N))));
13014
13015         --  If the prefix is an explicit dereference then this construct is a
13016         --  variable reference, which means it is to be considered to have
13017         --  side effects if Variable_Ref is True.
13018
13019         --  We do NOT exclude dereferences of access-to-constant types because
13020         --  we handle them as constant view of variables.
13021
13022         elsif Nkind (Prefix (N)) = N_Explicit_Dereference
13023           and then Variable_Ref
13024         then
13025            return False;
13026
13027         --  Note: The following test is the simplest way of solving a complex
13028         --  problem uncovered by the following test (Side effect on loop bound
13029         --  that is a subcomponent of a global variable:
13030
13031         --    with Text_Io; use Text_Io;
13032         --    procedure Tloop is
13033         --      type X is
13034         --        record
13035         --          V : Natural := 4;
13036         --          S : String (1..5) := (others => 'a');
13037         --        end record;
13038         --      X1 : X;
13039
13040         --      procedure Modi;
13041
13042         --      generic
13043         --        with procedure Action;
13044         --      procedure Loop_G (Arg : X; Msg : String)
13045
13046         --      procedure Loop_G (Arg : X; Msg : String) is
13047         --      begin
13048         --        Put_Line ("begin loop_g " & Msg & " will loop till: "
13049         --                  & Natural'Image (Arg.V));
13050         --        for Index in 1 .. Arg.V loop
13051         --          Text_Io.Put_Line
13052         --            (Natural'Image (Index) & " " & Arg.S (Index));
13053         --          if Index > 2 then
13054         --            Modi;
13055         --          end if;
13056         --        end loop;
13057         --        Put_Line ("end loop_g " & Msg);
13058         --      end;
13059
13060         --      procedure Loop1 is new Loop_G (Modi);
13061         --      procedure Modi is
13062         --      begin
13063         --        X1.V := 1;
13064         --        Loop1 (X1, "from modi");
13065         --      end;
13066         --
13067         --    begin
13068         --      Loop1 (X1, "initial");
13069         --    end;
13070
13071         --  The output of the above program should be:
13072
13073         --    begin loop_g initial will loop till:  4
13074         --     1 a
13075         --     2 a
13076         --     3 a
13077         --    begin loop_g from modi will loop till:  1
13078         --     1 a
13079         --    end loop_g from modi
13080         --     4 a
13081         --    begin loop_g from modi will loop till:  1
13082         --     1 a
13083         --    end loop_g from modi
13084         --    end loop_g initial
13085
13086         --  If a loop bound is a subcomponent of a global variable, a
13087         --  modification of that variable within the loop may incorrectly
13088         --  affect the execution of the loop.
13089
13090         elsif Nkind (Parent (Parent (N))) = N_Loop_Parameter_Specification
13091           and then Within_In_Parameter (Prefix (N))
13092           and then Variable_Ref
13093         then
13094            return False;
13095
13096         --  All other cases are side effect free
13097
13098         else
13099            return True;
13100         end if;
13101      end Safe_Prefixed_Reference;
13102
13103      -------------------------
13104      -- Within_In_Parameter --
13105      -------------------------
13106
13107      function Within_In_Parameter (N : Node_Id) return Boolean is
13108      begin
13109         if not Comes_From_Source (N) then
13110            return False;
13111
13112         elsif Is_Entity_Name (N) then
13113            return Ekind (Entity (N)) = E_In_Parameter;
13114
13115         elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
13116            return Within_In_Parameter (Prefix (N));
13117
13118         else
13119            return False;
13120         end if;
13121      end Within_In_Parameter;
13122
13123   --  Start of processing for Side_Effect_Free
13124
13125   begin
13126      --  If volatile reference, always consider it to have side effects
13127
13128      if Is_Volatile_Reference (N) then
13129         return False;
13130      end if;
13131
13132      --  Note on checks that could raise Constraint_Error. Strictly, if we
13133      --  take advantage of 11.6, these checks do not count as side effects.
13134      --  However, we would prefer to consider that they are side effects,
13135      --  since the back end CSE does not work very well on expressions which
13136      --  can raise Constraint_Error. On the other hand if we don't consider
13137      --  them to be side effect free, then we get some awkward expansions
13138      --  in -gnato mode, resulting in code insertions at a point where we
13139      --  do not have a clear model for performing the insertions.
13140
13141      --  Special handling for entity names
13142
13143      if Is_Entity_Name (N) then
13144
13145         --  A type reference is always side effect free
13146
13147         if Is_Type (Entity (N)) then
13148            return True;
13149
13150         --  Variables are considered to be a side effect if Variable_Ref
13151         --  is set or if we have a volatile reference and Name_Req is off.
13152         --  If Name_Req is True then we can't help returning a name which
13153         --  effectively allows multiple references in any case.
13154
13155         elsif Is_Variable (N, Use_Original_Node => False) then
13156            return not Variable_Ref
13157              and then (not Is_Volatile_Reference (N) or else Name_Req);
13158
13159         --  Any other entity (e.g. a subtype name) is definitely side
13160         --  effect free.
13161
13162         else
13163            return True;
13164         end if;
13165
13166      --  A value known at compile time is always side effect free
13167
13168      elsif Compile_Time_Known_Value (N) then
13169         return True;
13170
13171      --  A variable renaming is not side-effect free, because the renaming
13172      --  will function like a macro in the front-end in some cases, and an
13173      --  assignment can modify the component designated by N, so we need to
13174      --  create a temporary for it.
13175
13176      --  The guard testing for Entity being present is needed at least in
13177      --  the case of rewritten predicate expressions, and may well also be
13178      --  appropriate elsewhere. Obviously we can't go testing the entity
13179      --  field if it does not exist, so it's reasonable to say that this is
13180      --  not the renaming case if it does not exist.
13181
13182      elsif Is_Entity_Name (Original_Node (N))
13183        and then Present (Entity (Original_Node (N)))
13184        and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
13185        and then Ekind (Entity (Original_Node (N))) /= E_Constant
13186      then
13187         declare
13188            RO : constant Node_Id :=
13189                   Renamed_Object (Entity (Original_Node (N)));
13190
13191         begin
13192            --  If the renamed object is an indexed component, or an
13193            --  explicit dereference, then the designated object could
13194            --  be modified by an assignment.
13195
13196            if Nkind_In (RO, N_Indexed_Component,
13197                             N_Explicit_Dereference)
13198            then
13199               return False;
13200
13201            --  A selected component must have a safe prefix
13202
13203            elsif Nkind (RO) = N_Selected_Component then
13204               return Safe_Prefixed_Reference (RO);
13205
13206            --  In all other cases, designated object cannot be changed so
13207            --  we are side effect free.
13208
13209            else
13210               return True;
13211            end if;
13212         end;
13213
13214      --  Remove_Side_Effects generates an object renaming declaration to
13215      --  capture the expression of a class-wide expression. In VM targets
13216      --  the frontend performs no expansion for dispatching calls to
13217      --  class- wide types since they are handled by the VM. Hence, we must
13218      --  locate here if this node corresponds to a previous invocation of
13219      --  Remove_Side_Effects to avoid a never ending loop in the frontend.
13220
13221      elsif not Tagged_Type_Expansion
13222        and then not Comes_From_Source (N)
13223        and then Nkind (Parent (N)) = N_Object_Renaming_Declaration
13224        and then Is_Class_Wide_Type (Typ)
13225      then
13226         return True;
13227
13228      --  Generating C the type conversion of an access to constrained array
13229      --  type into an access to unconstrained array type involves initializing
13230      --  a fat pointer and the expression cannot be assumed to be free of side
13231      --  effects since it must referenced several times to compute its bounds.
13232
13233      elsif Modify_Tree_For_C
13234        and then Nkind (N) = N_Type_Conversion
13235        and then Is_Access_Type (Typ)
13236        and then Is_Array_Type (Designated_Type (Typ))
13237        and then not Is_Constrained (Designated_Type (Typ))
13238      then
13239         return False;
13240      end if;
13241
13242      --  For other than entity names and compile time known values,
13243      --  check the node kind for special processing.
13244
13245      case Nkind (N) is
13246
13247         --  An attribute reference is side effect free if its expressions
13248         --  are side effect free and its prefix is side effect free or
13249         --  is an entity reference.
13250
13251         --  Is this right? what about x'first where x is a variable???
13252
13253         when N_Attribute_Reference =>
13254            Attribute_Reference : declare
13255
13256               function Side_Effect_Free_Attribute
13257                 (Attribute_Name : Name_Id) return Boolean;
13258               --  Returns True if evaluation of the given attribute is
13259               --  considered side-effect free (independent of prefix and
13260               --  arguments).
13261
13262               --------------------------------
13263               -- Side_Effect_Free_Attribute --
13264               --------------------------------
13265
13266               function Side_Effect_Free_Attribute
13267                 (Attribute_Name : Name_Id) return Boolean
13268               is
13269               begin
13270                  case Attribute_Name is
13271                     when Name_Input =>
13272                        return False;
13273
13274                     when Name_Image
13275                        | Name_Img
13276                        | Name_Wide_Image
13277                        | Name_Wide_Wide_Image
13278                     =>
13279                        --  CodePeer doesn't want to see replicated copies of
13280                        --  'Image calls.
13281
13282                        return not CodePeer_Mode;
13283
13284                     when others =>
13285                        return True;
13286                  end case;
13287               end Side_Effect_Free_Attribute;
13288
13289            --  Start of processing for Attribute_Reference
13290
13291            begin
13292               return
13293                 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
13294                   and then Side_Effect_Free_Attribute (Attribute_Name (N))
13295                   and then (Is_Entity_Name (Prefix (N))
13296                              or else Side_Effect_Free
13297                                        (Prefix (N), Name_Req, Variable_Ref));
13298            end Attribute_Reference;
13299
13300         --  A binary operator is side effect free if and both operands are
13301         --  side effect free. For this purpose binary operators include
13302         --  membership tests and short circuit forms.
13303
13304         when N_Binary_Op
13305            | N_Membership_Test
13306            | N_Short_Circuit
13307         =>
13308            return Side_Effect_Free (Left_Opnd  (N), Name_Req, Variable_Ref)
13309                     and then
13310                   Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
13311
13312         --  An explicit dereference is side effect free only if it is
13313         --  a side effect free prefixed reference.
13314
13315         when N_Explicit_Dereference =>
13316            return Safe_Prefixed_Reference (N);
13317
13318         --  An expression with action is side effect free if its expression
13319         --  is side effect free and it has no actions.
13320
13321         when N_Expression_With_Actions =>
13322            return
13323              Is_Empty_List (Actions (N))
13324                and then Side_Effect_Free
13325                           (Expression (N), Name_Req, Variable_Ref);
13326
13327         --  A call to _rep_to_pos is side effect free, since we generate
13328         --  this pure function call ourselves. Moreover it is critically
13329         --  important to make this exception, since otherwise we can have
13330         --  discriminants in array components which don't look side effect
13331         --  free in the case of an array whose index type is an enumeration
13332         --  type with an enumeration rep clause.
13333
13334         --  All other function calls are not side effect free
13335
13336         when N_Function_Call =>
13337            return
13338              Nkind (Name (N)) = N_Identifier
13339                and then Is_TSS (Name (N), TSS_Rep_To_Pos)
13340                and then Side_Effect_Free
13341                           (First (Parameter_Associations (N)),
13342                            Name_Req, Variable_Ref);
13343
13344         --  An IF expression is side effect free if it's of a scalar type, and
13345         --  all its components are all side effect free (conditions and then
13346         --  actions and else actions). We restrict to scalar types, since it
13347         --  is annoying to deal with things like (if A then B else C)'First
13348         --  where the type involved is a string type.
13349
13350         when N_If_Expression =>
13351            return
13352              Is_Scalar_Type (Typ)
13353                and then Side_Effect_Free
13354                           (Expressions (N), Name_Req, Variable_Ref);
13355
13356         --  An indexed component is side effect free if it is a side
13357         --  effect free prefixed reference and all the indexing
13358         --  expressions are side effect free.
13359
13360         when N_Indexed_Component =>
13361            return
13362              Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
13363                and then Safe_Prefixed_Reference (N);
13364
13365         --  A type qualification, type conversion, or unchecked expression is
13366         --  side effect free if the expression is side effect free.
13367
13368         when N_Qualified_Expression
13369            | N_Type_Conversion
13370            | N_Unchecked_Expression
13371         =>
13372            return Side_Effect_Free (Expression (N), Name_Req, Variable_Ref);
13373
13374         --  A selected component is side effect free only if it is a side
13375         --  effect free prefixed reference.
13376
13377         when N_Selected_Component =>
13378            return Safe_Prefixed_Reference (N);
13379
13380         --  A range is side effect free if the bounds are side effect free
13381
13382         when N_Range =>
13383            return Side_Effect_Free (Low_Bound (N),  Name_Req, Variable_Ref)
13384                     and then
13385                   Side_Effect_Free (High_Bound (N), Name_Req, Variable_Ref);
13386
13387         --  A slice is side effect free if it is a side effect free
13388         --  prefixed reference and the bounds are side effect free.
13389
13390         when N_Slice =>
13391            return
13392               Side_Effect_Free (Discrete_Range (N), Name_Req, Variable_Ref)
13393                 and then Safe_Prefixed_Reference (N);
13394
13395         --  A unary operator is side effect free if the operand
13396         --  is side effect free.
13397
13398         when N_Unary_Op =>
13399            return Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
13400
13401         --  An unchecked type conversion is side effect free only if it
13402         --  is safe and its argument is side effect free.
13403
13404         when N_Unchecked_Type_Conversion =>
13405            return
13406              Safe_Unchecked_Type_Conversion (N)
13407                and then Side_Effect_Free
13408                           (Expression (N), Name_Req, Variable_Ref);
13409
13410         --  A literal is side effect free
13411
13412         when N_Character_Literal
13413            | N_Integer_Literal
13414            | N_Real_Literal
13415            | N_String_Literal
13416         =>
13417            return True;
13418
13419         --  We consider that anything else has side effects. This is a bit
13420         --  crude, but we are pretty close for most common cases, and we
13421         --  are certainly correct (i.e. we never return True when the
13422         --  answer should be False).
13423
13424         when others =>
13425            return False;
13426      end case;
13427   end Side_Effect_Free;
13428
13429   --  A list is side effect free if all elements of the list are side
13430   --  effect free.
13431
13432   function Side_Effect_Free
13433     (L            : List_Id;
13434      Name_Req     : Boolean := False;
13435      Variable_Ref : Boolean := False) return Boolean
13436   is
13437      N : Node_Id;
13438
13439   begin
13440      if L = No_List or else L = Error_List then
13441         return True;
13442
13443      else
13444         N := First (L);
13445         while Present (N) loop
13446            if not Side_Effect_Free (N, Name_Req, Variable_Ref) then
13447               return False;
13448            else
13449               Next (N);
13450            end if;
13451         end loop;
13452
13453         return True;
13454      end if;
13455   end Side_Effect_Free;
13456
13457   ----------------------------------
13458   -- Silly_Boolean_Array_Not_Test --
13459   ----------------------------------
13460
13461   --  This procedure implements an odd and silly test. We explicitly check
13462   --  for the case where the 'First of the component type is equal to the
13463   --  'Last of this component type, and if this is the case, we make sure
13464   --  that constraint error is raised. The reason is that the NOT is bound
13465   --  to cause CE in this case, and we will not otherwise catch it.
13466
13467   --  No such check is required for AND and OR, since for both these cases
13468   --  False op False = False, and True op True = True. For the XOR case,
13469   --  see Silly_Boolean_Array_Xor_Test.
13470
13471   --  Believe it or not, this was reported as a bug. Note that nearly always,
13472   --  the test will evaluate statically to False, so the code will be
13473   --  statically removed, and no extra overhead caused.
13474
13475   procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
13476      Loc : constant Source_Ptr := Sloc (N);
13477      CT  : constant Entity_Id  := Component_Type (T);
13478
13479   begin
13480      --  The check we install is
13481
13482      --    constraint_error when
13483      --      component_type'first = component_type'last
13484      --        and then array_type'Length /= 0)
13485
13486      --  We need the last guard because we don't want to raise CE for empty
13487      --  arrays since no out of range values result. (Empty arrays with a
13488      --  component type of True .. True -- very useful -- even the ACATS
13489      --  does not test that marginal case).
13490
13491      Insert_Action (N,
13492        Make_Raise_Constraint_Error (Loc,
13493          Condition =>
13494            Make_And_Then (Loc,
13495              Left_Opnd =>
13496                Make_Op_Eq (Loc,
13497                  Left_Opnd =>
13498                    Make_Attribute_Reference (Loc,
13499                      Prefix         => New_Occurrence_Of (CT, Loc),
13500                      Attribute_Name => Name_First),
13501
13502                  Right_Opnd =>
13503                    Make_Attribute_Reference (Loc,
13504                      Prefix         => New_Occurrence_Of (CT, Loc),
13505                      Attribute_Name => Name_Last)),
13506
13507              Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
13508          Reason => CE_Range_Check_Failed));
13509   end Silly_Boolean_Array_Not_Test;
13510
13511   ----------------------------------
13512   -- Silly_Boolean_Array_Xor_Test --
13513   ----------------------------------
13514
13515   --  This procedure implements an odd and silly test. We explicitly check
13516   --  for the XOR case where the component type is True .. True, since this
13517   --  will raise constraint error. A special check is required since CE
13518   --  will not be generated otherwise (cf Expand_Packed_Not).
13519
13520   --  No such check is required for AND and OR, since for both these cases
13521   --  False op False = False, and True op True = True, and no check is
13522   --  required for the case of False .. False, since False xor False = False.
13523   --  See also Silly_Boolean_Array_Not_Test
13524
13525   procedure Silly_Boolean_Array_Xor_Test
13526     (N : Node_Id;
13527      R : Node_Id;
13528      T : Entity_Id)
13529   is
13530      Loc : constant Source_Ptr := Sloc (N);
13531      CT  : constant Entity_Id  := Component_Type (T);
13532
13533   begin
13534      --  The check we install is
13535
13536      --    constraint_error when
13537      --      Boolean (component_type'First)
13538      --        and then Boolean (component_type'Last)
13539      --        and then array_type'Length /= 0)
13540
13541      --  We need the last guard because we don't want to raise CE for empty
13542      --  arrays since no out of range values result (Empty arrays with a
13543      --  component type of True .. True -- very useful -- even the ACATS
13544      --  does not test that marginal case).
13545
13546      Insert_Action (N,
13547        Make_Raise_Constraint_Error (Loc,
13548          Condition =>
13549            Make_And_Then (Loc,
13550              Left_Opnd  =>
13551                Make_And_Then (Loc,
13552                  Left_Opnd  =>
13553                    Convert_To (Standard_Boolean,
13554                      Make_Attribute_Reference (Loc,
13555                        Prefix         => New_Occurrence_Of (CT, Loc),
13556                        Attribute_Name => Name_First)),
13557
13558                  Right_Opnd =>
13559                    Convert_To (Standard_Boolean,
13560                      Make_Attribute_Reference (Loc,
13561                        Prefix         => New_Occurrence_Of (CT, Loc),
13562                        Attribute_Name => Name_Last))),
13563
13564              Right_Opnd => Make_Non_Empty_Check (Loc, R)),
13565          Reason    => CE_Range_Check_Failed));
13566   end Silly_Boolean_Array_Xor_Test;
13567
13568   --------------------------
13569   -- Target_Has_Fixed_Ops --
13570   --------------------------
13571
13572   Integer_Sized_Small : Ureal;
13573   --  Set to 2.0 ** -(Integer'Size - 1) the first time that this function is
13574   --  called (we don't want to compute it more than once).
13575
13576   Long_Integer_Sized_Small : Ureal;
13577   --  Set to 2.0 ** -(Long_Integer'Size - 1) the first time that this function
13578   --  is called (we don't want to compute it more than once)
13579
13580   First_Time_For_THFO : Boolean := True;
13581   --  Set to False after first call (if Fractional_Fixed_Ops_On_Target)
13582
13583   function Target_Has_Fixed_Ops
13584     (Left_Typ   : Entity_Id;
13585      Right_Typ  : Entity_Id;
13586      Result_Typ : Entity_Id) return Boolean
13587   is
13588      function Is_Fractional_Type (Typ : Entity_Id) return Boolean;
13589      --  Return True if the given type is a fixed-point type with a small
13590      --  value equal to 2 ** (-(T'Object_Size - 1)) and whose values have
13591      --  an absolute value less than 1.0. This is currently limited to
13592      --  fixed-point types that map to Integer or Long_Integer.
13593
13594      ------------------------
13595      -- Is_Fractional_Type --
13596      ------------------------
13597
13598      function Is_Fractional_Type (Typ : Entity_Id) return Boolean is
13599      begin
13600         if Esize (Typ) = Standard_Integer_Size then
13601            return Small_Value (Typ) = Integer_Sized_Small;
13602
13603         elsif Esize (Typ) = Standard_Long_Integer_Size then
13604            return Small_Value (Typ) = Long_Integer_Sized_Small;
13605
13606         else
13607            return False;
13608         end if;
13609      end Is_Fractional_Type;
13610
13611   --  Start of processing for Target_Has_Fixed_Ops
13612
13613   begin
13614      --  Return False if Fractional_Fixed_Ops_On_Target is false
13615
13616      if not Fractional_Fixed_Ops_On_Target then
13617         return False;
13618      end if;
13619
13620      --  Here the target has Fractional_Fixed_Ops, if first time, compute
13621      --  standard constants used by Is_Fractional_Type.
13622
13623      if First_Time_For_THFO then
13624         First_Time_For_THFO := False;
13625
13626         Integer_Sized_Small :=
13627           UR_From_Components
13628             (Num   => Uint_1,
13629              Den   => UI_From_Int (Standard_Integer_Size - 1),
13630              Rbase => 2);
13631
13632         Long_Integer_Sized_Small :=
13633           UR_From_Components
13634             (Num   => Uint_1,
13635              Den   => UI_From_Int (Standard_Long_Integer_Size - 1),
13636              Rbase => 2);
13637      end if;
13638
13639      --  Return True if target supports fixed-by-fixed multiply/divide for
13640      --  fractional fixed-point types (see Is_Fractional_Type) and the operand
13641      --  and result types are equivalent fractional types.
13642
13643      return Is_Fractional_Type (Base_Type (Left_Typ))
13644        and then Is_Fractional_Type (Base_Type (Right_Typ))
13645        and then Is_Fractional_Type (Base_Type (Result_Typ))
13646        and then Esize (Left_Typ) = Esize (Right_Typ)
13647        and then Esize (Left_Typ) = Esize (Result_Typ);
13648   end Target_Has_Fixed_Ops;
13649
13650   -------------------
13651   -- Type_Map_Hash --
13652   -------------------
13653
13654   function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header is
13655   begin
13656      return Type_Map_Header (Id mod Type_Map_Size);
13657   end Type_Map_Hash;
13658
13659   ------------------------------------------
13660   -- Type_May_Have_Bit_Aligned_Components --
13661   ------------------------------------------
13662
13663   function Type_May_Have_Bit_Aligned_Components
13664     (Typ : Entity_Id) return Boolean
13665   is
13666   begin
13667      --  Array type, check component type
13668
13669      if Is_Array_Type (Typ) then
13670         return
13671           Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
13672
13673      --  Record type, check components
13674
13675      elsif Is_Record_Type (Typ) then
13676         declare
13677            E : Entity_Id;
13678
13679         begin
13680            E := First_Component_Or_Discriminant (Typ);
13681            while Present (E) loop
13682               --  This is the crucial test: if the component itself causes
13683               --  trouble, then we can stop and return True.
13684
13685               if Component_May_Be_Bit_Aligned (E) then
13686                  return True;
13687               end if;
13688
13689               --  Otherwise, we need to test its type, to see if it may
13690               --  itself contain a troublesome component.
13691
13692               if Type_May_Have_Bit_Aligned_Components (Etype (E)) then
13693                  return True;
13694               end if;
13695
13696               Next_Component_Or_Discriminant (E);
13697            end loop;
13698
13699            return False;
13700         end;
13701
13702      --  Type other than array or record is always OK
13703
13704      else
13705         return False;
13706      end if;
13707   end Type_May_Have_Bit_Aligned_Components;
13708
13709   -------------------------------
13710   -- Update_Primitives_Mapping --
13711   -------------------------------
13712
13713   procedure Update_Primitives_Mapping
13714     (Inher_Id : Entity_Id;
13715      Subp_Id  : Entity_Id)
13716   is
13717   begin
13718      Map_Types
13719        (Parent_Type  => Find_Dispatching_Type (Inher_Id),
13720         Derived_Type => Find_Dispatching_Type (Subp_Id));
13721   end Update_Primitives_Mapping;
13722
13723   ----------------------------------
13724   -- Within_Case_Or_If_Expression --
13725   ----------------------------------
13726
13727   function Within_Case_Or_If_Expression (N : Node_Id) return Boolean is
13728      Par : Node_Id;
13729
13730   begin
13731      --  Locate an enclosing case or if expression. Note that these constructs
13732      --  can be expanded into Expression_With_Actions, hence the test of the
13733      --  original node.
13734
13735      Par := Parent (N);
13736      while Present (Par) loop
13737         if Nkind_In (Original_Node (Par), N_Case_Expression,
13738                                           N_If_Expression)
13739         then
13740            return True;
13741
13742         --  Prevent the search from going too far
13743
13744         elsif Is_Body_Or_Package_Declaration (Par) then
13745            return False;
13746         end if;
13747
13748         Par := Parent (Par);
13749      end loop;
13750
13751      return False;
13752   end Within_Case_Or_If_Expression;
13753
13754   --------------------------------
13755   -- Within_Internal_Subprogram --
13756   --------------------------------
13757
13758   function Within_Internal_Subprogram return Boolean is
13759      S : Entity_Id;
13760
13761   begin
13762      S := Current_Scope;
13763      while Present (S) and then not Is_Subprogram (S) loop
13764         S := Scope (S);
13765      end loop;
13766
13767      return Present (S)
13768        and then Get_TSS_Name (S) /= TSS_Null
13769        and then not Is_Predicate_Function (S)
13770        and then not Is_Predicate_Function_M (S);
13771   end Within_Internal_Subprogram;
13772
13773end Exp_Util;
13774