OSDN Git Service

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