cb61a42bb65aa81363988844e0bc4e4a9f29ea85
[platform/upstream/gcc.git] / gcc / ada / exp_util.adb
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-2013, 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
26 with Aspects;  use Aspects;
27 with Atree;    use Atree;
28 with Casing;   use Casing;
29 with Checks;   use Checks;
30 with Debug;    use Debug;
31 with Einfo;    use Einfo;
32 with Elists;   use Elists;
33 with Errout;   use Errout;
34 with Exp_Aggr; use Exp_Aggr;
35 with Exp_Ch6;  use Exp_Ch6;
36 with Exp_Ch7;  use Exp_Ch7;
37 with Inline;   use Inline;
38 with Itypes;   use Itypes;
39 with Lib;      use Lib;
40 with Nlists;   use Nlists;
41 with Nmake;    use Nmake;
42 with Opt;      use Opt;
43 with Restrict; use Restrict;
44 with Rident;   use Rident;
45 with Sem;      use Sem;
46 with Sem_Aux;  use Sem_Aux;
47 with Sem_Ch8;  use Sem_Ch8;
48 with Sem_Eval; use Sem_Eval;
49 with Sem_Prag; use Sem_Prag;
50 with Sem_Res;  use Sem_Res;
51 with Sem_Type; use Sem_Type;
52 with Sem_Util; use Sem_Util;
53 with Snames;   use Snames;
54 with Stand;    use Stand;
55 with Stringt;  use Stringt;
56 with Targparm; use Targparm;
57 with Tbuild;   use Tbuild;
58 with Ttypes;   use Ttypes;
59 with Urealp;   use Urealp;
60 with Validsw;  use Validsw;
61
62 package body Exp_Util is
63
64    -----------------------
65    -- Local Subprograms --
66    -----------------------
67
68    function Build_Task_Array_Image
69      (Loc    : Source_Ptr;
70       Id_Ref : Node_Id;
71       A_Type : Entity_Id;
72       Dyn    : Boolean := False) return Node_Id;
73    --  Build function to generate the image string for a task that is an array
74    --  component, concatenating the images of each index. To avoid storage
75    --  leaks, the string is built with successive slice assignments. The flag
76    --  Dyn indicates whether this is called for the initialization procedure of
77    --  an array of tasks, or for the name of a dynamically created task that is
78    --  assigned to an indexed component.
79
80    function Build_Task_Image_Function
81      (Loc   : Source_Ptr;
82       Decls : List_Id;
83       Stats : List_Id;
84       Res   : Entity_Id) return Node_Id;
85    --  Common processing for Task_Array_Image and Task_Record_Image. Build
86    --  function body that computes image.
87
88    procedure Build_Task_Image_Prefix
89       (Loc    : Source_Ptr;
90        Len    : out Entity_Id;
91        Res    : out Entity_Id;
92        Pos    : out Entity_Id;
93        Prefix : Entity_Id;
94        Sum    : Node_Id;
95        Decls  : List_Id;
96        Stats  : List_Id);
97    --  Common processing for Task_Array_Image and Task_Record_Image. Create
98    --  local variables and assign prefix of name to result string.
99
100    function Build_Task_Record_Image
101      (Loc    : Source_Ptr;
102       Id_Ref : Node_Id;
103       Dyn    : Boolean := False) return Node_Id;
104    --  Build function to generate the image string for a task that is a record
105    --  component. Concatenate name of variable with that of selector. The flag
106    --  Dyn indicates whether this is called for the initialization procedure of
107    --  record with task components, or for a dynamically created task that is
108    --  assigned to a selected component.
109
110    function Make_CW_Equivalent_Type
111      (T : Entity_Id;
112       E : Node_Id) return Entity_Id;
113    --  T is a class-wide type entity, E is the initial expression node that
114    --  constrains T in case such as: " X: T := E" or "new T'(E)". This function
115    --  returns the entity of the Equivalent type and inserts on the fly the
116    --  necessary declaration such as:
117    --
118    --    type anon is record
119    --       _parent : Root_Type (T); constrained with E discriminants (if any)
120    --       Extension : String (1 .. expr to match size of E);
121    --    end record;
122    --
123    --  This record is compatible with any object of the class of T thanks to
124    --  the first field and has the same size as E thanks to the second.
125
126    function Make_Literal_Range
127      (Loc         : Source_Ptr;
128       Literal_Typ : Entity_Id) return Node_Id;
129    --  Produce a Range node whose bounds are:
130    --    Low_Bound (Literal_Type) ..
131    --        Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1)
132    --  this is used for expanding declarations like X : String := "sdfgdfg";
133    --
134    --  If the index type of the target array is not integer, we generate:
135    --     Low_Bound (Literal_Type) ..
136    --        Literal_Type'Val
137    --          (Literal_Type'Pos (Low_Bound (Literal_Type))
138    --             + (Length (Literal_Typ) -1))
139
140    function Make_Non_Empty_Check
141      (Loc : Source_Ptr;
142       N   : Node_Id) return Node_Id;
143    --  Produce a boolean expression checking that the unidimensional array
144    --  node N is not empty.
145
146    function New_Class_Wide_Subtype
147      (CW_Typ : Entity_Id;
148       N      : Node_Id) return Entity_Id;
149    --  Create an implicit subtype of CW_Typ attached to node N
150
151    function Requires_Cleanup_Actions
152      (L                 : List_Id;
153       Lib_Level         : Boolean;
154       Nested_Constructs : Boolean) return Boolean;
155    --  Given a list L, determine whether it contains one of the following:
156    --
157    --    1) controlled objects
158    --    2) library-level tagged types
159    --
160    --  Lib_Level is True when the list comes from a construct at the library
161    --  level, and False otherwise. Nested_Constructs is True when any nested
162    --  packages declared in L must be processed, and False otherwise.
163
164    -------------------------------------
165    -- Activate_Atomic_Synchronization --
166    -------------------------------------
167
168    procedure Activate_Atomic_Synchronization (N : Node_Id) is
169       Msg_Node : Node_Id;
170
171    begin
172       case Nkind (Parent (N)) is
173
174          --  Check for cases of appearing in the prefix of a construct where
175          --  we don't need atomic synchronization for this kind of usage.
176
177          when
178               --  Nothing to do if we are the prefix of an attribute, since we
179               --  do not want an atomic sync operation for things like 'Size.
180
181               N_Attribute_Reference |
182
183               --  The N_Reference node is like an attribute
184
185               N_Reference           |
186
187               --  Nothing to do for a reference to a component (or components)
188               --  of a composite object. Only reads and updates of the object
189               --  as a whole require atomic synchronization (RM C.6 (15)).
190
191               N_Indexed_Component   |
192               N_Selected_Component  |
193               N_Slice               =>
194
195             --  For all the above cases, nothing to do if we are the prefix
196
197             if Prefix (Parent (N)) = N then
198                return;
199             end if;
200
201          when others => null;
202       end case;
203
204       --  Go ahead and set the flag
205
206       Set_Atomic_Sync_Required (N);
207
208       --  Generate info message if requested
209
210       if Warn_On_Atomic_Synchronization then
211          case Nkind (N) is
212             when N_Identifier =>
213                Msg_Node := N;
214
215             when N_Selected_Component | N_Expanded_Name =>
216                Msg_Node := Selector_Name (N);
217
218             when N_Explicit_Dereference | N_Indexed_Component =>
219                Msg_Node := Empty;
220
221             when others =>
222                pragma Assert (False);
223                return;
224          end case;
225
226          if Present (Msg_Node) then
227             Error_Msg_N
228               ("?N?info: atomic synchronization set for &", Msg_Node);
229          else
230             Error_Msg_N
231               ("?N?info: atomic synchronization set", N);
232          end if;
233       end if;
234    end Activate_Atomic_Synchronization;
235
236    ----------------------
237    -- Adjust_Condition --
238    ----------------------
239
240    procedure Adjust_Condition (N : Node_Id) is
241    begin
242       if No (N) then
243          return;
244       end if;
245
246       declare
247          Loc : constant Source_Ptr := Sloc (N);
248          T   : constant Entity_Id  := Etype (N);
249          Ti  : Entity_Id;
250
251       begin
252          --  Defend against a call where the argument has no type, or has a
253          --  type that is not Boolean. This can occur because of prior errors.
254
255          if No (T) or else not Is_Boolean_Type (T) then
256             return;
257          end if;
258
259          --  Apply validity checking if needed
260
261          if Validity_Checks_On and Validity_Check_Tests then
262             Ensure_Valid (N);
263          end if;
264
265          --  Immediate return if standard boolean, the most common case,
266          --  where nothing needs to be done.
267
268          if Base_Type (T) = Standard_Boolean then
269             return;
270          end if;
271
272          --  Case of zero/non-zero semantics or non-standard enumeration
273          --  representation. In each case, we rewrite the node as:
274
275          --      ityp!(N) /= False'Enum_Rep
276
277          --  where ityp is an integer type with large enough size to hold any
278          --  value of type T.
279
280          if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
281             if Esize (T) <= Esize (Standard_Integer) then
282                Ti := Standard_Integer;
283             else
284                Ti := Standard_Long_Long_Integer;
285             end if;
286
287             Rewrite (N,
288               Make_Op_Ne (Loc,
289                 Left_Opnd  => Unchecked_Convert_To (Ti, N),
290                 Right_Opnd =>
291                   Make_Attribute_Reference (Loc,
292                     Attribute_Name => Name_Enum_Rep,
293                     Prefix         =>
294                       New_Occurrence_Of (First_Literal (T), Loc))));
295             Analyze_And_Resolve (N, Standard_Boolean);
296
297          else
298             Rewrite (N, Convert_To (Standard_Boolean, N));
299             Analyze_And_Resolve (N, Standard_Boolean);
300          end if;
301       end;
302    end Adjust_Condition;
303
304    ------------------------
305    -- Adjust_Result_Type --
306    ------------------------
307
308    procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
309    begin
310       --  Ignore call if current type is not Standard.Boolean
311
312       if Etype (N) /= Standard_Boolean then
313          return;
314       end if;
315
316       --  If result is already of correct type, nothing to do. Note that
317       --  this will get the most common case where everything has a type
318       --  of Standard.Boolean.
319
320       if Base_Type (T) = Standard_Boolean then
321          return;
322
323       else
324          declare
325             KP : constant Node_Kind := Nkind (Parent (N));
326
327          begin
328             --  If result is to be used as a Condition in the syntax, no need
329             --  to convert it back, since if it was changed to Standard.Boolean
330             --  using Adjust_Condition, that is just fine for this usage.
331
332             if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
333                return;
334
335             --  If result is an operand of another logical operation, no need
336             --  to reset its type, since Standard.Boolean is just fine, and
337             --  such operations always do Adjust_Condition on their operands.
338
339             elsif     KP in N_Op_Boolean
340               or else KP in N_Short_Circuit
341               or else KP = N_Op_Not
342             then
343                return;
344
345             --  Otherwise we perform a conversion from the current type, which
346             --  must be Standard.Boolean, to the desired type.
347
348             else
349                Set_Analyzed (N);
350                Rewrite (N, Convert_To (T, N));
351                Analyze_And_Resolve (N, T);
352             end if;
353          end;
354       end if;
355    end Adjust_Result_Type;
356
357    --------------------------
358    -- Append_Freeze_Action --
359    --------------------------
360
361    procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
362       Fnode : Node_Id;
363
364    begin
365       Ensure_Freeze_Node (T);
366       Fnode := Freeze_Node (T);
367
368       if No (Actions (Fnode)) then
369          Set_Actions (Fnode, New_List (N));
370       else
371          Append (N, Actions (Fnode));
372       end if;
373
374    end Append_Freeze_Action;
375
376    ---------------------------
377    -- Append_Freeze_Actions --
378    ---------------------------
379
380    procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
381       Fnode : Node_Id;
382
383    begin
384       if No (L) then
385          return;
386       end if;
387
388       Ensure_Freeze_Node (T);
389       Fnode := Freeze_Node (T);
390
391       if No (Actions (Fnode)) then
392          Set_Actions (Fnode, L);
393       else
394          Append_List (L, Actions (Fnode));
395       end if;
396    end Append_Freeze_Actions;
397
398    ------------------------------------
399    -- Build_Allocate_Deallocate_Proc --
400    ------------------------------------
401
402    procedure Build_Allocate_Deallocate_Proc
403      (N           : Node_Id;
404       Is_Allocate : Boolean)
405    is
406       Desig_Typ    : Entity_Id;
407       Expr         : Node_Id;
408       Pool_Id      : Entity_Id;
409       Proc_To_Call : Node_Id := Empty;
410       Ptr_Typ      : Entity_Id;
411
412       function Find_Finalize_Address (Typ : Entity_Id) return Entity_Id;
413       --  Locate TSS primitive Finalize_Address in type Typ
414
415       function Find_Object (E : Node_Id) return Node_Id;
416       --  Given an arbitrary expression of an allocator, try to find an object
417       --  reference in it, otherwise return the original expression.
418
419       function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean;
420       --  Determine whether subprogram Subp denotes a custom allocate or
421       --  deallocate.
422
423       ---------------------------
424       -- Find_Finalize_Address --
425       ---------------------------
426
427       function Find_Finalize_Address (Typ : Entity_Id) return Entity_Id is
428          Utyp : Entity_Id := Typ;
429
430       begin
431          --  Handle protected class-wide or task class-wide types
432
433          if Is_Class_Wide_Type (Utyp) then
434             if Is_Concurrent_Type (Root_Type (Utyp)) then
435                Utyp := Root_Type (Utyp);
436
437             elsif Is_Private_Type (Root_Type (Utyp))
438               and then Present (Full_View (Root_Type (Utyp)))
439               and then Is_Concurrent_Type (Full_View (Root_Type (Utyp)))
440             then
441                Utyp := Full_View (Root_Type (Utyp));
442             end if;
443          end if;
444
445          --  Handle private types
446
447          if Is_Private_Type (Utyp) and then Present (Full_View (Utyp)) then
448             Utyp := Full_View (Utyp);
449          end if;
450
451          --  Handle protected and task types
452
453          if Is_Concurrent_Type (Utyp)
454            and then Present (Corresponding_Record_Type (Utyp))
455          then
456             Utyp := Corresponding_Record_Type (Utyp);
457          end if;
458
459          Utyp := Underlying_Type (Base_Type (Utyp));
460
461          --  Deal with non-tagged derivation of private views. If the parent is
462          --  now known to be protected, the finalization routine is the one
463          --  defined on the corresponding record of the ancestor (corresponding
464          --  records do not automatically inherit operations, but maybe they
465          --  should???)
466
467          if Is_Untagged_Derivation (Typ) then
468             if Is_Protected_Type (Typ) then
469                Utyp := Corresponding_Record_Type (Root_Type (Base_Type (Typ)));
470             else
471                Utyp := Underlying_Type (Root_Type (Base_Type (Typ)));
472
473                if Is_Protected_Type (Utyp) then
474                   Utyp := Corresponding_Record_Type (Utyp);
475                end if;
476             end if;
477          end if;
478
479          --  If the underlying_type is a subtype, we are dealing with the
480          --  completion of a private type. We need to access the base type and
481          --  generate a conversion to it.
482
483          if Utyp /= Base_Type (Utyp) then
484             pragma Assert (Is_Private_Type (Typ));
485
486             Utyp := Base_Type (Utyp);
487          end if;
488
489          --  When dealing with an internally built full view for a type with
490          --  unknown discriminants, use the original record type.
491
492          if Is_Underlying_Record_View (Utyp) then
493             Utyp := Etype (Utyp);
494          end if;
495
496          return TSS (Utyp, TSS_Finalize_Address);
497       end Find_Finalize_Address;
498
499       -----------------
500       -- Find_Object --
501       -----------------
502
503       function Find_Object (E : Node_Id) return Node_Id is
504          Expr : Node_Id;
505
506       begin
507          pragma Assert (Is_Allocate);
508
509          Expr := E;
510          loop
511             if Nkind_In (Expr, N_Qualified_Expression,
512                                N_Unchecked_Type_Conversion)
513             then
514                Expr := Expression (Expr);
515
516             elsif Nkind (Expr) = N_Explicit_Dereference then
517                Expr := Prefix (Expr);
518
519             else
520                exit;
521             end if;
522          end loop;
523
524          return Expr;
525       end Find_Object;
526
527       ---------------------------------
528       -- Is_Allocate_Deallocate_Proc --
529       ---------------------------------
530
531       function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is
532       begin
533          --  Look for a subprogram body with only one statement which is a
534          --  call to Allocate_Any_Controlled / Deallocate_Any_Controlled.
535
536          if Ekind (Subp) = E_Procedure
537            and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body
538          then
539             declare
540                HSS  : constant Node_Id :=
541                         Handled_Statement_Sequence (Parent (Parent (Subp)));
542                Proc : Entity_Id;
543
544             begin
545                if Present (Statements (HSS))
546                  and then Nkind (First (Statements (HSS))) =
547                             N_Procedure_Call_Statement
548                then
549                   Proc := Entity (Name (First (Statements (HSS))));
550
551                   return
552                     Is_RTE (Proc, RE_Allocate_Any_Controlled)
553                       or else Is_RTE (Proc, RE_Deallocate_Any_Controlled);
554                end if;
555             end;
556          end if;
557
558          return False;
559       end Is_Allocate_Deallocate_Proc;
560
561    --  Start of processing for Build_Allocate_Deallocate_Proc
562
563    begin
564       --  Do not perform this expansion in Alfa mode because it is not
565       --  necessary.
566
567       if Alfa_Mode then
568          return;
569       end if;
570
571       --  Obtain the attributes of the allocation / deallocation
572
573       if Nkind (N) = N_Free_Statement then
574          Expr := Expression (N);
575          Ptr_Typ := Base_Type (Etype (Expr));
576          Proc_To_Call := Procedure_To_Call (N);
577
578       else
579          if Nkind (N) = N_Object_Declaration then
580             Expr := Expression (N);
581          else
582             Expr := N;
583          end if;
584
585          --  In certain cases an allocator with a qualified expression may
586          --  be relocated and used as the initialization expression of a
587          --  temporary:
588
589          --    before:
590          --       Obj : Ptr_Typ := new Desig_Typ'(...);
591
592          --    after:
593          --       Tmp : Ptr_Typ := new Desig_Typ'(...);
594          --       Obj : Ptr_Typ := Tmp;
595
596          --  Since the allocator is always marked as analyzed to avoid infinite
597          --  expansion, it will never be processed by this routine given that
598          --  the designated type needs finalization actions. Detect this case
599          --  and complete the expansion of the allocator.
600
601          if Nkind (Expr) = N_Identifier
602            and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration
603            and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator
604          then
605             Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True);
606             return;
607          end if;
608
609          --  The allocator may have been rewritten into something else in which
610          --  case the expansion performed by this routine does not apply.
611
612          if Nkind (Expr) /= N_Allocator then
613             return;
614          end if;
615
616          Ptr_Typ := Base_Type (Etype (Expr));
617          Proc_To_Call := Procedure_To_Call (Expr);
618       end if;
619
620       Pool_Id := Associated_Storage_Pool (Ptr_Typ);
621       Desig_Typ := Available_View (Designated_Type (Ptr_Typ));
622
623       --  Handle concurrent types
624
625       if Is_Concurrent_Type (Desig_Typ)
626         and then Present (Corresponding_Record_Type (Desig_Typ))
627       then
628          Desig_Typ := Corresponding_Record_Type (Desig_Typ);
629       end if;
630
631       --  Do not process allocations / deallocations without a pool
632
633       if No (Pool_Id) then
634          return;
635
636       --  Do not process allocations on / deallocations from the secondary
637       --  stack.
638
639       elsif Is_RTE (Pool_Id, RE_SS_Pool) then
640          return;
641
642       --  Do not replicate the machinery if the allocator / free has already
643       --  been expanded and has a custom Allocate / Deallocate.
644
645       elsif Present (Proc_To_Call)
646         and then Is_Allocate_Deallocate_Proc (Proc_To_Call)
647       then
648          return;
649       end if;
650
651       if Needs_Finalization (Desig_Typ) then
652
653          --  Certain run-time configurations and targets do not provide support
654          --  for controlled types.
655
656          if Restriction_Active (No_Finalization) then
657             return;
658
659          --  Do nothing if the access type may never allocate / deallocate
660          --  objects.
661
662          elsif No_Pool_Assigned (Ptr_Typ) then
663             return;
664
665          --  Access-to-controlled types are not supported on .NET/JVM since
666          --  these targets cannot support pools and address arithmetic.
667
668          elsif VM_Target /= No_VM then
669             return;
670          end if;
671
672          --  The allocation / deallocation of a controlled object must be
673          --  chained on / detached from a finalization master.
674
675          pragma Assert (Present (Finalization_Master (Ptr_Typ)));
676
677       --  The only other kind of allocation / deallocation supported by this
678       --  routine is on / from a subpool.
679
680       elsif Nkind (Expr) = N_Allocator
681         and then No (Subpool_Handle_Name (Expr))
682       then
683          return;
684       end if;
685
686       declare
687          Loc     : constant Source_Ptr := Sloc (N);
688          Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A');
689          Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L');
690          Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
691          Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
692
693          Actuals      : List_Id;
694          Fin_Addr_Id  : Entity_Id;
695          Fin_Mas_Act  : Node_Id;
696          Fin_Mas_Id   : Entity_Id;
697          Proc_To_Call : Entity_Id;
698          Subpool      : Node_Id := Empty;
699
700       begin
701          --  Step 1: Construct all the actuals for the call to library routine
702          --  Allocate_Any_Controlled / Deallocate_Any_Controlled.
703
704          --  a) Storage pool
705
706          Actuals := New_List (New_Reference_To (Pool_Id, Loc));
707
708          if Is_Allocate then
709
710             --  b) Subpool
711
712             if Nkind (Expr) = N_Allocator then
713                Subpool := Subpool_Handle_Name (Expr);
714             end if;
715
716             --  If a subpool is present it can be an arbitrary name, so make
717             --  the actual by copying the tree.
718
719             if Present (Subpool) then
720                Append_To (Actuals, New_Copy_Tree (Subpool, New_Sloc => Loc));
721             else
722                Append_To (Actuals, Make_Null (Loc));
723             end if;
724
725             --  c) Finalization master
726
727             if Needs_Finalization (Desig_Typ) then
728                Fin_Mas_Id  := Finalization_Master (Ptr_Typ);
729                Fin_Mas_Act := New_Reference_To (Fin_Mas_Id, Loc);
730
731                --  Handle the case where the master is actually a pointer to a
732                --  master. This case arises in build-in-place functions.
733
734                if Is_Access_Type (Etype (Fin_Mas_Id)) then
735                   Append_To (Actuals, Fin_Mas_Act);
736                else
737                   Append_To (Actuals,
738                     Make_Attribute_Reference (Loc,
739                       Prefix         => Fin_Mas_Act,
740                       Attribute_Name => Name_Unrestricted_Access));
741                end if;
742             else
743                Append_To (Actuals, Make_Null (Loc));
744             end if;
745
746             --  d) Finalize_Address
747
748             --  Primitive Finalize_Address is never generated in CodePeer mode
749             --  since it contains an Unchecked_Conversion.
750
751             if Needs_Finalization (Desig_Typ) and then not CodePeer_Mode then
752                Fin_Addr_Id := Find_Finalize_Address (Desig_Typ);
753                pragma Assert (Present (Fin_Addr_Id));
754
755                Append_To (Actuals,
756                  Make_Attribute_Reference (Loc,
757                    Prefix         => New_Reference_To (Fin_Addr_Id, Loc),
758                    Attribute_Name => Name_Unrestricted_Access));
759             else
760                Append_To (Actuals, Make_Null (Loc));
761             end if;
762          end if;
763
764          --  e) Address
765          --  f) Storage_Size
766          --  g) Alignment
767
768          Append_To (Actuals, New_Reference_To (Addr_Id, Loc));
769          Append_To (Actuals, New_Reference_To (Size_Id, Loc));
770
771          if Is_Allocate or else not Is_Class_Wide_Type (Desig_Typ) then
772             Append_To (Actuals, New_Reference_To (Alig_Id, Loc));
773
774          --  For deallocation of class wide types we obtain the value of
775          --  alignment from the Type Specific Record of the deallocated object.
776          --  This is needed because the frontend expansion of class-wide types
777          --  into equivalent types confuses the backend.
778
779          else
780             --  Generate:
781             --     Obj.all'Alignment
782
783             --  ... because 'Alignment applied to class-wide types is expanded
784             --  into the code that reads the value of alignment from the TSD
785             --  (see Expand_N_Attribute_Reference)
786
787             Append_To (Actuals,
788               Unchecked_Convert_To (RTE (RE_Storage_Offset),
789                 Make_Attribute_Reference (Loc,
790                   Prefix         =>
791                     Make_Explicit_Dereference (Loc, Relocate_Node (Expr)),
792                   Attribute_Name => Name_Alignment)));
793          end if;
794
795          --  h) Is_Controlled
796
797          --  Generate a run-time check to determine whether a class-wide object
798          --  is truly controlled.
799
800          if Needs_Finalization (Desig_Typ) then
801             if Is_Class_Wide_Type (Desig_Typ)
802               or else Is_Generic_Actual_Type (Desig_Typ)
803             then
804                declare
805                   Flag_Id   : constant Entity_Id := Make_Temporary (Loc, 'F');
806                   Flag_Expr : Node_Id;
807                   Param     : Node_Id;
808                   Temp      : Node_Id;
809
810                begin
811                   if Is_Allocate then
812                      Temp := Find_Object (Expression (Expr));
813                   else
814                      Temp := Expr;
815                   end if;
816
817                   --  Processing for generic actuals
818
819                   if Is_Generic_Actual_Type (Desig_Typ) then
820                      Flag_Expr :=
821                        New_Reference_To (Boolean_Literals
822                          (Needs_Finalization (Base_Type (Desig_Typ))), Loc);
823
824                   --  Processing for subtype indications
825
826                   elsif Nkind (Temp) in N_Has_Entity
827                     and then Is_Type (Entity (Temp))
828                   then
829                      Flag_Expr :=
830                        New_Reference_To (Boolean_Literals
831                          (Needs_Finalization (Entity (Temp))), Loc);
832
833                   --  Generate a runtime check to test the controlled state of
834                   --  an object for the purposes of allocation / deallocation.
835
836                   else
837                      --  The following case arises when allocating through an
838                      --  interface class-wide type, generate:
839                      --
840                      --    Temp.all
841
842                      if Is_RTE (Etype (Temp), RE_Tag_Ptr) then
843                         Param :=
844                           Make_Explicit_Dereference (Loc,
845                             Prefix =>
846                               Relocate_Node (Temp));
847
848                      --  Generate:
849                      --    Temp'Tag
850
851                      else
852                         Param :=
853                           Make_Attribute_Reference (Loc,
854                             Prefix =>
855                               Relocate_Node (Temp),
856                             Attribute_Name => Name_Tag);
857                      end if;
858
859                      --  Generate:
860                      --    Needs_Finalization (<Param>)
861
862                      Flag_Expr :=
863                        Make_Function_Call (Loc,
864                          Name =>
865                            New_Reference_To (RTE (RE_Needs_Finalization), Loc),
866                          Parameter_Associations => New_List (Param));
867                   end if;
868
869                   --  Create the temporary which represents the finalization
870                   --  state of the expression. Generate:
871                   --
872                   --    F : constant Boolean := <Flag_Expr>;
873
874                   Insert_Action (N,
875                     Make_Object_Declaration (Loc,
876                       Defining_Identifier => Flag_Id,
877                       Constant_Present => True,
878                       Object_Definition =>
879                         New_Reference_To (Standard_Boolean, Loc),
880                       Expression => Flag_Expr));
881
882                   --  The flag acts as the last actual
883
884                   Append_To (Actuals, New_Reference_To (Flag_Id, Loc));
885                end;
886
887             --  The object is statically known to be controlled
888
889             else
890                Append_To (Actuals, New_Reference_To (Standard_True, Loc));
891             end if;
892
893          else
894             Append_To (Actuals, New_Reference_To (Standard_False, Loc));
895          end if;
896
897          --  i) On_Subpool
898
899          if Is_Allocate then
900             Append_To (Actuals,
901               New_Reference_To (Boolean_Literals (Present (Subpool)), Loc));
902          end if;
903
904          --  Step 2: Build a wrapper Allocate / Deallocate which internally
905          --  calls Allocate_Any_Controlled / Deallocate_Any_Controlled.
906
907          --  Select the proper routine to call
908
909          if Is_Allocate then
910             Proc_To_Call := RTE (RE_Allocate_Any_Controlled);
911          else
912             Proc_To_Call := RTE (RE_Deallocate_Any_Controlled);
913          end if;
914
915          --  Create a custom Allocate / Deallocate routine which has identical
916          --  profile to that of System.Storage_Pools.
917
918          Insert_Action (N,
919            Make_Subprogram_Body (Loc,
920              Specification =>
921
922                --  procedure Pnn
923
924                Make_Procedure_Specification (Loc,
925                  Defining_Unit_Name => Proc_Id,
926                  Parameter_Specifications => New_List (
927
928                   --  P : Root_Storage_Pool
929
930                    Make_Parameter_Specification (Loc,
931                      Defining_Identifier => Make_Temporary (Loc, 'P'),
932                      Parameter_Type =>
933                        New_Reference_To (RTE (RE_Root_Storage_Pool), Loc)),
934
935                   --  A : [out] Address
936
937                    Make_Parameter_Specification (Loc,
938                      Defining_Identifier => Addr_Id,
939                      Out_Present         => Is_Allocate,
940                      Parameter_Type      =>
941                        New_Reference_To (RTE (RE_Address), Loc)),
942
943                   --  S : Storage_Count
944
945                    Make_Parameter_Specification (Loc,
946                      Defining_Identifier => Size_Id,
947                      Parameter_Type      =>
948                        New_Reference_To (RTE (RE_Storage_Count), Loc)),
949
950                   --  L : Storage_Count
951
952                    Make_Parameter_Specification (Loc,
953                      Defining_Identifier => Alig_Id,
954                      Parameter_Type      =>
955                        New_Reference_To (RTE (RE_Storage_Count), Loc)))),
956
957              Declarations => No_List,
958
959              Handled_Statement_Sequence =>
960                Make_Handled_Sequence_Of_Statements (Loc,
961                  Statements => New_List (
962                    Make_Procedure_Call_Statement (Loc,
963                      Name => New_Reference_To (Proc_To_Call, Loc),
964                      Parameter_Associations => Actuals)))));
965
966          --  The newly generated Allocate / Deallocate becomes the default
967          --  procedure to call when the back end processes the allocation /
968          --  deallocation.
969
970          if Is_Allocate then
971             Set_Procedure_To_Call (Expr, Proc_Id);
972          else
973             Set_Procedure_To_Call (N, Proc_Id);
974          end if;
975       end;
976    end Build_Allocate_Deallocate_Proc;
977
978    ------------------------
979    -- Build_Runtime_Call --
980    ------------------------
981
982    function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
983    begin
984       --  If entity is not available, we can skip making the call (this avoids
985       --  junk duplicated error messages in a number of cases).
986
987       if not RTE_Available (RE) then
988          return Make_Null_Statement (Loc);
989       else
990          return
991            Make_Procedure_Call_Statement (Loc,
992              Name => New_Reference_To (RTE (RE), Loc));
993       end if;
994    end Build_Runtime_Call;
995
996    ----------------------------
997    -- Build_Task_Array_Image --
998    ----------------------------
999
1000    --  This function generates the body for a function that constructs the
1001    --  image string for a task that is an array component. The function is
1002    --  local to the init proc for the array type, and is called for each one
1003    --  of the components. The constructed image has the form of an indexed
1004    --  component, whose prefix is the outer variable of the array type.
1005    --  The n-dimensional array type has known indexes Index, Index2...
1006
1007    --  Id_Ref is an indexed component form created by the enclosing init proc.
1008    --  Its successive indexes are Val1, Val2, ... which are the loop variables
1009    --  in the loops that call the individual task init proc on each component.
1010
1011    --  The generated function has the following structure:
1012
1013    --  function F return String is
1014    --     Pref : string renames Task_Name;
1015    --     T1   : String := Index1'Image (Val1);
1016    --     ...
1017    --     Tn   : String := indexn'image (Valn);
1018    --     Len  : Integer := T1'Length + ... + Tn'Length + n + 1;
1019    --     --  Len includes commas and the end parentheses.
1020    --     Res  : String (1..Len);
1021    --     Pos  : Integer := Pref'Length;
1022    --
1023    --  begin
1024    --     Res (1 .. Pos) := Pref;
1025    --     Pos := Pos + 1;
1026    --     Res (Pos)    := '(';
1027    --     Pos := Pos + 1;
1028    --     Res (Pos .. Pos + T1'Length - 1) := T1;
1029    --     Pos := Pos + T1'Length;
1030    --     Res (Pos) := '.';
1031    --     Pos := Pos + 1;
1032    --     ...
1033    --     Res (Pos .. Pos + Tn'Length - 1) := Tn;
1034    --     Res (Len) := ')';
1035    --
1036    --     return Res;
1037    --  end F;
1038    --
1039    --  Needless to say, multidimensional arrays of tasks are rare enough that
1040    --  the bulkiness of this code is not really a concern.
1041
1042    function Build_Task_Array_Image
1043      (Loc    : Source_Ptr;
1044       Id_Ref : Node_Id;
1045       A_Type : Entity_Id;
1046       Dyn    : Boolean := False) return Node_Id
1047    is
1048       Dims : constant Nat := Number_Dimensions (A_Type);
1049       --  Number of dimensions for array of tasks
1050
1051       Temps : array (1 .. Dims) of Entity_Id;
1052       --  Array of temporaries to hold string for each index
1053
1054       Indx : Node_Id;
1055       --  Index expression
1056
1057       Len : Entity_Id;
1058       --  Total length of generated name
1059
1060       Pos : Entity_Id;
1061       --  Running index for substring assignments
1062
1063       Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
1064       --  Name of enclosing variable, prefix of resulting name
1065
1066       Res : Entity_Id;
1067       --  String to hold result
1068
1069       Val : Node_Id;
1070       --  Value of successive indexes
1071
1072       Sum : Node_Id;
1073       --  Expression to compute total size of string
1074
1075       T : Entity_Id;
1076       --  Entity for name at one index position
1077
1078       Decls : constant List_Id := New_List;
1079       Stats : constant List_Id := New_List;
1080
1081    begin
1082       --  For a dynamic task, the name comes from the target variable. For a
1083       --  static one it is a formal of the enclosing init proc.
1084
1085       if Dyn then
1086          Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
1087          Append_To (Decls,
1088            Make_Object_Declaration (Loc,
1089              Defining_Identifier => Pref,
1090              Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1091              Expression =>
1092                Make_String_Literal (Loc,
1093                  Strval => String_From_Name_Buffer)));
1094
1095       else
1096          Append_To (Decls,
1097            Make_Object_Renaming_Declaration (Loc,
1098              Defining_Identifier => Pref,
1099              Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
1100              Name                => Make_Identifier (Loc, Name_uTask_Name)));
1101       end if;
1102
1103       Indx := First_Index (A_Type);
1104       Val  := First (Expressions (Id_Ref));
1105
1106       for J in 1 .. Dims loop
1107          T := Make_Temporary (Loc, 'T');
1108          Temps (J) := T;
1109
1110          Append_To (Decls,
1111            Make_Object_Declaration (Loc,
1112              Defining_Identifier => T,
1113              Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
1114              Expression          =>
1115                Make_Attribute_Reference (Loc,
1116                  Attribute_Name => Name_Image,
1117                  Prefix         => New_Occurrence_Of (Etype (Indx), Loc),
1118                  Expressions    => New_List (New_Copy_Tree (Val)))));
1119
1120          Next_Index (Indx);
1121          Next (Val);
1122       end loop;
1123
1124       Sum := Make_Integer_Literal (Loc, Dims + 1);
1125
1126       Sum :=
1127         Make_Op_Add (Loc,
1128           Left_Opnd => Sum,
1129           Right_Opnd =>
1130             Make_Attribute_Reference (Loc,
1131               Attribute_Name => Name_Length,
1132               Prefix         => New_Occurrence_Of (Pref, Loc),
1133               Expressions    => New_List (Make_Integer_Literal (Loc, 1))));
1134
1135       for J in 1 .. Dims loop
1136          Sum :=
1137            Make_Op_Add (Loc,
1138              Left_Opnd  => Sum,
1139              Right_Opnd =>
1140                Make_Attribute_Reference (Loc,
1141                  Attribute_Name => Name_Length,
1142                  Prefix         =>
1143                   New_Occurrence_Of (Temps (J), Loc),
1144                 Expressions     => New_List (Make_Integer_Literal (Loc, 1))));
1145       end loop;
1146
1147       Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
1148
1149       Set_Character_Literal_Name (Char_Code (Character'Pos ('(')));
1150
1151       Append_To (Stats,
1152         Make_Assignment_Statement (Loc,
1153           Name       =>
1154             Make_Indexed_Component (Loc,
1155               Prefix      => New_Occurrence_Of (Res, Loc),
1156               Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1157           Expression =>
1158             Make_Character_Literal (Loc,
1159               Chars              => Name_Find,
1160               Char_Literal_Value => UI_From_Int (Character'Pos ('(')))));
1161
1162       Append_To (Stats,
1163         Make_Assignment_Statement (Loc,
1164           Name       => New_Occurrence_Of (Pos, Loc),
1165           Expression =>
1166             Make_Op_Add (Loc,
1167               Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1168               Right_Opnd => Make_Integer_Literal (Loc, 1))));
1169
1170       for J in 1 .. Dims loop
1171
1172          Append_To (Stats,
1173            Make_Assignment_Statement (Loc,
1174              Name =>
1175                Make_Slice (Loc,
1176                  Prefix          => New_Occurrence_Of (Res, Loc),
1177                  Discrete_Range  =>
1178                    Make_Range (Loc,
1179                      Low_Bound  => New_Occurrence_Of  (Pos, Loc),
1180                      High_Bound =>
1181                        Make_Op_Subtract (Loc,
1182                          Left_Opnd  =>
1183                            Make_Op_Add (Loc,
1184                              Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1185                              Right_Opnd =>
1186                                Make_Attribute_Reference (Loc,
1187                                  Attribute_Name => Name_Length,
1188                                  Prefix         =>
1189                                    New_Occurrence_Of (Temps (J), Loc),
1190                                  Expressions    =>
1191                                    New_List (Make_Integer_Literal (Loc, 1)))),
1192                          Right_Opnd => Make_Integer_Literal (Loc, 1)))),
1193
1194               Expression => New_Occurrence_Of (Temps (J), Loc)));
1195
1196          if J < Dims then
1197             Append_To (Stats,
1198                Make_Assignment_Statement (Loc,
1199                   Name       => New_Occurrence_Of (Pos, Loc),
1200                   Expression =>
1201                     Make_Op_Add (Loc,
1202                       Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1203                       Right_Opnd =>
1204                         Make_Attribute_Reference (Loc,
1205                           Attribute_Name => Name_Length,
1206                           Prefix         => New_Occurrence_Of (Temps (J), Loc),
1207                           Expressions    =>
1208                             New_List (Make_Integer_Literal (Loc, 1))))));
1209
1210             Set_Character_Literal_Name (Char_Code (Character'Pos (',')));
1211
1212             Append_To (Stats,
1213               Make_Assignment_Statement (Loc,
1214                 Name => Make_Indexed_Component (Loc,
1215                    Prefix => New_Occurrence_Of (Res, Loc),
1216                    Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1217                 Expression =>
1218                   Make_Character_Literal (Loc,
1219                     Chars              => Name_Find,
1220                     Char_Literal_Value => UI_From_Int (Character'Pos (',')))));
1221
1222             Append_To (Stats,
1223               Make_Assignment_Statement (Loc,
1224                 Name         => New_Occurrence_Of (Pos, Loc),
1225                   Expression =>
1226                     Make_Op_Add (Loc,
1227                       Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1228                       Right_Opnd => Make_Integer_Literal (Loc, 1))));
1229          end if;
1230       end loop;
1231
1232       Set_Character_Literal_Name (Char_Code (Character'Pos (')')));
1233
1234       Append_To (Stats,
1235         Make_Assignment_Statement (Loc,
1236           Name        =>
1237             Make_Indexed_Component (Loc,
1238               Prefix      => New_Occurrence_Of (Res, Loc),
1239               Expressions => New_List (New_Occurrence_Of (Len, Loc))),
1240            Expression =>
1241              Make_Character_Literal (Loc,
1242                Chars              => Name_Find,
1243                Char_Literal_Value => UI_From_Int (Character'Pos (')')))));
1244       return Build_Task_Image_Function (Loc, Decls, Stats, Res);
1245    end Build_Task_Array_Image;
1246
1247    ----------------------------
1248    -- Build_Task_Image_Decls --
1249    ----------------------------
1250
1251    function Build_Task_Image_Decls
1252      (Loc          : Source_Ptr;
1253       Id_Ref       : Node_Id;
1254       A_Type       : Entity_Id;
1255       In_Init_Proc : Boolean := False) return List_Id
1256    is
1257       Decls  : constant List_Id   := New_List;
1258       T_Id   : Entity_Id := Empty;
1259       Decl   : Node_Id;
1260       Expr   : Node_Id   := Empty;
1261       Fun    : Node_Id   := Empty;
1262       Is_Dyn : constant Boolean :=
1263                  Nkind (Parent (Id_Ref)) = N_Assignment_Statement
1264                    and then
1265                  Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
1266
1267    begin
1268       --  If Discard_Names or No_Implicit_Heap_Allocations are in effect,
1269       --  generate a dummy declaration only.
1270
1271       if Restriction_Active (No_Implicit_Heap_Allocations)
1272         or else Global_Discard_Names
1273       then
1274          T_Id := Make_Temporary (Loc, 'J');
1275          Name_Len := 0;
1276
1277          return
1278            New_List (
1279              Make_Object_Declaration (Loc,
1280                Defining_Identifier => T_Id,
1281                Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1282                Expression =>
1283                  Make_String_Literal (Loc,
1284                    Strval => String_From_Name_Buffer)));
1285
1286       else
1287          if Nkind (Id_Ref) = N_Identifier
1288            or else Nkind (Id_Ref) = N_Defining_Identifier
1289          then
1290             --  For a simple variable, the image of the task is built from
1291             --  the name of the variable. To avoid possible conflict with the
1292             --  anonymous type created for a single protected object, add a
1293             --  numeric suffix.
1294
1295             T_Id :=
1296               Make_Defining_Identifier (Loc,
1297                 New_External_Name (Chars (Id_Ref), 'T', 1));
1298
1299             Get_Name_String (Chars (Id_Ref));
1300
1301             Expr :=
1302               Make_String_Literal (Loc,
1303                 Strval => String_From_Name_Buffer);
1304
1305          elsif Nkind (Id_Ref) = N_Selected_Component then
1306             T_Id :=
1307               Make_Defining_Identifier (Loc,
1308                 New_External_Name (Chars (Selector_Name (Id_Ref)), 'T'));
1309             Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
1310
1311          elsif Nkind (Id_Ref) = N_Indexed_Component then
1312             T_Id :=
1313               Make_Defining_Identifier (Loc,
1314                 New_External_Name (Chars (A_Type), 'N'));
1315
1316             Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
1317          end if;
1318       end if;
1319
1320       if Present (Fun) then
1321          Append (Fun, Decls);
1322          Expr := Make_Function_Call (Loc,
1323            Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
1324
1325          if not In_Init_Proc and then VM_Target = No_VM then
1326             Set_Uses_Sec_Stack (Defining_Entity (Fun));
1327          end if;
1328       end if;
1329
1330       Decl := Make_Object_Declaration (Loc,
1331         Defining_Identifier => T_Id,
1332         Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
1333         Constant_Present    => True,
1334         Expression          => Expr);
1335
1336       Append (Decl, Decls);
1337       return Decls;
1338    end Build_Task_Image_Decls;
1339
1340    -------------------------------
1341    -- Build_Task_Image_Function --
1342    -------------------------------
1343
1344    function Build_Task_Image_Function
1345      (Loc   : Source_Ptr;
1346       Decls : List_Id;
1347       Stats : List_Id;
1348       Res   : Entity_Id) return Node_Id
1349    is
1350       Spec : Node_Id;
1351
1352    begin
1353       Append_To (Stats,
1354         Make_Simple_Return_Statement (Loc,
1355           Expression => New_Occurrence_Of (Res, Loc)));
1356
1357       Spec := Make_Function_Specification (Loc,
1358         Defining_Unit_Name => Make_Temporary (Loc, 'F'),
1359         Result_Definition  => New_Occurrence_Of (Standard_String, Loc));
1360
1361       --  Calls to 'Image use the secondary stack, which must be cleaned up
1362       --  after the task name is built.
1363
1364       return Make_Subprogram_Body (Loc,
1365          Specification => Spec,
1366          Declarations => Decls,
1367          Handled_Statement_Sequence =>
1368            Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats));
1369    end Build_Task_Image_Function;
1370
1371    -----------------------------
1372    -- Build_Task_Image_Prefix --
1373    -----------------------------
1374
1375    procedure Build_Task_Image_Prefix
1376       (Loc    : Source_Ptr;
1377        Len    : out Entity_Id;
1378        Res    : out Entity_Id;
1379        Pos    : out Entity_Id;
1380        Prefix : Entity_Id;
1381        Sum    : Node_Id;
1382        Decls  : List_Id;
1383        Stats  : List_Id)
1384    is
1385    begin
1386       Len := Make_Temporary (Loc, 'L', Sum);
1387
1388       Append_To (Decls,
1389         Make_Object_Declaration (Loc,
1390           Defining_Identifier => Len,
1391           Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc),
1392           Expression          => Sum));
1393
1394       Res := Make_Temporary (Loc, 'R');
1395
1396       Append_To (Decls,
1397          Make_Object_Declaration (Loc,
1398             Defining_Identifier => Res,
1399             Object_Definition =>
1400                Make_Subtype_Indication (Loc,
1401                   Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
1402                Constraint =>
1403                  Make_Index_Or_Discriminant_Constraint (Loc,
1404                    Constraints =>
1405                      New_List (
1406                        Make_Range (Loc,
1407                          Low_Bound => Make_Integer_Literal (Loc, 1),
1408                          High_Bound => New_Occurrence_Of (Len, Loc)))))));
1409
1410       Pos := Make_Temporary (Loc, 'P');
1411
1412       Append_To (Decls,
1413          Make_Object_Declaration (Loc,
1414             Defining_Identifier => Pos,
1415             Object_Definition   => New_Occurrence_Of (Standard_Integer, Loc)));
1416
1417       --  Pos := Prefix'Length;
1418
1419       Append_To (Stats,
1420          Make_Assignment_Statement (Loc,
1421             Name => New_Occurrence_Of (Pos, Loc),
1422             Expression =>
1423               Make_Attribute_Reference (Loc,
1424                 Attribute_Name => Name_Length,
1425                 Prefix         => New_Occurrence_Of (Prefix, Loc),
1426                 Expressions    => New_List (Make_Integer_Literal (Loc, 1)))));
1427
1428       --  Res (1 .. Pos) := Prefix;
1429
1430       Append_To (Stats,
1431         Make_Assignment_Statement (Loc,
1432           Name =>
1433             Make_Slice (Loc,
1434               Prefix          => New_Occurrence_Of (Res, Loc),
1435               Discrete_Range  =>
1436                 Make_Range (Loc,
1437                    Low_Bound  => Make_Integer_Literal (Loc, 1),
1438                    High_Bound => New_Occurrence_Of (Pos, Loc))),
1439
1440           Expression => New_Occurrence_Of (Prefix, Loc)));
1441
1442       Append_To (Stats,
1443          Make_Assignment_Statement (Loc,
1444             Name       => New_Occurrence_Of (Pos, Loc),
1445             Expression =>
1446               Make_Op_Add (Loc,
1447                 Left_Opnd  => New_Occurrence_Of (Pos, Loc),
1448                 Right_Opnd => Make_Integer_Literal (Loc, 1))));
1449    end Build_Task_Image_Prefix;
1450
1451    -----------------------------
1452    -- Build_Task_Record_Image --
1453    -----------------------------
1454
1455    function Build_Task_Record_Image
1456      (Loc    : Source_Ptr;
1457       Id_Ref : Node_Id;
1458       Dyn    : Boolean := False) return Node_Id
1459    is
1460       Len : Entity_Id;
1461       --  Total length of generated name
1462
1463       Pos : Entity_Id;
1464       --  Index into result
1465
1466       Res : Entity_Id;
1467       --  String to hold result
1468
1469       Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
1470       --  Name of enclosing variable, prefix of resulting name
1471
1472       Sum : Node_Id;
1473       --  Expression to compute total size of string
1474
1475       Sel : Entity_Id;
1476       --  Entity for selector name
1477
1478       Decls : constant List_Id := New_List;
1479       Stats : constant List_Id := New_List;
1480
1481    begin
1482       --  For a dynamic task, the name comes from the target variable. For a
1483       --  static one it is a formal of the enclosing init proc.
1484
1485       if Dyn then
1486          Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
1487          Append_To (Decls,
1488            Make_Object_Declaration (Loc,
1489              Defining_Identifier => Pref,
1490              Object_Definition => New_Occurrence_Of (Standard_String, Loc),
1491              Expression =>
1492                Make_String_Literal (Loc,
1493                  Strval => String_From_Name_Buffer)));
1494
1495       else
1496          Append_To (Decls,
1497            Make_Object_Renaming_Declaration (Loc,
1498              Defining_Identifier => Pref,
1499              Subtype_Mark        => New_Occurrence_Of (Standard_String, Loc),
1500              Name                => Make_Identifier (Loc, Name_uTask_Name)));
1501       end if;
1502
1503       Sel := Make_Temporary (Loc, 'S');
1504
1505       Get_Name_String (Chars (Selector_Name (Id_Ref)));
1506
1507       Append_To (Decls,
1508          Make_Object_Declaration (Loc,
1509            Defining_Identifier => Sel,
1510            Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
1511            Expression          =>
1512              Make_String_Literal (Loc,
1513                Strval => String_From_Name_Buffer)));
1514
1515       Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
1516
1517       Sum :=
1518         Make_Op_Add (Loc,
1519           Left_Opnd => Sum,
1520           Right_Opnd =>
1521            Make_Attribute_Reference (Loc,
1522              Attribute_Name => Name_Length,
1523              Prefix =>
1524                New_Occurrence_Of (Pref, Loc),
1525              Expressions => New_List (Make_Integer_Literal (Loc, 1))));
1526
1527       Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
1528
1529       Set_Character_Literal_Name (Char_Code (Character'Pos ('.')));
1530
1531       --  Res (Pos) := '.';
1532
1533       Append_To (Stats,
1534          Make_Assignment_Statement (Loc,
1535            Name => Make_Indexed_Component (Loc,
1536               Prefix => New_Occurrence_Of (Res, Loc),
1537               Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
1538            Expression =>
1539              Make_Character_Literal (Loc,
1540                Chars => Name_Find,
1541                Char_Literal_Value =>
1542                  UI_From_Int (Character'Pos ('.')))));
1543
1544       Append_To (Stats,
1545         Make_Assignment_Statement (Loc,
1546           Name => New_Occurrence_Of (Pos, Loc),
1547           Expression =>
1548             Make_Op_Add (Loc,
1549               Left_Opnd => New_Occurrence_Of (Pos, Loc),
1550               Right_Opnd => Make_Integer_Literal (Loc, 1))));
1551
1552       --  Res (Pos .. Len) := Selector;
1553
1554       Append_To (Stats,
1555         Make_Assignment_Statement (Loc,
1556           Name => Make_Slice (Loc,
1557              Prefix => New_Occurrence_Of (Res, Loc),
1558              Discrete_Range  =>
1559                Make_Range (Loc,
1560                  Low_Bound  => New_Occurrence_Of (Pos, Loc),
1561                  High_Bound => New_Occurrence_Of (Len, Loc))),
1562           Expression => New_Occurrence_Of (Sel, Loc)));
1563
1564       return Build_Task_Image_Function (Loc, Decls, Stats, Res);
1565    end Build_Task_Record_Image;
1566
1567    ----------------------------------
1568    -- Component_May_Be_Bit_Aligned --
1569    ----------------------------------
1570
1571    function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
1572       UT : Entity_Id;
1573
1574    begin
1575       --  If no component clause, then everything is fine, since the back end
1576       --  never bit-misaligns by default, even if there is a pragma Packed for
1577       --  the record.
1578
1579       if No (Comp) or else No (Component_Clause (Comp)) then
1580          return False;
1581       end if;
1582
1583       UT := Underlying_Type (Etype (Comp));
1584
1585       --  It is only array and record types that cause trouble
1586
1587       if not Is_Record_Type (UT) and then not Is_Array_Type (UT) then
1588          return False;
1589
1590       --  If we know that we have a small (64 bits or less) record or small
1591       --  bit-packed array, then everything is fine, since the back end can
1592       --  handle these cases correctly.
1593
1594       elsif Esize (Comp) <= 64
1595         and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT))
1596       then
1597          return False;
1598
1599       --  Otherwise if the component is not byte aligned, we know we have the
1600       --  nasty unaligned case.
1601
1602       elsif Normalized_First_Bit (Comp) /= Uint_0
1603         or else Esize (Comp) mod System_Storage_Unit /= Uint_0
1604       then
1605          return True;
1606
1607       --  If we are large and byte aligned, then OK at this level
1608
1609       else
1610          return False;
1611       end if;
1612    end Component_May_Be_Bit_Aligned;
1613
1614    -----------------------------------
1615    -- Corresponding_Runtime_Package --
1616    -----------------------------------
1617
1618    function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is
1619       Pkg_Id : RTU_Id := RTU_Null;
1620
1621    begin
1622       pragma Assert (Is_Concurrent_Type (Typ));
1623
1624       if Ekind (Typ) in Protected_Kind then
1625          if Has_Entries (Typ)
1626
1627             --  A protected type without entries that covers an interface and
1628             --  overrides the abstract routines with protected procedures is
1629             --  considered equivalent to a protected type with entries in the
1630             --  context of dispatching select statements. It is sufficient to
1631             --  check for the presence of an interface list in the declaration
1632             --  node to recognize this case.
1633
1634            or else Present (Interface_List (Parent (Typ)))
1635            or else
1636              (((Has_Attach_Handler (Typ) and then not Restricted_Profile)
1637                  or else Has_Interrupt_Handler (Typ))
1638                and then not Restriction_Active (No_Dynamic_Attachment))
1639          then
1640             if Abort_Allowed
1641               or else Restriction_Active (No_Entry_Queue) = False
1642               or else Number_Entries (Typ) > 1
1643               or else (Has_Attach_Handler (Typ)
1644                         and then not Restricted_Profile)
1645             then
1646                Pkg_Id := System_Tasking_Protected_Objects_Entries;
1647             else
1648                Pkg_Id := System_Tasking_Protected_Objects_Single_Entry;
1649             end if;
1650
1651          else
1652             Pkg_Id := System_Tasking_Protected_Objects;
1653          end if;
1654       end if;
1655
1656       return Pkg_Id;
1657    end Corresponding_Runtime_Package;
1658
1659    -------------------------------
1660    -- Convert_To_Actual_Subtype --
1661    -------------------------------
1662
1663    procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is
1664       Act_ST : Entity_Id;
1665
1666    begin
1667       Act_ST := Get_Actual_Subtype (Exp);
1668
1669       if Act_ST = Etype (Exp) then
1670          return;
1671       else
1672          Rewrite (Exp, Convert_To (Act_ST, Relocate_Node (Exp)));
1673          Analyze_And_Resolve (Exp, Act_ST);
1674       end if;
1675    end Convert_To_Actual_Subtype;
1676
1677    -----------------------------------
1678    -- Current_Sem_Unit_Declarations --
1679    -----------------------------------
1680
1681    function Current_Sem_Unit_Declarations return List_Id is
1682       U     : Node_Id := Unit (Cunit (Current_Sem_Unit));
1683       Decls : List_Id;
1684
1685    begin
1686       --  If the current unit is a package body, locate the visible
1687       --  declarations of the package spec.
1688
1689       if Nkind (U) = N_Package_Body then
1690          U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
1691       end if;
1692
1693       if Nkind (U) = N_Package_Declaration then
1694          U := Specification (U);
1695          Decls := Visible_Declarations (U);
1696
1697          if No (Decls) then
1698             Decls := New_List;
1699             Set_Visible_Declarations (U, Decls);
1700          end if;
1701
1702       else
1703          Decls := Declarations (U);
1704
1705          if No (Decls) then
1706             Decls := New_List;
1707             Set_Declarations (U, Decls);
1708          end if;
1709       end if;
1710
1711       return Decls;
1712    end Current_Sem_Unit_Declarations;
1713
1714    -----------------------
1715    -- Duplicate_Subexpr --
1716    -----------------------
1717
1718    function Duplicate_Subexpr
1719      (Exp      : Node_Id;
1720       Name_Req : Boolean := False) return Node_Id
1721    is
1722    begin
1723       Remove_Side_Effects (Exp, Name_Req);
1724       return New_Copy_Tree (Exp);
1725    end Duplicate_Subexpr;
1726
1727    ---------------------------------
1728    -- Duplicate_Subexpr_No_Checks --
1729    ---------------------------------
1730
1731    function Duplicate_Subexpr_No_Checks
1732      (Exp      : Node_Id;
1733       Name_Req : Boolean := False) return Node_Id
1734    is
1735       New_Exp : Node_Id;
1736    begin
1737       Remove_Side_Effects (Exp, Name_Req);
1738       New_Exp := New_Copy_Tree (Exp);
1739       Remove_Checks (New_Exp);
1740       return New_Exp;
1741    end Duplicate_Subexpr_No_Checks;
1742
1743    -----------------------------------
1744    -- Duplicate_Subexpr_Move_Checks --
1745    -----------------------------------
1746
1747    function Duplicate_Subexpr_Move_Checks
1748      (Exp      : Node_Id;
1749       Name_Req : Boolean := False) return Node_Id
1750    is
1751       New_Exp : Node_Id;
1752    begin
1753       Remove_Side_Effects (Exp, Name_Req);
1754       New_Exp := New_Copy_Tree (Exp);
1755       Remove_Checks (Exp);
1756       return New_Exp;
1757    end Duplicate_Subexpr_Move_Checks;
1758
1759    --------------------
1760    -- Ensure_Defined --
1761    --------------------
1762
1763    procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
1764       IR : Node_Id;
1765
1766    begin
1767       --  An itype reference must only be created if this is a local itype, so
1768       --  that gigi can elaborate it on the proper objstack.
1769
1770       if Is_Itype (Typ) and then Scope (Typ) = Current_Scope then
1771          IR := Make_Itype_Reference (Sloc (N));
1772          Set_Itype (IR, Typ);
1773          Insert_Action (N, IR);
1774       end if;
1775    end Ensure_Defined;
1776
1777    --------------------
1778    -- Entry_Names_OK --
1779    --------------------
1780
1781    function Entry_Names_OK return Boolean is
1782    begin
1783       return
1784         not Restricted_Profile
1785           and then not Global_Discard_Names
1786           and then not Restriction_Active (No_Implicit_Heap_Allocations)
1787           and then not Restriction_Active (No_Local_Allocators);
1788    end Entry_Names_OK;
1789
1790    -------------------
1791    -- Evaluate_Name --
1792    -------------------
1793
1794    procedure Evaluate_Name (Nam : Node_Id) is
1795       K : constant Node_Kind := Nkind (Nam);
1796
1797    begin
1798       --  For an explicit dereference, we simply force the evaluation of the
1799       --  name expression. The dereference provides a value that is the address
1800       --  for the renamed object, and it is precisely this value that we want
1801       --  to preserve.
1802
1803       if K = N_Explicit_Dereference then
1804          Force_Evaluation (Prefix (Nam));
1805
1806       --  For a selected component, we simply evaluate the prefix
1807
1808       elsif K = N_Selected_Component then
1809          Evaluate_Name (Prefix (Nam));
1810
1811       --  For an indexed component, or an attribute reference, we evaluate the
1812       --  prefix, which is itself a name, recursively, and then force the
1813       --  evaluation of all the subscripts (or attribute expressions).
1814
1815       elsif Nkind_In (K, N_Indexed_Component, N_Attribute_Reference) then
1816          Evaluate_Name (Prefix (Nam));
1817
1818          declare
1819             E : Node_Id;
1820
1821          begin
1822             E := First (Expressions (Nam));
1823             while Present (E) loop
1824                Force_Evaluation (E);
1825
1826                if Original_Node (E) /= E then
1827                   Set_Do_Range_Check (E, Do_Range_Check (Original_Node (E)));
1828                end if;
1829
1830                Next (E);
1831             end loop;
1832          end;
1833
1834       --  For a slice, we evaluate the prefix, as for the indexed component
1835       --  case and then, if there is a range present, either directly or as the
1836       --  constraint of a discrete subtype indication, we evaluate the two
1837       --  bounds of this range.
1838
1839       elsif K = N_Slice then
1840          Evaluate_Name (Prefix (Nam));
1841
1842          declare
1843             DR     : constant Node_Id := Discrete_Range (Nam);
1844             Constr : Node_Id;
1845             Rexpr  : Node_Id;
1846
1847          begin
1848             if Nkind (DR) = N_Range then
1849                Force_Evaluation (Low_Bound (DR));
1850                Force_Evaluation (High_Bound (DR));
1851
1852             elsif Nkind (DR) = N_Subtype_Indication then
1853                Constr := Constraint (DR);
1854
1855                if Nkind (Constr) = N_Range_Constraint then
1856                   Rexpr := Range_Expression (Constr);
1857
1858                   Force_Evaluation (Low_Bound (Rexpr));
1859                   Force_Evaluation (High_Bound (Rexpr));
1860                end if;
1861             end if;
1862          end;
1863
1864       --  For a type conversion, the expression of the conversion must be the
1865       --  name of an object, and we simply need to evaluate this name.
1866
1867       elsif K = N_Type_Conversion then
1868          Evaluate_Name (Expression (Nam));
1869
1870       --  For a function call, we evaluate the call
1871
1872       elsif K = N_Function_Call then
1873          Force_Evaluation (Nam);
1874
1875       --  The remaining cases are direct name, operator symbol and character
1876       --  literal. In all these cases, we do nothing, since we want to
1877       --  reevaluate each time the renamed object is used.
1878
1879       else
1880          return;
1881       end if;
1882    end Evaluate_Name;
1883
1884    ---------------------
1885    -- Evolve_And_Then --
1886    ---------------------
1887
1888    procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
1889    begin
1890       if No (Cond) then
1891          Cond := Cond1;
1892       else
1893          Cond :=
1894            Make_And_Then (Sloc (Cond1),
1895              Left_Opnd  => Cond,
1896              Right_Opnd => Cond1);
1897       end if;
1898    end Evolve_And_Then;
1899
1900    --------------------
1901    -- Evolve_Or_Else --
1902    --------------------
1903
1904    procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
1905    begin
1906       if No (Cond) then
1907          Cond := Cond1;
1908       else
1909          Cond :=
1910            Make_Or_Else (Sloc (Cond1),
1911              Left_Opnd  => Cond,
1912              Right_Opnd => Cond1);
1913       end if;
1914    end Evolve_Or_Else;
1915
1916    ------------------------------
1917    -- Expand_Subtype_From_Expr --
1918    ------------------------------
1919
1920    --  This function is applicable for both static and dynamic allocation of
1921    --  objects which are constrained by an initial expression. Basically it
1922    --  transforms an unconstrained subtype indication into a constrained one.
1923
1924    --  The expression may also be transformed in certain cases in order to
1925    --  avoid multiple evaluation. In the static allocation case, the general
1926    --  scheme is:
1927
1928    --     Val : T := Expr;
1929
1930    --        is transformed into
1931
1932    --     Val : Constrained_Subtype_of_T := Maybe_Modified_Expr;
1933    --
1934    --  Here are the main cases :
1935    --
1936    --  <if Expr is a Slice>
1937    --    Val : T ([Index_Subtype (Expr)]) := Expr;
1938    --
1939    --  <elsif Expr is a String Literal>
1940    --    Val : T (T'First .. T'First + Length (string literal) - 1) := Expr;
1941    --
1942    --  <elsif Expr is Constrained>
1943    --    subtype T is Type_Of_Expr
1944    --    Val : T := Expr;
1945    --
1946    --  <elsif Expr is an entity_name>
1947    --    Val : T (constraints taken from Expr) := Expr;
1948    --
1949    --  <else>
1950    --    type Axxx is access all T;
1951    --    Rval : Axxx := Expr'ref;
1952    --    Val  : T (constraints taken from Rval) := Rval.all;
1953
1954    --    ??? note: when the Expression is allocated in the secondary stack
1955    --              we could use it directly instead of copying it by declaring
1956    --              Val : T (...) renames Rval.all
1957
1958    procedure Expand_Subtype_From_Expr
1959      (N             : Node_Id;
1960       Unc_Type      : Entity_Id;
1961       Subtype_Indic : Node_Id;
1962       Exp           : Node_Id)
1963    is
1964       Loc     : constant Source_Ptr := Sloc (N);
1965       Exp_Typ : constant Entity_Id  := Etype (Exp);
1966       T       : Entity_Id;
1967
1968    begin
1969       --  In general we cannot build the subtype if expansion is disabled,
1970       --  because internal entities may not have been defined. However, to
1971       --  avoid some cascaded errors, we try to continue when the expression is
1972       --  an array (or string), because it is safe to compute the bounds. It is
1973       --  in fact required to do so even in a generic context, because there
1974       --  may be constants that depend on the bounds of a string literal, both
1975       --  standard string types and more generally arrays of characters.
1976
1977       if not Expander_Active
1978         and then (No (Etype (Exp)) or else not Is_String_Type (Etype (Exp)))
1979       then
1980          return;
1981       end if;
1982
1983       if Nkind (Exp) = N_Slice then
1984          declare
1985             Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
1986
1987          begin
1988             Rewrite (Subtype_Indic,
1989               Make_Subtype_Indication (Loc,
1990                 Subtype_Mark => New_Reference_To (Unc_Type, Loc),
1991                 Constraint =>
1992                   Make_Index_Or_Discriminant_Constraint (Loc,
1993                     Constraints => New_List
1994                       (New_Reference_To (Slice_Type, Loc)))));
1995
1996             --  This subtype indication may be used later for constraint checks
1997             --  we better make sure that if a variable was used as a bound of
1998             --  of the original slice, its value is frozen.
1999
2000             Force_Evaluation (Low_Bound (Scalar_Range (Slice_Type)));
2001             Force_Evaluation (High_Bound (Scalar_Range (Slice_Type)));
2002          end;
2003
2004       elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
2005          Rewrite (Subtype_Indic,
2006            Make_Subtype_Indication (Loc,
2007              Subtype_Mark => New_Reference_To (Unc_Type, Loc),
2008              Constraint =>
2009                Make_Index_Or_Discriminant_Constraint (Loc,
2010                  Constraints => New_List (
2011                    Make_Literal_Range (Loc,
2012                      Literal_Typ => Exp_Typ)))));
2013
2014       elsif Is_Constrained (Exp_Typ)
2015         and then not Is_Class_Wide_Type (Unc_Type)
2016       then
2017          if Is_Itype (Exp_Typ) then
2018
2019             --  Within an initialization procedure, a selected component
2020             --  denotes a component of the enclosing record, and it appears as
2021             --  an actual in a call to its own initialization procedure. If
2022             --  this component depends on the outer discriminant, we must
2023             --  generate the proper actual subtype for it.
2024
2025             if Nkind (Exp) = N_Selected_Component
2026               and then Within_Init_Proc
2027             then
2028                declare
2029                   Decl : constant Node_Id :=
2030                            Build_Actual_Subtype_Of_Component (Exp_Typ, Exp);
2031                begin
2032                   if Present (Decl) then
2033                      Insert_Action (N, Decl);
2034                      T := Defining_Identifier (Decl);
2035                   else
2036                      T := Exp_Typ;
2037                   end if;
2038                end;
2039
2040             --  No need to generate a new one (new what???)
2041
2042             else
2043                T := Exp_Typ;
2044             end if;
2045
2046          else
2047             T := Make_Temporary (Loc, 'T');
2048
2049             Insert_Action (N,
2050               Make_Subtype_Declaration (Loc,
2051                 Defining_Identifier => T,
2052                 Subtype_Indication  => New_Reference_To (Exp_Typ, Loc)));
2053
2054             --  This type is marked as an itype even though it has an explicit
2055             --  declaration since otherwise Is_Generic_Actual_Type can get
2056             --  set, resulting in the generation of spurious errors. (See
2057             --  sem_ch8.Analyze_Package_Renaming and sem_type.covers)
2058
2059             Set_Is_Itype (T);
2060             Set_Associated_Node_For_Itype (T, Exp);
2061          end if;
2062
2063          Rewrite (Subtype_Indic, New_Reference_To (T, Loc));
2064
2065       --  Nothing needs to be done for private types with unknown discriminants
2066       --  if the underlying type is not an unconstrained composite type or it
2067       --  is an unchecked union.
2068
2069       elsif Is_Private_Type (Unc_Type)
2070         and then Has_Unknown_Discriminants (Unc_Type)
2071         and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
2072                    or else Is_Constrained (Underlying_Type (Unc_Type))
2073                    or else Is_Unchecked_Union (Underlying_Type (Unc_Type)))
2074       then
2075          null;
2076
2077       --  Case of derived type with unknown discriminants where the parent type
2078       --  also has unknown discriminants.
2079
2080       elsif Is_Record_Type (Unc_Type)
2081         and then not Is_Class_Wide_Type (Unc_Type)
2082         and then Has_Unknown_Discriminants (Unc_Type)
2083         and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type))
2084       then
2085          --  Nothing to be done if no underlying record view available
2086
2087          if No (Underlying_Record_View (Unc_Type)) then
2088             null;
2089
2090          --  Otherwise use the Underlying_Record_View to create the proper
2091          --  constrained subtype for an object of a derived type with unknown
2092          --  discriminants.
2093
2094          else
2095             Remove_Side_Effects (Exp);
2096             Rewrite (Subtype_Indic,
2097               Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type)));
2098          end if;
2099
2100       --  Renamings of class-wide interface types require no equivalent
2101       --  constrained type declarations because we only need to reference
2102       --  the tag component associated with the interface. The same is
2103       --  presumably true for class-wide types in general, so this test
2104       --  is broadened to include all class-wide renamings, which also
2105       --  avoids cases of unbounded recursion in Remove_Side_Effects.
2106       --  (Is this really correct, or are there some cases of class-wide
2107       --  renamings that require action in this procedure???)
2108
2109       elsif Present (N)
2110         and then Nkind (N) = N_Object_Renaming_Declaration
2111         and then Is_Class_Wide_Type (Unc_Type)
2112       then
2113          null;
2114
2115       --  In Ada 95 nothing to be done if the type of the expression is limited
2116       --  because in this case the expression cannot be copied, and its use can
2117       --  only be by reference.
2118
2119       --  In Ada 2005 the context can be an object declaration whose expression
2120       --  is a function that returns in place. If the nominal subtype has
2121       --  unknown discriminants, the call still provides constraints on the
2122       --  object, and we have to create an actual subtype from it.
2123
2124       --  If the type is class-wide, the expression is dynamically tagged and
2125       --  we do not create an actual subtype either. Ditto for an interface.
2126       --  For now this applies only if the type is immutably limited, and the
2127       --  function being called is build-in-place. This will have to be revised
2128       --  when build-in-place functions are generalized to other types.
2129
2130       elsif Is_Immutably_Limited_Type (Exp_Typ)
2131         and then
2132          (Is_Class_Wide_Type (Exp_Typ)
2133            or else Is_Interface (Exp_Typ)
2134            or else not Has_Unknown_Discriminants (Exp_Typ)
2135            or else not Is_Composite_Type (Unc_Type))
2136       then
2137          null;
2138
2139       --  For limited objects initialized with build in place function calls,
2140       --  nothing to be done; otherwise we prematurely introduce an N_Reference
2141       --  node in the expression initializing the object, which breaks the
2142       --  circuitry that detects and adds the additional arguments to the
2143       --  called function.
2144
2145       elsif Is_Build_In_Place_Function_Call (Exp) then
2146          null;
2147
2148       else
2149          Remove_Side_Effects (Exp);
2150          Rewrite (Subtype_Indic,
2151            Make_Subtype_From_Expr (Exp, Unc_Type));
2152       end if;
2153    end Expand_Subtype_From_Expr;
2154
2155    ------------------------
2156    -- Find_Interface_ADT --
2157    ------------------------
2158
2159    function Find_Interface_ADT
2160      (T     : Entity_Id;
2161       Iface : Entity_Id) return Elmt_Id
2162    is
2163       ADT : Elmt_Id;
2164       Typ : Entity_Id := T;
2165
2166    begin
2167       pragma Assert (Is_Interface (Iface));
2168
2169       --  Handle private types
2170
2171       if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
2172          Typ := Full_View (Typ);
2173       end if;
2174
2175       --  Handle access types
2176
2177       if Is_Access_Type (Typ) then
2178          Typ := Designated_Type (Typ);
2179       end if;
2180
2181       --  Handle task and protected types implementing interfaces
2182
2183       if Is_Concurrent_Type (Typ) then
2184          Typ := Corresponding_Record_Type (Typ);
2185       end if;
2186
2187       pragma Assert
2188         (not Is_Class_Wide_Type (Typ)
2189           and then Ekind (Typ) /= E_Incomplete_Type);
2190
2191       if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
2192          return First_Elmt (Access_Disp_Table (Typ));
2193
2194       else
2195          ADT :=
2196            Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
2197          while Present (ADT)
2198            and then Present (Related_Type (Node (ADT)))
2199            and then Related_Type (Node (ADT)) /= Iface
2200            and then not Is_Ancestor (Iface, Related_Type (Node (ADT)),
2201                                      Use_Full_View => True)
2202          loop
2203             Next_Elmt (ADT);
2204          end loop;
2205
2206          pragma Assert (Present (Related_Type (Node (ADT))));
2207          return ADT;
2208       end if;
2209    end Find_Interface_ADT;
2210
2211    ------------------------
2212    -- Find_Interface_Tag --
2213    ------------------------
2214
2215    function Find_Interface_Tag
2216      (T     : Entity_Id;
2217       Iface : Entity_Id) return Entity_Id
2218    is
2219       AI_Tag : Entity_Id;
2220       Found  : Boolean   := False;
2221       Typ    : Entity_Id := T;
2222
2223       procedure Find_Tag (Typ : Entity_Id);
2224       --  Internal subprogram used to recursively climb to the ancestors
2225
2226       --------------
2227       -- Find_Tag --
2228       --------------
2229
2230       procedure Find_Tag (Typ : Entity_Id) is
2231          AI_Elmt : Elmt_Id;
2232          AI      : Node_Id;
2233
2234       begin
2235          --  This routine does not handle the case in which the interface is an
2236          --  ancestor of Typ. That case is handled by the enclosing subprogram.
2237
2238          pragma Assert (Typ /= Iface);
2239
2240          --  Climb to the root type handling private types
2241
2242          if Present (Full_View (Etype (Typ))) then
2243             if Full_View (Etype (Typ)) /= Typ then
2244                Find_Tag (Full_View (Etype (Typ)));
2245             end if;
2246
2247          elsif Etype (Typ) /= Typ then
2248             Find_Tag (Etype (Typ));
2249          end if;
2250
2251          --  Traverse the list of interfaces implemented by the type
2252
2253          if not Found
2254            and then Present (Interfaces (Typ))
2255            and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
2256          then
2257             --  Skip the tag associated with the primary table
2258
2259             pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
2260             AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
2261             pragma Assert (Present (AI_Tag));
2262
2263             AI_Elmt := First_Elmt (Interfaces (Typ));
2264             while Present (AI_Elmt) loop
2265                AI := Node (AI_Elmt);
2266
2267                if AI = Iface
2268                  or else Is_Ancestor (Iface, AI, Use_Full_View => True)
2269                then
2270                   Found := True;
2271                   return;
2272                end if;
2273
2274                AI_Tag := Next_Tag_Component (AI_Tag);
2275                Next_Elmt (AI_Elmt);
2276             end loop;
2277          end if;
2278       end Find_Tag;
2279
2280    --  Start of processing for Find_Interface_Tag
2281
2282    begin
2283       pragma Assert (Is_Interface (Iface));
2284
2285       --  Handle access types
2286
2287       if Is_Access_Type (Typ) then
2288          Typ := Designated_Type (Typ);
2289       end if;
2290
2291       --  Handle class-wide types
2292
2293       if Is_Class_Wide_Type (Typ) then
2294          Typ := Root_Type (Typ);
2295       end if;
2296
2297       --  Handle private types
2298
2299       if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
2300          Typ := Full_View (Typ);
2301       end if;
2302
2303       --  Handle entities from the limited view
2304
2305       if Ekind (Typ) = E_Incomplete_Type then
2306          pragma Assert (Present (Non_Limited_View (Typ)));
2307          Typ := Non_Limited_View (Typ);
2308       end if;
2309
2310       --  Handle task and protected types implementing interfaces
2311
2312       if Is_Concurrent_Type (Typ) then
2313          Typ := Corresponding_Record_Type (Typ);
2314       end if;
2315
2316       --  If the interface is an ancestor of the type, then it shared the
2317       --  primary dispatch table.
2318
2319       if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
2320          pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
2321          return First_Tag_Component (Typ);
2322
2323       --  Otherwise we need to search for its associated tag component
2324
2325       else
2326          Find_Tag (Typ);
2327          pragma Assert (Found);
2328          return AI_Tag;
2329       end if;
2330    end Find_Interface_Tag;
2331
2332    ------------------
2333    -- Find_Prim_Op --
2334    ------------------
2335
2336    function Find_Prim_Op (T : Entity_Id; Name : Name_Id) return Entity_Id is
2337       Prim : Elmt_Id;
2338       Typ  : Entity_Id := T;
2339       Op   : Entity_Id;
2340
2341    begin
2342       if Is_Class_Wide_Type (Typ) then
2343          Typ := Root_Type (Typ);
2344       end if;
2345
2346       Typ := Underlying_Type (Typ);
2347
2348       --  Loop through primitive operations
2349
2350       Prim := First_Elmt (Primitive_Operations (Typ));
2351       while Present (Prim) loop
2352          Op := Node (Prim);
2353
2354          --  We can retrieve primitive operations by name if it is an internal
2355          --  name. For equality we must check that both of its operands have
2356          --  the same type, to avoid confusion with user-defined equalities
2357          --  than may have a non-symmetric signature.
2358
2359          exit when Chars (Op) = Name
2360            and then
2361              (Name /= Name_Op_Eq
2362                or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op)));
2363
2364          Next_Elmt (Prim);
2365
2366          --  Raise Program_Error if no primitive found
2367
2368          if No (Prim) then
2369             raise Program_Error;
2370          end if;
2371       end loop;
2372
2373       return Node (Prim);
2374    end Find_Prim_Op;
2375
2376    ------------------
2377    -- Find_Prim_Op --
2378    ------------------
2379
2380    function Find_Prim_Op
2381      (T    : Entity_Id;
2382       Name : TSS_Name_Type) return Entity_Id
2383    is
2384       Inher_Op  : Entity_Id := Empty;
2385       Own_Op    : Entity_Id := Empty;
2386       Prim_Elmt : Elmt_Id;
2387       Prim_Id   : Entity_Id;
2388       Typ       : Entity_Id := T;
2389
2390    begin
2391       if Is_Class_Wide_Type (Typ) then
2392          Typ := Root_Type (Typ);
2393       end if;
2394
2395       Typ := Underlying_Type (Typ);
2396
2397       --  This search is based on the assertion that the dispatching version
2398       --  of the TSS routine always precedes the real primitive.
2399
2400       Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
2401       while Present (Prim_Elmt) loop
2402          Prim_Id := Node (Prim_Elmt);
2403
2404          if Is_TSS (Prim_Id, Name) then
2405             if Present (Alias (Prim_Id)) then
2406                Inher_Op := Prim_Id;
2407             else
2408                Own_Op := Prim_Id;
2409             end if;
2410          end if;
2411
2412          Next_Elmt (Prim_Elmt);
2413       end loop;
2414
2415       if Present (Own_Op) then
2416          return Own_Op;
2417       elsif Present (Inher_Op) then
2418          return Inher_Op;
2419       else
2420          raise Program_Error;
2421       end if;
2422    end Find_Prim_Op;
2423
2424    ----------------------------
2425    -- Find_Protection_Object --
2426    ----------------------------
2427
2428    function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
2429       S : Entity_Id;
2430
2431    begin
2432       S := Scop;
2433       while Present (S) loop
2434          if Ekind_In (S, E_Entry, E_Entry_Family, E_Function, E_Procedure)
2435            and then Present (Protection_Object (S))
2436          then
2437             return Protection_Object (S);
2438          end if;
2439
2440          S := Scope (S);
2441       end loop;
2442
2443       --  If we do not find a Protection object in the scope chain, then
2444       --  something has gone wrong, most likely the object was never created.
2445
2446       raise Program_Error;
2447    end Find_Protection_Object;
2448
2449    --------------------------
2450    -- Find_Protection_Type --
2451    --------------------------
2452
2453    function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is
2454       Comp : Entity_Id;
2455       Typ  : Entity_Id := Conc_Typ;
2456
2457    begin
2458       if Is_Concurrent_Type (Typ) then
2459          Typ := Corresponding_Record_Type (Typ);
2460       end if;
2461
2462       --  Since restriction violations are not considered serious errors, the
2463       --  expander remains active, but may leave the corresponding record type
2464       --  malformed. In such cases, component _object is not available so do
2465       --  not look for it.
2466
2467       if not Analyzed (Typ) then
2468          return Empty;
2469       end if;
2470
2471       Comp := First_Component (Typ);
2472       while Present (Comp) loop
2473          if Chars (Comp) = Name_uObject then
2474             return Base_Type (Etype (Comp));
2475          end if;
2476
2477          Next_Component (Comp);
2478       end loop;
2479
2480       --  The corresponding record of a protected type should always have an
2481       --  _object field.
2482
2483       raise Program_Error;
2484    end Find_Protection_Type;
2485
2486    ----------------------
2487    -- Force_Evaluation --
2488    ----------------------
2489
2490    procedure Force_Evaluation (Exp : Node_Id; Name_Req : Boolean := False) is
2491    begin
2492       Remove_Side_Effects (Exp, Name_Req, Variable_Ref => True);
2493    end Force_Evaluation;
2494
2495    ---------------------------------
2496    -- Fully_Qualified_Name_String --
2497    ---------------------------------
2498
2499    function Fully_Qualified_Name_String (E : Entity_Id) return String_Id is
2500       procedure Internal_Full_Qualified_Name (E : Entity_Id);
2501       --  Compute recursively the qualified name without NUL at the end, adding
2502       --  it to the currently started string being generated
2503
2504       ----------------------------------
2505       -- Internal_Full_Qualified_Name --
2506       ----------------------------------
2507
2508       procedure Internal_Full_Qualified_Name (E : Entity_Id) is
2509          Ent : Entity_Id;
2510
2511       begin
2512          --  Deal properly with child units
2513
2514          if Nkind (E) = N_Defining_Program_Unit_Name then
2515             Ent := Defining_Identifier (E);
2516          else
2517             Ent := E;
2518          end if;
2519
2520          --  Compute qualification recursively (only "Standard" has no scope)
2521
2522          if Present (Scope (Scope (Ent))) then
2523             Internal_Full_Qualified_Name (Scope (Ent));
2524             Store_String_Char (Get_Char_Code ('.'));
2525          end if;
2526
2527          --  Every entity should have a name except some expanded blocks
2528          --  don't bother about those.
2529
2530          if Chars (Ent) = No_Name then
2531             return;
2532          end if;
2533
2534          --  Generates the entity name in upper case
2535
2536          Get_Decoded_Name_String (Chars (Ent));
2537          Set_All_Upper_Case;
2538          Store_String_Chars (Name_Buffer (1 .. Name_Len));
2539          return;
2540       end Internal_Full_Qualified_Name;
2541
2542    --  Start of processing for Full_Qualified_Name
2543
2544    begin
2545       Start_String;
2546       Internal_Full_Qualified_Name (E);
2547       Store_String_Char (Get_Char_Code (ASCII.NUL));
2548       return End_String;
2549    end Fully_Qualified_Name_String;
2550
2551    ------------------------
2552    -- Generate_Poll_Call --
2553    ------------------------
2554
2555    procedure Generate_Poll_Call (N : Node_Id) is
2556    begin
2557       --  No poll call if polling not active
2558
2559       if not Polling_Required then
2560          return;
2561
2562       --  Otherwise generate require poll call
2563
2564       else
2565          Insert_Before_And_Analyze (N,
2566            Make_Procedure_Call_Statement (Sloc (N),
2567              Name => New_Occurrence_Of (RTE (RE_Poll), Sloc (N))));
2568       end if;
2569    end Generate_Poll_Call;
2570
2571    ---------------------------------
2572    -- Get_Current_Value_Condition --
2573    ---------------------------------
2574
2575    --  Note: the implementation of this procedure is very closely tied to the
2576    --  implementation of Set_Current_Value_Condition. In the Get procedure, we
2577    --  interpret Current_Value fields set by the Set procedure, so the two
2578    --  procedures need to be closely coordinated.
2579
2580    procedure Get_Current_Value_Condition
2581      (Var : Node_Id;
2582       Op  : out Node_Kind;
2583       Val : out Node_Id)
2584    is
2585       Loc : constant Source_Ptr := Sloc (Var);
2586       Ent : constant Entity_Id  := Entity (Var);
2587
2588       procedure Process_Current_Value_Condition
2589         (N : Node_Id;
2590          S : Boolean);
2591       --  N is an expression which holds either True (S = True) or False (S =
2592       --  False) in the condition. This procedure digs out the expression and
2593       --  if it refers to Ent, sets Op and Val appropriately.
2594
2595       -------------------------------------
2596       -- Process_Current_Value_Condition --
2597       -------------------------------------
2598
2599       procedure Process_Current_Value_Condition
2600         (N : Node_Id;
2601          S : Boolean)
2602       is
2603          Cond : Node_Id;
2604          Sens : Boolean;
2605
2606       begin
2607          Cond := N;
2608          Sens := S;
2609
2610          --  Deal with NOT operators, inverting sense
2611
2612          while Nkind (Cond) = N_Op_Not loop
2613             Cond := Right_Opnd (Cond);
2614             Sens := not Sens;
2615          end loop;
2616
2617          --  Deal with AND THEN and AND cases
2618
2619          if Nkind_In (Cond, N_And_Then, N_Op_And) then
2620
2621             --  Don't ever try to invert a condition that is of the form of an
2622             --  AND or AND THEN (since we are not doing sufficiently general
2623             --  processing to allow this).
2624
2625             if Sens = False then
2626                Op  := N_Empty;
2627                Val := Empty;
2628                return;
2629             end if;
2630
2631             --  Recursively process AND and AND THEN branches
2632
2633             Process_Current_Value_Condition (Left_Opnd (Cond), True);
2634
2635             if Op /= N_Empty then
2636                return;
2637             end if;
2638
2639             Process_Current_Value_Condition (Right_Opnd (Cond), True);
2640             return;
2641
2642          --  Case of relational operator
2643
2644          elsif Nkind (Cond) in N_Op_Compare then
2645             Op := Nkind (Cond);
2646
2647             --  Invert sense of test if inverted test
2648
2649             if Sens = False then
2650                case Op is
2651                   when N_Op_Eq => Op := N_Op_Ne;
2652                   when N_Op_Ne => Op := N_Op_Eq;
2653                   when N_Op_Lt => Op := N_Op_Ge;
2654                   when N_Op_Gt => Op := N_Op_Le;
2655                   when N_Op_Le => Op := N_Op_Gt;
2656                   when N_Op_Ge => Op := N_Op_Lt;
2657                   when others  => raise Program_Error;
2658                end case;
2659             end if;
2660
2661             --  Case of entity op value
2662
2663             if Is_Entity_Name (Left_Opnd (Cond))
2664               and then Ent = Entity (Left_Opnd (Cond))
2665               and then Compile_Time_Known_Value (Right_Opnd (Cond))
2666             then
2667                Val := Right_Opnd (Cond);
2668
2669             --  Case of value op entity
2670
2671             elsif Is_Entity_Name (Right_Opnd (Cond))
2672               and then Ent = Entity (Right_Opnd (Cond))
2673               and then Compile_Time_Known_Value (Left_Opnd (Cond))
2674             then
2675                Val := Left_Opnd (Cond);
2676
2677                --  We are effectively swapping operands
2678
2679                case Op is
2680                   when N_Op_Eq => null;
2681                   when N_Op_Ne => null;
2682                   when N_Op_Lt => Op := N_Op_Gt;
2683                   when N_Op_Gt => Op := N_Op_Lt;
2684                   when N_Op_Le => Op := N_Op_Ge;
2685                   when N_Op_Ge => Op := N_Op_Le;
2686                   when others  => raise Program_Error;
2687                end case;
2688
2689             else
2690                Op := N_Empty;
2691             end if;
2692
2693             return;
2694
2695             --  Case of Boolean variable reference, return as though the
2696             --  reference had said var = True.
2697
2698          else
2699             if Is_Entity_Name (Cond) and then Ent = Entity (Cond) then
2700                Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
2701
2702                if Sens = False then
2703                   Op := N_Op_Ne;
2704                else
2705                   Op := N_Op_Eq;
2706                end if;
2707             end if;
2708          end if;
2709       end Process_Current_Value_Condition;
2710
2711    --  Start of processing for Get_Current_Value_Condition
2712
2713    begin
2714       Op  := N_Empty;
2715       Val := Empty;
2716
2717       --  Immediate return, nothing doing, if this is not an object
2718
2719       if Ekind (Ent) not in Object_Kind then
2720          return;
2721       end if;
2722
2723       --  Otherwise examine current value
2724
2725       declare
2726          CV   : constant Node_Id := Current_Value (Ent);
2727          Sens : Boolean;
2728          Stm  : Node_Id;
2729
2730       begin
2731          --  If statement. Condition is known true in THEN section, known False
2732          --  in any ELSIF or ELSE part, and unknown outside the IF statement.
2733
2734          if Nkind (CV) = N_If_Statement then
2735
2736             --  Before start of IF statement
2737
2738             if Loc < Sloc (CV) then
2739                return;
2740
2741                --  After end of IF statement
2742
2743             elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
2744                return;
2745             end if;
2746
2747             --  At this stage we know that we are within the IF statement, but
2748             --  unfortunately, the tree does not record the SLOC of the ELSE so
2749             --  we cannot use a simple SLOC comparison to distinguish between
2750             --  the then/else statements, so we have to climb the tree.
2751
2752             declare
2753                N : Node_Id;
2754
2755             begin
2756                N := Parent (Var);
2757                while Parent (N) /= CV loop
2758                   N := Parent (N);
2759
2760                   --  If we fall off the top of the tree, then that's odd, but
2761                   --  perhaps it could occur in some error situation, and the
2762                   --  safest response is simply to assume that the outcome of
2763                   --  the condition is unknown. No point in bombing during an
2764                   --  attempt to optimize things.
2765
2766                   if No (N) then
2767                      return;
2768                   end if;
2769                end loop;
2770
2771                --  Now we have N pointing to a node whose parent is the IF
2772                --  statement in question, so now we can tell if we are within
2773                --  the THEN statements.
2774
2775                if Is_List_Member (N)
2776                  and then List_Containing (N) = Then_Statements (CV)
2777                then
2778                   Sens := True;
2779
2780                --  If the variable reference does not come from source, we
2781                --  cannot reliably tell whether it appears in the else part.
2782                --  In particular, if it appears in generated code for a node
2783                --  that requires finalization, it may be attached to a list
2784                --  that has not been yet inserted into the code. For now,
2785                --  treat it as unknown.
2786
2787                elsif not Comes_From_Source (N) then
2788                   return;
2789
2790                --  Otherwise we must be in ELSIF or ELSE part
2791
2792                else
2793                   Sens := False;
2794                end if;
2795             end;
2796
2797             --  ELSIF part. Condition is known true within the referenced
2798             --  ELSIF, known False in any subsequent ELSIF or ELSE part,
2799             --  and unknown before the ELSE part or after the IF statement.
2800
2801          elsif Nkind (CV) = N_Elsif_Part then
2802
2803             --  if the Elsif_Part had condition_actions, the elsif has been
2804             --  rewritten as a nested if, and the original elsif_part is
2805             --  detached from the tree, so there is no way to obtain useful
2806             --  information on the current value of the variable.
2807             --  Can this be improved ???
2808
2809             if No (Parent (CV)) then
2810                return;
2811             end if;
2812
2813             Stm := Parent (CV);
2814
2815             --  Before start of ELSIF part
2816
2817             if Loc < Sloc (CV) then
2818                return;
2819
2820                --  After end of IF statement
2821
2822             elsif Loc >= Sloc (Stm) +
2823               Text_Ptr (UI_To_Int (End_Span (Stm)))
2824             then
2825                return;
2826             end if;
2827
2828             --  Again we lack the SLOC of the ELSE, so we need to climb the
2829             --  tree to see if we are within the ELSIF part in question.
2830
2831             declare
2832                N : Node_Id;
2833
2834             begin
2835                N := Parent (Var);
2836                while Parent (N) /= Stm loop
2837                   N := Parent (N);
2838
2839                   --  If we fall off the top of the tree, then that's odd, but
2840                   --  perhaps it could occur in some error situation, and the
2841                   --  safest response is simply to assume that the outcome of
2842                   --  the condition is unknown. No point in bombing during an
2843                   --  attempt to optimize things.
2844
2845                   if No (N) then
2846                      return;
2847                   end if;
2848                end loop;
2849
2850                --  Now we have N pointing to a node whose parent is the IF
2851                --  statement in question, so see if is the ELSIF part we want.
2852                --  the THEN statements.
2853
2854                if N = CV then
2855                   Sens := True;
2856
2857                   --  Otherwise we must be in subsequent ELSIF or ELSE part
2858
2859                else
2860                   Sens := False;
2861                end if;
2862             end;
2863
2864          --  Iteration scheme of while loop. The condition is known to be
2865          --  true within the body of the loop.
2866
2867          elsif Nkind (CV) = N_Iteration_Scheme then
2868             declare
2869                Loop_Stmt : constant Node_Id := Parent (CV);
2870
2871             begin
2872                --  Before start of body of loop
2873
2874                if Loc < Sloc (Loop_Stmt) then
2875                   return;
2876
2877                --  After end of LOOP statement
2878
2879                elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
2880                   return;
2881
2882                --  We are within the body of the loop
2883
2884                else
2885                   Sens := True;
2886                end if;
2887             end;
2888
2889          --  All other cases of Current_Value settings
2890
2891          else
2892             return;
2893          end if;
2894
2895          --  If we fall through here, then we have a reportable condition, Sens
2896          --  is True if the condition is true and False if it needs inverting.
2897
2898          Process_Current_Value_Condition (Condition (CV), Sens);
2899       end;
2900    end Get_Current_Value_Condition;
2901
2902    ---------------------
2903    -- Get_Stream_Size --
2904    ---------------------
2905
2906    function Get_Stream_Size (E : Entity_Id) return Uint is
2907    begin
2908       --  If we have a Stream_Size clause for this type use it
2909
2910       if Has_Stream_Size_Clause (E) then
2911          return Static_Integer (Expression (Stream_Size_Clause (E)));
2912
2913       --  Otherwise the Stream_Size if the size of the type
2914
2915       else
2916          return Esize (E);
2917       end if;
2918    end Get_Stream_Size;
2919
2920    ---------------------------
2921    -- Has_Access_Constraint --
2922    ---------------------------
2923
2924    function Has_Access_Constraint (E : Entity_Id) return Boolean is
2925       Disc : Entity_Id;
2926       T    : constant Entity_Id := Etype (E);
2927
2928    begin
2929       if Has_Per_Object_Constraint (E) and then Has_Discriminants (T) then
2930          Disc := First_Discriminant (T);
2931          while Present (Disc) loop
2932             if Is_Access_Type (Etype (Disc)) then
2933                return True;
2934             end if;
2935
2936             Next_Discriminant (Disc);
2937          end loop;
2938
2939          return False;
2940       else
2941          return False;
2942       end if;
2943    end Has_Access_Constraint;
2944
2945    ----------------------------------
2946    -- Has_Following_Address_Clause --
2947    ----------------------------------
2948
2949    --  Should this function check the private part in a package ???
2950
2951    function Has_Following_Address_Clause (D : Node_Id) return Boolean is
2952       Id   : constant Entity_Id := Defining_Identifier (D);
2953       Decl : Node_Id;
2954
2955    begin
2956       Decl := Next (D);
2957       while Present (Decl) loop
2958          if Nkind (Decl) = N_At_Clause
2959            and then Chars (Identifier (Decl)) = Chars (Id)
2960          then
2961             return True;
2962
2963          elsif Nkind (Decl) = N_Attribute_Definition_Clause
2964            and then Chars (Decl) = Name_Address
2965            and then Chars (Name (Decl)) = Chars (Id)
2966          then
2967             return True;
2968          end if;
2969
2970          Next (Decl);
2971       end loop;
2972
2973       return False;
2974    end Has_Following_Address_Clause;
2975
2976    --------------------
2977    -- Homonym_Number --
2978    --------------------
2979
2980    function Homonym_Number (Subp : Entity_Id) return Nat is
2981       Count : Nat;
2982       Hom   : Entity_Id;
2983
2984    begin
2985       Count := 1;
2986       Hom := Homonym (Subp);
2987       while Present (Hom) loop
2988          if Scope (Hom) = Scope (Subp) then
2989             Count := Count + 1;
2990          end if;
2991
2992          Hom := Homonym (Hom);
2993       end loop;
2994
2995       return Count;
2996    end Homonym_Number;
2997
2998    -----------------------------------
2999    -- In_Library_Level_Package_Body --
3000    -----------------------------------
3001
3002    function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is
3003    begin
3004       --  First determine whether the entity appears at the library level, then
3005       --  look at the containing unit.
3006
3007       if Is_Library_Level_Entity (Id) then
3008          declare
3009             Container : constant Node_Id := Cunit (Get_Source_Unit (Id));
3010
3011          begin
3012             return Nkind (Unit (Container)) = N_Package_Body;
3013          end;
3014       end if;
3015
3016       return False;
3017    end In_Library_Level_Package_Body;
3018
3019    ------------------------------
3020    -- In_Unconditional_Context --
3021    ------------------------------
3022
3023    function In_Unconditional_Context (Node : Node_Id) return Boolean is
3024       P : Node_Id;
3025
3026    begin
3027       P := Node;
3028       while Present (P) loop
3029          case Nkind (P) is
3030             when N_Subprogram_Body =>
3031                return True;
3032
3033             when N_If_Statement =>
3034                return False;
3035
3036             when N_Loop_Statement =>
3037                return False;
3038
3039             when N_Case_Statement =>
3040                return False;
3041
3042             when others =>
3043                P := Parent (P);
3044          end case;
3045       end loop;
3046
3047       return False;
3048    end In_Unconditional_Context;
3049
3050    -------------------
3051    -- Insert_Action --
3052    -------------------
3053
3054    procedure Insert_Action (Assoc_Node : Node_Id; Ins_Action : Node_Id) is
3055    begin
3056       if Present (Ins_Action) then
3057          Insert_Actions (Assoc_Node, New_List (Ins_Action));
3058       end if;
3059    end Insert_Action;
3060
3061    --  Version with check(s) suppressed
3062
3063    procedure Insert_Action
3064      (Assoc_Node : Node_Id; Ins_Action : Node_Id; Suppress : Check_Id)
3065    is
3066    begin
3067       Insert_Actions (Assoc_Node, New_List (Ins_Action), Suppress);
3068    end Insert_Action;
3069
3070    -------------------------
3071    -- Insert_Action_After --
3072    -------------------------
3073
3074    procedure Insert_Action_After
3075      (Assoc_Node : Node_Id;
3076       Ins_Action : Node_Id)
3077    is
3078    begin
3079       Insert_Actions_After (Assoc_Node, New_List (Ins_Action));
3080    end Insert_Action_After;
3081
3082    --------------------
3083    -- Insert_Actions --
3084    --------------------
3085
3086    procedure Insert_Actions (Assoc_Node : Node_Id; Ins_Actions : List_Id) is
3087       N : Node_Id;
3088       P : Node_Id;
3089
3090       Wrapped_Node : Node_Id := Empty;
3091
3092    begin
3093       if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
3094          return;
3095       end if;
3096
3097       --  Ignore insert of actions from inside default expression (or other
3098       --  similar "spec expression") in the special spec-expression analyze
3099       --  mode. Any insertions at this point have no relevance, since we are
3100       --  only doing the analyze to freeze the types of any static expressions.
3101       --  See section "Handling of Default Expressions" in the spec of package
3102       --  Sem for further details.
3103
3104       if In_Spec_Expression then
3105          return;
3106       end if;
3107
3108       --  If the action derives from stuff inside a record, then the actions
3109       --  are attached to the current scope, to be inserted and analyzed on
3110       --  exit from the scope. The reason for this is that we may also be
3111       --  generating freeze actions at the same time, and they must eventually
3112       --  be elaborated in the correct order.
3113
3114       if Is_Record_Type (Current_Scope)
3115         and then not Is_Frozen (Current_Scope)
3116       then
3117          if No (Scope_Stack.Table
3118                   (Scope_Stack.Last).Pending_Freeze_Actions)
3119          then
3120             Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
3121               Ins_Actions;
3122          else
3123             Append_List
3124               (Ins_Actions,
3125                Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
3126          end if;
3127
3128          return;
3129       end if;
3130
3131       --  We now intend to climb up the tree to find the right point to
3132       --  insert the actions. We start at Assoc_Node, unless this node is a
3133       --  subexpression in which case we start with its parent. We do this for
3134       --  two reasons. First it speeds things up. Second, if Assoc_Node is
3135       --  itself one of the special nodes like N_And_Then, then we assume that
3136       --  an initial request to insert actions for such a node does not expect
3137       --  the actions to get deposited in the node for later handling when the
3138       --  node is expanded, since clearly the node is being dealt with by the
3139       --  caller. Note that in the subexpression case, N is always the child we
3140       --  came from.
3141
3142       --  N_Raise_xxx_Error is an annoying special case, it is a statement if
3143       --  it has type Standard_Void_Type, and a subexpression otherwise.
3144       --  otherwise. Procedure calls, and similarly procedure attribute
3145       --  references, are also statements.
3146
3147       if Nkind (Assoc_Node) in N_Subexpr
3148         and then (Nkind (Assoc_Node) not in N_Raise_xxx_Error
3149                    or else Etype (Assoc_Node) /= Standard_Void_Type)
3150         and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement
3151         and then (Nkind (Assoc_Node) /= N_Attribute_Reference
3152                    or else
3153                      not Is_Procedure_Attribute_Name
3154                            (Attribute_Name (Assoc_Node)))
3155       then
3156          N := Assoc_Node;
3157          P := Parent (Assoc_Node);
3158
3159       --  Non-subexpression case. Note that N is initially Empty in this case
3160       --  (N is only guaranteed Non-Empty in the subexpr case).
3161
3162       else
3163          N := Empty;
3164          P := Assoc_Node;
3165       end if;
3166
3167       --  Capture root of the transient scope
3168
3169       if Scope_Is_Transient then
3170          Wrapped_Node := Node_To_Be_Wrapped;
3171       end if;
3172
3173       loop
3174          pragma Assert (Present (P));
3175
3176          --  Make sure that inserted actions stay in the transient scope
3177
3178          if Present (Wrapped_Node) and then N = Wrapped_Node then
3179             Store_Before_Actions_In_Scope (Ins_Actions);
3180             return;
3181          end if;
3182
3183          case Nkind (P) is
3184
3185             --  Case of right operand of AND THEN or OR ELSE. Put the actions
3186             --  in the Actions field of the right operand. They will be moved
3187             --  out further when the AND THEN or OR ELSE operator is expanded.
3188             --  Nothing special needs to be done for the left operand since
3189             --  in that case the actions are executed unconditionally.
3190
3191             when N_Short_Circuit =>
3192                if N = Right_Opnd (P) then
3193
3194                   --  We are now going to either append the actions to the
3195                   --  actions field of the short-circuit operation. We will
3196                   --  also analyze the actions now.
3197
3198                   --  This analysis is really too early, the proper thing would
3199                   --  be to just park them there now, and only analyze them if
3200                   --  we find we really need them, and to it at the proper
3201                   --  final insertion point. However attempting to this proved
3202                   --  tricky, so for now we just kill current values before and
3203                   --  after the analyze call to make sure we avoid peculiar
3204                   --  optimizations from this out of order insertion.
3205
3206                   Kill_Current_Values;
3207
3208                   if Present (Actions (P)) then
3209                      Insert_List_After_And_Analyze
3210                        (Last (Actions (P)), Ins_Actions);
3211                   else
3212                      Set_Actions (P, Ins_Actions);
3213                      Analyze_List (Actions (P));
3214                   end if;
3215
3216                   Kill_Current_Values;
3217
3218                   return;
3219                end if;
3220
3221             --  Then or Else dependent expression of an if expression. Add
3222             --  actions to Then_Actions or Else_Actions field as appropriate.
3223             --  The actions will be moved further out when the if is expanded.
3224
3225             when N_If_Expression =>
3226                declare
3227                   ThenX : constant Node_Id := Next (First (Expressions (P)));
3228                   ElseX : constant Node_Id := Next (ThenX);
3229
3230                begin
3231                   --  If the enclosing expression is already analyzed, as
3232                   --  is the case for nested elaboration checks, insert the
3233                   --  conditional further out.
3234
3235                   if Analyzed (P) then
3236                      null;
3237
3238                   --  Actions belong to the then expression, temporarily place
3239                   --  them as Then_Actions of the if expression. They will be
3240                   --  moved to the proper place later when the if expression
3241                   --  is expanded.
3242
3243                   elsif N = ThenX then
3244                      if Present (Then_Actions (P)) then
3245                         Insert_List_After_And_Analyze
3246                           (Last (Then_Actions (P)), Ins_Actions);
3247                      else
3248                         Set_Then_Actions (P, Ins_Actions);
3249                         Analyze_List (Then_Actions (P));
3250                      end if;
3251
3252                      return;
3253
3254                   --  Actions belong to the else expression, temporarily place
3255                   --  them as Else_Actions of the if expression. They will be
3256                   --  moved to the proper place later when the if expression
3257                   --  is expanded.
3258
3259                   elsif N = ElseX then
3260                      if Present (Else_Actions (P)) then
3261                         Insert_List_After_And_Analyze
3262                           (Last (Else_Actions (P)), Ins_Actions);
3263                      else
3264                         Set_Else_Actions (P, Ins_Actions);
3265                         Analyze_List (Else_Actions (P));
3266                      end if;
3267
3268                      return;
3269
3270                   --  Actions belong to the condition. In this case they are
3271                   --  unconditionally executed, and so we can continue the
3272                   --  search for the proper insert point.
3273
3274                   else
3275                      null;
3276                   end if;
3277                end;
3278
3279             --  Alternative of case expression, we place the action in the
3280             --  Actions field of the case expression alternative, this will
3281             --  be handled when the case expression is expanded.
3282
3283             when N_Case_Expression_Alternative =>
3284                if Present (Actions (P)) then
3285                   Insert_List_After_And_Analyze
3286                     (Last (Actions (P)), Ins_Actions);
3287                else
3288                   Set_Actions (P, Ins_Actions);
3289                   Analyze_List (Actions (P));
3290                end if;
3291
3292                return;
3293
3294             --  Case of appearing within an Expressions_With_Actions node. When
3295             --  the new actions come from the expression of the expression with
3296             --  actions, they must be added to the existing actions. The other
3297             --  alternative is when the new actions are related to one of the
3298             --  existing actions of the expression with actions. In that case
3299             --  they must be inserted further up the tree.
3300
3301             when N_Expression_With_Actions =>
3302                if N = Expression (P) then
3303                   Insert_List_After_And_Analyze
3304                     (Last (Actions (P)), Ins_Actions);
3305                   return;
3306                end if;
3307
3308             --  Case of appearing in the condition of a while expression or
3309             --  elsif. We insert the actions into the Condition_Actions field.
3310             --  They will be moved further out when the while loop or elsif
3311             --  is analyzed.
3312
3313             when N_Iteration_Scheme |
3314                  N_Elsif_Part
3315             =>
3316                if N = Condition (P) then
3317                   if Present (Condition_Actions (P)) then
3318                      Insert_List_After_And_Analyze
3319                        (Last (Condition_Actions (P)), Ins_Actions);
3320                   else
3321                      Set_Condition_Actions (P, Ins_Actions);
3322
3323                      --  Set the parent of the insert actions explicitly. This
3324                      --  is not a syntactic field, but we need the parent field
3325                      --  set, in particular so that freeze can understand that
3326                      --  it is dealing with condition actions, and properly
3327                      --  insert the freezing actions.
3328
3329                      Set_Parent (Ins_Actions, P);
3330                      Analyze_List (Condition_Actions (P));
3331                   end if;
3332
3333                   return;
3334                end if;
3335
3336             --  Statements, declarations, pragmas, representation clauses
3337
3338             when
3339                --  Statements
3340
3341                N_Procedure_Call_Statement               |
3342                N_Statement_Other_Than_Procedure_Call    |
3343
3344                --  Pragmas
3345
3346                N_Pragma                                 |
3347
3348                --  Representation_Clause
3349
3350                N_At_Clause                              |
3351                N_Attribute_Definition_Clause            |
3352                N_Enumeration_Representation_Clause      |
3353                N_Record_Representation_Clause           |
3354
3355                --  Declarations
3356
3357                N_Abstract_Subprogram_Declaration        |
3358                N_Entry_Body                             |
3359                N_Exception_Declaration                  |
3360                N_Exception_Renaming_Declaration         |
3361                N_Expression_Function                    |
3362                N_Formal_Abstract_Subprogram_Declaration |
3363                N_Formal_Concrete_Subprogram_Declaration |
3364                N_Formal_Object_Declaration              |
3365                N_Formal_Type_Declaration                |
3366                N_Full_Type_Declaration                  |
3367                N_Function_Instantiation                 |
3368                N_Generic_Function_Renaming_Declaration  |
3369                N_Generic_Package_Declaration            |
3370                N_Generic_Package_Renaming_Declaration   |
3371                N_Generic_Procedure_Renaming_Declaration |
3372                N_Generic_Subprogram_Declaration         |
3373                N_Implicit_Label_Declaration             |
3374                N_Incomplete_Type_Declaration            |
3375                N_Number_Declaration                     |
3376                N_Object_Declaration                     |
3377                N_Object_Renaming_Declaration            |
3378                N_Package_Body                           |
3379                N_Package_Body_Stub                      |
3380                N_Package_Declaration                    |
3381                N_Package_Instantiation                  |
3382                N_Package_Renaming_Declaration           |
3383                N_Private_Extension_Declaration          |
3384                N_Private_Type_Declaration               |
3385                N_Procedure_Instantiation                |
3386                N_Protected_Body                         |
3387                N_Protected_Body_Stub                    |
3388                N_Protected_Type_Declaration             |
3389                N_Single_Task_Declaration                |
3390                N_Subprogram_Body                        |
3391                N_Subprogram_Body_Stub                   |
3392                N_Subprogram_Declaration                 |
3393                N_Subprogram_Renaming_Declaration        |
3394                N_Subtype_Declaration                    |
3395                N_Task_Body                              |
3396                N_Task_Body_Stub                         |
3397                N_Task_Type_Declaration                  |
3398
3399                --  Use clauses can appear in lists of declarations
3400
3401                N_Use_Package_Clause                     |
3402                N_Use_Type_Clause                        |
3403
3404                --  Freeze entity behaves like a declaration or statement
3405
3406                N_Freeze_Entity
3407             =>
3408                --  Do not insert here if the item is not a list member (this
3409                --  happens for example with a triggering statement, and the
3410                --  proper approach is to insert before the entire select).
3411
3412                if not Is_List_Member (P) then
3413                   null;
3414
3415                --  Do not insert if parent of P is an N_Component_Association
3416                --  node (i.e. we are in the context of an N_Aggregate or
3417                --  N_Extension_Aggregate node. In this case we want to insert
3418                --  before the entire aggregate.
3419
3420                elsif Nkind (Parent (P)) = N_Component_Association then
3421                   null;
3422
3423                --  Do not insert if the parent of P is either an N_Variant node
3424                --  or an N_Record_Definition node, meaning in either case that
3425                --  P is a member of a component list, and that therefore the
3426                --  actions should be inserted outside the complete record
3427                --  declaration.
3428
3429                elsif Nkind_In (Parent (P), N_Variant, N_Record_Definition) then
3430                   null;
3431
3432                --  Do not insert freeze nodes within the loop generated for
3433                --  an aggregate, because they may be elaborated too late for
3434                --  subsequent use in the back end: within a package spec the
3435                --  loop is part of the elaboration procedure and is only
3436                --  elaborated during the second pass.
3437
3438                --  If the loop comes from source, or the entity is local to the
3439                --  loop itself it must remain within.
3440
3441                elsif Nkind (Parent (P)) = N_Loop_Statement
3442                  and then not Comes_From_Source (Parent (P))
3443                  and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
3444                  and then
3445                    Scope (Entity (First (Ins_Actions))) /= Current_Scope
3446                then
3447                   null;
3448
3449                --  Otherwise we can go ahead and do the insertion
3450
3451                elsif P = Wrapped_Node then
3452                   Store_Before_Actions_In_Scope (Ins_Actions);
3453                   return;
3454
3455                else
3456                   Insert_List_Before_And_Analyze (P, Ins_Actions);
3457                   return;
3458                end if;
3459
3460             --  A special case, N_Raise_xxx_Error can act either as a statement
3461             --  or a subexpression. We tell the difference by looking at the
3462             --  Etype. It is set to Standard_Void_Type in the statement case.
3463
3464             when
3465                N_Raise_xxx_Error =>
3466                   if Etype (P) = Standard_Void_Type then
3467                      if  P = Wrapped_Node then
3468                         Store_Before_Actions_In_Scope (Ins_Actions);
3469                      else
3470                         Insert_List_Before_And_Analyze (P, Ins_Actions);
3471                      end if;
3472
3473                      return;
3474
3475                   --  In the subexpression case, keep climbing
3476
3477                   else
3478                      null;
3479                   end if;
3480
3481             --  If a component association appears within a loop created for
3482             --  an array aggregate, attach the actions to the association so
3483             --  they can be subsequently inserted within the loop. For other
3484             --  component associations insert outside of the aggregate. For
3485             --  an association that will generate a loop, its Loop_Actions
3486             --  attribute is already initialized (see exp_aggr.adb).
3487
3488             --  The list of loop_actions can in turn generate additional ones,
3489             --  that are inserted before the associated node. If the associated
3490             --  node is outside the aggregate, the new actions are collected
3491             --  at the end of the loop actions, to respect the order in which
3492             --  they are to be elaborated.
3493
3494             when
3495                N_Component_Association =>
3496                   if Nkind (Parent (P)) = N_Aggregate
3497                     and then Present (Loop_Actions (P))
3498                   then
3499                      if Is_Empty_List (Loop_Actions (P)) then
3500                         Set_Loop_Actions (P, Ins_Actions);
3501                         Analyze_List (Ins_Actions);
3502
3503                      else
3504                         declare
3505                            Decl : Node_Id;
3506
3507                         begin
3508                            --  Check whether these actions were generated by a
3509                            --  declaration that is part of the loop_ actions
3510                            --  for the component_association.
3511
3512                            Decl := Assoc_Node;
3513                            while Present (Decl) loop
3514                               exit when Parent (Decl) = P
3515                                 and then Is_List_Member (Decl)
3516                                 and then
3517                                   List_Containing (Decl) = Loop_Actions (P);
3518                               Decl := Parent (Decl);
3519                            end loop;
3520
3521                            if Present (Decl) then
3522                               Insert_List_Before_And_Analyze
3523                                 (Decl, Ins_Actions);
3524                            else
3525                               Insert_List_After_And_Analyze
3526                                 (Last (Loop_Actions (P)), Ins_Actions);
3527                            end if;
3528                         end;
3529                      end if;
3530
3531                      return;
3532
3533                   else
3534                      null;
3535                   end if;
3536
3537             --  Another special case, an attribute denoting a procedure call
3538
3539             when
3540                N_Attribute_Reference =>
3541                   if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
3542                      if P = Wrapped_Node then
3543                         Store_Before_Actions_In_Scope (Ins_Actions);
3544                      else
3545                         Insert_List_Before_And_Analyze (P, Ins_Actions);
3546                      end if;
3547
3548                      return;
3549
3550                   --  In the subexpression case, keep climbing
3551
3552                   else
3553                      null;
3554                   end if;
3555
3556             --  A contract node should not belong to the tree
3557
3558             when N_Contract =>
3559                raise Program_Error;
3560
3561             --  For all other node types, keep climbing tree
3562
3563             when
3564                N_Abortable_Part                         |
3565                N_Accept_Alternative                     |
3566                N_Access_Definition                      |
3567                N_Access_Function_Definition             |
3568                N_Access_Procedure_Definition            |
3569                N_Access_To_Object_Definition            |
3570                N_Aggregate                              |
3571                N_Allocator                              |
3572                N_Aspect_Specification                   |
3573                N_Case_Expression                        |
3574                N_Case_Statement_Alternative             |
3575                N_Character_Literal                      |
3576                N_Compilation_Unit                       |
3577                N_Compilation_Unit_Aux                   |
3578                N_Component_Clause                       |
3579                N_Component_Declaration                  |
3580                N_Component_Definition                   |
3581                N_Component_List                         |
3582                N_Constrained_Array_Definition           |
3583                N_Decimal_Fixed_Point_Definition         |
3584                N_Defining_Character_Literal             |
3585                N_Defining_Identifier                    |
3586                N_Defining_Operator_Symbol               |
3587                N_Defining_Program_Unit_Name             |
3588                N_Delay_Alternative                      |
3589                N_Delta_Constraint                       |
3590                N_Derived_Type_Definition                |
3591                N_Designator                             |
3592                N_Digits_Constraint                      |
3593                N_Discriminant_Association               |
3594                N_Discriminant_Specification             |
3595                N_Empty                                  |
3596                N_Entry_Body_Formal_Part                 |
3597                N_Entry_Call_Alternative                 |
3598                N_Entry_Declaration                      |
3599                N_Entry_Index_Specification              |
3600                N_Enumeration_Type_Definition            |
3601                N_Error                                  |
3602                N_Exception_Handler                      |
3603                N_Expanded_Name                          |
3604                N_Explicit_Dereference                   |
3605                N_Extension_Aggregate                    |
3606                N_Floating_Point_Definition              |
3607                N_Formal_Decimal_Fixed_Point_Definition  |
3608                N_Formal_Derived_Type_Definition         |
3609                N_Formal_Discrete_Type_Definition        |
3610                N_Formal_Floating_Point_Definition       |
3611                N_Formal_Modular_Type_Definition         |
3612                N_Formal_Ordinary_Fixed_Point_Definition |
3613                N_Formal_Package_Declaration             |
3614                N_Formal_Private_Type_Definition         |
3615                N_Formal_Incomplete_Type_Definition      |
3616                N_Formal_Signed_Integer_Type_Definition  |
3617                N_Function_Call                          |
3618                N_Function_Specification                 |
3619                N_Generic_Association                    |
3620                N_Handled_Sequence_Of_Statements         |
3621                N_Identifier                             |
3622                N_In                                     |
3623                N_Index_Or_Discriminant_Constraint       |
3624                N_Indexed_Component                      |
3625                N_Integer_Literal                        |
3626                N_Iterator_Specification                 |
3627                N_Itype_Reference                        |
3628                N_Label                                  |
3629                N_Loop_Parameter_Specification           |
3630                N_Mod_Clause                             |
3631                N_Modular_Type_Definition                |
3632                N_Not_In                                 |
3633                N_Null                                   |
3634                N_Op_Abs                                 |
3635                N_Op_Add                                 |
3636                N_Op_And                                 |
3637                N_Op_Concat                              |
3638                N_Op_Divide                              |
3639                N_Op_Eq                                  |
3640                N_Op_Expon                               |
3641                N_Op_Ge                                  |
3642                N_Op_Gt                                  |
3643                N_Op_Le                                  |
3644                N_Op_Lt                                  |
3645                N_Op_Minus                               |
3646                N_Op_Mod                                 |
3647                N_Op_Multiply                            |
3648                N_Op_Ne                                  |
3649                N_Op_Not                                 |
3650                N_Op_Or                                  |
3651                N_Op_Plus                                |
3652                N_Op_Rem                                 |
3653                N_Op_Rotate_Left                         |
3654                N_Op_Rotate_Right                        |
3655                N_Op_Shift_Left                          |
3656                N_Op_Shift_Right                         |
3657                N_Op_Shift_Right_Arithmetic              |
3658                N_Op_Subtract                            |
3659                N_Op_Xor                                 |
3660                N_Operator_Symbol                        |
3661                N_Ordinary_Fixed_Point_Definition        |
3662                N_Others_Choice                          |
3663                N_Package_Specification                  |
3664                N_Parameter_Association                  |
3665                N_Parameter_Specification                |
3666                N_Pop_Constraint_Error_Label             |
3667                N_Pop_Program_Error_Label                |
3668                N_Pop_Storage_Error_Label                |
3669                N_Pragma_Argument_Association            |
3670                N_Procedure_Specification                |
3671                N_Protected_Definition                   |
3672                N_Push_Constraint_Error_Label            |
3673                N_Push_Program_Error_Label               |
3674                N_Push_Storage_Error_Label               |
3675                N_Qualified_Expression                   |
3676                N_Quantified_Expression                  |
3677                N_Raise_Expression                       |
3678                N_Range                                  |
3679                N_Range_Constraint                       |
3680                N_Real_Literal                           |
3681                N_Real_Range_Specification               |
3682                N_Record_Definition                      |
3683                N_Reference                              |
3684                N_SCIL_Dispatch_Table_Tag_Init           |
3685                N_SCIL_Dispatching_Call                  |
3686                N_SCIL_Membership_Test                   |
3687                N_Selected_Component                     |
3688                N_Signed_Integer_Type_Definition         |
3689                N_Single_Protected_Declaration           |
3690                N_Slice                                  |
3691                N_String_Literal                         |
3692                N_Subprogram_Info                        |
3693                N_Subtype_Indication                     |
3694                N_Subunit                                |
3695                N_Task_Definition                        |
3696                N_Terminate_Alternative                  |
3697                N_Triggering_Alternative                 |
3698                N_Type_Conversion                        |
3699                N_Unchecked_Expression                   |
3700                N_Unchecked_Type_Conversion              |
3701                N_Unconstrained_Array_Definition         |
3702                N_Unused_At_End                          |
3703                N_Unused_At_Start                        |
3704                N_Variant                                |
3705                N_Variant_Part                           |
3706                N_Validate_Unchecked_Conversion          |
3707                N_With_Clause
3708             =>
3709                null;
3710
3711          end case;
3712
3713          --  If we fall through above tests, keep climbing tree
3714
3715          N := P;
3716
3717          if Nkind (Parent (N)) = N_Subunit then
3718
3719             --  This is the proper body corresponding to a stub. Insertion must
3720             --  be done at the point of the stub, which is in the declarative
3721             --  part of the parent unit.
3722
3723             P := Corresponding_Stub (Parent (N));
3724
3725          else
3726             P := Parent (N);
3727          end if;
3728       end loop;
3729    end Insert_Actions;
3730
3731    --  Version with check(s) suppressed
3732
3733    procedure Insert_Actions
3734      (Assoc_Node  : Node_Id;
3735       Ins_Actions : List_Id;
3736       Suppress    : Check_Id)
3737    is
3738    begin
3739       if Suppress = All_Checks then
3740          declare
3741             Sva : constant Suppress_Array := Scope_Suppress.Suppress;
3742          begin
3743             Scope_Suppress.Suppress := (others => True);
3744             Insert_Actions (Assoc_Node, Ins_Actions);
3745             Scope_Suppress.Suppress := Sva;
3746          end;
3747
3748       else
3749          declare
3750             Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
3751          begin
3752             Scope_Suppress.Suppress (Suppress) := True;
3753             Insert_Actions (Assoc_Node, Ins_Actions);
3754             Scope_Suppress.Suppress (Suppress) := Svg;
3755          end;
3756       end if;
3757    end Insert_Actions;
3758
3759    --------------------------
3760    -- Insert_Actions_After --
3761    --------------------------
3762
3763    procedure Insert_Actions_After
3764      (Assoc_Node  : Node_Id;
3765       Ins_Actions : List_Id)
3766    is
3767    begin
3768       if Scope_Is_Transient and then Assoc_Node = Node_To_Be_Wrapped then
3769          Store_After_Actions_In_Scope (Ins_Actions);
3770       else
3771          Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
3772       end if;
3773    end Insert_Actions_After;
3774
3775    ---------------------------------
3776    -- Insert_Library_Level_Action --
3777    ---------------------------------
3778
3779    procedure Insert_Library_Level_Action (N : Node_Id) is
3780       Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
3781
3782    begin
3783       Push_Scope (Cunit_Entity (Main_Unit));
3784       --  ??? should this be Current_Sem_Unit instead of Main_Unit?
3785
3786       if No (Actions (Aux)) then
3787          Set_Actions (Aux, New_List (N));
3788       else
3789          Append (N, Actions (Aux));
3790       end if;
3791
3792       Analyze (N);
3793       Pop_Scope;
3794    end Insert_Library_Level_Action;
3795
3796    ----------------------------------
3797    -- Insert_Library_Level_Actions --
3798    ----------------------------------
3799
3800    procedure Insert_Library_Level_Actions (L : List_Id) is
3801       Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
3802
3803    begin
3804       if Is_Non_Empty_List (L) then
3805          Push_Scope (Cunit_Entity (Main_Unit));
3806          --  ??? should this be Current_Sem_Unit instead of Main_Unit?
3807
3808          if No (Actions (Aux)) then
3809             Set_Actions (Aux, L);
3810             Analyze_List (L);
3811          else
3812             Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
3813          end if;
3814
3815          Pop_Scope;
3816       end if;
3817    end Insert_Library_Level_Actions;
3818
3819    ----------------------
3820    -- Inside_Init_Proc --
3821    ----------------------
3822
3823    function Inside_Init_Proc return Boolean is
3824       S : Entity_Id;
3825
3826    begin
3827       S := Current_Scope;
3828       while Present (S) and then S /= Standard_Standard loop
3829          if Is_Init_Proc (S) then
3830             return True;
3831          else
3832             S := Scope (S);
3833          end if;
3834       end loop;
3835
3836       return False;
3837    end Inside_Init_Proc;
3838
3839    ----------------------------
3840    -- Is_All_Null_Statements --
3841    ----------------------------
3842
3843    function Is_All_Null_Statements (L : List_Id) return Boolean is
3844       Stm : Node_Id;
3845
3846    begin
3847       Stm := First (L);
3848       while Present (Stm) loop
3849          if Nkind (Stm) /= N_Null_Statement then
3850             return False;
3851          end if;
3852
3853          Next (Stm);
3854       end loop;
3855
3856       return True;
3857    end Is_All_Null_Statements;
3858
3859    --------------------------------------------------
3860    -- Is_Displacement_Of_Object_Or_Function_Result --
3861    --------------------------------------------------
3862
3863    function Is_Displacement_Of_Object_Or_Function_Result
3864      (Obj_Id : Entity_Id) return Boolean
3865    is
3866       function Is_Controlled_Function_Call (N : Node_Id) return Boolean;
3867       --  Determine if particular node denotes a controlled function call
3868
3869       function Is_Displace_Call (N : Node_Id) return Boolean;
3870       --  Determine whether a particular node is a call to Ada.Tags.Displace.
3871       --  The call might be nested within other actions such as conversions.
3872
3873       function Is_Source_Object (N : Node_Id) return Boolean;
3874       --  Determine whether a particular node denotes a source object
3875
3876       ---------------------------------
3877       -- Is_Controlled_Function_Call --
3878       ---------------------------------
3879
3880       function Is_Controlled_Function_Call (N : Node_Id) return Boolean is
3881          Expr : Node_Id := Original_Node (N);
3882
3883       begin
3884          if Nkind (Expr) = N_Function_Call then
3885             Expr := Name (Expr);
3886          end if;
3887
3888          --  The function call may appear in object.operation format
3889
3890          if Nkind (Expr) = N_Selected_Component then
3891             Expr := Selector_Name (Expr);
3892          end if;
3893
3894          return
3895            Nkind_In (Expr, N_Expanded_Name, N_Identifier)
3896              and then Ekind (Entity (Expr)) = E_Function
3897              and then Needs_Finalization (Etype (Entity (Expr)));
3898       end Is_Controlled_Function_Call;
3899
3900       ----------------------
3901       -- Is_Displace_Call --
3902       ----------------------
3903
3904       function Is_Displace_Call (N : Node_Id) return Boolean is
3905          Call : Node_Id := N;
3906
3907       begin
3908          --  Strip various actions which may precede a call to Displace
3909
3910          loop
3911             if Nkind (Call) = N_Explicit_Dereference then
3912                Call := Prefix (Call);
3913
3914             elsif Nkind_In (Call, N_Type_Conversion,
3915                                   N_Unchecked_Type_Conversion)
3916             then
3917                Call := Expression (Call);
3918
3919             else
3920                exit;
3921             end if;
3922          end loop;
3923
3924          return
3925            Present (Call)
3926              and then Nkind (Call) = N_Function_Call
3927              and then Is_RTE (Entity (Name (Call)), RE_Displace);
3928       end Is_Displace_Call;
3929
3930       ----------------------
3931       -- Is_Source_Object --
3932       ----------------------
3933
3934       function Is_Source_Object (N : Node_Id) return Boolean is
3935       begin
3936          return
3937            Present (N)
3938              and then Nkind (N) in N_Has_Entity
3939              and then Is_Object (Entity (N))
3940              and then Comes_From_Source (N);
3941       end Is_Source_Object;
3942
3943       --  Local variables
3944
3945       Decl      : constant Node_Id   := Parent (Obj_Id);
3946       Obj_Typ   : constant Entity_Id := Base_Type (Etype (Obj_Id));
3947       Orig_Decl : constant Node_Id   := Original_Node (Decl);
3948
3949    --  Start of processing for Is_Displacement_Of_Object_Or_Function_Result
3950
3951    begin
3952       --  Case 1:
3953
3954       --     Obj : CW_Type := Function_Call (...);
3955
3956       --  rewritten into:
3957
3958       --     Tmp : ... := Function_Call (...)'reference;
3959       --     Obj : CW_Type renames (... Ada.Tags.Displace (Tmp));
3960
3961       --  where the return type of the function and the class-wide type require
3962       --  dispatch table pointer displacement.
3963
3964       --  Case 2:
3965
3966       --     Obj : CW_Type := Src_Obj;
3967
3968       --  rewritten into:
3969
3970       --     Obj : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
3971
3972       --  where the type of the source object and the class-wide type require
3973       --  dispatch table pointer displacement.
3974
3975       return
3976         Nkind (Decl) = N_Object_Renaming_Declaration
3977           and then Nkind (Orig_Decl) = N_Object_Declaration
3978           and then Comes_From_Source (Orig_Decl)
3979           and then Is_Class_Wide_Type (Obj_Typ)
3980           and then Is_Displace_Call (Renamed_Object (Obj_Id))
3981           and then
3982             (Is_Controlled_Function_Call (Expression (Orig_Decl))
3983               or else Is_Source_Object (Expression (Orig_Decl)));
3984    end Is_Displacement_Of_Object_Or_Function_Result;
3985
3986    ------------------------------
3987    -- Is_Finalizable_Transient --
3988    ------------------------------
3989
3990    function Is_Finalizable_Transient
3991      (Decl     : Node_Id;
3992       Rel_Node : Node_Id) return Boolean
3993    is
3994       Obj_Id  : constant Entity_Id := Defining_Identifier (Decl);
3995       Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
3996       Desig   : Entity_Id := Obj_Typ;
3997
3998       function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean;
3999       --  Determine whether transient object Trans_Id is initialized either
4000       --  by a function call which returns an access type or simply renames
4001       --  another pointer.
4002
4003       function Initialized_By_Aliased_BIP_Func_Call
4004         (Trans_Id : Entity_Id) return Boolean;
4005       --  Determine whether transient object Trans_Id is initialized by a
4006       --  build-in-place function call where the BIPalloc parameter is of
4007       --  value 1 and BIPaccess is not null. This case creates an aliasing
4008       --  between the returned value and the value denoted by BIPaccess.
4009
4010       function Is_Aliased
4011         (Trans_Id   : Entity_Id;
4012          First_Stmt : Node_Id) return Boolean;
4013       --  Determine whether transient object Trans_Id has been renamed or
4014       --  aliased through 'reference in the statement list starting from
4015       --  First_Stmt.
4016
4017       function Is_Allocated (Trans_Id : Entity_Id) return Boolean;
4018       --  Determine whether transient object Trans_Id is allocated on the heap
4019
4020       function Is_Iterated_Container
4021         (Trans_Id   : Entity_Id;
4022          First_Stmt : Node_Id) return Boolean;
4023       --  Determine whether transient object Trans_Id denotes a container which
4024       --  is in the process of being iterated in the statement list starting
4025       --  from First_Stmt.
4026
4027       ---------------------------
4028       -- Initialized_By_Access --
4029       ---------------------------
4030
4031       function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is
4032          Expr : constant Node_Id := Expression (Parent (Trans_Id));
4033
4034       begin
4035          return
4036            Present (Expr)
4037              and then Nkind (Expr) /= N_Reference
4038              and then Is_Access_Type (Etype (Expr));
4039       end Initialized_By_Access;
4040
4041       ------------------------------------------
4042       -- Initialized_By_Aliased_BIP_Func_Call --
4043       ------------------------------------------
4044
4045       function Initialized_By_Aliased_BIP_Func_Call
4046         (Trans_Id : Entity_Id) return Boolean
4047       is
4048          Call : Node_Id := Expression (Parent (Trans_Id));
4049
4050       begin
4051          --  Build-in-place calls usually appear in 'reference format
4052
4053          if Nkind (Call) = N_Reference then
4054             Call := Prefix (Call);
4055          end if;
4056
4057          if Is_Build_In_Place_Function_Call (Call) then
4058             declare
4059                Access_Nam : Name_Id := No_Name;
4060                Access_OK  : Boolean := False;
4061                Actual     : Node_Id;
4062                Alloc_Nam  : Name_Id := No_Name;
4063                Alloc_OK   : Boolean := False;
4064                Formal     : Node_Id;
4065                Func_Id    : Entity_Id;
4066                Param      : Node_Id;
4067
4068             begin
4069                --  Examine all parameter associations of the function call
4070
4071                Param := First (Parameter_Associations (Call));
4072                while Present (Param) loop
4073                   if Nkind (Param) = N_Parameter_Association
4074                     and then Nkind (Selector_Name (Param)) = N_Identifier
4075                   then
4076                      Actual := Explicit_Actual_Parameter (Param);
4077                      Formal := Selector_Name (Param);
4078
4079                      --  Construct the names of formals BIPaccess and BIPalloc
4080                      --  using the function name retrieved from an arbitrary
4081                      --  formal.
4082
4083                      if Access_Nam = No_Name
4084                        and then Alloc_Nam = No_Name
4085                        and then Present (Entity (Formal))
4086                      then
4087                         Func_Id := Scope (Entity (Formal));
4088
4089                         Access_Nam :=
4090                           New_External_Name (Chars (Func_Id),
4091                             BIP_Formal_Suffix (BIP_Object_Access));
4092
4093                         Alloc_Nam :=
4094                           New_External_Name (Chars (Func_Id),
4095                             BIP_Formal_Suffix (BIP_Alloc_Form));
4096                      end if;
4097
4098                      --  A match for BIPaccess => Temp has been found
4099
4100                      if Chars (Formal) = Access_Nam
4101                        and then Nkind (Actual) /= N_Null
4102                      then
4103                         Access_OK := True;
4104                      end if;
4105
4106                      --  A match for BIPalloc => 1 has been found
4107
4108                      if Chars (Formal) = Alloc_Nam
4109                        and then Nkind (Actual) = N_Integer_Literal
4110                        and then Intval (Actual) = Uint_1
4111                      then
4112                         Alloc_OK := True;
4113                      end if;
4114                   end if;
4115
4116                   Next (Param);
4117                end loop;
4118
4119                return Access_OK and Alloc_OK;
4120             end;
4121          end if;
4122
4123          return False;
4124       end Initialized_By_Aliased_BIP_Func_Call;
4125
4126       ----------------
4127       -- Is_Aliased --
4128       ----------------
4129
4130       function Is_Aliased
4131         (Trans_Id   : Entity_Id;
4132          First_Stmt : Node_Id) return Boolean
4133       is
4134          function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id;
4135          --  Given an object renaming declaration, retrieve the entity of the
4136          --  renamed name. Return Empty if the renamed name is anything other
4137          --  than a variable or a constant.
4138
4139          -------------------------
4140          -- Find_Renamed_Object --
4141          -------------------------
4142
4143          function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id is
4144             Ren_Obj : Node_Id := Empty;
4145
4146             function Find_Object (N : Node_Id) return Traverse_Result;
4147             --  Try to detect an object which is either a constant or a
4148             --  variable.
4149
4150             -----------------
4151             -- Find_Object --
4152             -----------------
4153
4154             function Find_Object (N : Node_Id) return Traverse_Result is
4155             begin
4156                --  Stop the search once a constant or a variable has been
4157                --  detected.
4158
4159                if Nkind (N) = N_Identifier
4160                  and then Present (Entity (N))
4161                  and then Ekind_In (Entity (N), E_Constant, E_Variable)
4162                then
4163                   Ren_Obj := Entity (N);
4164                   return Abandon;
4165                end if;
4166
4167                return OK;
4168             end Find_Object;
4169
4170             procedure Search is new Traverse_Proc (Find_Object);
4171
4172             --  Local variables
4173
4174             Typ : constant Entity_Id := Etype (Defining_Identifier (Ren_Decl));
4175
4176          --  Start of processing for Find_Renamed_Object
4177
4178          begin
4179             --  Actions related to dispatching calls may appear as renamings of
4180             --  tags. Do not process this type of renaming because it does not
4181             --  use the actual value of the object.
4182
4183             if not Is_RTE (Typ, RE_Tag_Ptr) then
4184                Search (Name (Ren_Decl));
4185             end if;
4186
4187             return Ren_Obj;
4188          end Find_Renamed_Object;
4189
4190          --  Local variables
4191
4192          Expr    : Node_Id;
4193          Ren_Obj : Entity_Id;
4194          Stmt    : Node_Id;
4195
4196       --  Start of processing for Is_Aliased
4197
4198       begin
4199          Stmt := First_Stmt;
4200          while Present (Stmt) loop
4201             if Nkind (Stmt) = N_Object_Declaration then
4202                Expr := Expression (Stmt);
4203
4204                if Present (Expr)
4205                  and then Nkind (Expr) = N_Reference
4206                  and then Nkind (Prefix (Expr)) = N_Identifier
4207                  and then Entity (Prefix (Expr)) = Trans_Id
4208                then
4209                   return True;
4210                end if;
4211
4212             elsif Nkind (Stmt) = N_Object_Renaming_Declaration then
4213                Ren_Obj := Find_Renamed_Object (Stmt);
4214
4215                if Present (Ren_Obj) and then Ren_Obj = Trans_Id then
4216                   return True;
4217                end if;
4218             end if;
4219
4220             Next (Stmt);
4221          end loop;
4222
4223          return False;
4224       end Is_Aliased;
4225
4226       ------------------
4227       -- Is_Allocated --
4228       ------------------
4229
4230       function Is_Allocated (Trans_Id : Entity_Id) return Boolean is
4231          Expr : constant Node_Id := Expression (Parent (Trans_Id));
4232       begin
4233          return
4234            Is_Access_Type (Etype (Trans_Id))
4235              and then Present (Expr)
4236              and then Nkind (Expr) = N_Allocator;
4237       end Is_Allocated;
4238
4239       ---------------------------
4240       -- Is_Iterated_Container --
4241       ---------------------------
4242
4243       function Is_Iterated_Container
4244         (Trans_Id   : Entity_Id;
4245          First_Stmt : Node_Id) return Boolean
4246       is
4247          Aspect : Node_Id;
4248          Call   : Node_Id;
4249          Iter   : Entity_Id;
4250          Param  : Node_Id;
4251          Stmt   : Node_Id;
4252          Typ    : Entity_Id;
4253
4254       begin
4255          --  It is not possible to iterate over containers in non-Ada 2012 code
4256
4257          if Ada_Version < Ada_2012 then
4258             return False;
4259          end if;
4260
4261          Typ := Etype (Trans_Id);
4262
4263          --  Handle access type created for secondary stack use
4264
4265          if Is_Access_Type (Typ) then
4266             Typ := Designated_Type (Typ);
4267          end if;
4268
4269          --  Look for aspect Default_Iterator
4270
4271          if Has_Aspects (Parent (Typ)) then
4272             Aspect := Find_Aspect (Typ, Aspect_Default_Iterator);
4273
4274             if Present (Aspect) then
4275                Iter := Entity (Aspect);
4276
4277                --  Examine the statements following the container object and
4278                --  look for a call to the default iterate routine where the
4279                --  first parameter is the transient. Such a call appears as:
4280
4281                --     It : Access_To_CW_Iterator :=
4282                --            Iterate (Tran_Id.all, ...)'reference;
4283
4284                Stmt := First_Stmt;
4285                while Present (Stmt) loop
4286
4287                   --  Detect an object declaration which is initialized by a
4288                   --  secondary stack function call.
4289
4290                   if Nkind (Stmt) = N_Object_Declaration
4291                     and then Present (Expression (Stmt))
4292                     and then Nkind (Expression (Stmt)) = N_Reference
4293                     and then Nkind (Prefix (Expression (Stmt))) =
4294                                N_Function_Call
4295                   then
4296                      Call := Prefix (Expression (Stmt));
4297
4298                      --  The call must invoke the default iterate routine of
4299                      --  the container and the transient object must appear as
4300                      --  the first actual parameter. Skip any calls whose names
4301                      --  are not entities.
4302
4303                      if Is_Entity_Name (Name (Call))
4304                        and then Entity (Name (Call)) = Iter
4305                        and then Present (Parameter_Associations (Call))
4306                      then
4307                         Param := First (Parameter_Associations (Call));
4308
4309                         if Nkind (Param) = N_Explicit_Dereference
4310                           and then Entity (Prefix (Param)) = Trans_Id
4311                         then
4312                            return True;
4313                         end if;
4314                      end if;
4315                   end if;
4316
4317                   Next (Stmt);
4318                end loop;
4319             end if;
4320          end if;
4321
4322          return False;
4323       end Is_Iterated_Container;
4324
4325    --  Start of processing for Is_Finalizable_Transient
4326
4327    begin
4328       --  Handle access types
4329
4330       if Is_Access_Type (Desig) then
4331          Desig := Available_View (Designated_Type (Desig));
4332       end if;
4333
4334       return
4335         Ekind_In (Obj_Id, E_Constant, E_Variable)
4336           and then Needs_Finalization (Desig)
4337           and then Requires_Transient_Scope (Desig)
4338           and then Nkind (Rel_Node) /= N_Simple_Return_Statement
4339
4340           --  Do not consider renamed or 'reference-d transient objects because
4341           --  the act of renaming extends the object's lifetime.
4342
4343           and then not Is_Aliased (Obj_Id, Decl)
4344
4345           --  Do not consider transient objects allocated on the heap since
4346           --  they are attached to a finalization master.
4347
4348           and then not Is_Allocated (Obj_Id)
4349
4350           --  If the transient object is a pointer, check that it is not
4351           --  initialized by a function which returns a pointer or acts as a
4352           --  renaming of another pointer.
4353
4354           and then
4355             (not Is_Access_Type (Obj_Typ)
4356                or else not Initialized_By_Access (Obj_Id))
4357
4358           --  Do not consider transient objects which act as indirect aliases
4359           --  of build-in-place function results.
4360
4361           and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id)
4362
4363           --  Do not consider conversions of tags to class-wide types
4364
4365           and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
4366
4367           --  Do not consider containers in the context of iterator loops. Such
4368           --  transient objects must exist for as long as the loop is around,
4369           --  otherwise any operation carried out by the iterator will fail.
4370
4371           and then not Is_Iterated_Container (Obj_Id, Decl);
4372    end Is_Finalizable_Transient;
4373
4374    ---------------------------------
4375    -- Is_Fully_Repped_Tagged_Type --
4376    ---------------------------------
4377
4378    function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is
4379       U    : constant Entity_Id := Underlying_Type (T);
4380       Comp : Entity_Id;
4381
4382    begin
4383       if No (U) or else not Is_Tagged_Type (U) then
4384          return False;
4385       elsif Has_Discriminants (U) then
4386          return False;
4387       elsif not Has_Specified_Layout (U) then
4388          return False;
4389       end if;
4390
4391       --  Here we have a tagged type, see if it has any unlayed out fields
4392       --  other than a possible tag and parent fields. If so, we return False.
4393
4394       Comp := First_Component (U);
4395       while Present (Comp) loop
4396          if not Is_Tag (Comp)
4397            and then Chars (Comp) /= Name_uParent
4398            and then No (Component_Clause (Comp))
4399          then
4400             return False;
4401          else
4402             Next_Component (Comp);
4403          end if;
4404       end loop;
4405
4406       --  All components are layed out
4407
4408       return True;
4409    end Is_Fully_Repped_Tagged_Type;
4410
4411    ----------------------------------
4412    -- Is_Library_Level_Tagged_Type --
4413    ----------------------------------
4414
4415    function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
4416    begin
4417       return Is_Tagged_Type (Typ) and then Is_Library_Level_Entity (Typ);
4418    end Is_Library_Level_Tagged_Type;
4419
4420    --------------------------
4421    -- Is_Non_BIP_Func_Call --
4422    --------------------------
4423
4424    function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is
4425    begin
4426       --  The expected call is of the format
4427       --
4428       --    Func_Call'reference
4429
4430       return
4431         Nkind (Expr) = N_Reference
4432           and then Nkind (Prefix (Expr)) = N_Function_Call
4433           and then not Is_Build_In_Place_Function_Call (Prefix (Expr));
4434    end Is_Non_BIP_Func_Call;
4435
4436    ----------------------------------
4437    -- Is_Possibly_Unaligned_Object --
4438    ----------------------------------
4439
4440    function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
4441       T  : constant Entity_Id := Etype (N);
4442
4443    begin
4444       --  If renamed object, apply test to underlying object
4445
4446       if Is_Entity_Name (N)
4447         and then Is_Object (Entity (N))
4448         and then Present (Renamed_Object (Entity (N)))
4449       then
4450          return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
4451       end if;
4452
4453       --  Tagged and controlled types and aliased types are always aligned, as
4454       --  are concurrent types.
4455
4456       if Is_Aliased (T)
4457         or else Has_Controlled_Component (T)
4458         or else Is_Concurrent_Type (T)
4459         or else Is_Tagged_Type (T)
4460         or else Is_Controlled (T)
4461       then
4462          return False;
4463       end if;
4464
4465       --  If this is an element of a packed array, may be unaligned
4466
4467       if Is_Ref_To_Bit_Packed_Array (N) then
4468          return True;
4469       end if;
4470
4471       --  Case of indexed component reference: test whether prefix is unaligned
4472
4473       if Nkind (N) = N_Indexed_Component then
4474          return Is_Possibly_Unaligned_Object (Prefix (N));
4475
4476       --  Case of selected component reference
4477
4478       elsif Nkind (N) = N_Selected_Component then
4479          declare
4480             P : constant Node_Id   := Prefix (N);
4481             C : constant Entity_Id := Entity (Selector_Name (N));
4482             M : Nat;
4483             S : Nat;
4484
4485          begin
4486             --  If component reference is for an array with non-static bounds,
4487             --  then it is always aligned: we can only process unaligned arrays
4488             --  with static bounds (more precisely compile time known bounds).
4489
4490             if Is_Array_Type (T)
4491               and then not Compile_Time_Known_Bounds (T)
4492             then
4493                return False;
4494             end if;
4495
4496             --  If component is aliased, it is definitely properly aligned
4497
4498             if Is_Aliased (C) then
4499                return False;
4500             end if;
4501
4502             --  If component is for a type implemented as a scalar, and the
4503             --  record is packed, and the component is other than the first
4504             --  component of the record, then the component may be unaligned.
4505
4506             if Is_Packed (Etype (P))
4507               and then Represented_As_Scalar (Etype (C))
4508               and then First_Entity (Scope (C)) /= C
4509             then
4510                return True;
4511             end if;
4512
4513             --  Compute maximum possible alignment for T
4514
4515             --  If alignment is known, then that settles things
4516
4517             if Known_Alignment (T) then
4518                M := UI_To_Int (Alignment (T));
4519
4520             --  If alignment is not known, tentatively set max alignment
4521
4522             else
4523                M := Ttypes.Maximum_Alignment;
4524
4525                --  We can reduce this if the Esize is known since the default
4526                --  alignment will never be more than the smallest power of 2
4527                --  that does not exceed this Esize value.
4528
4529                if Known_Esize (T) then
4530                   S := UI_To_Int (Esize (T));
4531
4532                   while (M / 2) >= S loop
4533                      M := M / 2;
4534                   end loop;
4535                end if;
4536             end if;
4537
4538             --  The following code is historical, it used to be present but it
4539             --  is too cautious, because the front-end does not know the proper
4540             --  default alignments for the target. Also, if the alignment is
4541             --  not known, the front end can't know in any case! If a copy is
4542             --  needed, the back-end will take care of it. This whole section
4543             --  including this comment can be removed later ???
4544
4545             --  If the component reference is for a record that has a specified
4546             --  alignment, and we either know it is too small, or cannot tell,
4547             --  then the component may be unaligned.
4548
4549             --  What is the following commented out code ???
4550
4551             --  if Known_Alignment (Etype (P))
4552             --    and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment
4553             --    and then M > Alignment (Etype (P))
4554             --  then
4555             --     return True;
4556             --  end if;
4557
4558             --  Case of component clause present which may specify an
4559             --  unaligned position.
4560
4561             if Present (Component_Clause (C)) then
4562
4563                --  Otherwise we can do a test to make sure that the actual
4564                --  start position in the record, and the length, are both
4565                --  consistent with the required alignment. If not, we know
4566                --  that we are unaligned.
4567
4568                declare
4569                   Align_In_Bits : constant Nat := M * System_Storage_Unit;
4570                begin
4571                   if Component_Bit_Offset (C) mod Align_In_Bits /= 0
4572                     or else Esize (C) mod Align_In_Bits /= 0
4573                   then
4574                      return True;
4575                   end if;
4576                end;
4577             end if;
4578
4579             --  Otherwise, for a component reference, test prefix
4580
4581             return Is_Possibly_Unaligned_Object (P);
4582          end;
4583
4584       --  If not a component reference, must be aligned
4585
4586       else
4587          return False;
4588       end if;
4589    end Is_Possibly_Unaligned_Object;
4590
4591    ---------------------------------
4592    -- Is_Possibly_Unaligned_Slice --
4593    ---------------------------------
4594
4595    function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
4596    begin
4597       --  Go to renamed object
4598
4599       if Is_Entity_Name (N)
4600         and then Is_Object (Entity (N))
4601         and then Present (Renamed_Object (Entity (N)))
4602       then
4603          return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
4604       end if;
4605
4606       --  The reference must be a slice
4607
4608       if Nkind (N) /= N_Slice then
4609          return False;
4610       end if;
4611
4612       --  Always assume the worst for a nested record component with a
4613       --  component clause, which gigi/gcc does not appear to handle well.
4614       --  It is not clear why this special test is needed at all ???
4615
4616       if Nkind (Prefix (N)) = N_Selected_Component
4617         and then Nkind (Prefix (Prefix (N))) = N_Selected_Component
4618         and then
4619           Present (Component_Clause (Entity (Selector_Name (Prefix (N)))))
4620       then
4621          return True;
4622       end if;
4623
4624       --  We only need to worry if the target has strict alignment
4625
4626       if not Target_Strict_Alignment then
4627          return False;
4628       end if;
4629
4630       --  If it is a slice, then look at the array type being sliced
4631
4632       declare
4633          Sarr : constant Node_Id := Prefix (N);
4634          --  Prefix of the slice, i.e. the array being sliced
4635
4636          Styp : constant Entity_Id := Etype (Prefix (N));
4637          --  Type of the array being sliced
4638
4639          Pref : Node_Id;
4640          Ptyp : Entity_Id;
4641
4642       begin
4643          --  The problems arise if the array object that is being sliced
4644          --  is a component of a record or array, and we cannot guarantee
4645          --  the alignment of the array within its containing object.
4646
4647          --  To investigate this, we look at successive prefixes to see
4648          --  if we have a worrisome indexed or selected component.
4649
4650          Pref := Sarr;
4651          loop
4652             --  Case of array is part of an indexed component reference
4653
4654             if Nkind (Pref) = N_Indexed_Component then
4655                Ptyp := Etype (Prefix (Pref));
4656
4657                --  The only problematic case is when the array is packed, in
4658                --  which case we really know nothing about the alignment of
4659                --  individual components.
4660
4661                if Is_Bit_Packed_Array (Ptyp) then
4662                   return True;
4663                end if;
4664
4665             --  Case of array is part of a selected component reference
4666
4667             elsif Nkind (Pref) = N_Selected_Component then
4668                Ptyp := Etype (Prefix (Pref));
4669
4670                --  We are definitely in trouble if the record in question
4671                --  has an alignment, and either we know this alignment is
4672                --  inconsistent with the alignment of the slice, or we don't
4673                --  know what the alignment of the slice should be.
4674
4675                if Known_Alignment (Ptyp)
4676                  and then (Unknown_Alignment (Styp)
4677                             or else Alignment (Styp) > Alignment (Ptyp))
4678                then
4679                   return True;
4680                end if;
4681
4682                --  We are in potential trouble if the record type is packed.
4683                --  We could special case when we know that the array is the
4684                --  first component, but that's not such a simple case ???
4685
4686                if Is_Packed (Ptyp) then
4687                   return True;
4688                end if;
4689
4690                --  We are in trouble if there is a component clause, and
4691                --  either we do not know the alignment of the slice, or
4692                --  the alignment of the slice is inconsistent with the
4693                --  bit position specified by the component clause.
4694
4695                declare
4696                   Field : constant Entity_Id := Entity (Selector_Name (Pref));
4697                begin
4698                   if Present (Component_Clause (Field))
4699                     and then
4700                       (Unknown_Alignment (Styp)
4701                         or else
4702                          (Component_Bit_Offset (Field) mod
4703                            (System_Storage_Unit * Alignment (Styp))) /= 0)
4704                   then
4705                      return True;
4706                   end if;
4707                end;
4708
4709             --  For cases other than selected or indexed components we know we
4710             --  are OK, since no issues arise over alignment.
4711
4712             else
4713                return False;
4714             end if;
4715
4716             --  We processed an indexed component or selected component
4717             --  reference that looked safe, so keep checking prefixes.
4718
4719             Pref := Prefix (Pref);
4720          end loop;
4721       end;
4722    end Is_Possibly_Unaligned_Slice;
4723
4724    -------------------------------
4725    -- Is_Related_To_Func_Return --
4726    -------------------------------
4727
4728    function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is
4729       Expr : constant Node_Id := Related_Expression (Id);
4730    begin
4731       return
4732         Present (Expr)
4733           and then Nkind (Expr) = N_Explicit_Dereference
4734           and then Nkind (Parent (Expr)) = N_Simple_Return_Statement;
4735    end Is_Related_To_Func_Return;
4736
4737    --------------------------------
4738    -- Is_Ref_To_Bit_Packed_Array --
4739    --------------------------------
4740
4741    function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
4742       Result : Boolean;
4743       Expr   : Node_Id;
4744
4745    begin
4746       if Is_Entity_Name (N)
4747         and then Is_Object (Entity (N))
4748         and then Present (Renamed_Object (Entity (N)))
4749       then
4750          return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
4751       end if;
4752
4753       if Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
4754          if Is_Bit_Packed_Array (Etype (Prefix (N))) then
4755             Result := True;
4756          else
4757             Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
4758          end if;
4759
4760          if Result and then Nkind (N) = N_Indexed_Component then
4761             Expr := First (Expressions (N));
4762             while Present (Expr) loop
4763                Force_Evaluation (Expr);
4764                Next (Expr);
4765             end loop;
4766          end if;
4767
4768          return Result;
4769
4770       else
4771          return False;
4772       end if;
4773    end Is_Ref_To_Bit_Packed_Array;
4774
4775    --------------------------------
4776    -- Is_Ref_To_Bit_Packed_Slice --
4777    --------------------------------
4778
4779    function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
4780    begin
4781       if Nkind (N) = N_Type_Conversion then
4782          return Is_Ref_To_Bit_Packed_Slice (Expression (N));
4783
4784       elsif Is_Entity_Name (N)
4785         and then Is_Object (Entity (N))
4786         and then Present (Renamed_Object (Entity (N)))
4787       then
4788          return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
4789
4790       elsif Nkind (N) = N_Slice
4791         and then Is_Bit_Packed_Array (Etype (Prefix (N)))
4792       then
4793          return True;
4794
4795       elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
4796          return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
4797
4798       else
4799          return False;
4800       end if;
4801    end Is_Ref_To_Bit_Packed_Slice;
4802
4803    -----------------------
4804    -- Is_Renamed_Object --
4805    -----------------------
4806
4807    function Is_Renamed_Object (N : Node_Id) return Boolean is
4808       Pnod : constant Node_Id   := Parent (N);
4809       Kind : constant Node_Kind := Nkind (Pnod);
4810    begin
4811       if Kind = N_Object_Renaming_Declaration then
4812          return True;
4813       elsif Nkind_In (Kind, N_Indexed_Component, N_Selected_Component) then
4814          return Is_Renamed_Object (Pnod);
4815       else
4816          return False;
4817       end if;
4818    end Is_Renamed_Object;
4819
4820    --------------------------------------
4821    -- Is_Secondary_Stack_BIP_Func_Call --
4822    --------------------------------------
4823
4824    function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is
4825       Call : Node_Id := Expr;
4826
4827    begin
4828       --  Build-in-place calls usually appear in 'reference format. Note that
4829       --  the accessibility check machinery may add an extra 'reference due to
4830       --  side effect removal.
4831
4832       while Nkind (Call) = N_Reference loop
4833          Call := Prefix (Call);
4834       end loop;
4835
4836       if Nkind_In (Call, N_Qualified_Expression,
4837                          N_Unchecked_Type_Conversion)
4838       then
4839          Call := Expression (Call);
4840       end if;
4841
4842       if Is_Build_In_Place_Function_Call (Call) then
4843          declare
4844             Access_Nam : Name_Id := No_Name;
4845             Actual     : Node_Id;
4846             Param      : Node_Id;
4847             Formal     : Node_Id;
4848
4849          begin
4850             --  Examine all parameter associations of the function call
4851
4852             Param := First (Parameter_Associations (Call));
4853             while Present (Param) loop
4854                if Nkind (Param) = N_Parameter_Association
4855                  and then Nkind (Selector_Name (Param)) = N_Identifier
4856                then
4857                   Formal := Selector_Name (Param);
4858                   Actual := Explicit_Actual_Parameter (Param);
4859
4860                   --  Construct the name of formal BIPalloc. It is much easier
4861                   --  to extract the name of the function using an arbitrary
4862                   --  formal's scope rather than the Name field of Call.
4863
4864                   if Access_Nam = No_Name
4865                     and then Present (Entity (Formal))
4866                   then
4867                      Access_Nam :=
4868                        New_External_Name
4869                          (Chars (Scope (Entity (Formal))),
4870                           BIP_Formal_Suffix (BIP_Alloc_Form));
4871                   end if;
4872
4873                   --  A match for BIPalloc => 2 has been found
4874
4875                   if Chars (Formal) = Access_Nam
4876                     and then Nkind (Actual) = N_Integer_Literal
4877                     and then Intval (Actual) = Uint_2
4878                   then
4879                      return True;
4880                   end if;
4881                end if;
4882
4883                Next (Param);
4884             end loop;
4885          end;
4886       end if;
4887
4888       return False;
4889    end Is_Secondary_Stack_BIP_Func_Call;
4890
4891    -------------------------------------
4892    -- Is_Tag_To_Class_Wide_Conversion --
4893    -------------------------------------
4894
4895    function Is_Tag_To_Class_Wide_Conversion
4896      (Obj_Id : Entity_Id) return Boolean
4897    is
4898       Expr : constant Node_Id := Expression (Parent (Obj_Id));
4899
4900    begin
4901       return
4902         Is_Class_Wide_Type (Etype (Obj_Id))
4903           and then Present (Expr)
4904           and then Nkind (Expr) = N_Unchecked_Type_Conversion
4905           and then Etype (Expression (Expr)) = RTE (RE_Tag);
4906    end Is_Tag_To_Class_Wide_Conversion;
4907
4908    ----------------------------
4909    -- Is_Untagged_Derivation --
4910    ----------------------------
4911
4912    function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
4913    begin
4914       return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
4915                or else
4916              (Is_Private_Type (T) and then Present (Full_View (T))
4917                and then not Is_Tagged_Type (Full_View (T))
4918                and then Is_Derived_Type (Full_View (T))
4919                and then Etype (Full_View (T)) /= T);
4920    end Is_Untagged_Derivation;
4921
4922    ---------------------------
4923    -- Is_Volatile_Reference --
4924    ---------------------------
4925
4926    function Is_Volatile_Reference (N : Node_Id) return Boolean is
4927    begin
4928       if Nkind (N) in N_Has_Etype
4929         and then Present (Etype (N))
4930         and then Treat_As_Volatile (Etype (N))
4931       then
4932          return True;
4933
4934       elsif Is_Entity_Name (N) then
4935          return Treat_As_Volatile (Entity (N));
4936
4937       elsif Nkind (N) = N_Slice then
4938          return Is_Volatile_Reference (Prefix (N));
4939
4940       elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
4941          if (Is_Entity_Name (Prefix (N))
4942               and then Has_Volatile_Components (Entity (Prefix (N))))
4943            or else (Present (Etype (Prefix (N)))
4944                      and then Has_Volatile_Components (Etype (Prefix (N))))
4945          then
4946             return True;
4947          else
4948             return Is_Volatile_Reference (Prefix (N));
4949          end if;
4950
4951       else
4952          return False;
4953       end if;
4954    end Is_Volatile_Reference;
4955
4956    --------------------------
4957    -- Is_VM_By_Copy_Actual --
4958    --------------------------
4959
4960    function Is_VM_By_Copy_Actual (N : Node_Id) return Boolean is
4961    begin
4962       return VM_Target /= No_VM
4963         and then (Nkind (N) = N_Slice
4964                     or else
4965                       (Nkind (N) = N_Identifier
4966                         and then Present (Renamed_Object (Entity (N)))
4967                         and then Nkind (Renamed_Object (Entity (N))) =
4968                                                                  N_Slice));
4969    end Is_VM_By_Copy_Actual;
4970
4971    --------------------
4972    -- Kill_Dead_Code --
4973    --------------------
4974
4975    procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
4976       W : Boolean := Warn;
4977       --  Set False if warnings suppressed
4978
4979    begin
4980       if Present (N) then
4981          Remove_Warning_Messages (N);
4982
4983          --  Generate warning if appropriate
4984
4985          if W then
4986
4987             --  We suppress the warning if this code is under control of an
4988             --  if statement, whose condition is a simple identifier, and
4989             --  either we are in an instance, or warnings off is set for this
4990             --  identifier. The reason for killing it in the instance case is
4991             --  that it is common and reasonable for code to be deleted in
4992             --  instances for various reasons.
4993
4994             if Nkind (Parent (N)) = N_If_Statement then
4995                declare
4996                   C : constant Node_Id := Condition (Parent (N));
4997                begin
4998                   if Nkind (C) = N_Identifier
4999                     and then
5000                       (In_Instance
5001                         or else (Present (Entity (C))
5002                                   and then Has_Warnings_Off (Entity (C))))
5003                   then
5004                      W := False;
5005                   end if;
5006                end;
5007             end if;
5008
5009             --  Generate warning if not suppressed
5010
5011             if W then
5012                Error_Msg_F
5013                  ("?t?this code can never be executed and has been deleted!",
5014                   N);
5015             end if;
5016          end if;
5017
5018          --  Recurse into block statements and bodies to process declarations
5019          --  and statements.
5020
5021          if Nkind (N) = N_Block_Statement
5022            or else Nkind (N) = N_Subprogram_Body
5023            or else Nkind (N) = N_Package_Body
5024          then
5025             Kill_Dead_Code (Declarations (N), False);
5026             Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
5027
5028             if Nkind (N) = N_Subprogram_Body then
5029                Set_Is_Eliminated (Defining_Entity (N));
5030             end if;
5031
5032          elsif Nkind (N) = N_Package_Declaration then
5033             Kill_Dead_Code (Visible_Declarations (Specification (N)));
5034             Kill_Dead_Code (Private_Declarations (Specification (N)));
5035
5036             --  ??? After this point, Delete_Tree has been called on all
5037             --  declarations in Specification (N), so references to entities
5038             --  therein look suspicious.
5039
5040             declare
5041                E : Entity_Id := First_Entity (Defining_Entity (N));
5042             begin
5043                while Present (E) loop
5044                   if Ekind (E) = E_Operator then
5045                      Set_Is_Eliminated (E);
5046                   end if;
5047
5048                   Next_Entity (E);
5049                end loop;
5050             end;
5051
5052          --  Recurse into composite statement to kill individual statements in
5053          --  particular instantiations.
5054
5055          elsif Nkind (N) = N_If_Statement then
5056             Kill_Dead_Code (Then_Statements (N));
5057             Kill_Dead_Code (Elsif_Parts (N));
5058             Kill_Dead_Code (Else_Statements (N));
5059
5060          elsif Nkind (N) = N_Loop_Statement then
5061             Kill_Dead_Code (Statements (N));
5062
5063          elsif Nkind (N) = N_Case_Statement then
5064             declare
5065                Alt : Node_Id;
5066             begin
5067                Alt := First (Alternatives (N));
5068                while Present (Alt) loop
5069                   Kill_Dead_Code (Statements (Alt));
5070                   Next (Alt);
5071                end loop;
5072             end;
5073
5074          elsif Nkind (N) = N_Case_Statement_Alternative then
5075             Kill_Dead_Code (Statements (N));
5076
5077          --  Deal with dead instances caused by deleting instantiations
5078
5079          elsif Nkind (N) in N_Generic_Instantiation then
5080             Remove_Dead_Instance (N);
5081          end if;
5082       end if;
5083    end Kill_Dead_Code;
5084
5085    --  Case where argument is a list of nodes to be killed
5086
5087    procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
5088       N : Node_Id;
5089       W : Boolean;
5090    begin
5091       W := Warn;
5092       if Is_Non_Empty_List (L) then
5093          N := First (L);
5094          while Present (N) loop
5095             Kill_Dead_Code (N, W);
5096             W := False;
5097             Next (N);
5098          end loop;
5099       end if;
5100    end Kill_Dead_Code;
5101
5102    ------------------------
5103    -- Known_Non_Negative --
5104    ------------------------
5105
5106    function Known_Non_Negative (Opnd : Node_Id) return Boolean is
5107    begin
5108       if Is_OK_Static_Expression (Opnd) and then Expr_Value (Opnd) >= 0 then
5109          return True;
5110
5111       else
5112          declare
5113             Lo : constant Node_Id := Type_Low_Bound (Etype (Opnd));
5114          begin
5115             return
5116               Is_OK_Static_Expression (Lo) and then Expr_Value (Lo) >= 0;
5117          end;
5118       end if;
5119    end Known_Non_Negative;
5120
5121    --------------------
5122    -- Known_Non_Null --
5123    --------------------
5124
5125    function Known_Non_Null (N : Node_Id) return Boolean is
5126    begin
5127       --  Checks for case where N is an entity reference
5128
5129       if Is_Entity_Name (N) and then Present (Entity (N)) then
5130          declare
5131             E   : constant Entity_Id := Entity (N);
5132             Op  : Node_Kind;
5133             Val : Node_Id;
5134
5135          begin
5136             --  First check if we are in decisive conditional
5137
5138             Get_Current_Value_Condition (N, Op, Val);
5139
5140             if Known_Null (Val) then
5141                if Op = N_Op_Eq then
5142                   return False;
5143                elsif Op = N_Op_Ne then
5144                   return True;
5145                end if;
5146             end if;
5147
5148             --  If OK to do replacement, test Is_Known_Non_Null flag
5149
5150             if OK_To_Do_Constant_Replacement (E) then
5151                return Is_Known_Non_Null (E);
5152
5153             --  Otherwise if not safe to do replacement, then say so
5154
5155             else
5156                return False;
5157             end if;
5158          end;
5159
5160       --  True if access attribute
5161
5162       elsif Nkind (N) = N_Attribute_Reference
5163         and then (Attribute_Name (N) = Name_Access
5164                     or else
5165                   Attribute_Name (N) = Name_Unchecked_Access
5166                     or else
5167                   Attribute_Name (N) = Name_Unrestricted_Access)
5168       then
5169          return True;
5170
5171       --  True if allocator
5172
5173       elsif Nkind (N) = N_Allocator then
5174          return True;
5175
5176       --  For a conversion, true if expression is known non-null
5177
5178       elsif Nkind (N) = N_Type_Conversion then
5179          return Known_Non_Null (Expression (N));
5180
5181       --  Above are all cases where the value could be determined to be
5182       --  non-null. In all other cases, we don't know, so return False.
5183
5184       else
5185          return False;
5186       end if;
5187    end Known_Non_Null;
5188
5189    ----------------
5190    -- Known_Null --
5191    ----------------
5192
5193    function Known_Null (N : Node_Id) return Boolean is
5194    begin
5195       --  Checks for case where N is an entity reference
5196
5197       if Is_Entity_Name (N) and then Present (Entity (N)) then
5198          declare
5199             E   : constant Entity_Id := Entity (N);
5200             Op  : Node_Kind;
5201             Val : Node_Id;
5202
5203          begin
5204             --  Constant null value is for sure null
5205
5206             if Ekind (E) = E_Constant
5207               and then Known_Null (Constant_Value (E))
5208             then
5209                return True;
5210             end if;
5211
5212             --  First check if we are in decisive conditional
5213
5214             Get_Current_Value_Condition (N, Op, Val);
5215
5216             if Known_Null (Val) then
5217                if Op = N_Op_Eq then
5218                   return True;
5219                elsif Op = N_Op_Ne then
5220                   return False;
5221                end if;
5222             end if;
5223
5224             --  If OK to do replacement, test Is_Known_Null flag
5225
5226             if OK_To_Do_Constant_Replacement (E) then
5227                return Is_Known_Null (E);
5228
5229             --  Otherwise if not safe to do replacement, then say so
5230
5231             else
5232                return False;
5233             end if;
5234          end;
5235
5236       --  True if explicit reference to null
5237
5238       elsif Nkind (N) = N_Null then
5239          return True;
5240
5241       --  For a conversion, true if expression is known null
5242
5243       elsif Nkind (N) = N_Type_Conversion then
5244          return Known_Null (Expression (N));
5245
5246       --  Above are all cases where the value could be determined to be null.
5247       --  In all other cases, we don't know, so return False.
5248
5249       else
5250          return False;
5251       end if;
5252    end Known_Null;
5253
5254    -----------------------------
5255    -- Make_CW_Equivalent_Type --
5256    -----------------------------
5257
5258    --  Create a record type used as an equivalent of any member of the class
5259    --  which takes its size from exp.
5260
5261    --  Generate the following code:
5262
5263    --   type Equiv_T is record
5264    --     _parent :  T (List of discriminant constraints taken from Exp);
5265    --     Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8);
5266    --   end Equiv_T;
5267    --
5268    --   ??? Note that this type does not guarantee same alignment as all
5269    --   derived types
5270
5271    function Make_CW_Equivalent_Type
5272      (T : Entity_Id;
5273       E : Node_Id) return Entity_Id
5274    is
5275       Loc         : constant Source_Ptr := Sloc (E);
5276       Root_Typ    : constant Entity_Id  := Root_Type (T);
5277       List_Def    : constant List_Id    := Empty_List;
5278       Comp_List   : constant List_Id    := New_List;
5279       Equiv_Type  : Entity_Id;
5280       Range_Type  : Entity_Id;
5281       Str_Type    : Entity_Id;
5282       Constr_Root : Entity_Id;
5283       Sizexpr     : Node_Id;
5284
5285    begin
5286       --  If the root type is already constrained, there are no discriminants
5287       --  in the expression.
5288
5289       if not Has_Discriminants (Root_Typ)
5290         or else Is_Constrained (Root_Typ)
5291       then
5292          Constr_Root := Root_Typ;
5293       else
5294          Constr_Root := Make_Temporary (Loc, 'R');
5295
5296          --  subtype cstr__n is T (List of discr constraints taken from Exp)
5297
5298          Append_To (List_Def,
5299            Make_Subtype_Declaration (Loc,
5300              Defining_Identifier => Constr_Root,
5301              Subtype_Indication  => Make_Subtype_From_Expr (E, Root_Typ)));
5302       end if;
5303
5304       --  Generate the range subtype declaration
5305
5306       Range_Type := Make_Temporary (Loc, 'G');
5307
5308       if not Is_Interface (Root_Typ) then
5309
5310          --  subtype rg__xx is
5311          --    Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit
5312
5313          Sizexpr :=
5314            Make_Op_Subtract (Loc,
5315              Left_Opnd =>
5316                Make_Attribute_Reference (Loc,
5317                  Prefix =>
5318                    OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
5319                  Attribute_Name => Name_Size),
5320              Right_Opnd =>
5321                Make_Attribute_Reference (Loc,
5322                  Prefix => New_Reference_To (Constr_Root, Loc),
5323                  Attribute_Name => Name_Object_Size));
5324       else
5325          --  subtype rg__xx is
5326          --    Storage_Offset range 1 .. Expr'size / Storage_Unit
5327
5328          Sizexpr :=
5329            Make_Attribute_Reference (Loc,
5330              Prefix =>
5331                OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
5332              Attribute_Name => Name_Size);
5333       end if;
5334
5335       Set_Paren_Count (Sizexpr, 1);
5336
5337       Append_To (List_Def,
5338         Make_Subtype_Declaration (Loc,
5339           Defining_Identifier => Range_Type,
5340           Subtype_Indication =>
5341             Make_Subtype_Indication (Loc,
5342               Subtype_Mark => New_Reference_To (RTE (RE_Storage_Offset), Loc),
5343               Constraint => Make_Range_Constraint (Loc,
5344                 Range_Expression =>
5345                   Make_Range (Loc,
5346                     Low_Bound => Make_Integer_Literal (Loc, 1),
5347                     High_Bound =>
5348                       Make_Op_Divide (Loc,
5349                         Left_Opnd => Sizexpr,
5350                         Right_Opnd => Make_Integer_Literal (Loc,
5351                             Intval => System_Storage_Unit)))))));
5352
5353       --  subtype str__nn is Storage_Array (rg__x);
5354
5355       Str_Type := Make_Temporary (Loc, 'S');
5356       Append_To (List_Def,
5357         Make_Subtype_Declaration (Loc,
5358           Defining_Identifier => Str_Type,
5359           Subtype_Indication =>
5360             Make_Subtype_Indication (Loc,
5361               Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
5362               Constraint =>
5363                 Make_Index_Or_Discriminant_Constraint (Loc,
5364                   Constraints =>
5365                     New_List (New_Reference_To (Range_Type, Loc))))));
5366
5367       --  type Equiv_T is record
5368       --    [ _parent : Tnn; ]
5369       --    E : Str_Type;
5370       --  end Equiv_T;
5371
5372       Equiv_Type := Make_Temporary (Loc, 'T');
5373       Set_Ekind (Equiv_Type, E_Record_Type);
5374       Set_Parent_Subtype (Equiv_Type, Constr_Root);
5375
5376       --  Set Is_Class_Wide_Equivalent_Type very early to trigger the special
5377       --  treatment for this type. In particular, even though _parent's type
5378       --  is a controlled type or contains controlled components, we do not
5379       --  want to set Has_Controlled_Component on it to avoid making it gain
5380       --  an unwanted _controller component.
5381
5382       Set_Is_Class_Wide_Equivalent_Type (Equiv_Type);
5383
5384       if not Is_Interface (Root_Typ) then
5385          Append_To (Comp_List,
5386            Make_Component_Declaration (Loc,
5387              Defining_Identifier =>
5388                Make_Defining_Identifier (Loc, Name_uParent),
5389              Component_Definition =>
5390                Make_Component_Definition (Loc,
5391                  Aliased_Present    => False,
5392                  Subtype_Indication => New_Reference_To (Constr_Root, Loc))));
5393       end if;
5394
5395       Append_To (Comp_List,
5396         Make_Component_Declaration (Loc,
5397           Defining_Identifier  => Make_Temporary (Loc, 'C'),
5398           Component_Definition =>
5399             Make_Component_Definition (Loc,
5400               Aliased_Present    => False,
5401               Subtype_Indication => New_Reference_To (Str_Type, Loc))));
5402
5403       Append_To (List_Def,
5404         Make_Full_Type_Declaration (Loc,
5405           Defining_Identifier => Equiv_Type,
5406           Type_Definition =>
5407             Make_Record_Definition (Loc,
5408               Component_List =>
5409                 Make_Component_List (Loc,
5410                   Component_Items => Comp_List,
5411                   Variant_Part    => Empty))));
5412
5413       --  Suppress all checks during the analysis of the expanded code to avoid
5414       --  the generation of spurious warnings under ZFP run-time.
5415
5416       Insert_Actions (E, List_Def, Suppress => All_Checks);
5417       return Equiv_Type;
5418    end Make_CW_Equivalent_Type;
5419
5420    -------------------------
5421    -- Make_Invariant_Call --
5422    -------------------------
5423
5424    function Make_Invariant_Call (Expr : Node_Id) return Node_Id is
5425       Loc : constant Source_Ptr := Sloc (Expr);
5426       Typ : constant Entity_Id  := Etype (Expr);
5427
5428    begin
5429       pragma Assert
5430         (Has_Invariants (Typ) and then Present (Invariant_Procedure (Typ)));
5431
5432       if Check_Enabled (Name_Invariant)
5433            or else
5434          Check_Enabled (Name_Assertion)
5435       then
5436          return
5437            Make_Procedure_Call_Statement (Loc,
5438              Name                   =>
5439                New_Occurrence_Of (Invariant_Procedure (Typ), Loc),
5440              Parameter_Associations => New_List (Relocate_Node (Expr)));
5441
5442       else
5443          return
5444            Make_Null_Statement (Loc);
5445       end if;
5446    end Make_Invariant_Call;
5447
5448    ------------------------
5449    -- Make_Literal_Range --
5450    ------------------------
5451
5452    function Make_Literal_Range
5453      (Loc         : Source_Ptr;
5454       Literal_Typ : Entity_Id) return Node_Id
5455    is
5456       Lo          : constant Node_Id :=
5457                       New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
5458       Index       : constant Entity_Id := Etype (Lo);
5459
5460       Hi          : Node_Id;
5461       Length_Expr : constant Node_Id :=
5462                       Make_Op_Subtract (Loc,
5463                         Left_Opnd =>
5464                           Make_Integer_Literal (Loc,
5465                             Intval => String_Literal_Length (Literal_Typ)),
5466                         Right_Opnd =>
5467                           Make_Integer_Literal (Loc, 1));
5468
5469    begin
5470       Set_Analyzed (Lo, False);
5471
5472          if Is_Integer_Type (Index) then
5473             Hi :=
5474               Make_Op_Add (Loc,
5475                 Left_Opnd  => New_Copy_Tree (Lo),
5476                 Right_Opnd => Length_Expr);
5477          else
5478             Hi :=
5479               Make_Attribute_Reference (Loc,
5480                 Attribute_Name => Name_Val,
5481                 Prefix => New_Occurrence_Of (Index, Loc),
5482                 Expressions => New_List (
5483                  Make_Op_Add (Loc,
5484                    Left_Opnd =>
5485                      Make_Attribute_Reference (Loc,
5486                        Attribute_Name => Name_Pos,
5487                        Prefix => New_Occurrence_Of (Index, Loc),
5488                        Expressions => New_List (New_Copy_Tree (Lo))),
5489                   Right_Opnd => Length_Expr)));
5490          end if;
5491
5492          return
5493            Make_Range (Loc,
5494              Low_Bound  => Lo,
5495              High_Bound => Hi);
5496    end Make_Literal_Range;
5497
5498    --------------------------
5499    -- Make_Non_Empty_Check --
5500    --------------------------
5501
5502    function Make_Non_Empty_Check
5503      (Loc : Source_Ptr;
5504       N   : Node_Id) return Node_Id
5505    is
5506    begin
5507       return
5508         Make_Op_Ne (Loc,
5509           Left_Opnd =>
5510             Make_Attribute_Reference (Loc,
5511               Attribute_Name => Name_Length,
5512               Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
5513           Right_Opnd =>
5514             Make_Integer_Literal (Loc, 0));
5515    end Make_Non_Empty_Check;
5516
5517    -------------------------
5518    -- Make_Predicate_Call --
5519    -------------------------
5520
5521    function Make_Predicate_Call
5522      (Typ  : Entity_Id;
5523       Expr : Node_Id;
5524       Mem  : Boolean := False) return Node_Id
5525    is
5526       Loc : constant Source_Ptr := Sloc (Expr);
5527
5528    begin
5529       pragma Assert (Present (Predicate_Function (Typ)));
5530
5531       --  Call special membership version if requested and available
5532
5533       if Mem then
5534          declare
5535             PFM : constant Entity_Id := Predicate_Function_M (Typ);
5536          begin
5537             if Present (PFM) then
5538                return
5539                  Make_Function_Call (Loc,
5540                    Name                   => New_Occurrence_Of (PFM, Loc),
5541                    Parameter_Associations => New_List (Relocate_Node (Expr)));
5542             end if;
5543          end;
5544       end if;
5545
5546       --  Case of calling normal predicate function
5547
5548       return
5549           Make_Function_Call (Loc,
5550             Name                   =>
5551               New_Occurrence_Of (Predicate_Function (Typ), Loc),
5552             Parameter_Associations => New_List (Relocate_Node (Expr)));
5553    end Make_Predicate_Call;
5554
5555    --------------------------
5556    -- Make_Predicate_Check --
5557    --------------------------
5558
5559    function Make_Predicate_Check
5560      (Typ  : Entity_Id;
5561       Expr : Node_Id) return Node_Id
5562    is
5563       Loc : constant Source_Ptr := Sloc (Expr);
5564
5565    begin
5566       return
5567         Make_Pragma (Loc,
5568           Pragma_Identifier            => Make_Identifier (Loc, Name_Check),
5569           Pragma_Argument_Associations => New_List (
5570             Make_Pragma_Argument_Association (Loc,
5571               Expression => Make_Identifier (Loc, Name_Predicate)),
5572             Make_Pragma_Argument_Association (Loc,
5573               Expression => Make_Predicate_Call (Typ, Expr))));
5574    end Make_Predicate_Check;
5575
5576    ----------------------------
5577    -- Make_Subtype_From_Expr --
5578    ----------------------------
5579
5580    --  1. If Expr is an unconstrained array expression, creates
5581    --    Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
5582
5583    --  2. If Expr is a unconstrained discriminated type expression, creates
5584    --    Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
5585
5586    --  3. If Expr is class-wide, creates an implicit class wide subtype
5587
5588    function Make_Subtype_From_Expr
5589      (E       : Node_Id;
5590       Unc_Typ : Entity_Id) return Node_Id
5591    is
5592       Loc         : constant Source_Ptr := Sloc (E);
5593       List_Constr : constant List_Id    := New_List;
5594       D           : Entity_Id;
5595
5596       Full_Subtyp  : Entity_Id;
5597       Priv_Subtyp  : Entity_Id;
5598       Utyp         : Entity_Id;
5599       Full_Exp     : Node_Id;
5600
5601    begin
5602       if Is_Private_Type (Unc_Typ)
5603         and then Has_Unknown_Discriminants (Unc_Typ)
5604       then
5605          --  Prepare the subtype completion, Go to base type to
5606          --  find underlying type, because the type may be a generic
5607          --  actual or an explicit subtype.
5608
5609          Utyp        := Underlying_Type (Base_Type (Unc_Typ));
5610          Full_Subtyp := Make_Temporary (Loc, 'C');
5611          Full_Exp    :=
5612            Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E));
5613          Set_Parent (Full_Exp, Parent (E));
5614
5615          Priv_Subtyp := Make_Temporary (Loc, 'P');
5616
5617          Insert_Action (E,
5618            Make_Subtype_Declaration (Loc,
5619              Defining_Identifier => Full_Subtyp,
5620              Subtype_Indication  => Make_Subtype_From_Expr (Full_Exp, Utyp)));
5621
5622          --  Define the dummy private subtype
5623
5624          Set_Ekind          (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
5625          Set_Etype          (Priv_Subtyp, Base_Type (Unc_Typ));
5626          Set_Scope          (Priv_Subtyp, Full_Subtyp);
5627          Set_Is_Constrained (Priv_Subtyp);
5628          Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
5629          Set_Is_Itype       (Priv_Subtyp);
5630          Set_Associated_Node_For_Itype (Priv_Subtyp, E);
5631
5632          if Is_Tagged_Type  (Priv_Subtyp) then
5633             Set_Class_Wide_Type
5634               (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
5635             Set_Direct_Primitive_Operations (Priv_Subtyp,
5636               Direct_Primitive_Operations (Unc_Typ));
5637          end if;
5638
5639          Set_Full_View (Priv_Subtyp, Full_Subtyp);
5640
5641          return New_Reference_To (Priv_Subtyp, Loc);
5642
5643       elsif Is_Array_Type (Unc_Typ) then
5644          for J in 1 .. Number_Dimensions (Unc_Typ) loop
5645             Append_To (List_Constr,
5646               Make_Range (Loc,
5647                 Low_Bound =>
5648                   Make_Attribute_Reference (Loc,
5649                     Prefix => Duplicate_Subexpr_No_Checks (E),
5650                     Attribute_Name => Name_First,
5651                     Expressions => New_List (
5652                       Make_Integer_Literal (Loc, J))),
5653
5654                 High_Bound =>
5655                   Make_Attribute_Reference (Loc,
5656                     Prefix         => Duplicate_Subexpr_No_Checks (E),
5657                     Attribute_Name => Name_Last,
5658                     Expressions    => New_List (
5659                       Make_Integer_Literal (Loc, J)))));
5660          end loop;
5661
5662       elsif Is_Class_Wide_Type (Unc_Typ) then
5663          declare
5664             CW_Subtype : Entity_Id;
5665             EQ_Typ     : Entity_Id := Empty;
5666
5667          begin
5668             --  A class-wide equivalent type is not needed when VM_Target
5669             --  because the VM back-ends handle the class-wide object
5670             --  initialization itself (and doesn't need or want the
5671             --  additional intermediate type to handle the assignment).
5672
5673             if Expander_Active and then Tagged_Type_Expansion then
5674
5675                --  If this is the class_wide type of a completion that is a
5676                --  record subtype, set the type of the class_wide type to be
5677                --  the full base type, for use in the expanded code for the
5678                --  equivalent type. Should this be done earlier when the
5679                --  completion is analyzed ???
5680
5681                if Is_Private_Type (Etype (Unc_Typ))
5682                  and then
5683                    Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype
5684                then
5685                   Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ))));
5686                end if;
5687
5688                EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
5689             end if;
5690
5691             CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
5692             Set_Equivalent_Type (CW_Subtype, EQ_Typ);
5693             Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
5694
5695             return New_Occurrence_Of (CW_Subtype, Loc);
5696          end;
5697
5698       --  Indefinite record type with discriminants
5699
5700       else
5701          D := First_Discriminant (Unc_Typ);
5702          while Present (D) loop
5703             Append_To (List_Constr,
5704               Make_Selected_Component (Loc,
5705                 Prefix        => Duplicate_Subexpr_No_Checks (E),
5706                 Selector_Name => New_Reference_To (D, Loc)));
5707
5708             Next_Discriminant (D);
5709          end loop;
5710       end if;
5711
5712       return
5713         Make_Subtype_Indication (Loc,
5714           Subtype_Mark => New_Reference_To (Unc_Typ, Loc),
5715           Constraint   =>
5716             Make_Index_Or_Discriminant_Constraint (Loc,
5717               Constraints => List_Constr));
5718    end Make_Subtype_From_Expr;
5719
5720    -----------------------------
5721    -- May_Generate_Large_Temp --
5722    -----------------------------
5723
5724    --  At the current time, the only types that we return False for (i.e. where
5725    --  we decide we know they cannot generate large temps) are ones where we
5726    --  know the size is 256 bits or less at compile time, and we are still not
5727    --  doing a thorough job on arrays and records ???
5728
5729    function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
5730    begin
5731       if not Size_Known_At_Compile_Time (Typ) then
5732          return False;
5733
5734       elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
5735          return False;
5736
5737       elsif Is_Array_Type (Typ) and then Present (Packed_Array_Type (Typ)) then
5738          return May_Generate_Large_Temp (Packed_Array_Type (Typ));
5739
5740       --  We could do more here to find other small types ???
5741
5742       else
5743          return True;
5744       end if;
5745    end May_Generate_Large_Temp;
5746
5747    ------------------------
5748    -- Needs_Finalization --
5749    ------------------------
5750
5751    function Needs_Finalization (T : Entity_Id) return Boolean is
5752       function Has_Some_Controlled_Component (Rec : Entity_Id) return Boolean;
5753       --  If type is not frozen yet, check explicitly among its components,
5754       --  because the Has_Controlled_Component flag is not necessarily set.
5755
5756       -----------------------------------
5757       -- Has_Some_Controlled_Component --
5758       -----------------------------------
5759
5760       function Has_Some_Controlled_Component
5761         (Rec : Entity_Id) return Boolean
5762       is
5763          Comp : Entity_Id;
5764
5765       begin
5766          if Has_Controlled_Component (Rec) then
5767             return True;
5768
5769          elsif not Is_Frozen (Rec) then
5770             if Is_Record_Type (Rec) then
5771                Comp := First_Entity (Rec);
5772
5773                while Present (Comp) loop
5774                   if not Is_Type (Comp)
5775                     and then Needs_Finalization (Etype (Comp))
5776                   then
5777                      return True;
5778                   end if;
5779
5780                   Next_Entity (Comp);
5781                end loop;
5782
5783                return False;
5784
5785             elsif Is_Array_Type (Rec) then
5786                return Needs_Finalization (Component_Type (Rec));
5787
5788             else
5789                return Has_Controlled_Component (Rec);
5790             end if;
5791          else
5792             return False;
5793          end if;
5794       end Has_Some_Controlled_Component;
5795
5796    --  Start of processing for Needs_Finalization
5797
5798    begin
5799       --  Certain run-time configurations and targets do not provide support
5800       --  for controlled types.
5801
5802       if Restriction_Active (No_Finalization) then
5803          return False;
5804
5805       --  C, C++, CIL and Java types are not considered controlled. It is
5806       --  assumed that the non-Ada side will handle their clean up.
5807
5808       elsif Convention (T) = Convention_C
5809         or else Convention (T) = Convention_CIL
5810         or else Convention (T) = Convention_CPP
5811         or else Convention (T) = Convention_Java
5812       then
5813          return False;
5814
5815       else
5816          --  Class-wide types are treated as controlled because derivations
5817          --  from the root type can introduce controlled components.
5818
5819          return
5820            Is_Class_Wide_Type (T)
5821              or else Is_Controlled (T)
5822              or else Has_Controlled_Component (T)
5823              or else Has_Some_Controlled_Component (T)
5824              or else
5825                (Is_Concurrent_Type (T)
5826                  and then Present (Corresponding_Record_Type (T))
5827                  and then Needs_Finalization (Corresponding_Record_Type (T)));
5828       end if;
5829    end Needs_Finalization;
5830
5831    ----------------------------
5832    -- Needs_Constant_Address --
5833    ----------------------------
5834
5835    function Needs_Constant_Address
5836      (Decl : Node_Id;
5837       Typ  : Entity_Id) return Boolean
5838    is
5839    begin
5840
5841       --  If we have no initialization of any kind, then we don't need to place
5842       --  any restrictions on the address clause, because the object will be
5843       --  elaborated after the address clause is evaluated. This happens if the
5844       --  declaration has no initial expression, or the type has no implicit
5845       --  initialization, or the object is imported.
5846
5847       --  The same holds for all initialized scalar types and all access types.
5848       --  Packed bit arrays of size up to 64 are represented using a modular
5849       --  type with an initialization (to zero) and can be processed like other
5850       --  initialized scalar types.
5851
5852       --  If the type is controlled, code to attach the object to a
5853       --  finalization chain is generated at the point of declaration, and
5854       --  therefore the elaboration of the object cannot be delayed: the
5855       --  address expression must be a constant.
5856
5857       if No (Expression (Decl))
5858         and then not Needs_Finalization (Typ)
5859         and then
5860           (not Has_Non_Null_Base_Init_Proc (Typ)
5861             or else Is_Imported (Defining_Identifier (Decl)))
5862       then
5863          return False;
5864
5865       elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ))
5866         or else Is_Access_Type (Typ)
5867         or else
5868           (Is_Bit_Packed_Array (Typ)
5869             and then Is_Modular_Integer_Type (Packed_Array_Type (Typ)))
5870       then
5871          return False;
5872
5873       else
5874
5875          --  Otherwise, we require the address clause to be constant because
5876          --  the call to the initialization procedure (or the attach code) has
5877          --  to happen at the point of the declaration.
5878
5879          --  Actually the IP call has been moved to the freeze actions anyway,
5880          --  so maybe we can relax this restriction???
5881
5882          return True;
5883       end if;
5884    end Needs_Constant_Address;
5885
5886    ----------------------------
5887    -- New_Class_Wide_Subtype --
5888    ----------------------------
5889
5890    function New_Class_Wide_Subtype
5891      (CW_Typ : Entity_Id;
5892       N      : Node_Id) return Entity_Id
5893    is
5894       Res       : constant Entity_Id := Create_Itype (E_Void, N);
5895       Res_Name  : constant Name_Id   := Chars (Res);
5896       Res_Scope : constant Entity_Id := Scope (Res);
5897
5898    begin
5899       Copy_Node (CW_Typ, Res);
5900       Set_Comes_From_Source (Res, False);
5901       Set_Sloc (Res, Sloc (N));
5902       Set_Is_Itype (Res);
5903       Set_Associated_Node_For_Itype (Res, N);
5904       Set_Is_Public (Res, False);   --  By default, may be changed below.
5905       Set_Public_Status (Res);
5906       Set_Chars (Res, Res_Name);
5907       Set_Scope (Res, Res_Scope);
5908       Set_Ekind (Res, E_Class_Wide_Subtype);
5909       Set_Next_Entity (Res, Empty);
5910       Set_Etype (Res, Base_Type (CW_Typ));
5911       Set_Is_Frozen (Res, False);
5912       Set_Freeze_Node (Res, Empty);
5913       return (Res);
5914    end New_Class_Wide_Subtype;
5915
5916    --------------------------------
5917    -- Non_Limited_Designated_Type --
5918    ---------------------------------
5919
5920    function Non_Limited_Designated_Type (T : Entity_Id) return Entity_Id is
5921       Desig : constant Entity_Id := Designated_Type (T);
5922    begin
5923       if Ekind (Desig) = E_Incomplete_Type
5924         and then Present (Non_Limited_View (Desig))
5925       then
5926          return Non_Limited_View (Desig);
5927       else
5928          return Desig;
5929       end if;
5930    end Non_Limited_Designated_Type;
5931
5932    -----------------------------------
5933    -- OK_To_Do_Constant_Replacement --
5934    -----------------------------------
5935
5936    function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
5937       ES : constant Entity_Id := Scope (E);
5938       CS : Entity_Id;
5939
5940    begin
5941       --  Do not replace statically allocated objects, because they may be
5942       --  modified outside the current scope.
5943
5944       if Is_Statically_Allocated (E) then
5945          return False;
5946
5947       --  Do not replace aliased or volatile objects, since we don't know what
5948       --  else might change the value.
5949
5950       elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
5951          return False;
5952
5953       --  Debug flag -gnatdM disconnects this optimization
5954
5955       elsif Debug_Flag_MM then
5956          return False;
5957
5958       --  Otherwise check scopes
5959
5960       else
5961          CS := Current_Scope;
5962
5963          loop
5964             --  If we are in right scope, replacement is safe
5965
5966             if CS = ES then
5967                return True;
5968
5969             --  Packages do not affect the determination of safety
5970
5971             elsif Ekind (CS) = E_Package then
5972                exit when CS = Standard_Standard;
5973                CS := Scope (CS);
5974
5975             --  Blocks do not affect the determination of safety
5976
5977             elsif Ekind (CS) = E_Block then
5978                CS := Scope (CS);
5979
5980             --  Loops do not affect the determination of safety. Note that we
5981             --  kill all current values on entry to a loop, so we are just
5982             --  talking about processing within a loop here.
5983
5984             elsif Ekind (CS) = E_Loop then
5985                CS := Scope (CS);
5986
5987             --  Otherwise, the reference is dubious, and we cannot be sure that
5988             --  it is safe to do the replacement.
5989
5990             else
5991                exit;
5992             end if;
5993          end loop;
5994
5995          return False;
5996       end if;
5997    end OK_To_Do_Constant_Replacement;
5998
5999    ------------------------------------
6000    -- Possible_Bit_Aligned_Component --
6001    ------------------------------------
6002
6003    function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
6004    begin
6005       case Nkind (N) is
6006
6007          --  Case of indexed component
6008
6009          when N_Indexed_Component =>
6010             declare
6011                P    : constant Node_Id   := Prefix (N);
6012                Ptyp : constant Entity_Id := Etype (P);
6013
6014             begin
6015                --  If we know the component size and it is less than 64, then
6016                --  we are definitely OK. The back end always does assignment of
6017                --  misaligned small objects correctly.
6018
6019                if Known_Static_Component_Size (Ptyp)
6020                  and then Component_Size (Ptyp) <= 64
6021                then
6022                   return False;
6023
6024                --  Otherwise, we need to test the prefix, to see if we are
6025                --  indexing from a possibly unaligned component.
6026
6027                else
6028                   return Possible_Bit_Aligned_Component (P);
6029                end if;
6030             end;
6031
6032          --  Case of selected component
6033
6034          when N_Selected_Component =>
6035             declare
6036                P    : constant Node_Id   := Prefix (N);
6037                Comp : constant Entity_Id := Entity (Selector_Name (N));
6038
6039             begin
6040                --  If there is no component clause, then we are in the clear
6041                --  since the back end will never misalign a large component
6042                --  unless it is forced to do so. In the clear means we need
6043                --  only the recursive test on the prefix.
6044
6045                if Component_May_Be_Bit_Aligned (Comp) then
6046                   return True;
6047                else
6048                   return Possible_Bit_Aligned_Component (P);
6049                end if;
6050             end;
6051
6052          --  For a slice, test the prefix, if that is possibly misaligned,
6053          --  then for sure the slice is!
6054
6055          when N_Slice =>
6056             return Possible_Bit_Aligned_Component (Prefix (N));
6057
6058          --  For an unchecked conversion, check whether the expression may
6059          --  be bit-aligned.
6060
6061          when N_Unchecked_Type_Conversion =>
6062             return Possible_Bit_Aligned_Component (Expression (N));
6063
6064          --  If we have none of the above, it means that we have fallen off the
6065          --  top testing prefixes recursively, and we now have a stand alone
6066          --  object, where we don't have a problem.
6067
6068          when others =>
6069             return False;
6070
6071       end case;
6072    end Possible_Bit_Aligned_Component;
6073
6074    -----------------------------------------------
6075    -- Process_Statements_For_Controlled_Objects --
6076    -----------------------------------------------
6077
6078    procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is
6079       Loc : constant Source_Ptr := Sloc (N);
6080
6081       function Are_Wrapped (L : List_Id) return Boolean;
6082       --  Determine whether list L contains only one statement which is a block
6083
6084       function Wrap_Statements_In_Block (L : List_Id) return Node_Id;
6085       --  Given a list of statements L, wrap it in a block statement and return
6086       --  the generated node.
6087
6088       -----------------
6089       -- Are_Wrapped --
6090       -----------------
6091
6092       function Are_Wrapped (L : List_Id) return Boolean is
6093          Stmt : constant Node_Id := First (L);
6094       begin
6095          return
6096            Present (Stmt)
6097              and then No (Next (Stmt))
6098              and then Nkind (Stmt) = N_Block_Statement;
6099       end Are_Wrapped;
6100
6101       ------------------------------
6102       -- Wrap_Statements_In_Block --
6103       ------------------------------
6104
6105       function Wrap_Statements_In_Block (L : List_Id) return Node_Id is
6106       begin
6107          return
6108            Make_Block_Statement (Loc,
6109              Declarations => No_List,
6110              Handled_Statement_Sequence =>
6111                Make_Handled_Sequence_Of_Statements (Loc,
6112                  Statements => L));
6113       end Wrap_Statements_In_Block;
6114
6115       --  Local variables
6116
6117       Block : Node_Id;
6118
6119    --  Start of processing for Process_Statements_For_Controlled_Objects
6120
6121    begin
6122       --  Whenever a non-handled statement list is wrapped in a block, the
6123       --  block must be explicitly analyzed to redecorate all entities in the
6124       --  list and ensure that a finalizer is properly built.
6125
6126       case Nkind (N) is
6127          when N_Elsif_Part             |
6128               N_If_Statement           |
6129               N_Conditional_Entry_Call |
6130               N_Selective_Accept       =>
6131
6132             --  Check the "then statements" for elsif parts and if statements
6133
6134             if Nkind_In (N, N_Elsif_Part, N_If_Statement)
6135               and then not Is_Empty_List (Then_Statements (N))
6136               and then not Are_Wrapped (Then_Statements (N))
6137               and then Requires_Cleanup_Actions
6138                          (Then_Statements (N), False, False)
6139             then
6140                Block := Wrap_Statements_In_Block (Then_Statements (N));
6141                Set_Then_Statements (N, New_List (Block));
6142
6143                Analyze (Block);
6144             end if;
6145
6146             --  Check the "else statements" for conditional entry calls, if
6147             --  statements and selective accepts.
6148
6149             if Nkind_In (N, N_Conditional_Entry_Call,
6150                             N_If_Statement,
6151                             N_Selective_Accept)
6152               and then not Is_Empty_List (Else_Statements (N))
6153               and then not Are_Wrapped (Else_Statements (N))
6154               and then Requires_Cleanup_Actions
6155                          (Else_Statements (N), False, False)
6156             then
6157                Block := Wrap_Statements_In_Block (Else_Statements (N));
6158                Set_Else_Statements (N, New_List (Block));
6159
6160                Analyze (Block);
6161             end if;
6162
6163          when N_Abortable_Part             |
6164               N_Accept_Alternative         |
6165               N_Case_Statement_Alternative |
6166               N_Delay_Alternative          |
6167               N_Entry_Call_Alternative     |
6168               N_Exception_Handler          |
6169               N_Loop_Statement             |
6170               N_Triggering_Alternative     =>
6171
6172             if not Is_Empty_List (Statements (N))
6173               and then not Are_Wrapped (Statements (N))
6174               and then Requires_Cleanup_Actions (Statements (N), False, False)
6175             then
6176                Block := Wrap_Statements_In_Block (Statements (N));
6177                Set_Statements (N, New_List (Block));
6178
6179                Analyze (Block);
6180             end if;
6181
6182          when others                       =>
6183             null;
6184       end case;
6185    end Process_Statements_For_Controlled_Objects;
6186
6187    ----------------------
6188    -- Remove_Init_Call --
6189    ----------------------
6190
6191    function Remove_Init_Call
6192      (Var        : Entity_Id;
6193       Rep_Clause : Node_Id) return Node_Id
6194    is
6195       Par : constant Node_Id   := Parent (Var);
6196       Typ : constant Entity_Id := Etype (Var);
6197
6198       Init_Proc : Entity_Id;
6199       --  Initialization procedure for Typ
6200
6201       function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
6202       --  Look for init call for Var starting at From and scanning the
6203       --  enclosing list until Rep_Clause or the end of the list is reached.
6204
6205       ----------------------------
6206       -- Find_Init_Call_In_List --
6207       ----------------------------
6208
6209       function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
6210          Init_Call : Node_Id;
6211
6212       begin
6213          Init_Call := From;
6214          while Present (Init_Call) and then Init_Call /= Rep_Clause loop
6215             if Nkind (Init_Call) = N_Procedure_Call_Statement
6216               and then Is_Entity_Name (Name (Init_Call))
6217               and then Entity (Name (Init_Call)) = Init_Proc
6218             then
6219                return Init_Call;
6220             end if;
6221
6222             Next (Init_Call);
6223          end loop;
6224
6225          return Empty;
6226       end Find_Init_Call_In_List;
6227
6228       Init_Call : Node_Id;
6229
6230    --  Start of processing for Find_Init_Call
6231
6232    begin
6233       if Present (Initialization_Statements (Var)) then
6234          Init_Call := Initialization_Statements (Var);
6235          Set_Initialization_Statements (Var, Empty);
6236
6237       elsif not Has_Non_Null_Base_Init_Proc (Typ) then
6238
6239          --  No init proc for the type, so obviously no call to be found
6240
6241          return Empty;
6242
6243       else
6244          --  We might be able to handle other cases below by just properly
6245          --  setting Initialization_Statements at the point where the init proc
6246          --  call is generated???
6247
6248          Init_Proc := Base_Init_Proc (Typ);
6249
6250          --  First scan the list containing the declaration of Var
6251
6252          Init_Call := Find_Init_Call_In_List (From => Next (Par));
6253
6254          --  If not found, also look on Var's freeze actions list, if any,
6255          --  since the init call may have been moved there (case of an address
6256          --  clause applying to Var).
6257
6258          if No (Init_Call) and then Present (Freeze_Node (Var)) then
6259             Init_Call :=
6260               Find_Init_Call_In_List (First (Actions (Freeze_Node (Var))));
6261          end if;
6262
6263          --  If the initialization call has actuals that use the secondary
6264          --  stack, the call may have been wrapped into a temporary block, in
6265          --  which case the block itself has to be removed.
6266
6267          if No (Init_Call) and then Nkind (Next (Par)) = N_Block_Statement then
6268             declare
6269                Blk : constant Node_Id := Next (Par);
6270             begin
6271                if Present
6272                     (Find_Init_Call_In_List
6273                       (First (Statements (Handled_Statement_Sequence (Blk)))))
6274                then
6275                   Init_Call := Blk;
6276                end if;
6277             end;
6278          end if;
6279       end if;
6280
6281       if Present (Init_Call) then
6282          Remove (Init_Call);
6283       end if;
6284       return Init_Call;
6285    end Remove_Init_Call;
6286
6287    -------------------------
6288    -- Remove_Side_Effects --
6289    -------------------------
6290
6291    procedure Remove_Side_Effects
6292      (Exp          : Node_Id;
6293       Name_Req     : Boolean := False;
6294       Variable_Ref : Boolean := False)
6295    is
6296       Loc          : constant Source_Ptr      := Sloc (Exp);
6297       Exp_Type     : constant Entity_Id       := Etype (Exp);
6298       Svg_Suppress : constant Suppress_Record := Scope_Suppress;
6299       Def_Id       : Entity_Id;
6300       E            : Node_Id;
6301       New_Exp      : Node_Id;
6302       Ptr_Typ_Decl : Node_Id;
6303       Ref_Type     : Entity_Id;
6304       Res          : Node_Id;
6305
6306       function Side_Effect_Free (N : Node_Id) return Boolean;
6307       --  Determines if the tree N represents an expression that is known not
6308       --  to have side effects, and for which no processing is required.
6309
6310       function Side_Effect_Free (L : List_Id) return Boolean;
6311       --  Determines if all elements of the list L are side effect free
6312
6313       function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
6314       --  The argument N is a construct where the Prefix is dereferenced if it
6315       --  is an access type and the result is a variable. The call returns True
6316       --  if the construct is side effect free (not considering side effects in
6317       --  other than the prefix which are to be tested by the caller).
6318
6319       function Within_In_Parameter (N : Node_Id) return Boolean;
6320       --  Determines if N is a subcomponent of a composite in-parameter. If so,
6321       --  N is not side-effect free when the actual is global and modifiable
6322       --  indirectly from within a subprogram, because it may be passed by
6323       --  reference. The front-end must be conservative here and assume that
6324       --  this may happen with any array or record type. On the other hand, we
6325       --  cannot create temporaries for all expressions for which this
6326       --  condition is true, for various reasons that might require clearing up
6327       --  ??? For example, discriminant references that appear out of place, or
6328       --  spurious type errors with class-wide expressions. As a result, we
6329       --  limit the transformation to loop bounds, which is so far the only
6330       --  case that requires it.
6331
6332       -----------------------------
6333       -- Safe_Prefixed_Reference --
6334       -----------------------------
6335
6336       function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
6337       begin
6338          --  If prefix is not side effect free, definitely not safe
6339
6340          if not Side_Effect_Free (Prefix (N)) then
6341             return False;
6342
6343          --  If the prefix is of an access type that is not access-to-constant,
6344          --  then this construct is a variable reference, which means it is to
6345          --  be considered to have side effects if Variable_Ref is set True.
6346
6347          elsif Is_Access_Type (Etype (Prefix (N)))
6348            and then not Is_Access_Constant (Etype (Prefix (N)))
6349            and then Variable_Ref
6350          then
6351             --  Exception is a prefix that is the result of a previous removal
6352             --  of side-effects.
6353
6354             return Is_Entity_Name (Prefix (N))
6355               and then not Comes_From_Source (Prefix (N))
6356               and then Ekind (Entity (Prefix (N))) = E_Constant
6357               and then Is_Internal_Name (Chars (Entity (Prefix (N))));
6358
6359          --  If the prefix is an explicit dereference then this construct is a
6360          --  variable reference, which means it is to be considered to have
6361          --  side effects if Variable_Ref is True.
6362
6363          --  We do NOT exclude dereferences of access-to-constant types because
6364          --  we handle them as constant view of variables.
6365
6366          elsif Nkind (Prefix (N)) = N_Explicit_Dereference
6367            and then Variable_Ref
6368          then
6369             return False;
6370
6371          --  Note: The following test is the simplest way of solving a complex
6372          --  problem uncovered by the following test (Side effect on loop bound
6373          --  that is a subcomponent of a global variable:
6374
6375          --    with Text_Io; use Text_Io;
6376          --    procedure Tloop is
6377          --      type X is
6378          --        record
6379          --          V : Natural := 4;
6380          --          S : String (1..5) := (others => 'a');
6381          --        end record;
6382          --      X1 : X;
6383
6384          --      procedure Modi;
6385
6386          --      generic
6387          --        with procedure Action;
6388          --      procedure Loop_G (Arg : X; Msg : String)
6389
6390          --      procedure Loop_G (Arg : X; Msg : String) is
6391          --      begin
6392          --        Put_Line ("begin loop_g " & Msg & " will loop till: "
6393          --                  & Natural'Image (Arg.V));
6394          --        for Index in 1 .. Arg.V loop
6395          --          Text_Io.Put_Line
6396          --            (Natural'Image (Index) & " " & Arg.S (Index));
6397          --          if Index > 2 then
6398          --            Modi;
6399          --          end if;
6400          --        end loop;
6401          --        Put_Line ("end loop_g " & Msg);
6402          --      end;
6403
6404          --      procedure Loop1 is new Loop_G (Modi);
6405          --      procedure Modi is
6406          --      begin
6407          --        X1.V := 1;
6408          --        Loop1 (X1, "from modi");
6409          --      end;
6410          --
6411          --    begin
6412          --      Loop1 (X1, "initial");
6413          --    end;
6414
6415          --  The output of the above program should be:
6416
6417          --    begin loop_g initial will loop till:  4
6418          --     1 a
6419          --     2 a
6420          --     3 a
6421          --    begin loop_g from modi will loop till:  1
6422          --     1 a
6423          --    end loop_g from modi
6424          --     4 a
6425          --    begin loop_g from modi will loop till:  1
6426          --     1 a
6427          --    end loop_g from modi
6428          --    end loop_g initial
6429
6430          --  If a loop bound is a subcomponent of a global variable, a
6431          --  modification of that variable within the loop may incorrectly
6432          --  affect the execution of the loop.
6433
6434          elsif Nkind (Parent (Parent (N))) = N_Loop_Parameter_Specification
6435            and then Within_In_Parameter (Prefix (N))
6436            and then Variable_Ref
6437          then
6438             return False;
6439
6440          --  All other cases are side effect free
6441
6442          else
6443             return True;
6444          end if;
6445       end Safe_Prefixed_Reference;
6446
6447       ----------------------
6448       -- Side_Effect_Free --
6449       ----------------------
6450
6451       function Side_Effect_Free (N : Node_Id) return Boolean is
6452       begin
6453          --  Note on checks that could raise Constraint_Error. Strictly, if we
6454          --  take advantage of 11.6, these checks do not count as side effects.
6455          --  However, we would prefer to consider that they are side effects,
6456          --  since the backend CSE does not work very well on expressions which
6457          --  can raise Constraint_Error. On the other hand if we don't consider
6458          --  them to be side effect free, then we get some awkward expansions
6459          --  in -gnato mode, resulting in code insertions at a point where we
6460          --  do not have a clear model for performing the insertions.
6461
6462          --  Special handling for entity names
6463
6464          if Is_Entity_Name (N) then
6465
6466             --  Variables are considered to be a side effect if Variable_Ref
6467             --  is set or if we have a volatile reference and Name_Req is off.
6468             --  If Name_Req is True then we can't help returning a name which
6469             --  effectively allows multiple references in any case.
6470
6471             if Is_Variable (N, Use_Original_Node => False) then
6472                return not Variable_Ref
6473                  and then (not Is_Volatile_Reference (N) or else Name_Req);
6474
6475             --  Any other entity (e.g. a subtype name) is definitely side
6476             --  effect free.
6477
6478             else
6479                return True;
6480             end if;
6481
6482          --  A value known at compile time is always side effect free
6483
6484          elsif Compile_Time_Known_Value (N) then
6485             return True;
6486
6487          --  A variable renaming is not side-effect free, because the renaming
6488          --  will function like a macro in the front-end in some cases, and an
6489          --  assignment can modify the component designated by N, so we need to
6490          --  create a temporary for it.
6491
6492          --  The guard testing for Entity being present is needed at least in
6493          --  the case of rewritten predicate expressions, and may well also be
6494          --  appropriate elsewhere. Obviously we can't go testing the entity
6495          --  field if it does not exist, so it's reasonable to say that this is
6496          --  not the renaming case if it does not exist.
6497
6498          elsif Is_Entity_Name (Original_Node (N))
6499            and then Present (Entity (Original_Node (N)))
6500            and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
6501            and then Ekind (Entity (Original_Node (N))) /= E_Constant
6502          then
6503             declare
6504                RO : constant Node_Id :=
6505                       Renamed_Object (Entity (Original_Node (N)));
6506
6507             begin
6508                --  If the renamed object is an indexed component, or an
6509                --  explicit dereference, then the designated object could
6510                --  be modified by an assignment.
6511
6512                if Nkind_In (RO, N_Indexed_Component,
6513                                 N_Explicit_Dereference)
6514                then
6515                   return False;
6516
6517                --  A selected component must have a safe prefix
6518
6519                elsif Nkind (RO) = N_Selected_Component then
6520                   return Safe_Prefixed_Reference (RO);
6521
6522                --  In all other cases, designated object cannot be changed so
6523                --  we are side effect free.
6524
6525                else
6526                   return True;
6527                end if;
6528             end;
6529
6530          --  Remove_Side_Effects generates an object renaming declaration to
6531          --  capture the expression of a class-wide expression. In VM targets
6532          --  the frontend performs no expansion for dispatching calls to
6533          --  class- wide types since they are handled by the VM. Hence, we must
6534          --  locate here if this node corresponds to a previous invocation of
6535          --  Remove_Side_Effects to avoid a never ending loop in the frontend.
6536
6537          elsif VM_Target /= No_VM
6538             and then not Comes_From_Source (N)
6539             and then Nkind (Parent (N)) = N_Object_Renaming_Declaration
6540             and then Is_Class_Wide_Type (Etype (N))
6541          then
6542             return True;
6543          end if;
6544
6545          --  For other than entity names and compile time known values,
6546          --  check the node kind for special processing.
6547
6548          case Nkind (N) is
6549
6550             --  An attribute reference is side effect free if its expressions
6551             --  are side effect free and its prefix is side effect free or
6552             --  is an entity reference.
6553
6554             --  Is this right? what about x'first where x is a variable???
6555
6556             when N_Attribute_Reference =>
6557                return Side_Effect_Free (Expressions (N))
6558                  and then Attribute_Name (N) /= Name_Input
6559                  and then (Is_Entity_Name (Prefix (N))
6560                             or else Side_Effect_Free (Prefix (N)));
6561
6562             --  A binary operator is side effect free if and both operands are
6563             --  side effect free. For this purpose binary operators include
6564             --  membership tests and short circuit forms.
6565
6566             when N_Binary_Op | N_Membership_Test | N_Short_Circuit =>
6567                return Side_Effect_Free (Left_Opnd  (N))
6568                         and then
6569                       Side_Effect_Free (Right_Opnd (N));
6570
6571             --  An explicit dereference is side effect free only if it is
6572             --  a side effect free prefixed reference.
6573
6574             when N_Explicit_Dereference =>
6575                return Safe_Prefixed_Reference (N);
6576
6577             --  A call to _rep_to_pos is side effect free, since we generate
6578             --  this pure function call ourselves. Moreover it is critically
6579             --  important to make this exception, since otherwise we can have
6580             --  discriminants in array components which don't look side effect
6581             --  free in the case of an array whose index type is an enumeration
6582             --  type with an enumeration rep clause.
6583
6584             --  All other function calls are not side effect free
6585
6586             when N_Function_Call =>
6587                return Nkind (Name (N)) = N_Identifier
6588                  and then Is_TSS (Name (N), TSS_Rep_To_Pos)
6589                  and then
6590                    Side_Effect_Free (First (Parameter_Associations (N)));
6591
6592             --  An indexed component is side effect free if it is a side
6593             --  effect free prefixed reference and all the indexing
6594             --  expressions are side effect free.
6595
6596             when N_Indexed_Component =>
6597                return Side_Effect_Free (Expressions (N))
6598                  and then Safe_Prefixed_Reference (N);
6599
6600             --  A type qualification is side effect free if the expression
6601             --  is side effect free.
6602
6603             when N_Qualified_Expression =>
6604                return Side_Effect_Free (Expression (N));
6605
6606             --  A selected component is side effect free only if it is a side
6607             --  effect free prefixed reference. If it designates a component
6608             --  with a rep. clause it must be treated has having a potential
6609             --  side effect, because it may be modified through a renaming, and
6610             --  a subsequent use of the renaming as a macro will yield the
6611             --  wrong value. This complex interaction between renaming and
6612             --  removing side effects is a reminder that the latter has become
6613             --  a headache to maintain, and that it should be removed in favor
6614             --  of the gcc mechanism to capture values ???
6615
6616             when N_Selected_Component =>
6617                if Nkind (Parent (N)) = N_Explicit_Dereference
6618                  and then Has_Non_Standard_Rep (Designated_Type (Etype (N)))
6619                then
6620                   return False;
6621                else
6622                   return Safe_Prefixed_Reference (N);
6623                end if;
6624
6625             --  A range is side effect free if the bounds are side effect free
6626
6627             when N_Range =>
6628                return Side_Effect_Free (Low_Bound (N))
6629                  and then Side_Effect_Free (High_Bound (N));
6630
6631             --  A slice is side effect free if it is a side effect free
6632             --  prefixed reference and the bounds are side effect free.
6633
6634             when N_Slice =>
6635                return Side_Effect_Free (Discrete_Range (N))
6636                  and then Safe_Prefixed_Reference (N);
6637
6638             --  A type conversion is side effect free if the expression to be
6639             --  converted is side effect free.
6640
6641             when N_Type_Conversion =>
6642                return Side_Effect_Free (Expression (N));
6643
6644             --  A unary operator is side effect free if the operand
6645             --  is side effect free.
6646
6647             when N_Unary_Op =>
6648                return Side_Effect_Free (Right_Opnd (N));
6649
6650             --  An unchecked type conversion is side effect free only if it
6651             --  is safe and its argument is side effect free.
6652
6653             when N_Unchecked_Type_Conversion =>
6654                return Safe_Unchecked_Type_Conversion (N)
6655                  and then Side_Effect_Free (Expression (N));
6656
6657             --  An unchecked expression is side effect free if its expression
6658             --  is side effect free.
6659
6660             when N_Unchecked_Expression =>
6661                return Side_Effect_Free (Expression (N));
6662
6663             --  A literal is side effect free
6664
6665             when N_Character_Literal    |
6666                  N_Integer_Literal      |
6667                  N_Real_Literal         |
6668                  N_String_Literal       =>
6669                return True;
6670
6671             --  We consider that anything else has side effects. This is a bit
6672             --  crude, but we are pretty close for most common cases, and we
6673             --  are certainly correct (i.e. we never return True when the
6674             --  answer should be False).
6675
6676             when others =>
6677                return False;
6678          end case;
6679       end Side_Effect_Free;
6680
6681       --  A list is side effect free if all elements of the list are side
6682       --  effect free.
6683
6684       function Side_Effect_Free (L : List_Id) return Boolean is
6685          N : Node_Id;
6686
6687       begin
6688          if L = No_List or else L = Error_List then
6689             return True;
6690
6691          else
6692             N := First (L);
6693             while Present (N) loop
6694                if not Side_Effect_Free (N) then
6695                   return False;
6696                else
6697                   Next (N);
6698                end if;
6699             end loop;
6700
6701             return True;
6702          end if;
6703       end Side_Effect_Free;
6704
6705       -------------------------
6706       -- Within_In_Parameter --
6707       -------------------------
6708
6709       function Within_In_Parameter (N : Node_Id) return Boolean is
6710       begin
6711          if not Comes_From_Source (N) then
6712             return False;
6713
6714          elsif Is_Entity_Name (N) then
6715             return Ekind (Entity (N)) = E_In_Parameter;
6716
6717          elsif Nkind_In (N, N_Indexed_Component, N_Selected_Component) then
6718             return Within_In_Parameter (Prefix (N));
6719
6720          else
6721             return False;
6722          end if;
6723       end Within_In_Parameter;
6724
6725    --  Start of processing for Remove_Side_Effects
6726
6727    begin
6728       --  Handle cases in which there is nothing to do
6729
6730       if not Expander_Active then
6731          return;
6732       end if;
6733
6734       --  Cannot generate temporaries if the invocation to remove side effects
6735       --  was issued too early and the type of the expression is not resolved
6736       --  (this happens because routines Duplicate_Subexpr_XX implicitly invoke
6737       --  Remove_Side_Effects).
6738
6739       if No (Exp_Type)
6740         or else Ekind (Exp_Type) = E_Access_Attribute_Type
6741       then
6742          return;
6743
6744       --  No action needed for side-effect free expressions
6745
6746       elsif Side_Effect_Free (Exp) then
6747          return;
6748       end if;
6749
6750       --  The remaining procesaing is done with all checks suppressed
6751
6752       --  Note: from now on, don't use return statements, instead do a goto
6753       --  Leave, to ensure that we properly restore Scope_Suppress.Suppress.
6754
6755       Scope_Suppress.Suppress := (others => True);
6756
6757       --  If it is a scalar type and we need to capture the value, just make
6758       --  a copy. Likewise for a function call, an attribute reference, an
6759       --  allocator, or an operator. And if we have a volatile reference and
6760       --  Name_Req is not set (see comments above for Side_Effect_Free).
6761
6762       if Is_Elementary_Type (Exp_Type)
6763         and then (Variable_Ref
6764                    or else Nkind_In (Exp, N_Function_Call,
6765                                           N_Attribute_Reference,
6766                                           N_Allocator)
6767                    or else Nkind (Exp) in N_Op
6768                    or else (not Name_Req and then Is_Volatile_Reference (Exp)))
6769       then
6770          Def_Id := Make_Temporary (Loc, 'R', Exp);
6771          Set_Etype (Def_Id, Exp_Type);
6772          Res := New_Reference_To (Def_Id, Loc);
6773
6774          --  If the expression is a packed reference, it must be reanalyzed and
6775          --  expanded, depending on context. This is the case for actuals where
6776          --  a constraint check may capture the actual before expansion of the
6777          --  call is complete.
6778
6779          if Nkind (Exp) = N_Indexed_Component
6780            and then Is_Packed (Etype (Prefix (Exp)))
6781          then
6782             Set_Analyzed (Exp, False);
6783             Set_Analyzed (Prefix (Exp), False);
6784          end if;
6785
6786          E :=
6787            Make_Object_Declaration (Loc,
6788              Defining_Identifier => Def_Id,
6789              Object_Definition   => New_Reference_To (Exp_Type, Loc),
6790              Constant_Present    => True,
6791              Expression          => Relocate_Node (Exp));
6792
6793          Set_Assignment_OK (E);
6794          Insert_Action (Exp, E);
6795
6796       --  If the expression has the form v.all then we can just capture the
6797       --  pointer, and then do an explicit dereference on the result.
6798
6799       elsif Nkind (Exp) = N_Explicit_Dereference then
6800          Def_Id := Make_Temporary (Loc, 'R', Exp);
6801          Res :=
6802            Make_Explicit_Dereference (Loc, New_Reference_To (Def_Id, Loc));
6803
6804          Insert_Action (Exp,
6805            Make_Object_Declaration (Loc,
6806              Defining_Identifier => Def_Id,
6807              Object_Definition   =>
6808                New_Reference_To (Etype (Prefix (Exp)), Loc),
6809              Constant_Present    => True,
6810              Expression          => Relocate_Node (Prefix (Exp))));
6811
6812       --  Similar processing for an unchecked conversion of an expression of
6813       --  the form v.all, where we want the same kind of treatment.
6814
6815       elsif Nkind (Exp) = N_Unchecked_Type_Conversion
6816         and then Nkind (Expression (Exp)) = N_Explicit_Dereference
6817       then
6818          Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
6819          goto Leave;
6820
6821       --  If this is a type conversion, leave the type conversion and remove
6822       --  the side effects in the expression. This is important in several
6823       --  circumstances: for change of representations, and also when this is a
6824       --  view conversion to a smaller object, where gigi can end up creating
6825       --  its own temporary of the wrong size.
6826
6827       elsif Nkind (Exp) = N_Type_Conversion then
6828          Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
6829          goto Leave;
6830
6831       --  If this is an unchecked conversion that Gigi can't handle, make
6832       --  a copy or a use a renaming to capture the value.
6833
6834       elsif Nkind (Exp) = N_Unchecked_Type_Conversion
6835         and then not Safe_Unchecked_Type_Conversion (Exp)
6836       then
6837          if CW_Or_Has_Controlled_Part (Exp_Type) then
6838
6839             --  Use a renaming to capture the expression, rather than create
6840             --  a controlled temporary.
6841
6842             Def_Id := Make_Temporary (Loc, 'R', Exp);
6843             Res := New_Reference_To (Def_Id, Loc);
6844
6845             Insert_Action (Exp,
6846               Make_Object_Renaming_Declaration (Loc,
6847                 Defining_Identifier => Def_Id,
6848                 Subtype_Mark        => New_Reference_To (Exp_Type, Loc),
6849                 Name                => Relocate_Node (Exp)));
6850
6851          else
6852             Def_Id := Make_Temporary (Loc, 'R', Exp);
6853             Set_Etype (Def_Id, Exp_Type);
6854             Res := New_Reference_To (Def_Id, Loc);
6855
6856             E :=
6857               Make_Object_Declaration (Loc,
6858                 Defining_Identifier => Def_Id,
6859                 Object_Definition   => New_Reference_To (Exp_Type, Loc),
6860                 Constant_Present    => not Is_Variable (Exp),
6861                 Expression          => Relocate_Node (Exp));
6862
6863             Set_Assignment_OK (E);
6864             Insert_Action (Exp, E);
6865          end if;
6866
6867       --  For expressions that denote objects, we can use a renaming scheme.
6868       --  This is needed for correctness in the case of a volatile object of
6869       --  a non-volatile type because the Make_Reference call of the "default"
6870       --  approach would generate an illegal access value (an access value
6871       --  cannot designate such an object - see Analyze_Reference). We skip
6872       --  using this scheme if we have an object of a volatile type and we do
6873       --  not have Name_Req set true (see comments above for Side_Effect_Free).
6874
6875       --  In Ada 2012 a qualified expression is an object, but for purposes of
6876       --  removing side effects it still need to be transformed into a separate
6877       --  declaration, particularly if the expression is an aggregate.
6878
6879       elsif Is_Object_Reference (Exp)
6880         and then Nkind (Exp) /= N_Function_Call
6881         and then Nkind (Exp) /= N_Qualified_Expression
6882         and then (Name_Req or else not Treat_As_Volatile (Exp_Type))
6883       then
6884          Def_Id := Make_Temporary (Loc, 'R', Exp);
6885
6886          if Nkind (Exp) = N_Selected_Component
6887            and then Nkind (Prefix (Exp)) = N_Function_Call
6888            and then Is_Array_Type (Exp_Type)
6889          then
6890             --  Avoid generating a variable-sized temporary, by generating
6891             --  the renaming declaration just for the function call. The
6892             --  transformation could be refined to apply only when the array
6893             --  component is constrained by a discriminant???
6894
6895             Res :=
6896               Make_Selected_Component (Loc,
6897                 Prefix => New_Occurrence_Of (Def_Id, Loc),
6898                 Selector_Name => Selector_Name (Exp));
6899
6900             Insert_Action (Exp,
6901               Make_Object_Renaming_Declaration (Loc,
6902                 Defining_Identifier => Def_Id,
6903                 Subtype_Mark        =>
6904                   New_Reference_To (Base_Type (Etype (Prefix (Exp))), Loc),
6905                 Name                => Relocate_Node (Prefix (Exp))));
6906
6907          else
6908             Res := New_Reference_To (Def_Id, Loc);
6909
6910             Insert_Action (Exp,
6911               Make_Object_Renaming_Declaration (Loc,
6912                 Defining_Identifier => Def_Id,
6913                 Subtype_Mark        => New_Reference_To (Exp_Type, Loc),
6914                 Name                => Relocate_Node (Exp)));
6915          end if;
6916
6917          --  If this is a packed reference, or a selected component with
6918          --  a non-standard representation, a reference to the temporary
6919          --  will be replaced by a copy of the original expression (see
6920          --  Exp_Ch2.Expand_Renaming). Otherwise the temporary must be
6921          --  elaborated by gigi, and is of course not to be replaced in-line
6922          --  by the expression it renames, which would defeat the purpose of
6923          --  removing the side-effect.
6924
6925          if Nkind_In (Exp, N_Selected_Component, N_Indexed_Component)
6926            and then Has_Non_Standard_Rep (Etype (Prefix (Exp)))
6927          then
6928             null;
6929          else
6930             Set_Is_Renaming_Of_Object (Def_Id, False);
6931          end if;
6932
6933       --  Otherwise we generate a reference to the value
6934
6935       else
6936          --  An expression which is in Alfa mode is considered side effect free
6937          --  if the resulting value is captured by a variable or a constant.
6938
6939          if Alfa_Mode and then Nkind (Parent (Exp)) = N_Object_Declaration then
6940             goto Leave;
6941          end if;
6942
6943          --  Special processing for function calls that return a limited type.
6944          --  We need to build a declaration that will enable build-in-place
6945          --  expansion of the call. This is not done if the context is already
6946          --  an object declaration, to prevent infinite recursion.
6947
6948          --  This is relevant only in Ada 2005 mode. In Ada 95 programs we have
6949          --  to accommodate functions returning limited objects by reference.
6950
6951          if Ada_Version >= Ada_2005
6952            and then Nkind (Exp) = N_Function_Call
6953            and then Is_Immutably_Limited_Type (Etype (Exp))
6954            and then Nkind (Parent (Exp)) /= N_Object_Declaration
6955          then
6956             declare
6957                Obj  : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
6958                Decl : Node_Id;
6959
6960             begin
6961                Decl :=
6962                  Make_Object_Declaration (Loc,
6963                    Defining_Identifier => Obj,
6964                    Object_Definition   => New_Occurrence_Of (Exp_Type, Loc),
6965                    Expression          => Relocate_Node (Exp));
6966
6967                Insert_Action (Exp, Decl);
6968                Set_Etype (Obj, Exp_Type);
6969                Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
6970                goto Leave;
6971             end;
6972          end if;
6973
6974          Def_Id := Make_Temporary (Loc, 'R', Exp);
6975          Set_Etype (Def_Id, Exp_Type);
6976
6977          --  The regular expansion of functions with side effects involves the
6978          --  generation of an access type to capture the return value found on
6979          --  the secondary stack. Since Alfa (and why) cannot process access
6980          --  types, use a different approach which ignores the secondary stack
6981          --  and "copies" the returned object.
6982
6983          if Alfa_Mode then
6984             Res := New_Reference_To (Def_Id, Loc);
6985             Ref_Type := Exp_Type;
6986
6987          --  Regular expansion utilizing an access type and 'reference
6988
6989          else
6990             Res :=
6991               Make_Explicit_Dereference (Loc,
6992                 Prefix => New_Reference_To (Def_Id, Loc));
6993
6994             --  Generate:
6995             --    type Ann is access all <Exp_Type>;
6996
6997             Ref_Type := Make_Temporary (Loc, 'A');
6998
6999             Ptr_Typ_Decl :=
7000               Make_Full_Type_Declaration (Loc,
7001                 Defining_Identifier => Ref_Type,
7002                 Type_Definition     =>
7003                   Make_Access_To_Object_Definition (Loc,
7004                     All_Present        => True,
7005                     Subtype_Indication =>
7006                       New_Reference_To (Exp_Type, Loc)));
7007
7008             Insert_Action (Exp, Ptr_Typ_Decl);
7009          end if;
7010
7011          E := Exp;
7012          if Nkind (E) = N_Explicit_Dereference then
7013             New_Exp := Relocate_Node (Prefix (E));
7014          else
7015             E := Relocate_Node (E);
7016
7017             --  Do not generate a 'reference in Alfa mode since the access type
7018             --  is not created in the first place.
7019
7020             if Alfa_Mode then
7021                New_Exp := E;
7022
7023             --  Otherwise generate reference, marking the value as non-null
7024             --  since we know it cannot be null and we don't want a check.
7025
7026             else
7027                New_Exp := Make_Reference (Loc, E);
7028                Set_Is_Known_Non_Null (Def_Id);
7029             end if;
7030          end if;
7031
7032          if Is_Delayed_Aggregate (E) then
7033
7034             --  The expansion of nested aggregates is delayed until the
7035             --  enclosing aggregate is expanded. As aggregates are often
7036             --  qualified, the predicate applies to qualified expressions as
7037             --  well, indicating that the enclosing aggregate has not been
7038             --  expanded yet. At this point the aggregate is part of a
7039             --  stand-alone declaration, and must be fully expanded.
7040
7041             if Nkind (E) = N_Qualified_Expression then
7042                Set_Expansion_Delayed (Expression (E), False);
7043                Set_Analyzed (Expression (E), False);
7044             else
7045                Set_Expansion_Delayed (E, False);
7046             end if;
7047
7048             Set_Analyzed (E, False);
7049          end if;
7050
7051          Insert_Action (Exp,
7052            Make_Object_Declaration (Loc,
7053              Defining_Identifier => Def_Id,
7054              Object_Definition   => New_Reference_To (Ref_Type, Loc),
7055              Constant_Present    => True,
7056              Expression          => New_Exp));
7057       end if;
7058
7059       --  Preserve the Assignment_OK flag in all copies, since at least one
7060       --  copy may be used in a context where this flag must be set (otherwise
7061       --  why would the flag be set in the first place).
7062
7063       Set_Assignment_OK (Res, Assignment_OK (Exp));
7064
7065       --  Finally rewrite the original expression and we are done
7066
7067       Rewrite (Exp, Res);
7068       Analyze_And_Resolve (Exp, Exp_Type);
7069
7070    <<Leave>>
7071       Scope_Suppress := Svg_Suppress;
7072    end Remove_Side_Effects;
7073
7074    ---------------------------
7075    -- Represented_As_Scalar --
7076    ---------------------------
7077
7078    function Represented_As_Scalar (T : Entity_Id) return Boolean is
7079       UT : constant Entity_Id := Underlying_Type (T);
7080    begin
7081       return Is_Scalar_Type (UT)
7082         or else (Is_Bit_Packed_Array (UT)
7083                   and then Is_Scalar_Type (Packed_Array_Type (UT)));
7084    end Represented_As_Scalar;
7085
7086    ------------------------------
7087    -- Requires_Cleanup_Actions --
7088    ------------------------------
7089
7090    function Requires_Cleanup_Actions
7091      (N         : Node_Id;
7092       Lib_Level : Boolean) return Boolean
7093    is
7094       At_Lib_Level : constant Boolean :=
7095                        Lib_Level
7096                          and then Nkind_In (N, N_Package_Body,
7097                                                N_Package_Specification);
7098       --  N is at the library level if the top-most context is a package and
7099       --  the path taken to reach N does not inlcude non-package constructs.
7100
7101    begin
7102       case Nkind (N) is
7103          when N_Accept_Statement      |
7104               N_Block_Statement       |
7105               N_Entry_Body            |
7106               N_Package_Body          |
7107               N_Protected_Body        |
7108               N_Subprogram_Body       |
7109               N_Task_Body             =>
7110             return
7111               Requires_Cleanup_Actions (Declarations (N), At_Lib_Level, True)
7112                 or else
7113                   (Present (Handled_Statement_Sequence (N))
7114                     and then
7115                       Requires_Cleanup_Actions
7116                         (Statements (Handled_Statement_Sequence (N)),
7117                          At_Lib_Level, True));
7118
7119          when N_Package_Specification =>
7120             return
7121               Requires_Cleanup_Actions
7122                 (Visible_Declarations (N), At_Lib_Level, True)
7123                   or else
7124               Requires_Cleanup_Actions
7125                 (Private_Declarations (N), At_Lib_Level, True);
7126
7127          when others                  =>
7128             return False;
7129       end case;
7130    end Requires_Cleanup_Actions;
7131
7132    ------------------------------
7133    -- Requires_Cleanup_Actions --
7134    ------------------------------
7135
7136    function Requires_Cleanup_Actions
7137      (L                 : List_Id;
7138       Lib_Level         : Boolean;
7139       Nested_Constructs : Boolean) return Boolean
7140    is
7141       Decl    : Node_Id;
7142       Expr    : Node_Id;
7143       Obj_Id  : Entity_Id;
7144       Obj_Typ : Entity_Id;
7145       Pack_Id : Entity_Id;
7146       Typ     : Entity_Id;
7147
7148    begin
7149       if No (L)
7150         or else Is_Empty_List (L)
7151       then
7152          return False;
7153       end if;
7154
7155       Decl := First (L);
7156       while Present (Decl) loop
7157
7158          --  Library-level tagged types
7159
7160          if Nkind (Decl) = N_Full_Type_Declaration then
7161             Typ := Defining_Identifier (Decl);
7162
7163             if Is_Tagged_Type (Typ)
7164               and then Is_Library_Level_Entity (Typ)
7165               and then Convention (Typ) = Convention_Ada
7166               and then Present (Access_Disp_Table (Typ))
7167               and then RTE_Available (RE_Unregister_Tag)
7168               and then not No_Run_Time_Mode
7169               and then not Is_Abstract_Type (Typ)
7170             then
7171                return True;
7172             end if;
7173
7174          --  Regular object declarations
7175
7176          elsif Nkind (Decl) = N_Object_Declaration then
7177             Obj_Id  := Defining_Identifier (Decl);
7178             Obj_Typ := Base_Type (Etype (Obj_Id));
7179             Expr    := Expression (Decl);
7180
7181             --  Bypass any form of processing for objects which have their
7182             --  finalization disabled. This applies only to objects at the
7183             --  library level.
7184
7185             if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
7186                null;
7187
7188             --  Transient variables are treated separately in order to minimize
7189             --  the size of the generated code. See Exp_Ch7.Process_Transient_
7190             --  Objects.
7191
7192             elsif Is_Processed_Transient (Obj_Id) then
7193                null;
7194
7195             --  The object is of the form:
7196             --    Obj : Typ [:= Expr];
7197             --
7198             --  Do not process the incomplete view of a deferred constant. Do
7199             --  not consider tag-to-class-wide conversions.
7200
7201             elsif not Is_Imported (Obj_Id)
7202               and then Needs_Finalization (Obj_Typ)
7203               and then not (Ekind (Obj_Id) = E_Constant
7204                              and then not Has_Completion (Obj_Id))
7205               and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
7206             then
7207                return True;
7208
7209             --  The object is of the form:
7210             --    Obj : Access_Typ := Non_BIP_Function_Call'reference;
7211             --
7212             --    Obj : Access_Typ :=
7213             --            BIP_Function_Call (BIPalloc => 2, ...)'reference;
7214
7215             elsif Is_Access_Type (Obj_Typ)
7216               and then Needs_Finalization
7217                          (Available_View (Designated_Type (Obj_Typ)))
7218               and then Present (Expr)
7219               and then
7220                 (Is_Secondary_Stack_BIP_Func_Call (Expr)
7221                   or else
7222                     (Is_Non_BIP_Func_Call (Expr)
7223                       and then not Is_Related_To_Func_Return (Obj_Id)))
7224             then
7225                return True;
7226
7227             --  Processing for "hook" objects generated for controlled
7228             --  transients declared inside an Expression_With_Actions.
7229
7230             elsif Is_Access_Type (Obj_Typ)
7231               and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
7232               and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
7233                                                       N_Object_Declaration
7234               and then Is_Finalizable_Transient
7235                          (Status_Flag_Or_Transient_Decl (Obj_Id), Decl)
7236             then
7237                return True;
7238
7239             --  Processing for intermediate results of if expressions where
7240             --  one of the alternatives uses a controlled function call.
7241
7242             elsif Is_Access_Type (Obj_Typ)
7243               and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
7244               and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
7245                                                       N_Defining_Identifier
7246               and then Present (Expr)
7247               and then Nkind (Expr) = N_Null
7248             then
7249                return True;
7250
7251             --  Simple protected objects which use type System.Tasking.
7252             --  Protected_Objects.Protection to manage their locks should be
7253             --  treated as controlled since they require manual cleanup.
7254
7255             elsif Ekind (Obj_Id) = E_Variable
7256               and then
7257                 (Is_Simple_Protected_Type (Obj_Typ)
7258                   or else Has_Simple_Protected_Object (Obj_Typ))
7259             then
7260                return True;
7261             end if;
7262
7263          --  Specific cases of object renamings
7264
7265          elsif Nkind (Decl) = N_Object_Renaming_Declaration then
7266             Obj_Id  := Defining_Identifier (Decl);
7267             Obj_Typ := Base_Type (Etype (Obj_Id));
7268
7269             --  Bypass any form of processing for objects which have their
7270             --  finalization disabled. This applies only to objects at the
7271             --  library level.
7272
7273             if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
7274                null;
7275
7276             --  Return object of a build-in-place function. This case is
7277             --  recognized and marked by the expansion of an extended return
7278             --  statement (see Expand_N_Extended_Return_Statement).
7279
7280             elsif Needs_Finalization (Obj_Typ)
7281               and then Is_Return_Object (Obj_Id)
7282               and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
7283             then
7284                return True;
7285
7286             --  Detect a case where a source object has been initialized by
7287             --  a controlled function call or another object which was later
7288             --  rewritten as a class-wide conversion of Ada.Tags.Displace.
7289
7290             --     Obj1 : CW_Type := Src_Obj;
7291             --     Obj2 : CW_Type := Function_Call (...);
7292
7293             --     Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
7294             --     Tmp  : ... := Function_Call (...)'reference;
7295             --     Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
7296
7297             elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
7298                return True;
7299             end if;
7300
7301          --  Inspect the freeze node of an access-to-controlled type and look
7302          --  for a delayed finalization master. This case arises when the
7303          --  freeze actions are inserted at a later time than the expansion of
7304          --  the context. Since Build_Finalizer is never called on a single
7305          --  construct twice, the master will be ultimately left out and never
7306          --  finalized. This is also needed for freeze actions of designated
7307          --  types themselves, since in some cases the finalization master is
7308          --  associated with a designated type's freeze node rather than that
7309          --  of the access type (see handling for freeze actions in
7310          --  Build_Finalization_Master).
7311
7312          elsif Nkind (Decl) = N_Freeze_Entity
7313            and then Present (Actions (Decl))
7314          then
7315             Typ := Entity (Decl);
7316
7317             if ((Is_Access_Type (Typ)
7318                   and then not Is_Access_Subprogram_Type (Typ)
7319                   and then Needs_Finalization
7320                              (Available_View (Designated_Type (Typ))))
7321                or else
7322                 (Is_Type (Typ)
7323                   and then Needs_Finalization (Typ)))
7324               and then Requires_Cleanup_Actions
7325                          (Actions (Decl), Lib_Level, Nested_Constructs)
7326             then
7327                return True;
7328             end if;
7329
7330          --  Nested package declarations
7331
7332          elsif Nested_Constructs
7333            and then Nkind (Decl) = N_Package_Declaration
7334          then
7335             Pack_Id := Defining_Unit_Name (Specification (Decl));
7336
7337             if Nkind (Pack_Id) = N_Defining_Program_Unit_Name then
7338                Pack_Id := Defining_Identifier (Pack_Id);
7339             end if;
7340
7341             if Ekind (Pack_Id) /= E_Generic_Package
7342               and then
7343                 Requires_Cleanup_Actions (Specification (Decl), Lib_Level)
7344             then
7345                return True;
7346             end if;
7347
7348          --  Nested package bodies
7349
7350          elsif Nested_Constructs and then Nkind (Decl) = N_Package_Body then
7351             Pack_Id := Corresponding_Spec (Decl);
7352
7353             if Ekind (Pack_Id) /= E_Generic_Package
7354               and then Requires_Cleanup_Actions (Decl, Lib_Level)
7355             then
7356                return True;
7357             end if;
7358          end if;
7359
7360          Next (Decl);
7361       end loop;
7362
7363       return False;
7364    end Requires_Cleanup_Actions;
7365
7366    ------------------------------------
7367    -- Safe_Unchecked_Type_Conversion --
7368    ------------------------------------
7369
7370    --  Note: this function knows quite a bit about the exact requirements of
7371    --  Gigi with respect to unchecked type conversions, and its code must be
7372    --  coordinated with any changes in Gigi in this area.
7373
7374    --  The above requirements should be documented in Sinfo ???
7375
7376    function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
7377       Otyp   : Entity_Id;
7378       Ityp   : Entity_Id;
7379       Oalign : Uint;
7380       Ialign : Uint;
7381       Pexp   : constant Node_Id := Parent (Exp);
7382
7383    begin
7384       --  If the expression is the RHS of an assignment or object declaration
7385       --   we are always OK because there will always be a target.
7386
7387       --  Object renaming declarations, (generated for view conversions of
7388       --  actuals in inlined calls), like object declarations, provide an
7389       --  explicit type, and are safe as well.
7390
7391       if (Nkind (Pexp) = N_Assignment_Statement
7392            and then Expression (Pexp) = Exp)
7393         or else Nkind_In (Pexp, N_Object_Declaration,
7394                                 N_Object_Renaming_Declaration)
7395       then
7396          return True;
7397
7398       --  If the expression is the prefix of an N_Selected_Component we should
7399       --  also be OK because GCC knows to look inside the conversion except if
7400       --  the type is discriminated. We assume that we are OK anyway if the
7401       --  type is not set yet or if it is controlled since we can't afford to
7402       --  introduce a temporary in this case.
7403
7404       elsif Nkind (Pexp) = N_Selected_Component
7405         and then Prefix (Pexp) = Exp
7406       then
7407          if No (Etype (Pexp)) then
7408             return True;
7409          else
7410             return
7411               not Has_Discriminants (Etype (Pexp))
7412                 or else Is_Constrained (Etype (Pexp));
7413          end if;
7414       end if;
7415
7416       --  Set the output type, this comes from Etype if it is set, otherwise we
7417       --  take it from the subtype mark, which we assume was already fully
7418       --  analyzed.
7419
7420       if Present (Etype (Exp)) then
7421          Otyp := Etype (Exp);
7422       else
7423          Otyp := Entity (Subtype_Mark (Exp));
7424       end if;
7425
7426       --  The input type always comes from the expression, and we assume
7427       --  this is indeed always analyzed, so we can simply get the Etype.
7428
7429       Ityp := Etype (Expression (Exp));
7430
7431       --  Initialize alignments to unknown so far
7432
7433       Oalign := No_Uint;
7434       Ialign := No_Uint;
7435
7436       --  Replace a concurrent type by its corresponding record type and each
7437       --  type by its underlying type and do the tests on those. The original
7438       --  type may be a private type whose completion is a concurrent type, so
7439       --  find the underlying type first.
7440
7441       if Present (Underlying_Type (Otyp)) then
7442          Otyp := Underlying_Type (Otyp);
7443       end if;
7444
7445       if Present (Underlying_Type (Ityp)) then
7446          Ityp := Underlying_Type (Ityp);
7447       end if;
7448
7449       if Is_Concurrent_Type (Otyp) then
7450          Otyp := Corresponding_Record_Type (Otyp);
7451       end if;
7452
7453       if Is_Concurrent_Type (Ityp) then
7454          Ityp := Corresponding_Record_Type (Ityp);
7455       end if;
7456
7457       --  If the base types are the same, we know there is no problem since
7458       --  this conversion will be a noop.
7459
7460       if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
7461          return True;
7462
7463       --  Same if this is an upwards conversion of an untagged type, and there
7464       --  are no constraints involved (could be more general???)
7465
7466       elsif Etype (Ityp) = Otyp
7467         and then not Is_Tagged_Type (Ityp)
7468         and then not Has_Discriminants (Ityp)
7469         and then No (First_Rep_Item (Base_Type (Ityp)))
7470       then
7471          return True;
7472
7473       --  If the expression has an access type (object or subprogram) we assume
7474       --  that the conversion is safe, because the size of the target is safe,
7475       --  even if it is a record (which might be treated as having unknown size
7476       --  at this point).
7477
7478       elsif Is_Access_Type (Ityp) then
7479          return True;
7480
7481       --  If the size of output type is known at compile time, there is never
7482       --  a problem. Note that unconstrained records are considered to be of
7483       --  known size, but we can't consider them that way here, because we are
7484       --  talking about the actual size of the object.
7485
7486       --  We also make sure that in addition to the size being known, we do not
7487       --  have a case which might generate an embarrassingly large temp in
7488       --  stack checking mode.
7489
7490       elsif Size_Known_At_Compile_Time (Otyp)
7491         and then
7492           (not Stack_Checking_Enabled
7493             or else not May_Generate_Large_Temp (Otyp))
7494         and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
7495       then
7496          return True;
7497
7498       --  If either type is tagged, then we know the alignment is OK so
7499       --  Gigi will be able to use pointer punning.
7500
7501       elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
7502          return True;
7503
7504       --  If either type is a limited record type, we cannot do a copy, so say
7505       --  safe since there's nothing else we can do.
7506
7507       elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
7508          return True;
7509
7510       --  Conversions to and from packed array types are always ignored and
7511       --  hence are safe.
7512
7513       elsif Is_Packed_Array_Type (Otyp)
7514         or else Is_Packed_Array_Type (Ityp)
7515       then
7516          return True;
7517       end if;
7518
7519       --  The only other cases known to be safe is if the input type's
7520       --  alignment is known to be at least the maximum alignment for the
7521       --  target or if both alignments are known and the output type's
7522       --  alignment is no stricter than the input's. We can use the component
7523       --  type alignement for an array if a type is an unpacked array type.
7524
7525       if Present (Alignment_Clause (Otyp)) then
7526          Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
7527
7528       elsif Is_Array_Type (Otyp)
7529         and then Present (Alignment_Clause (Component_Type (Otyp)))
7530       then
7531          Oalign := Expr_Value (Expression (Alignment_Clause
7532                                            (Component_Type (Otyp))));
7533       end if;
7534
7535       if Present (Alignment_Clause (Ityp)) then
7536          Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
7537
7538       elsif Is_Array_Type (Ityp)
7539         and then Present (Alignment_Clause (Component_Type (Ityp)))
7540       then
7541          Ialign := Expr_Value (Expression (Alignment_Clause
7542                                            (Component_Type (Ityp))));
7543       end if;
7544
7545       if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
7546          return True;
7547
7548       elsif Ialign /= No_Uint and then Oalign /= No_Uint
7549         and then Ialign <= Oalign
7550       then
7551          return True;
7552
7553       --   Otherwise, Gigi cannot handle this and we must make a temporary
7554
7555       else
7556          return False;
7557       end if;
7558    end Safe_Unchecked_Type_Conversion;
7559
7560    ---------------------------------
7561    -- Set_Current_Value_Condition --
7562    ---------------------------------
7563
7564    --  Note: the implementation of this procedure is very closely tied to the
7565    --  implementation of Get_Current_Value_Condition. Here we set required
7566    --  Current_Value fields, and in Get_Current_Value_Condition, we interpret
7567    --  them, so they must have a consistent view.
7568
7569    procedure Set_Current_Value_Condition (Cnode : Node_Id) is
7570
7571       procedure Set_Entity_Current_Value (N : Node_Id);
7572       --  If N is an entity reference, where the entity is of an appropriate
7573       --  kind, then set the current value of this entity to Cnode, unless
7574       --  there is already a definite value set there.
7575
7576       procedure Set_Expression_Current_Value (N : Node_Id);
7577       --  If N is of an appropriate form, sets an appropriate entry in current
7578       --  value fields of relevant entities. Multiple entities can be affected
7579       --  in the case of an AND or AND THEN.
7580
7581       ------------------------------
7582       -- Set_Entity_Current_Value --
7583       ------------------------------
7584
7585       procedure Set_Entity_Current_Value (N : Node_Id) is
7586       begin
7587          if Is_Entity_Name (N) then
7588             declare
7589                Ent : constant Entity_Id := Entity (N);
7590
7591             begin
7592                --  Don't capture if not safe to do so
7593
7594                if not Safe_To_Capture_Value (N, Ent, Cond => True) then
7595                   return;
7596                end if;
7597
7598                --  Here we have a case where the Current_Value field may need
7599                --  to be set. We set it if it is not already set to a compile
7600                --  time expression value.
7601
7602                --  Note that this represents a decision that one condition
7603                --  blots out another previous one. That's certainly right if
7604                --  they occur at the same level. If the second one is nested,
7605                --  then the decision is neither right nor wrong (it would be
7606                --  equally OK to leave the outer one in place, or take the new
7607                --  inner one. Really we should record both, but our data
7608                --  structures are not that elaborate.
7609
7610                if Nkind (Current_Value (Ent)) not in N_Subexpr then
7611                   Set_Current_Value (Ent, Cnode);
7612                end if;
7613             end;
7614          end if;
7615       end Set_Entity_Current_Value;
7616
7617       ----------------------------------
7618       -- Set_Expression_Current_Value --
7619       ----------------------------------
7620
7621       procedure Set_Expression_Current_Value (N : Node_Id) is
7622          Cond : Node_Id;
7623
7624       begin
7625          Cond := N;
7626
7627          --  Loop to deal with (ignore for now) any NOT operators present. The
7628          --  presence of NOT operators will be handled properly when we call
7629          --  Get_Current_Value_Condition.
7630
7631          while Nkind (Cond) = N_Op_Not loop
7632             Cond := Right_Opnd (Cond);
7633          end loop;
7634
7635          --  For an AND or AND THEN, recursively process operands
7636
7637          if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
7638             Set_Expression_Current_Value (Left_Opnd (Cond));
7639             Set_Expression_Current_Value (Right_Opnd (Cond));
7640             return;
7641          end if;
7642
7643          --  Check possible relational operator
7644
7645          if Nkind (Cond) in N_Op_Compare then
7646             if Compile_Time_Known_Value (Right_Opnd (Cond)) then
7647                Set_Entity_Current_Value (Left_Opnd (Cond));
7648             elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
7649                Set_Entity_Current_Value (Right_Opnd (Cond));
7650             end if;
7651
7652             --  Check possible boolean variable reference
7653
7654          else
7655             Set_Entity_Current_Value (Cond);
7656          end if;
7657       end Set_Expression_Current_Value;
7658
7659    --  Start of processing for Set_Current_Value_Condition
7660
7661    begin
7662       Set_Expression_Current_Value (Condition (Cnode));
7663    end Set_Current_Value_Condition;
7664
7665    --------------------------
7666    -- Set_Elaboration_Flag --
7667    --------------------------
7668
7669    procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
7670       Loc : constant Source_Ptr := Sloc (N);
7671       Ent : constant Entity_Id  := Elaboration_Entity (Spec_Id);
7672       Asn : Node_Id;
7673
7674    begin
7675       if Present (Ent) then
7676
7677          --  Nothing to do if at the compilation unit level, because in this
7678          --  case the flag is set by the binder generated elaboration routine.
7679
7680          if Nkind (Parent (N)) = N_Compilation_Unit then
7681             null;
7682
7683          --  Here we do need to generate an assignment statement
7684
7685          else
7686             Check_Restriction (No_Elaboration_Code, N);
7687             Asn :=
7688               Make_Assignment_Statement (Loc,
7689                 Name       => New_Occurrence_Of (Ent, Loc),
7690                 Expression => Make_Integer_Literal (Loc, Uint_1));
7691
7692             if Nkind (Parent (N)) = N_Subunit then
7693                Insert_After (Corresponding_Stub (Parent (N)), Asn);
7694             else
7695                Insert_After (N, Asn);
7696             end if;
7697
7698             Analyze (Asn);
7699
7700             --  Kill current value indication. This is necessary because the
7701             --  tests of this flag are inserted out of sequence and must not
7702             --  pick up bogus indications of the wrong constant value.
7703
7704             Set_Current_Value (Ent, Empty);
7705          end if;
7706       end if;
7707    end Set_Elaboration_Flag;
7708
7709    ----------------------------
7710    -- Set_Renamed_Subprogram --
7711    ----------------------------
7712
7713    procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
7714    begin
7715       --  If input node is an identifier, we can just reset it
7716
7717       if Nkind (N) = N_Identifier then
7718          Set_Chars  (N, Chars (E));
7719          Set_Entity (N, E);
7720
7721          --  Otherwise we have to do a rewrite, preserving Comes_From_Source
7722
7723       else
7724          declare
7725             CS : constant Boolean := Comes_From_Source (N);
7726          begin
7727             Rewrite (N, Make_Identifier (Sloc (N), Chars (E)));
7728             Set_Entity (N, E);
7729             Set_Comes_From_Source (N, CS);
7730             Set_Analyzed (N, True);
7731          end;
7732       end if;
7733    end Set_Renamed_Subprogram;
7734
7735    ----------------------------------
7736    -- Silly_Boolean_Array_Not_Test --
7737    ----------------------------------
7738
7739    --  This procedure implements an odd and silly test. We explicitly check
7740    --  for the case where the 'First of the component type is equal to the
7741    --  'Last of this component type, and if this is the case, we make sure
7742    --  that constraint error is raised. The reason is that the NOT is bound
7743    --  to cause CE in this case, and we will not otherwise catch it.
7744
7745    --  No such check is required for AND and OR, since for both these cases
7746    --  False op False = False, and True op True = True. For the XOR case,
7747    --  see Silly_Boolean_Array_Xor_Test.
7748
7749    --  Believe it or not, this was reported as a bug. Note that nearly always,
7750    --  the test will evaluate statically to False, so the code will be
7751    --  statically removed, and no extra overhead caused.
7752
7753    procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
7754       Loc : constant Source_Ptr := Sloc (N);
7755       CT  : constant Entity_Id  := Component_Type (T);
7756
7757    begin
7758       --  The check we install is
7759
7760       --    constraint_error when
7761       --      component_type'first = component_type'last
7762       --        and then array_type'Length /= 0)
7763
7764       --  We need the last guard because we don't want to raise CE for empty
7765       --  arrays since no out of range values result. (Empty arrays with a
7766       --  component type of True .. True -- very useful -- even the ACATS
7767       --  does not test that marginal case!)
7768
7769       Insert_Action (N,
7770         Make_Raise_Constraint_Error (Loc,
7771           Condition =>
7772             Make_And_Then (Loc,
7773               Left_Opnd =>
7774                 Make_Op_Eq (Loc,
7775                   Left_Opnd =>
7776                     Make_Attribute_Reference (Loc,
7777                       Prefix         => New_Occurrence_Of (CT, Loc),
7778                       Attribute_Name => Name_First),
7779
7780                   Right_Opnd =>
7781                     Make_Attribute_Reference (Loc,
7782                       Prefix         => New_Occurrence_Of (CT, Loc),
7783                       Attribute_Name => Name_Last)),
7784
7785               Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
7786           Reason => CE_Range_Check_Failed));
7787    end Silly_Boolean_Array_Not_Test;
7788
7789    ----------------------------------
7790    -- Silly_Boolean_Array_Xor_Test --
7791    ----------------------------------
7792
7793    --  This procedure implements an odd and silly test. We explicitly check
7794    --  for the XOR case where the component type is True .. True, since this
7795    --  will raise constraint error. A special check is required since CE
7796    --  will not be generated otherwise (cf Expand_Packed_Not).
7797
7798    --  No such check is required for AND and OR, since for both these cases
7799    --  False op False = False, and True op True = True, and no check is
7800    --  required for the case of False .. False, since False xor False = False.
7801    --  See also Silly_Boolean_Array_Not_Test
7802
7803    procedure Silly_Boolean_Array_Xor_Test (N : Node_Id; T : Entity_Id) is
7804       Loc : constant Source_Ptr := Sloc (N);
7805       CT  : constant Entity_Id  := Component_Type (T);
7806
7807    begin
7808       --  The check we install is
7809
7810       --    constraint_error when
7811       --      Boolean (component_type'First)
7812       --        and then Boolean (component_type'Last)
7813       --        and then array_type'Length /= 0)
7814
7815       --  We need the last guard because we don't want to raise CE for empty
7816       --  arrays since no out of range values result (Empty arrays with a
7817       --  component type of True .. True -- very useful -- even the ACATS
7818       --  does not test that marginal case!).
7819
7820       Insert_Action (N,
7821         Make_Raise_Constraint_Error (Loc,
7822           Condition =>
7823             Make_And_Then (Loc,
7824               Left_Opnd =>
7825                 Make_And_Then (Loc,
7826                   Left_Opnd =>
7827                     Convert_To (Standard_Boolean,
7828                       Make_Attribute_Reference (Loc,
7829                         Prefix         => New_Occurrence_Of (CT, Loc),
7830                         Attribute_Name => Name_First)),
7831
7832                   Right_Opnd =>
7833                     Convert_To (Standard_Boolean,
7834                       Make_Attribute_Reference (Loc,
7835                         Prefix         => New_Occurrence_Of (CT, Loc),
7836                         Attribute_Name => Name_Last))),
7837
7838               Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
7839           Reason => CE_Range_Check_Failed));
7840    end Silly_Boolean_Array_Xor_Test;
7841
7842    --------------------------
7843    -- Target_Has_Fixed_Ops --
7844    --------------------------
7845
7846    Integer_Sized_Small : Ureal;
7847    --  Set to 2.0 ** -(Integer'Size - 1) the first time that this function is
7848    --  called (we don't want to compute it more than once!)
7849
7850    Long_Integer_Sized_Small : Ureal;
7851    --  Set to 2.0 ** -(Long_Integer'Size - 1) the first time that this function
7852    --  is called (we don't want to compute it more than once)
7853
7854    First_Time_For_THFO : Boolean := True;
7855    --  Set to False after first call (if Fractional_Fixed_Ops_On_Target)
7856
7857    function Target_Has_Fixed_Ops
7858      (Left_Typ   : Entity_Id;
7859       Right_Typ  : Entity_Id;
7860       Result_Typ : Entity_Id) return Boolean
7861    is
7862       function Is_Fractional_Type (Typ : Entity_Id) return Boolean;
7863       --  Return True if the given type is a fixed-point type with a small
7864       --  value equal to 2 ** (-(T'Object_Size - 1)) and whose values have
7865       --  an absolute value less than 1.0. This is currently limited to
7866       --  fixed-point types that map to Integer or Long_Integer.
7867
7868       ------------------------
7869       -- Is_Fractional_Type --
7870       ------------------------
7871
7872       function Is_Fractional_Type (Typ : Entity_Id) return Boolean is
7873       begin
7874          if Esize (Typ) = Standard_Integer_Size then
7875             return Small_Value (Typ) = Integer_Sized_Small;
7876
7877          elsif Esize (Typ) = Standard_Long_Integer_Size then
7878             return Small_Value (Typ) = Long_Integer_Sized_Small;
7879
7880          else
7881             return False;
7882          end if;
7883       end Is_Fractional_Type;
7884
7885    --  Start of processing for Target_Has_Fixed_Ops
7886
7887    begin
7888       --  Return False if Fractional_Fixed_Ops_On_Target is false
7889
7890       if not Fractional_Fixed_Ops_On_Target then
7891          return False;
7892       end if;
7893
7894       --  Here the target has Fractional_Fixed_Ops, if first time, compute
7895       --  standard constants used by Is_Fractional_Type.
7896
7897       if First_Time_For_THFO then
7898          First_Time_For_THFO := False;
7899
7900          Integer_Sized_Small :=
7901            UR_From_Components
7902              (Num   => Uint_1,
7903               Den   => UI_From_Int (Standard_Integer_Size - 1),
7904               Rbase => 2);
7905
7906          Long_Integer_Sized_Small :=
7907            UR_From_Components
7908              (Num   => Uint_1,
7909               Den   => UI_From_Int (Standard_Long_Integer_Size - 1),
7910               Rbase => 2);
7911       end if;
7912
7913       --  Return True if target supports fixed-by-fixed multiply/divide for
7914       --  fractional fixed-point types (see Is_Fractional_Type) and the operand
7915       --  and result types are equivalent fractional types.
7916
7917       return Is_Fractional_Type (Base_Type (Left_Typ))
7918         and then Is_Fractional_Type (Base_Type (Right_Typ))
7919         and then Is_Fractional_Type (Base_Type (Result_Typ))
7920         and then Esize (Left_Typ) = Esize (Right_Typ)
7921         and then Esize (Left_Typ) = Esize (Result_Typ);
7922    end Target_Has_Fixed_Ops;
7923
7924    ------------------------------------------
7925    -- Type_May_Have_Bit_Aligned_Components --
7926    ------------------------------------------
7927
7928    function Type_May_Have_Bit_Aligned_Components
7929      (Typ : Entity_Id) return Boolean
7930    is
7931    begin
7932       --  Array type, check component type
7933
7934       if Is_Array_Type (Typ) then
7935          return
7936            Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
7937
7938       --  Record type, check components
7939
7940       elsif Is_Record_Type (Typ) then
7941          declare
7942             E : Entity_Id;
7943
7944          begin
7945             E := First_Component_Or_Discriminant (Typ);
7946             while Present (E) loop
7947                if Component_May_Be_Bit_Aligned (E)
7948                  or else Type_May_Have_Bit_Aligned_Components (Etype (E))
7949                then
7950                   return True;
7951                end if;
7952
7953                Next_Component_Or_Discriminant (E);
7954             end loop;
7955
7956             return False;
7957          end;
7958
7959       --  Type other than array or record is always OK
7960
7961       else
7962          return False;
7963       end if;
7964    end Type_May_Have_Bit_Aligned_Components;
7965
7966    ----------------------------------
7967    -- Within_Case_Or_If_Expression --
7968    ----------------------------------
7969
7970    function Within_Case_Or_If_Expression (N : Node_Id) return Boolean is
7971       Par : Node_Id;
7972
7973    begin
7974       --  Locate an enclosing case or if expression. Note: these constructs can
7975       --  get expanded into Expression_With_Actions, hence the need to test
7976       --  using the original node.
7977
7978       Par := N;
7979       while Present (Par) loop
7980          if Nkind_In (Original_Node (Par), N_Case_Expression,
7981                                            N_If_Expression)
7982          then
7983             return True;
7984
7985          --  Prevent the search from going too far
7986
7987          elsif Nkind_In (Par, N_Entry_Body,
7988                               N_Package_Body,
7989                               N_Package_Declaration,
7990                               N_Protected_Body,
7991                               N_Subprogram_Body,
7992                               N_Task_Body)
7993          then
7994             return False;
7995          end if;
7996
7997          Par := Parent (Par);
7998       end loop;
7999
8000       return False;
8001    end Within_Case_Or_If_Expression;
8002
8003    ----------------------------
8004    -- Wrap_Cleanup_Procedure --
8005    ----------------------------
8006
8007    procedure Wrap_Cleanup_Procedure (N : Node_Id) is
8008       Loc   : constant Source_Ptr := Sloc (N);
8009       Stseq : constant Node_Id    := Handled_Statement_Sequence (N);
8010       Stmts : constant List_Id    := Statements (Stseq);
8011
8012    begin
8013       if Abort_Allowed then
8014          Prepend_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
8015          Append_To  (Stmts, Build_Runtime_Call (Loc, RE_Abort_Undefer));
8016       end if;
8017    end Wrap_Cleanup_Procedure;
8018
8019 end Exp_Util;