OSDN Git Service

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