OSDN Git Service

2009-04-09 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / exp_ch4.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              E X P _ C H 4                               --
6 --                                                               g           --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2008, 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 Atree;    use Atree;
27 with Checks;   use Checks;
28 with Einfo;    use Einfo;
29 with Elists;   use Elists;
30 with Errout;   use Errout;
31 with Exp_Aggr; use Exp_Aggr;
32 with Exp_Atag; use Exp_Atag;
33 with Exp_Ch3;  use Exp_Ch3;
34 with Exp_Ch6;  use Exp_Ch6;
35 with Exp_Ch7;  use Exp_Ch7;
36 with Exp_Ch9;  use Exp_Ch9;
37 with Exp_Disp; use Exp_Disp;
38 with Exp_Fixd; use Exp_Fixd;
39 with Exp_Pakd; use Exp_Pakd;
40 with Exp_Tss;  use Exp_Tss;
41 with Exp_Util; use Exp_Util;
42 with Exp_VFpt; use Exp_VFpt;
43 with Freeze;   use Freeze;
44 with Inline;   use Inline;
45 with Namet;    use Namet;
46 with Nlists;   use Nlists;
47 with Nmake;    use Nmake;
48 with Opt;      use Opt;
49 with Restrict; use Restrict;
50 with Rident;   use Rident;
51 with Rtsfind;  use Rtsfind;
52 with Sem;      use Sem;
53 with Sem_Cat;  use Sem_Cat;
54 with Sem_Ch3;  use Sem_Ch3;
55 with Sem_Ch8;  use Sem_Ch8;
56 with Sem_Ch13; use Sem_Ch13;
57 with Sem_Eval; use Sem_Eval;
58 with Sem_Res;  use Sem_Res;
59 with Sem_Type; use Sem_Type;
60 with Sem_Util; use Sem_Util;
61 with Sem_Warn; use Sem_Warn;
62 with Sinfo;    use Sinfo;
63 with Snames;   use Snames;
64 with Stand;    use Stand;
65 with Targparm; use Targparm;
66 with Tbuild;   use Tbuild;
67 with Ttypes;   use Ttypes;
68 with Uintp;    use Uintp;
69 with Urealp;   use Urealp;
70 with Validsw;  use Validsw;
71
72 package body Exp_Ch4 is
73
74    -----------------------
75    -- Local Subprograms --
76    -----------------------
77
78    procedure Binary_Op_Validity_Checks (N : Node_Id);
79    pragma Inline (Binary_Op_Validity_Checks);
80    --  Performs validity checks for a binary operator
81
82    procedure Build_Boolean_Array_Proc_Call
83      (N   : Node_Id;
84       Op1 : Node_Id;
85       Op2 : Node_Id);
86    --  If a boolean array assignment can be done in place, build call to
87    --  corresponding library procedure.
88
89    procedure Displace_Allocator_Pointer (N : Node_Id);
90    --  Ada 2005 (AI-251): Subsidiary procedure to Expand_N_Allocator and
91    --  Expand_Allocator_Expression. Allocating class-wide interface objects
92    --  this routine displaces the pointer to the allocated object to reference
93    --  the component referencing the corresponding secondary dispatch table.
94
95    procedure Expand_Allocator_Expression (N : Node_Id);
96    --  Subsidiary to Expand_N_Allocator, for the case when the expression
97    --  is a qualified expression or an aggregate.
98
99    procedure Expand_Array_Comparison (N : Node_Id);
100    --  This routine handles expansion of the comparison operators (N_Op_Lt,
101    --  N_Op_Le, N_Op_Gt, N_Op_Ge) when operating on an array type. The basic
102    --  code for these operators is similar, differing only in the details of
103    --  the actual comparison call that is made. Special processing (call a
104    --  run-time routine)
105
106    function Expand_Array_Equality
107      (Nod    : Node_Id;
108       Lhs    : Node_Id;
109       Rhs    : Node_Id;
110       Bodies : List_Id;
111       Typ    : Entity_Id) return Node_Id;
112    --  Expand an array equality into a call to a function implementing this
113    --  equality, and a call to it. Loc is the location for the generated nodes.
114    --  Lhs and Rhs are the array expressions to be compared. Bodies is a list
115    --  on which to attach bodies of local functions that are created in the
116    --  process. It is the responsibility of the caller to insert those bodies
117    --  at the right place. Nod provides the Sloc value for the generated code.
118    --  Normally the types used for the generated equality routine are taken
119    --  from Lhs and Rhs. However, in some situations of generated code, the
120    --  Etype fields of Lhs and Rhs are not set yet. In such cases, Typ supplies
121    --  the type to be used for the formal parameters.
122
123    procedure Expand_Boolean_Operator (N : Node_Id);
124    --  Common expansion processing for Boolean operators (And, Or, Xor) for the
125    --  case of array type arguments.
126
127    function Expand_Composite_Equality
128      (Nod    : Node_Id;
129       Typ    : Entity_Id;
130       Lhs    : Node_Id;
131       Rhs    : Node_Id;
132       Bodies : List_Id) return Node_Id;
133    --  Local recursive function used to expand equality for nested composite
134    --  types. Used by Expand_Record/Array_Equality, Bodies is a list on which
135    --  to attach bodies of local functions that are created in the process.
136    --  This is the responsibility of the caller to insert those bodies at the
137    --  right place. Nod provides the Sloc value for generated code. Lhs and Rhs
138    --  are the left and right sides for the comparison, and Typ is the type of
139    --  the arrays to compare.
140
141    procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id);
142    --  Routine to expand concatenation of a sequence of two or more operands
143    --  (in the list Operands) and replace node Cnode with the result of the
144    --  concatenation. The operands can be of any appropriate type, and can
145    --  include both arrays and singleton elements.
146
147    procedure Fixup_Universal_Fixed_Operation (N : Node_Id);
148    --  N is a N_Op_Divide or N_Op_Multiply node whose result is universal
149    --  fixed. We do not have such a type at runtime, so the purpose of this
150    --  routine is to find the real type by looking up the tree. We also
151    --  determine if the operation must be rounded.
152
153    function Get_Allocator_Final_List
154      (N    : Node_Id;
155       T    : Entity_Id;
156       PtrT : Entity_Id) return Entity_Id;
157    --  If the designated type is controlled, build final_list expression for
158    --  created object. If context is an access parameter, create a local access
159    --  type to have a usable finalization list.
160
161    function Has_Inferable_Discriminants (N : Node_Id) return Boolean;
162    --  Ada 2005 (AI-216): A view of an Unchecked_Union object has inferable
163    --  discriminants if it has a constrained nominal type, unless the object
164    --  is a component of an enclosing Unchecked_Union object that is subject
165    --  to a per-object constraint and the enclosing object lacks inferable
166    --  discriminants.
167    --
168    --  An expression of an Unchecked_Union type has inferable discriminants
169    --  if it is either a name of an object with inferable discriminants or a
170    --  qualified expression whose subtype mark denotes a constrained subtype.
171
172    procedure Insert_Dereference_Action (N : Node_Id);
173    --  N is an expression whose type is an access. When the type of the
174    --  associated storage pool is derived from Checked_Pool, generate a
175    --  call to the 'Dereference' primitive operation.
176
177    function Make_Array_Comparison_Op
178      (Typ : Entity_Id;
179       Nod : Node_Id) return Node_Id;
180    --  Comparisons between arrays are expanded in line. This function produces
181    --  the body of the implementation of (a > b), where a and b are one-
182    --  dimensional arrays of some discrete type. The original node is then
183    --  expanded into the appropriate call to this function. Nod provides the
184    --  Sloc value for the generated code.
185
186    function Make_Boolean_Array_Op
187      (Typ : Entity_Id;
188       N   : Node_Id) return Node_Id;
189    --  Boolean operations on boolean arrays are expanded in line. This function
190    --  produce the body for the node N, which is (a and b), (a or b), or (a xor
191    --  b). It is used only the normal case and not the packed case. The type
192    --  involved, Typ, is the Boolean array type, and the logical operations in
193    --  the body are simple boolean operations. Note that Typ is always a
194    --  constrained type (the caller has ensured this by using
195    --  Convert_To_Actual_Subtype if necessary).
196
197    procedure Rewrite_Comparison (N : Node_Id);
198    --  If N is the node for a comparison whose outcome can be determined at
199    --  compile time, then the node N can be rewritten with True or False. If
200    --  the outcome cannot be determined at compile time, the call has no
201    --  effect. If N is a type conversion, then this processing is applied to
202    --  its expression. If N is neither comparison nor a type conversion, the
203    --  call has no effect.
204
205    function Tagged_Membership (N : Node_Id) return Node_Id;
206    --  Construct the expression corresponding to the tagged membership test.
207    --  Deals with a second operand being (or not) a class-wide type.
208
209    function Safe_In_Place_Array_Op
210      (Lhs : Node_Id;
211       Op1 : Node_Id;
212       Op2 : Node_Id) return Boolean;
213    --  In the context of an assignment, where the right-hand side is a boolean
214    --  operation on arrays, check whether operation can be performed in place.
215
216    procedure Unary_Op_Validity_Checks (N : Node_Id);
217    pragma Inline (Unary_Op_Validity_Checks);
218    --  Performs validity checks for a unary operator
219
220    -------------------------------
221    -- Binary_Op_Validity_Checks --
222    -------------------------------
223
224    procedure Binary_Op_Validity_Checks (N : Node_Id) is
225    begin
226       if Validity_Checks_On and Validity_Check_Operands then
227          Ensure_Valid (Left_Opnd (N));
228          Ensure_Valid (Right_Opnd (N));
229       end if;
230    end Binary_Op_Validity_Checks;
231
232    ------------------------------------
233    -- Build_Boolean_Array_Proc_Call --
234    ------------------------------------
235
236    procedure Build_Boolean_Array_Proc_Call
237      (N   : Node_Id;
238       Op1 : Node_Id;
239       Op2 : Node_Id)
240    is
241       Loc       : constant Source_Ptr := Sloc (N);
242       Kind      : constant Node_Kind := Nkind (Expression (N));
243       Target    : constant Node_Id   :=
244                     Make_Attribute_Reference (Loc,
245                       Prefix         => Name (N),
246                       Attribute_Name => Name_Address);
247
248       Arg1      : constant Node_Id := Op1;
249       Arg2      : Node_Id := Op2;
250       Call_Node : Node_Id;
251       Proc_Name : Entity_Id;
252
253    begin
254       if Kind = N_Op_Not then
255          if Nkind (Op1) in N_Binary_Op then
256
257             --  Use negated version of the binary operators
258
259             if Nkind (Op1) = N_Op_And then
260                Proc_Name := RTE (RE_Vector_Nand);
261
262             elsif Nkind (Op1) = N_Op_Or then
263                Proc_Name := RTE (RE_Vector_Nor);
264
265             else pragma Assert (Nkind (Op1) = N_Op_Xor);
266                Proc_Name := RTE (RE_Vector_Xor);
267             end if;
268
269             Call_Node :=
270               Make_Procedure_Call_Statement (Loc,
271                 Name => New_Occurrence_Of (Proc_Name, Loc),
272
273                 Parameter_Associations => New_List (
274                   Target,
275                   Make_Attribute_Reference (Loc,
276                     Prefix => Left_Opnd (Op1),
277                     Attribute_Name => Name_Address),
278
279                   Make_Attribute_Reference (Loc,
280                     Prefix => Right_Opnd (Op1),
281                     Attribute_Name => Name_Address),
282
283                   Make_Attribute_Reference (Loc,
284                     Prefix => Left_Opnd (Op1),
285                     Attribute_Name => Name_Length)));
286
287          else
288             Proc_Name := RTE (RE_Vector_Not);
289
290             Call_Node :=
291               Make_Procedure_Call_Statement (Loc,
292                 Name => New_Occurrence_Of (Proc_Name, Loc),
293                 Parameter_Associations => New_List (
294                   Target,
295
296                   Make_Attribute_Reference (Loc,
297                     Prefix => Op1,
298                     Attribute_Name => Name_Address),
299
300                   Make_Attribute_Reference (Loc,
301                     Prefix => Op1,
302                      Attribute_Name => Name_Length)));
303          end if;
304
305       else
306          --  We use the following equivalences:
307
308          --   (not X) or  (not Y)  =  not (X and Y)  =  Nand (X, Y)
309          --   (not X) and (not Y)  =  not (X or Y)   =  Nor  (X, Y)
310          --   (not X) xor (not Y)  =  X xor Y
311          --   X       xor (not Y)  =  not (X xor Y)  =  Nxor (X, Y)
312
313          if Nkind (Op1) = N_Op_Not then
314             if Kind = N_Op_And then
315                Proc_Name := RTE (RE_Vector_Nor);
316
317             elsif Kind = N_Op_Or then
318                Proc_Name := RTE (RE_Vector_Nand);
319
320             else
321                Proc_Name := RTE (RE_Vector_Xor);
322             end if;
323
324          else
325             if Kind = N_Op_And then
326                Proc_Name := RTE (RE_Vector_And);
327
328             elsif Kind = N_Op_Or then
329                Proc_Name := RTE (RE_Vector_Or);
330
331             elsif Nkind (Op2) = N_Op_Not then
332                Proc_Name := RTE (RE_Vector_Nxor);
333                Arg2 := Right_Opnd (Op2);
334
335             else
336                Proc_Name := RTE (RE_Vector_Xor);
337             end if;
338          end if;
339
340          Call_Node :=
341            Make_Procedure_Call_Statement (Loc,
342              Name => New_Occurrence_Of (Proc_Name, Loc),
343              Parameter_Associations => New_List (
344                Target,
345                   Make_Attribute_Reference (Loc,
346                     Prefix => Arg1,
347                     Attribute_Name => Name_Address),
348                   Make_Attribute_Reference (Loc,
349                     Prefix => Arg2,
350                     Attribute_Name => Name_Address),
351                  Make_Attribute_Reference (Loc,
352                    Prefix => Op1,
353                     Attribute_Name => Name_Length)));
354       end if;
355
356       Rewrite (N, Call_Node);
357       Analyze (N);
358
359    exception
360       when RE_Not_Available =>
361          return;
362    end Build_Boolean_Array_Proc_Call;
363
364    --------------------------------
365    -- Displace_Allocator_Pointer --
366    --------------------------------
367
368    procedure Displace_Allocator_Pointer (N : Node_Id) is
369       Loc       : constant Source_Ptr := Sloc (N);
370       Orig_Node : constant Node_Id := Original_Node (N);
371       Dtyp      : Entity_Id;
372       Etyp      : Entity_Id;
373       PtrT      : Entity_Id;
374
375    begin
376       --  Do nothing in case of VM targets: the virtual machine will handle
377       --  interfaces directly.
378
379       if VM_Target /= No_VM then
380          return;
381       end if;
382
383       pragma Assert (Nkind (N) = N_Identifier
384         and then Nkind (Orig_Node) = N_Allocator);
385
386       PtrT := Etype (Orig_Node);
387       Dtyp := Designated_Type (PtrT);
388       Etyp := Etype (Expression (Orig_Node));
389
390       if Is_Class_Wide_Type (Dtyp)
391         and then Is_Interface (Dtyp)
392       then
393          --  If the type of the allocator expression is not an interface type
394          --  we can generate code to reference the record component containing
395          --  the pointer to the secondary dispatch table.
396
397          if not Is_Interface (Etyp) then
398             declare
399                Saved_Typ : constant Entity_Id := Etype (Orig_Node);
400
401             begin
402                --  1) Get access to the allocated object
403
404                Rewrite (N,
405                  Make_Explicit_Dereference (Loc,
406                    Relocate_Node (N)));
407                Set_Etype (N, Etyp);
408                Set_Analyzed (N);
409
410                --  2) Add the conversion to displace the pointer to reference
411                --     the secondary dispatch table.
412
413                Rewrite (N, Convert_To (Dtyp, Relocate_Node (N)));
414                Analyze_And_Resolve (N, Dtyp);
415
416                --  3) The 'access to the secondary dispatch table will be used
417                --     as the value returned by the allocator.
418
419                Rewrite (N,
420                  Make_Attribute_Reference (Loc,
421                    Prefix         => Relocate_Node (N),
422                    Attribute_Name => Name_Access));
423                Set_Etype (N, Saved_Typ);
424                Set_Analyzed (N);
425             end;
426
427          --  If the type of the allocator expression is an interface type we
428          --  generate a run-time call to displace "this" to reference the
429          --  component containing the pointer to the secondary dispatch table
430          --  or else raise Constraint_Error if the actual object does not
431          --  implement the target interface. This case corresponds with the
432          --  following example:
433
434          --   function Op (Obj : Iface_1'Class) return access Iface_2'Class is
435          --   begin
436          --      return new Iface_2'Class'(Obj);
437          --   end Op;
438
439          else
440             Rewrite (N,
441               Unchecked_Convert_To (PtrT,
442                 Make_Function_Call (Loc,
443                   Name => New_Reference_To (RTE (RE_Displace), Loc),
444                   Parameter_Associations => New_List (
445                     Unchecked_Convert_To (RTE (RE_Address),
446                       Relocate_Node (N)),
447
448                     New_Occurrence_Of
449                       (Elists.Node
450                         (First_Elmt
451                           (Access_Disp_Table (Etype (Base_Type (Dtyp))))),
452                        Loc)))));
453             Analyze_And_Resolve (N, PtrT);
454          end if;
455       end if;
456    end Displace_Allocator_Pointer;
457
458    ---------------------------------
459    -- Expand_Allocator_Expression --
460    ---------------------------------
461
462    procedure Expand_Allocator_Expression (N : Node_Id) is
463       Loc    : constant Source_Ptr := Sloc (N);
464       Exp    : constant Node_Id    := Expression (Expression (N));
465       PtrT   : constant Entity_Id  := Etype (N);
466       DesigT : constant Entity_Id  := Designated_Type (PtrT);
467
468       procedure Apply_Accessibility_Check
469         (Ref            : Node_Id;
470          Built_In_Place : Boolean := False);
471       --  Ada 2005 (AI-344): For an allocator with a class-wide designated
472       --  type, generate an accessibility check to verify that the level of the
473       --  type of the created object is not deeper than the level of the access
474       --  type. If the type of the qualified expression is class- wide, then
475       --  always generate the check (except in the case where it is known to be
476       --  unnecessary, see comment below). Otherwise, only generate the check
477       --  if the level of the qualified expression type is statically deeper
478       --  than the access type.
479       --
480       --  Although the static accessibility will generally have been performed
481       --  as a legality check, it won't have been done in cases where the
482       --  allocator appears in generic body, so a run-time check is needed in
483       --  general. One special case is when the access type is declared in the
484       --  same scope as the class-wide allocator, in which case the check can
485       --  never fail, so it need not be generated.
486       --
487       --  As an open issue, there seem to be cases where the static level
488       --  associated with the class-wide object's underlying type is not
489       --  sufficient to perform the proper accessibility check, such as for
490       --  allocators in nested subprograms or accept statements initialized by
491       --  class-wide formals when the actual originates outside at a deeper
492       --  static level. The nested subprogram case might require passing
493       --  accessibility levels along with class-wide parameters, and the task
494       --  case seems to be an actual gap in the language rules that needs to
495       --  be fixed by the ARG. ???
496
497       -------------------------------
498       -- Apply_Accessibility_Check --
499       -------------------------------
500
501       procedure Apply_Accessibility_Check
502         (Ref            : Node_Id;
503          Built_In_Place : Boolean := False)
504       is
505          Ref_Node : Node_Id;
506
507       begin
508          --  Note: we skip the accessibility check for the VM case, since
509          --  there does not seem to be any practical way of implementing it.
510
511          if Ada_Version >= Ada_05
512            and then VM_Target = No_VM
513            and then Is_Class_Wide_Type (DesigT)
514            and then not Scope_Suppress (Accessibility_Check)
515            and then
516              (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
517                or else
518                  (Is_Class_Wide_Type (Etype (Exp))
519                    and then Scope (PtrT) /= Current_Scope))
520          then
521             --  If the allocator was built in place Ref is already a reference
522             --  to the access object initialized to the result of the allocator
523             --  (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). Otherwise
524             --  it is the entity associated with the object containing the
525             --  address of the allocated object.
526
527             if Built_In_Place then
528                Ref_Node := New_Copy (Ref);
529             else
530                Ref_Node := New_Reference_To (Ref, Loc);
531             end if;
532
533             Insert_Action (N,
534                Make_Raise_Program_Error (Loc,
535                  Condition =>
536                    Make_Op_Gt (Loc,
537                      Left_Opnd  =>
538                        Build_Get_Access_Level (Loc,
539                          Make_Attribute_Reference (Loc,
540                            Prefix => Ref_Node,
541                            Attribute_Name => Name_Tag)),
542                      Right_Opnd =>
543                        Make_Integer_Literal (Loc,
544                          Type_Access_Level (PtrT))),
545                  Reason => PE_Accessibility_Check_Failed));
546          end if;
547       end Apply_Accessibility_Check;
548
549       --  Local variables
550
551       Indic : constant Node_Id   := Subtype_Mark (Expression (N));
552       T     : constant Entity_Id := Entity (Indic);
553       Flist : Node_Id;
554       Node  : Node_Id;
555       Temp  : Entity_Id;
556
557       TagT : Entity_Id := Empty;
558       --  Type used as source for tag assignment
559
560       TagR : Node_Id := Empty;
561       --  Target reference for tag assignment
562
563       Aggr_In_Place : constant Boolean := Is_Delayed_Aggregate (Exp);
564
565       Tag_Assign : Node_Id;
566       Tmp_Node   : Node_Id;
567
568    --  Start of processing for Expand_Allocator_Expression
569
570    begin
571       if Is_Tagged_Type (T) or else Needs_Finalization (T) then
572
573          --  Ada 2005 (AI-318-02): If the initialization expression is a call
574          --  to a build-in-place function, then access to the allocated object
575          --  must be passed to the function. Currently we limit such functions
576          --  to those with constrained limited result subtypes, but eventually
577          --  we plan to expand the allowed forms of functions that are treated
578          --  as build-in-place.
579
580          if Ada_Version >= Ada_05
581            and then Is_Build_In_Place_Function_Call (Exp)
582          then
583             Make_Build_In_Place_Call_In_Allocator (N, Exp);
584             Apply_Accessibility_Check (N, Built_In_Place => True);
585             return;
586          end if;
587
588          --    Actions inserted before:
589          --              Temp : constant ptr_T := new T'(Expression);
590          --   <no CW>    Temp._tag := T'tag;
591          --   <CTRL>     Adjust (Finalizable (Temp.all));
592          --   <CTRL>     Attach_To_Final_List (Finalizable (Temp.all));
593
594          --  We analyze by hand the new internal allocator to avoid
595          --  any recursion and inappropriate call to Initialize
596
597          --  We don't want to remove side effects when the expression must be
598          --  built in place. In the case of a build-in-place function call,
599          --  that could lead to a duplication of the call, which was already
600          --  substituted for the allocator.
601
602          if not Aggr_In_Place then
603             Remove_Side_Effects (Exp);
604          end if;
605
606          Temp :=
607            Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
608
609          --  For a class wide allocation generate the following code:
610
611          --    type Equiv_Record is record ... end record;
612          --    implicit subtype CW is <Class_Wide_Subytpe>;
613          --    temp : PtrT := new CW'(CW!(expr));
614
615          if Is_Class_Wide_Type (T) then
616             Expand_Subtype_From_Expr (Empty, T, Indic, Exp);
617
618             --  Ada 2005 (AI-251): If the expression is a class-wide interface
619             --  object we generate code to move up "this" to reference the
620             --  base of the object before allocating the new object.
621
622             --  Note that Exp'Address is recursively expanded into a call
623             --  to Base_Address (Exp.Tag)
624
625             if Is_Class_Wide_Type (Etype (Exp))
626               and then Is_Interface (Etype (Exp))
627               and then VM_Target = No_VM
628             then
629                Set_Expression
630                  (Expression (N),
631                   Unchecked_Convert_To (Entity (Indic),
632                     Make_Explicit_Dereference (Loc,
633                       Unchecked_Convert_To (RTE (RE_Tag_Ptr),
634                         Make_Attribute_Reference (Loc,
635                           Prefix         => Exp,
636                           Attribute_Name => Name_Address)))));
637
638             else
639                Set_Expression
640                  (Expression (N),
641                   Unchecked_Convert_To (Entity (Indic), Exp));
642             end if;
643
644             Analyze_And_Resolve (Expression (N), Entity (Indic));
645          end if;
646
647          --  Keep separate the management of allocators returning interfaces
648
649          if not Is_Interface (Directly_Designated_Type (PtrT)) then
650             if Aggr_In_Place then
651                Tmp_Node :=
652                  Make_Object_Declaration (Loc,
653                    Defining_Identifier => Temp,
654                    Object_Definition   => New_Reference_To (PtrT, Loc),
655                    Expression          =>
656                      Make_Allocator (Loc,
657                        New_Reference_To (Etype (Exp), Loc)));
658
659                Set_Comes_From_Source
660                  (Expression (Tmp_Node), Comes_From_Source (N));
661
662                Set_No_Initialization (Expression (Tmp_Node));
663                Insert_Action (N, Tmp_Node);
664
665                if Needs_Finalization (T)
666                  and then Ekind (PtrT) = E_Anonymous_Access_Type
667                then
668                   --  Create local finalization list for access parameter
669
670                   Flist := Get_Allocator_Final_List (N, Base_Type (T), PtrT);
671                end if;
672
673                Convert_Aggr_In_Allocator (N, Tmp_Node, Exp);
674             else
675                Node := Relocate_Node (N);
676                Set_Analyzed (Node);
677                Insert_Action (N,
678                  Make_Object_Declaration (Loc,
679                    Defining_Identifier => Temp,
680                    Constant_Present    => True,
681                    Object_Definition   => New_Reference_To (PtrT, Loc),
682                    Expression          => Node));
683             end if;
684
685          --  Ada 2005 (AI-251): Handle allocators whose designated type is an
686          --  interface type. In this case we use the type of the qualified
687          --  expression to allocate the object.
688
689          else
690             declare
691                Def_Id   : constant Entity_Id :=
692                             Make_Defining_Identifier (Loc,
693                               New_Internal_Name ('T'));
694                New_Decl : Node_Id;
695
696             begin
697                New_Decl :=
698                  Make_Full_Type_Declaration (Loc,
699                    Defining_Identifier => Def_Id,
700                    Type_Definition =>
701                      Make_Access_To_Object_Definition (Loc,
702                        All_Present            => True,
703                        Null_Exclusion_Present => False,
704                        Constant_Present       => False,
705                        Subtype_Indication     =>
706                          New_Reference_To (Etype (Exp), Loc)));
707
708                Insert_Action (N, New_Decl);
709
710                --  Inherit the final chain to ensure that the expansion of the
711                --  aggregate is correct in case of controlled types
712
713                if Needs_Finalization (Directly_Designated_Type (PtrT)) then
714                   Set_Associated_Final_Chain (Def_Id,
715                     Associated_Final_Chain (PtrT));
716                end if;
717
718                --  Declare the object using the previous type declaration
719
720                if Aggr_In_Place then
721                   Tmp_Node :=
722                     Make_Object_Declaration (Loc,
723                       Defining_Identifier => Temp,
724                       Object_Definition   => New_Reference_To (Def_Id, Loc),
725                       Expression          =>
726                         Make_Allocator (Loc,
727                           New_Reference_To (Etype (Exp), Loc)));
728
729                   Set_Comes_From_Source
730                     (Expression (Tmp_Node), Comes_From_Source (N));
731
732                   Set_No_Initialization (Expression (Tmp_Node));
733                   Insert_Action (N, Tmp_Node);
734
735                   if Needs_Finalization (T)
736                     and then Ekind (PtrT) = E_Anonymous_Access_Type
737                   then
738                      --  Create local finalization list for access parameter
739
740                      Flist :=
741                        Get_Allocator_Final_List (N, Base_Type (T), PtrT);
742                   end if;
743
744                   Convert_Aggr_In_Allocator (N, Tmp_Node, Exp);
745                else
746                   Node := Relocate_Node (N);
747                   Set_Analyzed (Node);
748                   Insert_Action (N,
749                     Make_Object_Declaration (Loc,
750                       Defining_Identifier => Temp,
751                       Constant_Present    => True,
752                       Object_Definition   => New_Reference_To (Def_Id, Loc),
753                       Expression          => Node));
754                end if;
755
756                --  Generate an additional object containing the address of the
757                --  returned object. The type of this second object declaration
758                --  is the correct type required for the common processing that
759                --  is still performed by this subprogram. The displacement of
760                --  this pointer to reference the component associated with the
761                --  interface type will be done at the end of common processing.
762
763                New_Decl :=
764                  Make_Object_Declaration (Loc,
765                    Defining_Identifier => Make_Defining_Identifier (Loc,
766                                              New_Internal_Name ('P')),
767                    Object_Definition   => New_Reference_To (PtrT, Loc),
768                    Expression          => Unchecked_Convert_To (PtrT,
769                                             New_Reference_To (Temp, Loc)));
770
771                Insert_Action (N, New_Decl);
772
773                Tmp_Node := New_Decl;
774                Temp     := Defining_Identifier (New_Decl);
775             end;
776          end if;
777
778          Apply_Accessibility_Check (Temp);
779
780          --  Generate the tag assignment
781
782          --  Suppress the tag assignment when VM_Target because VM tags are
783          --  represented implicitly in objects.
784
785          if VM_Target /= No_VM then
786             null;
787
788          --  Ada 2005 (AI-251): Suppress the tag assignment with class-wide
789          --  interface objects because in this case the tag does not change.
790
791          elsif Is_Interface (Directly_Designated_Type (Etype (N))) then
792             pragma Assert (Is_Class_Wide_Type
793                             (Directly_Designated_Type (Etype (N))));
794             null;
795
796          elsif Is_Tagged_Type (T) and then not Is_Class_Wide_Type (T) then
797             TagT := T;
798             TagR := New_Reference_To (Temp, Loc);
799
800          elsif Is_Private_Type (T)
801            and then Is_Tagged_Type (Underlying_Type (T))
802          then
803             TagT := Underlying_Type (T);
804             TagR :=
805               Unchecked_Convert_To (Underlying_Type (T),
806                 Make_Explicit_Dereference (Loc,
807                   Prefix => New_Reference_To (Temp, Loc)));
808          end if;
809
810          if Present (TagT) then
811             Tag_Assign :=
812               Make_Assignment_Statement (Loc,
813                 Name =>
814                   Make_Selected_Component (Loc,
815                     Prefix => TagR,
816                     Selector_Name =>
817                       New_Reference_To (First_Tag_Component (TagT), Loc)),
818
819                 Expression =>
820                   Unchecked_Convert_To (RTE (RE_Tag),
821                     New_Reference_To
822                       (Elists.Node (First_Elmt (Access_Disp_Table (TagT))),
823                        Loc)));
824
825             --  The previous assignment has to be done in any case
826
827             Set_Assignment_OK (Name (Tag_Assign));
828             Insert_Action (N, Tag_Assign);
829          end if;
830
831          if Needs_Finalization (DesigT)
832             and then Needs_Finalization (T)
833          then
834             declare
835                Attach : Node_Id;
836                Apool  : constant Entity_Id :=
837                           Associated_Storage_Pool (PtrT);
838
839             begin
840                --  If it is an allocation on the secondary stack (i.e. a value
841                --  returned from a function), the object is attached on the
842                --  caller side as soon as the call is completed (see
843                --  Expand_Ctrl_Function_Call)
844
845                if Is_RTE (Apool, RE_SS_Pool) then
846                   declare
847                      F : constant Entity_Id :=
848                            Make_Defining_Identifier (Loc,
849                              New_Internal_Name ('F'));
850                   begin
851                      Insert_Action (N,
852                        Make_Object_Declaration (Loc,
853                          Defining_Identifier => F,
854                          Object_Definition   => New_Reference_To (RTE
855                           (RE_Finalizable_Ptr), Loc)));
856
857                      Flist := New_Reference_To (F, Loc);
858                      Attach :=  Make_Integer_Literal (Loc, 1);
859                   end;
860
861                --  Normal case, not a secondary stack allocation
862
863                else
864                   if Needs_Finalization (T)
865                     and then Ekind (PtrT) = E_Anonymous_Access_Type
866                   then
867                      --  Create local finalization list for access parameter
868
869                      Flist :=
870                        Get_Allocator_Final_List (N, Base_Type (T), PtrT);
871                   else
872                      Flist := Find_Final_List (PtrT);
873                   end if;
874
875                   Attach :=  Make_Integer_Literal (Loc, 2);
876                end if;
877
878                --  Generate an Adjust call if the object will be moved. In Ada
879                --  2005, the object may be inherently limited, in which case
880                --  there is no Adjust procedure, and the object is built in
881                --  place. In Ada 95, the object can be limited but not
882                --  inherently limited if this allocator came from a return
883                --  statement (we're allocating the result on the secondary
884                --  stack). In that case, the object will be moved, so we _do_
885                --  want to Adjust.
886
887                if not Aggr_In_Place
888                  and then not Is_Inherently_Limited_Type (T)
889                then
890                   Insert_Actions (N,
891                     Make_Adjust_Call (
892                       Ref          =>
893
894                      --  An unchecked conversion is needed in the classwide
895                      --  case because the designated type can be an ancestor of
896                      --  the subtype mark of the allocator.
897
898                       Unchecked_Convert_To (T,
899                         Make_Explicit_Dereference (Loc,
900                           Prefix => New_Reference_To (Temp, Loc))),
901
902                       Typ          => T,
903                       Flist_Ref    => Flist,
904                       With_Attach  => Attach,
905                       Allocator    => True));
906                end if;
907             end;
908          end if;
909
910          Rewrite (N, New_Reference_To (Temp, Loc));
911          Analyze_And_Resolve (N, PtrT);
912
913          --  Ada 2005 (AI-251): Displace the pointer to reference the record
914          --  component containing the secondary dispatch table of the interface
915          --  type.
916
917          if Is_Interface (Directly_Designated_Type (PtrT)) then
918             Displace_Allocator_Pointer (N);
919          end if;
920
921       elsif Aggr_In_Place then
922          Temp :=
923            Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
924          Tmp_Node :=
925            Make_Object_Declaration (Loc,
926              Defining_Identifier => Temp,
927              Object_Definition   => New_Reference_To (PtrT, Loc),
928              Expression          => Make_Allocator (Loc,
929                  New_Reference_To (Etype (Exp), Loc)));
930
931          Set_Comes_From_Source
932            (Expression (Tmp_Node), Comes_From_Source (N));
933
934          Set_No_Initialization (Expression (Tmp_Node));
935          Insert_Action (N, Tmp_Node);
936          Convert_Aggr_In_Allocator (N, Tmp_Node, Exp);
937          Rewrite (N, New_Reference_To (Temp, Loc));
938          Analyze_And_Resolve (N, PtrT);
939
940       elsif Is_Access_Type (T)
941         and then Can_Never_Be_Null (T)
942       then
943          Install_Null_Excluding_Check (Exp);
944
945       elsif Is_Access_Type (DesigT)
946         and then Nkind (Exp) = N_Allocator
947         and then Nkind (Expression (Exp)) /= N_Qualified_Expression
948       then
949          --  Apply constraint to designated subtype indication
950
951          Apply_Constraint_Check (Expression (Exp),
952            Designated_Type (DesigT),
953            No_Sliding => True);
954
955          if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then
956
957             --  Propagate constraint_error to enclosing allocator
958
959             Rewrite (Exp, New_Copy (Expression (Exp)));
960          end if;
961       else
962          --  First check against the type of the qualified expression
963          --
964          --  NOTE: The commented call should be correct, but for some reason
965          --  causes the compiler to bomb (sigsegv) on ACVC test c34007g, so for
966          --  now we just perform the old (incorrect) test against the
967          --  designated subtype with no sliding in the else part of the if
968          --  statement below. ???
969          --
970          --  Apply_Constraint_Check (Exp, T, No_Sliding => True);
971
972          --  A check is also needed in cases where the designated subtype is
973          --  constrained and differs from the subtype given in the qualified
974          --  expression. Note that the check on the qualified expression does
975          --  not allow sliding, but this check does (a relaxation from Ada 83).
976
977          if Is_Constrained (DesigT)
978            and then not Subtypes_Statically_Match (T, DesigT)
979          then
980             Apply_Constraint_Check
981               (Exp, DesigT, No_Sliding => False);
982
983          --  The nonsliding check should really be performed (unconditionally)
984          --  against the subtype of the qualified expression, but that causes a
985          --  problem with c34007g (see above), so for now we retain this.
986
987          else
988             Apply_Constraint_Check
989               (Exp, DesigT, No_Sliding => True);
990          end if;
991
992          --  For an access to unconstrained packed array, GIGI needs to see an
993          --  expression with a constrained subtype in order to compute the
994          --  proper size for the allocator.
995
996          if Is_Array_Type (T)
997            and then not Is_Constrained (T)
998            and then Is_Packed (T)
999          then
1000             declare
1001                ConstrT      : constant Entity_Id :=
1002                                 Make_Defining_Identifier (Loc,
1003                                   Chars => New_Internal_Name ('A'));
1004                Internal_Exp : constant Node_Id   := Relocate_Node (Exp);
1005             begin
1006                Insert_Action (Exp,
1007                  Make_Subtype_Declaration (Loc,
1008                    Defining_Identifier => ConstrT,
1009                    Subtype_Indication  =>
1010                      Make_Subtype_From_Expr (Exp, T)));
1011                Freeze_Itype (ConstrT, Exp);
1012                Rewrite (Exp, OK_Convert_To (ConstrT, Internal_Exp));
1013             end;
1014          end if;
1015
1016          --  Ada 2005 (AI-318-02): If the initialization expression is a call
1017          --  to a build-in-place function, then access to the allocated object
1018          --  must be passed to the function. Currently we limit such functions
1019          --  to those with constrained limited result subtypes, but eventually
1020          --  we plan to expand the allowed forms of functions that are treated
1021          --  as build-in-place.
1022
1023          if Ada_Version >= Ada_05
1024            and then Is_Build_In_Place_Function_Call (Exp)
1025          then
1026             Make_Build_In_Place_Call_In_Allocator (N, Exp);
1027          end if;
1028       end if;
1029
1030    exception
1031       when RE_Not_Available =>
1032          return;
1033    end Expand_Allocator_Expression;
1034
1035    -----------------------------
1036    -- Expand_Array_Comparison --
1037    -----------------------------
1038
1039    --  Expansion is only required in the case of array types. For the unpacked
1040    --  case, an appropriate runtime routine is called. For packed cases, and
1041    --  also in some other cases where a runtime routine cannot be called, the
1042    --  form of the expansion is:
1043
1044    --     [body for greater_nn; boolean_expression]
1045
1046    --  The body is built by Make_Array_Comparison_Op, and the form of the
1047    --  Boolean expression depends on the operator involved.
1048
1049    procedure Expand_Array_Comparison (N : Node_Id) is
1050       Loc  : constant Source_Ptr := Sloc (N);
1051       Op1  : Node_Id             := Left_Opnd (N);
1052       Op2  : Node_Id             := Right_Opnd (N);
1053       Typ1 : constant Entity_Id  := Base_Type (Etype (Op1));
1054       Ctyp : constant Entity_Id  := Component_Type (Typ1);
1055
1056       Expr      : Node_Id;
1057       Func_Body : Node_Id;
1058       Func_Name : Entity_Id;
1059
1060       Comp : RE_Id;
1061
1062       Byte_Addressable : constant Boolean := System_Storage_Unit = Byte'Size;
1063       --  True for byte addressable target
1064
1065       function Length_Less_Than_4 (Opnd : Node_Id) return Boolean;
1066       --  Returns True if the length of the given operand is known to be less
1067       --  than 4. Returns False if this length is known to be four or greater
1068       --  or is not known at compile time.
1069
1070       ------------------------
1071       -- Length_Less_Than_4 --
1072       ------------------------
1073
1074       function Length_Less_Than_4 (Opnd : Node_Id) return Boolean is
1075          Otyp : constant Entity_Id := Etype (Opnd);
1076
1077       begin
1078          if Ekind (Otyp) = E_String_Literal_Subtype then
1079             return String_Literal_Length (Otyp) < 4;
1080
1081          else
1082             declare
1083                Ityp : constant Entity_Id := Etype (First_Index (Otyp));
1084                Lo   : constant Node_Id   := Type_Low_Bound (Ityp);
1085                Hi   : constant Node_Id   := Type_High_Bound (Ityp);
1086                Lov  : Uint;
1087                Hiv  : Uint;
1088
1089             begin
1090                if Compile_Time_Known_Value (Lo) then
1091                   Lov := Expr_Value (Lo);
1092                else
1093                   return False;
1094                end if;
1095
1096                if Compile_Time_Known_Value (Hi) then
1097                   Hiv := Expr_Value (Hi);
1098                else
1099                   return False;
1100                end if;
1101
1102                return Hiv < Lov + 3;
1103             end;
1104          end if;
1105       end Length_Less_Than_4;
1106
1107    --  Start of processing for Expand_Array_Comparison
1108
1109    begin
1110       --  Deal first with unpacked case, where we can call a runtime routine
1111       --  except that we avoid this for targets for which are not addressable
1112       --  by bytes, and for the JVM/CIL, since they do not support direct
1113       --  addressing of array components.
1114
1115       if not Is_Bit_Packed_Array (Typ1)
1116         and then Byte_Addressable
1117         and then VM_Target = No_VM
1118       then
1119          --  The call we generate is:
1120
1121          --  Compare_Array_xn[_Unaligned]
1122          --    (left'address, right'address, left'length, right'length) <op> 0
1123
1124          --  x = U for unsigned, S for signed
1125          --  n = 8,16,32,64 for component size
1126          --  Add _Unaligned if length < 4 and component size is 8.
1127          --  <op> is the standard comparison operator
1128
1129          if Component_Size (Typ1) = 8 then
1130             if Length_Less_Than_4 (Op1)
1131                  or else
1132                Length_Less_Than_4 (Op2)
1133             then
1134                if Is_Unsigned_Type (Ctyp) then
1135                   Comp := RE_Compare_Array_U8_Unaligned;
1136                else
1137                   Comp := RE_Compare_Array_S8_Unaligned;
1138                end if;
1139
1140             else
1141                if Is_Unsigned_Type (Ctyp) then
1142                   Comp := RE_Compare_Array_U8;
1143                else
1144                   Comp := RE_Compare_Array_S8;
1145                end if;
1146             end if;
1147
1148          elsif Component_Size (Typ1) = 16 then
1149             if Is_Unsigned_Type (Ctyp) then
1150                Comp := RE_Compare_Array_U16;
1151             else
1152                Comp := RE_Compare_Array_S16;
1153             end if;
1154
1155          elsif Component_Size (Typ1) = 32 then
1156             if Is_Unsigned_Type (Ctyp) then
1157                Comp := RE_Compare_Array_U32;
1158             else
1159                Comp := RE_Compare_Array_S32;
1160             end if;
1161
1162          else pragma Assert (Component_Size (Typ1) = 64);
1163             if Is_Unsigned_Type (Ctyp) then
1164                Comp := RE_Compare_Array_U64;
1165             else
1166                Comp := RE_Compare_Array_S64;
1167             end if;
1168          end if;
1169
1170          Remove_Side_Effects (Op1, Name_Req => True);
1171          Remove_Side_Effects (Op2, Name_Req => True);
1172
1173          Rewrite (Op1,
1174            Make_Function_Call (Sloc (Op1),
1175              Name => New_Occurrence_Of (RTE (Comp), Loc),
1176
1177              Parameter_Associations => New_List (
1178                Make_Attribute_Reference (Loc,
1179                  Prefix         => Relocate_Node (Op1),
1180                  Attribute_Name => Name_Address),
1181
1182                Make_Attribute_Reference (Loc,
1183                  Prefix         => Relocate_Node (Op2),
1184                  Attribute_Name => Name_Address),
1185
1186                Make_Attribute_Reference (Loc,
1187                  Prefix         => Relocate_Node (Op1),
1188                  Attribute_Name => Name_Length),
1189
1190                Make_Attribute_Reference (Loc,
1191                  Prefix         => Relocate_Node (Op2),
1192                  Attribute_Name => Name_Length))));
1193
1194          Rewrite (Op2,
1195            Make_Integer_Literal (Sloc (Op2),
1196              Intval => Uint_0));
1197
1198          Analyze_And_Resolve (Op1, Standard_Integer);
1199          Analyze_And_Resolve (Op2, Standard_Integer);
1200          return;
1201       end if;
1202
1203       --  Cases where we cannot make runtime call
1204
1205       --  For (a <= b) we convert to not (a > b)
1206
1207       if Chars (N) = Name_Op_Le then
1208          Rewrite (N,
1209            Make_Op_Not (Loc,
1210              Right_Opnd =>
1211                 Make_Op_Gt (Loc,
1212                  Left_Opnd  => Op1,
1213                  Right_Opnd => Op2)));
1214          Analyze_And_Resolve (N, Standard_Boolean);
1215          return;
1216
1217       --  For < the Boolean expression is
1218       --    greater__nn (op2, op1)
1219
1220       elsif Chars (N) = Name_Op_Lt then
1221          Func_Body := Make_Array_Comparison_Op (Typ1, N);
1222
1223          --  Switch operands
1224
1225          Op1 := Right_Opnd (N);
1226          Op2 := Left_Opnd  (N);
1227
1228       --  For (a >= b) we convert to not (a < b)
1229
1230       elsif Chars (N) = Name_Op_Ge then
1231          Rewrite (N,
1232            Make_Op_Not (Loc,
1233              Right_Opnd =>
1234                Make_Op_Lt (Loc,
1235                  Left_Opnd  => Op1,
1236                  Right_Opnd => Op2)));
1237          Analyze_And_Resolve (N, Standard_Boolean);
1238          return;
1239
1240       --  For > the Boolean expression is
1241       --    greater__nn (op1, op2)
1242
1243       else
1244          pragma Assert (Chars (N) = Name_Op_Gt);
1245          Func_Body := Make_Array_Comparison_Op (Typ1, N);
1246       end if;
1247
1248       Func_Name := Defining_Unit_Name (Specification (Func_Body));
1249       Expr :=
1250         Make_Function_Call (Loc,
1251           Name => New_Reference_To (Func_Name, Loc),
1252           Parameter_Associations => New_List (Op1, Op2));
1253
1254       Insert_Action (N, Func_Body);
1255       Rewrite (N, Expr);
1256       Analyze_And_Resolve (N, Standard_Boolean);
1257
1258    exception
1259       when RE_Not_Available =>
1260          return;
1261    end Expand_Array_Comparison;
1262
1263    ---------------------------
1264    -- Expand_Array_Equality --
1265    ---------------------------
1266
1267    --  Expand an equality function for multi-dimensional arrays. Here is an
1268    --  example of such a function for Nb_Dimension = 2
1269
1270    --  function Enn (A : atyp; B : btyp) return boolean is
1271    --  begin
1272    --     if (A'length (1) = 0 or else A'length (2) = 0)
1273    --          and then
1274    --        (B'length (1) = 0 or else B'length (2) = 0)
1275    --     then
1276    --        return True;    -- RM 4.5.2(22)
1277    --     end if;
1278
1279    --     if A'length (1) /= B'length (1)
1280    --               or else
1281    --           A'length (2) /= B'length (2)
1282    --     then
1283    --        return False;   -- RM 4.5.2(23)
1284    --     end if;
1285
1286    --     declare
1287    --        A1 : Index_T1 := A'first (1);
1288    --        B1 : Index_T1 := B'first (1);
1289    --     begin
1290    --        loop
1291    --           declare
1292    --              A2 : Index_T2 := A'first (2);
1293    --              B2 : Index_T2 := B'first (2);
1294    --           begin
1295    --              loop
1296    --                 if A (A1, A2) /= B (B1, B2) then
1297    --                    return False;
1298    --                 end if;
1299
1300    --                 exit when A2 = A'last (2);
1301    --                 A2 := Index_T2'succ (A2);
1302    --                 B2 := Index_T2'succ (B2);
1303    --              end loop;
1304    --           end;
1305
1306    --           exit when A1 = A'last (1);
1307    --           A1 := Index_T1'succ (A1);
1308    --           B1 := Index_T1'succ (B1);
1309    --        end loop;
1310    --     end;
1311
1312    --     return true;
1313    --  end Enn;
1314
1315    --  Note on the formal types used (atyp and btyp). If either of the arrays
1316    --  is of a private type, we use the underlying type, and do an unchecked
1317    --  conversion of the actual. If either of the arrays has a bound depending
1318    --  on a discriminant, then we use the base type since otherwise we have an
1319    --  escaped discriminant in the function.
1320
1321    --  If both arrays are constrained and have the same bounds, we can generate
1322    --  a loop with an explicit iteration scheme using a 'Range attribute over
1323    --  the first array.
1324
1325    function Expand_Array_Equality
1326      (Nod    : Node_Id;
1327       Lhs    : Node_Id;
1328       Rhs    : Node_Id;
1329       Bodies : List_Id;
1330       Typ    : Entity_Id) return Node_Id
1331    is
1332       Loc         : constant Source_Ptr := Sloc (Nod);
1333       Decls       : constant List_Id    := New_List;
1334       Index_List1 : constant List_Id    := New_List;
1335       Index_List2 : constant List_Id    := New_List;
1336
1337       Actuals   : List_Id;
1338       Formals   : List_Id;
1339       Func_Name : Entity_Id;
1340       Func_Body : Node_Id;
1341
1342       A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
1343       B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
1344
1345       Ltyp : Entity_Id;
1346       Rtyp : Entity_Id;
1347       --  The parameter types to be used for the formals
1348
1349       function Arr_Attr
1350         (Arr : Entity_Id;
1351          Nam : Name_Id;
1352          Num : Int) return Node_Id;
1353       --  This builds the attribute reference Arr'Nam (Expr)
1354
1355       function Component_Equality (Typ : Entity_Id) return Node_Id;
1356       --  Create one statement to compare corresponding components, designated
1357       --  by a full set of indices.
1358
1359       function Get_Arg_Type (N : Node_Id) return Entity_Id;
1360       --  Given one of the arguments, computes the appropriate type to be used
1361       --  for that argument in the corresponding function formal
1362
1363       function Handle_One_Dimension
1364         (N     : Int;
1365          Index : Node_Id) return Node_Id;
1366       --  This procedure returns the following code
1367       --
1368       --    declare
1369       --       Bn : Index_T := B'First (N);
1370       --    begin
1371       --       loop
1372       --          xxx
1373       --          exit when An = A'Last (N);
1374       --          An := Index_T'Succ (An)
1375       --          Bn := Index_T'Succ (Bn)
1376       --       end loop;
1377       --    end;
1378       --
1379       --  If both indices are constrained and identical, the procedure
1380       --  returns a simpler loop:
1381       --
1382       --      for An in A'Range (N) loop
1383       --         xxx
1384       --      end loop
1385       --
1386       --  N is the dimension for which we are generating a loop. Index is the
1387       --  N'th index node, whose Etype is Index_Type_n in the above code. The
1388       --  xxx statement is either the loop or declare for the next dimension
1389       --  or if this is the last dimension the comparison of corresponding
1390       --  components of the arrays.
1391       --
1392       --  The actual way the code works is to return the comparison of
1393       --  corresponding components for the N+1 call. That's neater!
1394
1395       function Test_Empty_Arrays return Node_Id;
1396       --  This function constructs the test for both arrays being empty
1397       --    (A'length (1) = 0 or else A'length (2) = 0 or else ...)
1398       --      and then
1399       --    (B'length (1) = 0 or else B'length (2) = 0 or else ...)
1400
1401       function Test_Lengths_Correspond return Node_Id;
1402       --  This function constructs the test for arrays having different lengths
1403       --  in at least one index position, in which case the resulting code is:
1404
1405       --     A'length (1) /= B'length (1)
1406       --       or else
1407       --     A'length (2) /= B'length (2)
1408       --       or else
1409       --       ...
1410
1411       --------------
1412       -- Arr_Attr --
1413       --------------
1414
1415       function Arr_Attr
1416         (Arr : Entity_Id;
1417          Nam : Name_Id;
1418          Num : Int) return Node_Id
1419       is
1420       begin
1421          return
1422            Make_Attribute_Reference (Loc,
1423             Attribute_Name => Nam,
1424             Prefix => New_Reference_To (Arr, Loc),
1425             Expressions => New_List (Make_Integer_Literal (Loc, Num)));
1426       end Arr_Attr;
1427
1428       ------------------------
1429       -- Component_Equality --
1430       ------------------------
1431
1432       function Component_Equality (Typ : Entity_Id) return Node_Id is
1433          Test : Node_Id;
1434          L, R : Node_Id;
1435
1436       begin
1437          --  if a(i1...) /= b(j1...) then return false; end if;
1438
1439          L :=
1440            Make_Indexed_Component (Loc,
1441              Prefix => Make_Identifier (Loc, Chars (A)),
1442              Expressions => Index_List1);
1443
1444          R :=
1445            Make_Indexed_Component (Loc,
1446              Prefix => Make_Identifier (Loc, Chars (B)),
1447              Expressions => Index_List2);
1448
1449          Test := Expand_Composite_Equality
1450                    (Nod, Component_Type (Typ), L, R, Decls);
1451
1452          --  If some (sub)component is an unchecked_union, the whole operation
1453          --  will raise program error.
1454
1455          if Nkind (Test) = N_Raise_Program_Error then
1456
1457             --  This node is going to be inserted at a location where a
1458             --  statement is expected: clear its Etype so analysis will set
1459             --  it to the expected Standard_Void_Type.
1460
1461             Set_Etype (Test, Empty);
1462             return Test;
1463
1464          else
1465             return
1466               Make_Implicit_If_Statement (Nod,
1467                 Condition => Make_Op_Not (Loc, Right_Opnd => Test),
1468                 Then_Statements => New_List (
1469                   Make_Simple_Return_Statement (Loc,
1470                     Expression => New_Occurrence_Of (Standard_False, Loc))));
1471          end if;
1472       end Component_Equality;
1473
1474       ------------------
1475       -- Get_Arg_Type --
1476       ------------------
1477
1478       function Get_Arg_Type (N : Node_Id) return Entity_Id is
1479          T : Entity_Id;
1480          X : Node_Id;
1481
1482       begin
1483          T := Etype (N);
1484
1485          if No (T) then
1486             return Typ;
1487
1488          else
1489             T := Underlying_Type (T);
1490
1491             X := First_Index (T);
1492             while Present (X) loop
1493                if Denotes_Discriminant (Type_Low_Bound (Etype (X)))
1494                  or else
1495                    Denotes_Discriminant (Type_High_Bound (Etype (X)))
1496                then
1497                   T := Base_Type (T);
1498                   exit;
1499                end if;
1500
1501                Next_Index (X);
1502             end loop;
1503
1504             return T;
1505          end if;
1506       end Get_Arg_Type;
1507
1508       --------------------------
1509       -- Handle_One_Dimension --
1510       ---------------------------
1511
1512       function Handle_One_Dimension
1513         (N     : Int;
1514          Index : Node_Id) return Node_Id
1515       is
1516          Need_Separate_Indexes : constant Boolean :=
1517                                    Ltyp /= Rtyp
1518                                      or else not Is_Constrained (Ltyp);
1519          --  If the index types are identical, and we are working with
1520          --  constrained types, then we can use the same index for both
1521          --  of the arrays.
1522
1523          An : constant Entity_Id := Make_Defining_Identifier (Loc,
1524                                       Chars => New_Internal_Name ('A'));
1525
1526          Bn       : Entity_Id;
1527          Index_T  : Entity_Id;
1528          Stm_List : List_Id;
1529          Loop_Stm : Node_Id;
1530
1531       begin
1532          if N > Number_Dimensions (Ltyp) then
1533             return Component_Equality (Ltyp);
1534          end if;
1535
1536          --  Case where we generate a loop
1537
1538          Index_T := Base_Type (Etype (Index));
1539
1540          if Need_Separate_Indexes then
1541             Bn :=
1542               Make_Defining_Identifier (Loc,
1543                 Chars => New_Internal_Name ('B'));
1544          else
1545             Bn := An;
1546          end if;
1547
1548          Append (New_Reference_To (An, Loc), Index_List1);
1549          Append (New_Reference_To (Bn, Loc), Index_List2);
1550
1551          Stm_List := New_List (
1552            Handle_One_Dimension (N + 1, Next_Index (Index)));
1553
1554          if Need_Separate_Indexes then
1555
1556             --  Generate guard for loop, followed by increments of indices
1557
1558             Append_To (Stm_List,
1559                Make_Exit_Statement (Loc,
1560                  Condition =>
1561                    Make_Op_Eq (Loc,
1562                       Left_Opnd => New_Reference_To (An, Loc),
1563                       Right_Opnd => Arr_Attr (A, Name_Last, N))));
1564
1565             Append_To (Stm_List,
1566               Make_Assignment_Statement (Loc,
1567                 Name       => New_Reference_To (An, Loc),
1568                 Expression =>
1569                   Make_Attribute_Reference (Loc,
1570                     Prefix         => New_Reference_To (Index_T, Loc),
1571                     Attribute_Name => Name_Succ,
1572                     Expressions    => New_List (New_Reference_To (An, Loc)))));
1573
1574             Append_To (Stm_List,
1575               Make_Assignment_Statement (Loc,
1576                 Name       => New_Reference_To (Bn, Loc),
1577                 Expression =>
1578                   Make_Attribute_Reference (Loc,
1579                     Prefix         => New_Reference_To (Index_T, Loc),
1580                     Attribute_Name => Name_Succ,
1581                     Expressions    => New_List (New_Reference_To (Bn, Loc)))));
1582          end if;
1583
1584          --  If separate indexes, we need a declare block for An and Bn, and a
1585          --  loop without an iteration scheme.
1586
1587          if Need_Separate_Indexes then
1588             Loop_Stm :=
1589               Make_Implicit_Loop_Statement (Nod, Statements => Stm_List);
1590
1591             return
1592               Make_Block_Statement (Loc,
1593                 Declarations => New_List (
1594                   Make_Object_Declaration (Loc,
1595                     Defining_Identifier => An,
1596                     Object_Definition   => New_Reference_To (Index_T, Loc),
1597                     Expression          => Arr_Attr (A, Name_First, N)),
1598
1599                   Make_Object_Declaration (Loc,
1600                     Defining_Identifier => Bn,
1601                     Object_Definition   => New_Reference_To (Index_T, Loc),
1602                     Expression          => Arr_Attr (B, Name_First, N))),
1603
1604                 Handled_Statement_Sequence =>
1605                   Make_Handled_Sequence_Of_Statements (Loc,
1606                     Statements => New_List (Loop_Stm)));
1607
1608          --  If no separate indexes, return loop statement with explicit
1609          --  iteration scheme on its own
1610
1611          else
1612             Loop_Stm :=
1613               Make_Implicit_Loop_Statement (Nod,
1614                 Statements       => Stm_List,
1615                 Iteration_Scheme =>
1616                   Make_Iteration_Scheme (Loc,
1617                     Loop_Parameter_Specification =>
1618                       Make_Loop_Parameter_Specification (Loc,
1619                         Defining_Identifier         => An,
1620                         Discrete_Subtype_Definition =>
1621                           Arr_Attr (A, Name_Range, N))));
1622             return Loop_Stm;
1623          end if;
1624       end Handle_One_Dimension;
1625
1626       -----------------------
1627       -- Test_Empty_Arrays --
1628       -----------------------
1629
1630       function Test_Empty_Arrays return Node_Id is
1631          Alist : Node_Id;
1632          Blist : Node_Id;
1633
1634          Atest : Node_Id;
1635          Btest : Node_Id;
1636
1637       begin
1638          Alist := Empty;
1639          Blist := Empty;
1640          for J in 1 .. Number_Dimensions (Ltyp) loop
1641             Atest :=
1642               Make_Op_Eq (Loc,
1643                 Left_Opnd  => Arr_Attr (A, Name_Length, J),
1644                 Right_Opnd => Make_Integer_Literal (Loc, 0));
1645
1646             Btest :=
1647               Make_Op_Eq (Loc,
1648                 Left_Opnd  => Arr_Attr (B, Name_Length, J),
1649                 Right_Opnd => Make_Integer_Literal (Loc, 0));
1650
1651             if No (Alist) then
1652                Alist := Atest;
1653                Blist := Btest;
1654
1655             else
1656                Alist :=
1657                  Make_Or_Else (Loc,
1658                    Left_Opnd  => Relocate_Node (Alist),
1659                    Right_Opnd => Atest);
1660
1661                Blist :=
1662                  Make_Or_Else (Loc,
1663                    Left_Opnd  => Relocate_Node (Blist),
1664                    Right_Opnd => Btest);
1665             end if;
1666          end loop;
1667
1668          return
1669            Make_And_Then (Loc,
1670              Left_Opnd  => Alist,
1671              Right_Opnd => Blist);
1672       end Test_Empty_Arrays;
1673
1674       -----------------------------
1675       -- Test_Lengths_Correspond --
1676       -----------------------------
1677
1678       function Test_Lengths_Correspond return Node_Id is
1679          Result : Node_Id;
1680          Rtest  : Node_Id;
1681
1682       begin
1683          Result := Empty;
1684          for J in 1 .. Number_Dimensions (Ltyp) loop
1685             Rtest :=
1686               Make_Op_Ne (Loc,
1687                 Left_Opnd  => Arr_Attr (A, Name_Length, J),
1688                 Right_Opnd => Arr_Attr (B, Name_Length, J));
1689
1690             if No (Result) then
1691                Result := Rtest;
1692             else
1693                Result :=
1694                  Make_Or_Else (Loc,
1695                    Left_Opnd  => Relocate_Node (Result),
1696                    Right_Opnd => Rtest);
1697             end if;
1698          end loop;
1699
1700          return Result;
1701       end Test_Lengths_Correspond;
1702
1703    --  Start of processing for Expand_Array_Equality
1704
1705    begin
1706       Ltyp := Get_Arg_Type (Lhs);
1707       Rtyp := Get_Arg_Type (Rhs);
1708
1709       --  For now, if the argument types are not the same, go to the base type,
1710       --  since the code assumes that the formals have the same type. This is
1711       --  fixable in future ???
1712
1713       if Ltyp /= Rtyp then
1714          Ltyp := Base_Type (Ltyp);
1715          Rtyp := Base_Type (Rtyp);
1716          pragma Assert (Ltyp = Rtyp);
1717       end if;
1718
1719       --  Build list of formals for function
1720
1721       Formals := New_List (
1722         Make_Parameter_Specification (Loc,
1723           Defining_Identifier => A,
1724           Parameter_Type      => New_Reference_To (Ltyp, Loc)),
1725
1726         Make_Parameter_Specification (Loc,
1727           Defining_Identifier => B,
1728           Parameter_Type      => New_Reference_To (Rtyp, Loc)));
1729
1730       Func_Name := Make_Defining_Identifier (Loc,  New_Internal_Name ('E'));
1731
1732       --  Build statement sequence for function
1733
1734       Func_Body :=
1735         Make_Subprogram_Body (Loc,
1736           Specification =>
1737             Make_Function_Specification (Loc,
1738               Defining_Unit_Name       => Func_Name,
1739               Parameter_Specifications => Formals,
1740               Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
1741
1742           Declarations =>  Decls,
1743
1744           Handled_Statement_Sequence =>
1745             Make_Handled_Sequence_Of_Statements (Loc,
1746               Statements => New_List (
1747
1748                 Make_Implicit_If_Statement (Nod,
1749                   Condition => Test_Empty_Arrays,
1750                   Then_Statements => New_List (
1751                     Make_Simple_Return_Statement (Loc,
1752                       Expression =>
1753                         New_Occurrence_Of (Standard_True, Loc)))),
1754
1755                 Make_Implicit_If_Statement (Nod,
1756                   Condition => Test_Lengths_Correspond,
1757                   Then_Statements => New_List (
1758                     Make_Simple_Return_Statement (Loc,
1759                       Expression =>
1760                         New_Occurrence_Of (Standard_False, Loc)))),
1761
1762                 Handle_One_Dimension (1, First_Index (Ltyp)),
1763
1764                 Make_Simple_Return_Statement (Loc,
1765                   Expression => New_Occurrence_Of (Standard_True, Loc)))));
1766
1767          Set_Has_Completion (Func_Name, True);
1768          Set_Is_Inlined (Func_Name);
1769
1770          --  If the array type is distinct from the type of the arguments, it
1771          --  is the full view of a private type. Apply an unchecked conversion
1772          --  to insure that analysis of the call succeeds.
1773
1774          declare
1775             L, R : Node_Id;
1776
1777          begin
1778             L := Lhs;
1779             R := Rhs;
1780
1781             if No (Etype (Lhs))
1782               or else Base_Type (Etype (Lhs)) /= Base_Type (Ltyp)
1783             then
1784                L := OK_Convert_To (Ltyp, Lhs);
1785             end if;
1786
1787             if No (Etype (Rhs))
1788               or else Base_Type (Etype (Rhs)) /= Base_Type (Rtyp)
1789             then
1790                R := OK_Convert_To (Rtyp, Rhs);
1791             end if;
1792
1793             Actuals := New_List (L, R);
1794          end;
1795
1796          Append_To (Bodies, Func_Body);
1797
1798          return
1799            Make_Function_Call (Loc,
1800              Name                   => New_Reference_To (Func_Name, Loc),
1801              Parameter_Associations => Actuals);
1802    end Expand_Array_Equality;
1803
1804    -----------------------------
1805    -- Expand_Boolean_Operator --
1806    -----------------------------
1807
1808    --  Note that we first get the actual subtypes of the operands, since we
1809    --  always want to deal with types that have bounds.
1810
1811    procedure Expand_Boolean_Operator (N : Node_Id) is
1812       Typ : constant Entity_Id  := Etype (N);
1813
1814    begin
1815       --  Special case of bit packed array where both operands are known to be
1816       --  properly aligned. In this case we use an efficient run time routine
1817       --  to carry out the operation (see System.Bit_Ops).
1818
1819       if Is_Bit_Packed_Array (Typ)
1820         and then not Is_Possibly_Unaligned_Object (Left_Opnd (N))
1821         and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
1822       then
1823          Expand_Packed_Boolean_Operator (N);
1824          return;
1825       end if;
1826
1827       --  For the normal non-packed case, the general expansion is to build
1828       --  function for carrying out the comparison (use Make_Boolean_Array_Op)
1829       --  and then inserting it into the tree. The original operator node is
1830       --  then rewritten as a call to this function. We also use this in the
1831       --  packed case if either operand is a possibly unaligned object.
1832
1833       declare
1834          Loc       : constant Source_Ptr := Sloc (N);
1835          L         : constant Node_Id    := Relocate_Node (Left_Opnd  (N));
1836          R         : constant Node_Id    := Relocate_Node (Right_Opnd (N));
1837          Func_Body : Node_Id;
1838          Func_Name : Entity_Id;
1839
1840       begin
1841          Convert_To_Actual_Subtype (L);
1842          Convert_To_Actual_Subtype (R);
1843          Ensure_Defined (Etype (L), N);
1844          Ensure_Defined (Etype (R), N);
1845          Apply_Length_Check (R, Etype (L));
1846
1847          if Nkind (N) = N_Op_Xor then
1848             Silly_Boolean_Array_Xor_Test (N, Etype (L));
1849          end if;
1850
1851          if Nkind (Parent (N)) = N_Assignment_Statement
1852            and then Safe_In_Place_Array_Op (Name (Parent (N)), L, R)
1853          then
1854             Build_Boolean_Array_Proc_Call (Parent (N), L, R);
1855
1856          elsif Nkind (Parent (N)) = N_Op_Not
1857            and then Nkind (N) = N_Op_And
1858            and then
1859              Safe_In_Place_Array_Op (Name (Parent (Parent (N))), L, R)
1860          then
1861             return;
1862          else
1863
1864             Func_Body := Make_Boolean_Array_Op (Etype (L), N);
1865             Func_Name := Defining_Unit_Name (Specification (Func_Body));
1866             Insert_Action (N, Func_Body);
1867
1868             --  Now rewrite the expression with a call
1869
1870             Rewrite (N,
1871               Make_Function_Call (Loc,
1872                 Name                   => New_Reference_To (Func_Name, Loc),
1873                 Parameter_Associations =>
1874                   New_List (
1875                     L,
1876                     Make_Type_Conversion
1877                       (Loc, New_Reference_To (Etype (L), Loc), R))));
1878
1879             Analyze_And_Resolve (N, Typ);
1880          end if;
1881       end;
1882    end Expand_Boolean_Operator;
1883
1884    -------------------------------
1885    -- Expand_Composite_Equality --
1886    -------------------------------
1887
1888    --  This function is only called for comparing internal fields of composite
1889    --  types when these fields are themselves composites. This is a special
1890    --  case because it is not possible to respect normal Ada visibility rules.
1891
1892    function Expand_Composite_Equality
1893      (Nod    : Node_Id;
1894       Typ    : Entity_Id;
1895       Lhs    : Node_Id;
1896       Rhs    : Node_Id;
1897       Bodies : List_Id) return Node_Id
1898    is
1899       Loc       : constant Source_Ptr := Sloc (Nod);
1900       Full_Type : Entity_Id;
1901       Prim      : Elmt_Id;
1902       Eq_Op     : Entity_Id;
1903
1904    begin
1905       if Is_Private_Type (Typ) then
1906          Full_Type := Underlying_Type (Typ);
1907       else
1908          Full_Type := Typ;
1909       end if;
1910
1911       --  Defense against malformed private types with no completion the error
1912       --  will be diagnosed later by check_completion
1913
1914       if No (Full_Type) then
1915          return New_Reference_To (Standard_False, Loc);
1916       end if;
1917
1918       Full_Type := Base_Type (Full_Type);
1919
1920       if Is_Array_Type (Full_Type) then
1921
1922          --  If the operand is an elementary type other than a floating-point
1923          --  type, then we can simply use the built-in block bitwise equality,
1924          --  since the predefined equality operators always apply and bitwise
1925          --  equality is fine for all these cases.
1926
1927          if Is_Elementary_Type (Component_Type (Full_Type))
1928            and then not Is_Floating_Point_Type (Component_Type (Full_Type))
1929          then
1930             return Make_Op_Eq (Loc, Left_Opnd  => Lhs, Right_Opnd => Rhs);
1931
1932          --  For composite component types, and floating-point types, use the
1933          --  expansion. This deals with tagged component types (where we use
1934          --  the applicable equality routine) and floating-point, (where we
1935          --  need to worry about negative zeroes), and also the case of any
1936          --  composite type recursively containing such fields.
1937
1938          else
1939             return Expand_Array_Equality (Nod, Lhs, Rhs, Bodies, Full_Type);
1940          end if;
1941
1942       elsif Is_Tagged_Type (Full_Type) then
1943
1944          --  Call the primitive operation "=" of this type
1945
1946          if Is_Class_Wide_Type (Full_Type) then
1947             Full_Type := Root_Type (Full_Type);
1948          end if;
1949
1950          --  If this is derived from an untagged private type completed with a
1951          --  tagged type, it does not have a full view, so we use the primitive
1952          --  operations of the private type. This check should no longer be
1953          --  necessary when these types receive their full views ???
1954
1955          if Is_Private_Type (Typ)
1956            and then not Is_Tagged_Type (Typ)
1957            and then not Is_Controlled (Typ)
1958            and then Is_Derived_Type (Typ)
1959            and then No (Full_View (Typ))
1960          then
1961             Prim := First_Elmt (Collect_Primitive_Operations (Typ));
1962          else
1963             Prim := First_Elmt (Primitive_Operations (Full_Type));
1964          end if;
1965
1966          loop
1967             Eq_Op := Node (Prim);
1968             exit when Chars (Eq_Op) = Name_Op_Eq
1969               and then Etype (First_Formal (Eq_Op)) =
1970                        Etype (Next_Formal (First_Formal (Eq_Op)))
1971               and then Base_Type (Etype (Eq_Op)) = Standard_Boolean;
1972             Next_Elmt (Prim);
1973             pragma Assert (Present (Prim));
1974          end loop;
1975
1976          Eq_Op := Node (Prim);
1977
1978          return
1979            Make_Function_Call (Loc,
1980              Name => New_Reference_To (Eq_Op, Loc),
1981              Parameter_Associations =>
1982                New_List
1983                  (Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Lhs),
1984                   Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Rhs)));
1985
1986       elsif Is_Record_Type (Full_Type) then
1987          Eq_Op := TSS (Full_Type, TSS_Composite_Equality);
1988
1989          if Present (Eq_Op) then
1990             if Etype (First_Formal (Eq_Op)) /= Full_Type then
1991
1992                --  Inherited equality from parent type. Convert the actuals to
1993                --  match signature of operation.
1994
1995                declare
1996                   T : constant Entity_Id := Etype (First_Formal (Eq_Op));
1997
1998                begin
1999                   return
2000                     Make_Function_Call (Loc,
2001                       Name => New_Reference_To (Eq_Op, Loc),
2002                       Parameter_Associations =>
2003                         New_List (OK_Convert_To (T, Lhs),
2004                                   OK_Convert_To (T, Rhs)));
2005                end;
2006
2007             else
2008                --  Comparison between Unchecked_Union components
2009
2010                if Is_Unchecked_Union (Full_Type) then
2011                   declare
2012                      Lhs_Type      : Node_Id := Full_Type;
2013                      Rhs_Type      : Node_Id := Full_Type;
2014                      Lhs_Discr_Val : Node_Id;
2015                      Rhs_Discr_Val : Node_Id;
2016
2017                   begin
2018                      --  Lhs subtype
2019
2020                      if Nkind (Lhs) = N_Selected_Component then
2021                         Lhs_Type := Etype (Entity (Selector_Name (Lhs)));
2022                      end if;
2023
2024                      --  Rhs subtype
2025
2026                      if Nkind (Rhs) = N_Selected_Component then
2027                         Rhs_Type := Etype (Entity (Selector_Name (Rhs)));
2028                      end if;
2029
2030                      --  Lhs of the composite equality
2031
2032                      if Is_Constrained (Lhs_Type) then
2033
2034                         --  Since the enclosing record type can never be an
2035                         --  Unchecked_Union (this code is executed for records
2036                         --  that do not have variants), we may reference its
2037                         --  discriminant(s).
2038
2039                         if Nkind (Lhs) = N_Selected_Component
2040                           and then Has_Per_Object_Constraint (
2041                                      Entity (Selector_Name (Lhs)))
2042                         then
2043                            Lhs_Discr_Val :=
2044                              Make_Selected_Component (Loc,
2045                                Prefix => Prefix (Lhs),
2046                                Selector_Name =>
2047                                  New_Copy (
2048                                    Get_Discriminant_Value (
2049                                      First_Discriminant (Lhs_Type),
2050                                      Lhs_Type,
2051                                      Stored_Constraint (Lhs_Type))));
2052
2053                         else
2054                            Lhs_Discr_Val := New_Copy (
2055                              Get_Discriminant_Value (
2056                                First_Discriminant (Lhs_Type),
2057                                Lhs_Type,
2058                                Stored_Constraint (Lhs_Type)));
2059
2060                         end if;
2061                      else
2062                         --  It is not possible to infer the discriminant since
2063                         --  the subtype is not constrained.
2064
2065                         return
2066                           Make_Raise_Program_Error (Loc,
2067                             Reason => PE_Unchecked_Union_Restriction);
2068                      end if;
2069
2070                      --  Rhs of the composite equality
2071
2072                      if Is_Constrained (Rhs_Type) then
2073                         if Nkind (Rhs) = N_Selected_Component
2074                           and then Has_Per_Object_Constraint (
2075                                      Entity (Selector_Name (Rhs)))
2076                         then
2077                            Rhs_Discr_Val :=
2078                              Make_Selected_Component (Loc,
2079                                Prefix => Prefix (Rhs),
2080                                Selector_Name =>
2081                                  New_Copy (
2082                                    Get_Discriminant_Value (
2083                                      First_Discriminant (Rhs_Type),
2084                                      Rhs_Type,
2085                                      Stored_Constraint (Rhs_Type))));
2086
2087                         else
2088                            Rhs_Discr_Val := New_Copy (
2089                              Get_Discriminant_Value (
2090                                First_Discriminant (Rhs_Type),
2091                                Rhs_Type,
2092                                Stored_Constraint (Rhs_Type)));
2093
2094                         end if;
2095                      else
2096                         return
2097                           Make_Raise_Program_Error (Loc,
2098                             Reason => PE_Unchecked_Union_Restriction);
2099                      end if;
2100
2101                      --  Call the TSS equality function with the inferred
2102                      --  discriminant values.
2103
2104                      return
2105                        Make_Function_Call (Loc,
2106                          Name => New_Reference_To (Eq_Op, Loc),
2107                          Parameter_Associations => New_List (
2108                            Lhs,
2109                            Rhs,
2110                            Lhs_Discr_Val,
2111                            Rhs_Discr_Val));
2112                   end;
2113                end if;
2114
2115                --  Shouldn't this be an else, we can't fall through the above
2116                --  IF, right???
2117
2118                return
2119                  Make_Function_Call (Loc,
2120                    Name => New_Reference_To (Eq_Op, Loc),
2121                    Parameter_Associations => New_List (Lhs, Rhs));
2122             end if;
2123
2124          else
2125             return Expand_Record_Equality (Nod, Full_Type, Lhs, Rhs, Bodies);
2126          end if;
2127
2128       else
2129          --  It can be a simple record or the full view of a scalar private
2130
2131          return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
2132       end if;
2133    end Expand_Composite_Equality;
2134
2135    ------------------------
2136    -- Expand_Concatenate --
2137    ------------------------
2138
2139    procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id) is
2140       Loc : constant Source_Ptr := Sloc (Cnode);
2141
2142       Atyp : constant Entity_Id := Base_Type (Etype (Cnode));
2143       --  Result type of concatenation
2144
2145       Ctyp : constant Entity_Id := Base_Type (Component_Type (Etype (Cnode)));
2146       --  Component type. Elements of this component type can appear as one
2147       --  of the operands of concatenation as well as arrays.
2148
2149       Istyp : constant Entity_Id := Etype (First_Index (Atyp));
2150       --  Index subtype
2151
2152       Ityp : constant Entity_Id := Base_Type (Istyp);
2153       --  Index type. This is the base type of the index subtype, and is used
2154       --  for all computed bounds (which may be out of range of Istyp in the
2155       --  case of null ranges).
2156
2157       Artyp : Entity_Id;
2158       --  This is the type we use to do arithmetic to compute the bounds and
2159       --  lengths of operands. The choice of this type is a little subtle and
2160       --  is discussed in a separate section at the start of the body code.
2161
2162       Concatenation_Error : exception;
2163       --  Raised if concatenation is sure to raise a CE
2164
2165       Result_May_Be_Null : Boolean := True;
2166       --  Reset to False if at least one operand is encountered which is known
2167       --  at compile time to be non-null. Used for handling the special case
2168       --  of setting the high bound to the last operand high bound for a null
2169       --  result, thus ensuring a proper high bound in the super-flat case.
2170
2171       N : constant Nat := List_Length (Opnds);
2172       --  Number of concatenation operands including possibly null operands
2173
2174       NN : Nat := 0;
2175       --  Number of operands excluding any known to be null, except that the
2176       --  last operand is always retained, in case it provides the bounds for
2177       --  a null result.
2178
2179       Opnd : Node_Id;
2180       --  Current operand being processed in the loop through operands. After
2181       --  this loop is complete, always contains the last operand (which is not
2182       --  the same as Operands (NN), since null operands are skipped).
2183
2184       --  Arrays describing the operands, only the first NN entries of each
2185       --  array are set (NN < N when we exclude known null operands).
2186
2187       Is_Fixed_Length : array (1 .. N) of Boolean;
2188       --  True if length of corresponding operand known at compile time
2189
2190       Operands : array (1 .. N) of Node_Id;
2191       --  Set to the corresponding entry in the Opnds list (but note that null
2192       --  operands are excluded, so not all entries in the list are stored).
2193
2194       Fixed_Length : array (1 .. N) of Uint;
2195       --  Set to length of operand. Entries in this array are set only if the
2196       --  corresponding entry in Is_Fixed_Length is True.
2197
2198       Opnd_Low_Bound : array (1 .. N) of Node_Id;
2199       --  Set to lower bound of operand. Either an integer literal in the case
2200       --  where the bound is known at compile time, else actual lower bound.
2201       --  The operand low bound is of type Ityp.
2202
2203       Var_Length : array (1 .. N) of Entity_Id;
2204       --  Set to an entity of type Natural that contains the length of an
2205       --  operand whose length is not known at compile time. Entries in this
2206       --  array are set only if the corresponding entry in Is_Fixed_Length
2207       --  is False. The entity is of type Artyp.
2208
2209       Aggr_Length : array (0 .. N) of Node_Id;
2210       --  The J'th entry in an expression node that represents the total length
2211       --  of operands 1 through J. It is either an integer literal node, or a
2212       --  reference to a constant entity with the right value, so it is fine
2213       --  to just do a Copy_Node to get an appropriate copy. The extra zero'th
2214       --  entry always is set to zero. The length is of type Artyp.
2215
2216       Low_Bound : Node_Id;
2217       --  A tree node representing the low bound of the result (of type Ityp).
2218       --  This is either an integer literal node, or an identifier reference to
2219       --  a constant entity initialized to the appropriate value.
2220
2221       Last_Opnd_High_Bound : Node_Id;
2222       --  A tree node representing the high bound of the last operand. This
2223       --  need only be set if the result could be null. It is used for the
2224       --  special case of setting the right high bound for a null result.
2225       --  This is of type Ityp.
2226
2227       High_Bound : Node_Id;
2228       --  A tree node representing the high bound of the result (of type Ityp)
2229
2230       Result : Node_Id;
2231       --  Result of the concatenation (of type Ityp)
2232
2233       Known_Non_Null_Operand_Seen : Boolean;
2234       --  Set True during generation of the assignements of operands into
2235       --  result once an operand known to be non-null has been seen.
2236
2237       function Make_Artyp_Literal (Val : Nat) return Node_Id;
2238       --  This function makes an N_Integer_Literal node that is returned in
2239       --  analyzed form with the type set to Artyp. Importantly this literal
2240       --  is not flagged as static, so that if we do computations with it that
2241       --  result in statically detected out of range conditions, we will not
2242       --  generate error messages but instead warning messages.
2243
2244       function To_Artyp (X : Node_Id) return Node_Id;
2245       --  Given a node of type Ityp, returns the corresponding value of type
2246       --  Artyp. For non-enumeration types, this is a plain integer conversion.
2247       --  For enum types, the Pos of the value is returned.
2248
2249       function To_Ityp (X : Node_Id) return Node_Id;
2250       --  The inverse function (uses Val in the case of enumeration types)
2251
2252       ------------------------
2253       -- Make_Artyp_Literal --
2254       ------------------------
2255
2256       function Make_Artyp_Literal (Val : Nat) return Node_Id is
2257          Result : constant Node_Id := Make_Integer_Literal (Loc, Val);
2258       begin
2259          Set_Etype (Result, Artyp);
2260          Set_Analyzed (Result, True);
2261          Set_Is_Static_Expression (Result, False);
2262          return Result;
2263       end Make_Artyp_Literal;
2264
2265       --------------
2266       -- To_Artyp --
2267       --------------
2268
2269       function To_Artyp (X : Node_Id) return Node_Id is
2270       begin
2271          if Ityp = Base_Type (Artyp) then
2272             return X;
2273
2274          elsif Is_Enumeration_Type (Ityp) then
2275             return
2276               Make_Attribute_Reference (Loc,
2277                 Prefix         => New_Occurrence_Of (Ityp, Loc),
2278                 Attribute_Name => Name_Pos,
2279                 Expressions    => New_List (X));
2280
2281          else
2282             return Convert_To (Artyp, X);
2283          end if;
2284       end To_Artyp;
2285
2286       -------------
2287       -- To_Ityp --
2288       -------------
2289
2290       function To_Ityp (X : Node_Id) return Node_Id is
2291       begin
2292          if Is_Enumeration_Type (Ityp) then
2293             return
2294               Make_Attribute_Reference (Loc,
2295                 Prefix         => New_Occurrence_Of (Ityp, Loc),
2296                 Attribute_Name => Name_Val,
2297                 Expressions    => New_List (X));
2298
2299          --  Case where we will do a type conversion
2300
2301          else
2302             if Ityp = Base_Type (Artyp) then
2303                return X;
2304             else
2305                return Convert_To (Ityp, X);
2306             end if;
2307          end if;
2308       end To_Ityp;
2309
2310       --  Local Declarations
2311
2312       Opnd_Typ : Entity_Id;
2313       Ent      : Entity_Id;
2314       Len      : Uint;
2315       J        : Nat;
2316       Clen     : Node_Id;
2317       Set      : Boolean;
2318
2319    begin
2320       --  Choose an appropriate computational type
2321
2322       --  We will be doing calculations of lengths and bounds in this routine
2323       --  and computing one from the other in some cases, e.g. getting the high
2324       --  bound by adding the length-1 to the low bound.
2325
2326       --  We can't just use the index type, or even its base type for this
2327       --  purpose for two reasons. First it might be an enumeration type which
2328       --  is not suitable fo computations of any kind, and second it may simply
2329       --  not have enough range. For example if the index type is -128..+127
2330       --  then lengths can be up to 256, which is out of range of the type.
2331
2332       --  For enumeration types, we can simply use Standard_Integer, this is
2333       --  sufficient since the actual number of enumeration literals cannot
2334       --  possibly exceed the range of integer (remember we will be doing the
2335       --  arithmetic with POS values, not representation values).
2336
2337       if Is_Enumeration_Type (Ityp) then
2338          Artyp := Standard_Integer;
2339
2340       --  For modular types, we use a 32-bit modular type for types whose size
2341       --  is in the range 1-31 bits. For 32-bit unsigned types, we use the
2342       --  identity type, and for larger unsigned types we use 64-bits.
2343
2344       elsif Is_Modular_Integer_Type (Ityp) then
2345          if RM_Size (Ityp) < RM_Size (Standard_Unsigned) then
2346             Artyp := Standard_Unsigned;
2347          elsif RM_Size (Ityp) = RM_Size (Standard_Unsigned) then
2348             Artyp := Ityp;
2349          else
2350             Artyp := RTE (RE_Long_Long_Unsigned);
2351          end if;
2352
2353       --  Similar treatment for signed types
2354
2355       else
2356          if RM_Size (Ityp) < RM_Size (Standard_Integer) then
2357             Artyp := Standard_Integer;
2358          elsif RM_Size (Ityp) = RM_Size (Standard_Integer) then
2359             Artyp := Ityp;
2360          else
2361             Artyp := Standard_Long_Long_Integer;
2362          end if;
2363       end if;
2364
2365       --  Supply dummy entry at start of length array
2366
2367       Aggr_Length (0) := Make_Artyp_Literal (0);
2368
2369       --  Go through operands setting up the above arrays
2370
2371       J := 1;
2372       while J <= N loop
2373          Opnd := Remove_Head (Opnds);
2374          Opnd_Typ := Etype (Opnd);
2375
2376          --  The parent got messed up when we put the operands in a list,
2377          --  so now put back the proper parent for the saved operand.
2378
2379          Set_Parent (Opnd, Parent (Cnode));
2380
2381          --  Set will be True when we have setup one entry in the array
2382
2383          Set := False;
2384
2385          --  Singleton element (or character literal) case
2386
2387          if Base_Type (Opnd_Typ) = Ctyp then
2388             NN := NN + 1;
2389             Operands (NN) := Opnd;
2390             Is_Fixed_Length (NN) := True;
2391             Fixed_Length (NN) := Uint_1;
2392             Result_May_Be_Null := False;
2393
2394             --  Set low bound of operand (no need to set Last_Opnd_High_Bound
2395             --  since we know that the result cannot be null).
2396
2397             Opnd_Low_Bound (NN) :=
2398               Make_Attribute_Reference (Loc,
2399                 Prefix         => New_Reference_To (Istyp, Loc),
2400                 Attribute_Name => Name_First);
2401
2402             Set := True;
2403
2404          --  String literal case (can only occur for strings of course)
2405
2406          elsif Nkind (Opnd) = N_String_Literal then
2407             Len := String_Literal_Length (Opnd_Typ);
2408
2409             if Len /= 0 then
2410                Result_May_Be_Null := False;
2411             end if;
2412
2413             --  Capture last operand high bound if result could be null
2414
2415             if J = N and then Result_May_Be_Null then
2416                Last_Opnd_High_Bound :=
2417                  Make_Op_Add (Loc,
2418                    Left_Opnd  =>
2419                      New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)),
2420                    Right_Opnd => Make_Artyp_Literal (1));
2421             end if;
2422
2423             --  Skip null string literal
2424
2425             if J < N and then Len = 0 then
2426                goto Continue;
2427             end if;
2428
2429             NN := NN + 1;
2430             Operands (NN) := Opnd;
2431             Is_Fixed_Length (NN) := True;
2432
2433             --  Set length and bounds
2434
2435             Fixed_Length (NN) := Len;
2436
2437             Opnd_Low_Bound (NN) :=
2438               New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));
2439
2440             Set := True;
2441
2442          --  All other cases
2443
2444          else
2445             --  Check constrained case with known bounds
2446
2447             if Is_Constrained (Opnd_Typ) then
2448                declare
2449                   Index    : constant Node_Id   := First_Index (Opnd_Typ);
2450                   Indx_Typ : constant Entity_Id := Etype (Index);
2451                   Lo       : constant Node_Id   := Type_Low_Bound  (Indx_Typ);
2452                   Hi       : constant Node_Id   := Type_High_Bound (Indx_Typ);
2453
2454                begin
2455                   --  Fixed length constrained array type with known at compile
2456                   --  time bounds is last case of fixed length operand.
2457
2458                   if Compile_Time_Known_Value (Lo)
2459                        and then
2460                      Compile_Time_Known_Value (Hi)
2461                   then
2462                      declare
2463                         Loval : constant Uint := Expr_Value (Lo);
2464                         Hival : constant Uint := Expr_Value (Hi);
2465                         Len   : constant Uint :=
2466                                   UI_Max (Hival - Loval + 1, Uint_0);
2467
2468                      begin
2469                         if Len > 0 then
2470                            Result_May_Be_Null := False;
2471                         end if;
2472
2473                         --  Capture last operand bound if result could be null
2474
2475                         if J = N and then Result_May_Be_Null then
2476                            Last_Opnd_High_Bound :=
2477                              Convert_To (Ityp,
2478                                Make_Integer_Literal (Loc,
2479                                  Intval => Expr_Value (Hi)));
2480                         end if;
2481
2482                         --  Exclude null length case unless last operand
2483
2484                         if J < N and then Len = 0 then
2485                            goto Continue;
2486                         end if;
2487
2488                         NN := NN + 1;
2489                         Operands (NN) := Opnd;
2490                         Is_Fixed_Length (NN) := True;
2491                         Fixed_Length (NN)    := Len;
2492
2493                         Opnd_Low_Bound (NN) := To_Ityp (
2494                           Make_Integer_Literal (Loc,
2495                             Intval => Expr_Value (Lo)));
2496
2497                         Set := True;
2498                      end;
2499                   end if;
2500                end;
2501             end if;
2502
2503             --  All cases where the length is not known at compile time, or the
2504             --  special case of an operand which is known to be null but has a
2505             --  lower bound other than 1 or is other than a string type.
2506
2507             if not Set then
2508                NN := NN + 1;
2509
2510                --  Capture operand bounds
2511
2512                Opnd_Low_Bound (NN) :=
2513                  Make_Attribute_Reference (Loc,
2514                    Prefix         =>
2515                      Duplicate_Subexpr (Opnd, Name_Req => True),
2516                    Attribute_Name => Name_First);
2517
2518                if J = N and Result_May_Be_Null then
2519                   Last_Opnd_High_Bound :=
2520                     Convert_To (Ityp,
2521                       Make_Attribute_Reference (Loc,
2522                         Prefix         =>
2523                           Duplicate_Subexpr (Opnd, Name_Req => True),
2524                         Attribute_Name => Name_Last));
2525                end if;
2526
2527                --  Capture length of operand in entity
2528
2529                Operands (NN) := Opnd;
2530                Is_Fixed_Length (NN) := False;
2531
2532                Var_Length (NN) :=
2533                  Make_Defining_Identifier (Loc,
2534                    Chars => New_Internal_Name ('L'));
2535
2536                Insert_Action (Cnode,
2537                  Make_Object_Declaration (Loc,
2538                    Defining_Identifier => Var_Length (NN),
2539                    Constant_Present    => True,
2540
2541                    Object_Definition   =>
2542                      New_Occurrence_Of (Artyp, Loc),
2543
2544                    Expression          =>
2545                      Make_Attribute_Reference (Loc,
2546                        Prefix         =>
2547                          Duplicate_Subexpr (Opnd, Name_Req => True),
2548                        Attribute_Name => Name_Length)),
2549
2550                  Suppress => All_Checks);
2551             end if;
2552          end if;
2553
2554          --  Set next entry in aggregate length array
2555
2556          --  For first entry, make either integer literal for fixed length
2557          --  or a reference to the saved length for variable length.
2558
2559          if NN = 1 then
2560             if Is_Fixed_Length (1) then
2561                Aggr_Length (1) :=
2562                  Make_Integer_Literal (Loc,
2563                    Intval => Fixed_Length (1));
2564             else
2565                Aggr_Length (1) :=
2566                  New_Reference_To (Var_Length (1), Loc);
2567             end if;
2568
2569          --  If entry is fixed length and only fixed lengths so far, make
2570          --  appropriate new integer literal adding new length.
2571
2572          elsif Is_Fixed_Length (NN)
2573            and then Nkind (Aggr_Length (NN - 1)) = N_Integer_Literal
2574          then
2575             Aggr_Length (NN) :=
2576               Make_Integer_Literal (Loc,
2577                 Intval => Fixed_Length (NN) + Intval (Aggr_Length (NN - 1)));
2578
2579             --  All other cases, construct an addition node for the length and
2580             --  create an entity initialized to this length.
2581
2582          else
2583             Ent :=
2584               Make_Defining_Identifier (Loc,
2585                 Chars => New_Internal_Name ('L'));
2586
2587             if Is_Fixed_Length (NN) then
2588                Clen := Make_Integer_Literal (Loc, Fixed_Length (NN));
2589             else
2590                Clen := New_Reference_To (Var_Length (NN), Loc);
2591             end if;
2592
2593             Insert_Action (Cnode,
2594               Make_Object_Declaration (Loc,
2595                 Defining_Identifier => Ent,
2596                 Constant_Present    => True,
2597
2598                 Object_Definition   =>
2599                   New_Occurrence_Of (Artyp, Loc),
2600
2601                 Expression          =>
2602                   Make_Op_Add (Loc,
2603                     Left_Opnd  => New_Copy (Aggr_Length (NN - 1)),
2604                     Right_Opnd => Clen)),
2605
2606               Suppress => All_Checks);
2607
2608             Aggr_Length (NN) := Make_Identifier (Loc, Chars => Chars (Ent));
2609          end if;
2610
2611       <<Continue>>
2612          J := J + 1;
2613       end loop;
2614
2615       --  If we have only skipped null operands, return the last operand
2616
2617       if NN = 0 then
2618          Result := Opnd;
2619          goto Done;
2620       end if;
2621
2622       --  If we have only one non-null operand, return it and we are done.
2623       --  There is one case in which this cannot be done, and that is when
2624       --  the sole operand is of the element type, in which case it must be
2625       --  converted to an array, and the easiest way of doing that is to go
2626       --  through the normal general circuit.
2627
2628       if NN = 1
2629         and then Base_Type (Etype (Operands (1))) /= Ctyp
2630       then
2631          Result := Operands (1);
2632          goto Done;
2633       end if;
2634
2635       --  Cases where we have a real concatenation
2636
2637       --  Next step is to find the low bound for the result array that we
2638       --  will allocate. The rules for this are in (RM 4.5.6(5-7)).
2639
2640       --  If the ultimate ancestor of the index subtype is a constrained array
2641       --  definition, then the lower bound is that of the index subtype as
2642       --  specified by (RM 4.5.3(6)).
2643
2644       --  The right test here is to go to the root type, and then the ultimate
2645       --  ancestor is the first subtype of this root type.
2646
2647       if Is_Constrained (First_Subtype (Root_Type (Atyp))) then
2648          Low_Bound :=
2649            Make_Attribute_Reference (Loc,
2650              Prefix         =>
2651                New_Occurrence_Of (First_Subtype (Root_Type (Atyp)), Loc),
2652              Attribute_Name => Name_First);
2653
2654       --  If the first operand in the list has known length we know that
2655       --  the lower bound of the result is the lower bound of this operand.
2656
2657       elsif Is_Fixed_Length (1) then
2658          Low_Bound := Opnd_Low_Bound (1);
2659
2660       --  OK, we don't know the lower bound, we have to build a horrible
2661       --  expression actions node of the form
2662
2663       --     if Cond1'Length /= 0 then
2664       --        Opnd1 low bound
2665       --     else
2666       --        if Opnd2'Length /= 0 then
2667       --          Opnd2 low bound
2668       --        else
2669       --           ...
2670
2671       --  The nesting ends either when we hit an operand whose length is known
2672       --  at compile time, or on reaching the last operand, whose low bound we
2673       --  take unconditionally whether or not it is null. It's easiest to do
2674       --  this with a recursive procedure:
2675
2676       else
2677          declare
2678             function Get_Known_Bound (J : Nat) return Node_Id;
2679             --  Returns the lower bound determined by operands J .. NN
2680
2681             ---------------------
2682             -- Get_Known_Bound --
2683             ---------------------
2684
2685             function Get_Known_Bound (J : Nat) return Node_Id is
2686             begin
2687                if Is_Fixed_Length (J) or else J = NN then
2688                   return New_Copy (Opnd_Low_Bound (J));
2689
2690                else
2691                   return
2692                     Make_Conditional_Expression (Loc,
2693                       Expressions => New_List (
2694
2695                         Make_Op_Ne (Loc,
2696                           Left_Opnd  => New_Reference_To (Var_Length (J), Loc),
2697                           Right_Opnd => Make_Integer_Literal (Loc, 0)),
2698
2699                         New_Copy (Opnd_Low_Bound (J)),
2700                         Get_Known_Bound (J + 1)));
2701                end if;
2702             end Get_Known_Bound;
2703
2704          begin
2705             Ent :=
2706               Make_Defining_Identifier (Loc, Chars => New_Internal_Name ('L'));
2707
2708             Insert_Action (Cnode,
2709               Make_Object_Declaration (Loc,
2710                 Defining_Identifier => Ent,
2711                 Constant_Present    => True,
2712                 Object_Definition   => New_Occurrence_Of (Ityp, Loc),
2713                 Expression          => Get_Known_Bound (1)),
2714               Suppress => All_Checks);
2715
2716             Low_Bound := New_Reference_To (Ent, Loc);
2717          end;
2718       end if;
2719
2720       --  Now we can safely compute the upper bound, normally
2721       --  Low_Bound + Length - 1.
2722
2723       High_Bound :=
2724         To_Ityp (
2725           Make_Op_Add (Loc,
2726             Left_Opnd  => To_Artyp (New_Copy (Low_Bound)),
2727             Right_Opnd =>
2728               Make_Op_Subtract (Loc,
2729                 Left_Opnd  => New_Copy (Aggr_Length (NN)),
2730                 Right_Opnd => Make_Artyp_Literal (1))));
2731
2732       --  Now force overflow checking on High_Bound
2733
2734       Activate_Overflow_Check (High_Bound);
2735
2736       --  Handle the exceptional case where the result is null, in which case
2737       --  case the bounds come from the last operand (so that we get the proper
2738       --  bounds if the last operand is super-flat).
2739
2740       if Result_May_Be_Null then
2741          High_Bound :=
2742            Make_Conditional_Expression (Loc,
2743              Expressions => New_List (
2744                Make_Op_Eq (Loc,
2745                  Left_Opnd  => New_Copy (Aggr_Length (NN)),
2746                  Right_Opnd => Make_Artyp_Literal (0)),
2747                Last_Opnd_High_Bound,
2748                High_Bound));
2749       end if;
2750
2751       --  Now we construct an array object with appropriate bounds
2752
2753       Ent :=
2754         Make_Defining_Identifier (Loc,
2755           Chars => New_Internal_Name ('S'));
2756
2757       --  If the bound is statically known to be out of range, we do not want
2758       --  to abort, we want a warning and a runtime constraint error. Note that
2759       --  we have arranged that the result will not be treated as a static
2760       --  constant, so we won't get an illegality during this insertion.
2761
2762       Insert_Action (Cnode,
2763         Make_Object_Declaration (Loc,
2764           Defining_Identifier => Ent,
2765           Object_Definition   =>
2766             Make_Subtype_Indication (Loc,
2767               Subtype_Mark => New_Occurrence_Of (Atyp, Loc),
2768               Constraint   =>
2769                 Make_Index_Or_Discriminant_Constraint (Loc,
2770                   Constraints => New_List (
2771                     Make_Range (Loc,
2772                       Low_Bound  => Low_Bound,
2773                       High_Bound => High_Bound))))),
2774         Suppress => All_Checks);
2775
2776       --  Catch the static out of range case now
2777
2778       if Raises_Constraint_Error (High_Bound) then
2779          raise Concatenation_Error;
2780       end if;
2781
2782       --  Now we will generate the assignments to do the actual concatenation
2783
2784       Known_Non_Null_Operand_Seen := False;
2785
2786       for J in 1 .. NN loop
2787          declare
2788             Lo : constant Node_Id :=
2789                    Make_Op_Add (Loc,
2790                      Left_Opnd  => To_Artyp (New_Copy (Low_Bound)),
2791                      Right_Opnd => Aggr_Length (J - 1));
2792
2793             Hi : constant Node_Id :=
2794                    Make_Op_Add (Loc,
2795                      Left_Opnd  => To_Artyp (New_Copy (Low_Bound)),
2796                      Right_Opnd =>
2797                        Make_Op_Subtract (Loc,
2798                          Left_Opnd  => Aggr_Length (J),
2799                          Right_Opnd => Make_Artyp_Literal (1)));
2800
2801          begin
2802             --  Singleton case, simple assignment
2803
2804             if Base_Type (Etype (Operands (J))) = Ctyp then
2805                Known_Non_Null_Operand_Seen := True;
2806                Insert_Action (Cnode,
2807                  Make_Assignment_Statement (Loc,
2808                    Name       =>
2809                      Make_Indexed_Component (Loc,
2810                        Prefix      => New_Occurrence_Of (Ent, Loc),
2811                        Expressions => New_List (To_Ityp (Lo))),
2812                    Expression => Operands (J)),
2813                  Suppress => All_Checks);
2814
2815             --  Array case, slice assignment, skipped when argument is fixed
2816             --  length and known to be null.
2817
2818             elsif (not Is_Fixed_Length (J)) or else (Fixed_Length (J) > 0) then
2819                declare
2820                   Assign : Node_Id :=
2821                              Make_Assignment_Statement (Loc,
2822                                Name       =>
2823                                  Make_Slice (Loc,
2824                                    Prefix         =>
2825                                      New_Occurrence_Of (Ent, Loc),
2826                                    Discrete_Range =>
2827                                      Make_Range (Loc,
2828                                        Low_Bound  => To_Ityp (Lo),
2829                                        High_Bound => To_Ityp (Hi))),
2830                                Expression => Operands (J));
2831                begin
2832                   if Is_Fixed_Length (J) then
2833                      Known_Non_Null_Operand_Seen := True;
2834
2835                   elsif not Known_Non_Null_Operand_Seen then
2836
2837                      --  Here if operand length is not statically known and no
2838                      --  operand known to be non-null has been processed yet.
2839                      --  If operand length is 0, we do not need to perform the
2840                      --  assignment, and we must avoid the evaluation of the
2841                      --  high bound of the slice, since it may underflow if the
2842                      --  low bound is Ityp'First.
2843
2844                      Assign :=
2845                        Make_Implicit_If_Statement (Cnode,
2846                          Condition =>
2847                            Make_Op_Ne (Loc,
2848                              Left_Opnd =>
2849                                New_Occurrence_Of (Var_Length (J), Loc),
2850                              Right_Opnd => Make_Integer_Literal (Loc, 0)),
2851                          Then_Statements =>
2852                            New_List (Assign));
2853                   end if;
2854
2855                   Insert_Action (Cnode, Assign, Suppress => All_Checks);
2856                end;
2857             end if;
2858          end;
2859       end loop;
2860
2861       --  Finally we build the result, which is a reference to the array object
2862
2863       Result := New_Reference_To (Ent, Loc);
2864
2865    <<Done>>
2866       Rewrite (Cnode, Result);
2867       Analyze_And_Resolve (Cnode, Atyp);
2868
2869    exception
2870       when Concatenation_Error =>
2871
2872          --  Kill warning generated for the declaration of the static out of
2873          --  range high bound, and instead generate a Constraint_Error with
2874          --  an appropriate specific message.
2875
2876          Kill_Dead_Code (Declaration_Node (Entity (High_Bound)));
2877          Apply_Compile_Time_Constraint_Error
2878            (N      => Cnode,
2879             Msg    => "concatenation result upper bound out of range?",
2880             Reason => CE_Range_Check_Failed);
2881          --  Set_Etype (Cnode, Atyp);
2882    end Expand_Concatenate;
2883
2884    ------------------------
2885    -- Expand_N_Allocator --
2886    ------------------------
2887
2888    procedure Expand_N_Allocator (N : Node_Id) is
2889       PtrT  : constant Entity_Id  := Etype (N);
2890       Dtyp  : constant Entity_Id  := Designated_Type (PtrT);
2891       Etyp  : constant Entity_Id  := Etype (Expression (N));
2892       Loc   : constant Source_Ptr := Sloc (N);
2893       Desig : Entity_Id;
2894       Temp  : Entity_Id;
2895       Nod   : Node_Id;
2896
2897       procedure Complete_Coextension_Finalization;
2898       --  Generate finalization calls for all nested coextensions of N. This
2899       --  routine may allocate list controllers if necessary.
2900
2901       procedure Rewrite_Coextension (N : Node_Id);
2902       --  Static coextensions have the same lifetime as the entity they
2903       --  constrain. Such occurrences can be rewritten as aliased objects
2904       --  and their unrestricted access used instead of the coextension.
2905
2906       ---------------------------------------
2907       -- Complete_Coextension_Finalization --
2908       ---------------------------------------
2909
2910       procedure Complete_Coextension_Finalization is
2911          Coext      : Node_Id;
2912          Coext_Elmt : Elmt_Id;
2913          Flist      : Node_Id;
2914          Ref        : Node_Id;
2915
2916          function Inside_A_Return_Statement (N : Node_Id) return Boolean;
2917          --  Determine whether node N is part of a return statement
2918
2919          function Needs_Initialization_Call (N : Node_Id) return Boolean;
2920          --  Determine whether node N is a subtype indicator allocator which
2921          --  acts a coextension. Such coextensions need initialization.
2922
2923          -------------------------------
2924          -- Inside_A_Return_Statement --
2925          -------------------------------
2926
2927          function Inside_A_Return_Statement (N : Node_Id) return Boolean is
2928             P : Node_Id;
2929
2930          begin
2931             P := Parent (N);
2932             while Present (P) loop
2933                if Nkind_In
2934                    (P, N_Extended_Return_Statement, N_Simple_Return_Statement)
2935                then
2936                   return True;
2937
2938                --  Stop the traversal when we reach a subprogram body
2939
2940                elsif Nkind (P) = N_Subprogram_Body then
2941                   return False;
2942                end if;
2943
2944                P := Parent (P);
2945             end loop;
2946
2947             return False;
2948          end Inside_A_Return_Statement;
2949
2950          -------------------------------
2951          -- Needs_Initialization_Call --
2952          -------------------------------
2953
2954          function Needs_Initialization_Call (N : Node_Id) return Boolean is
2955             Obj_Decl : Node_Id;
2956
2957          begin
2958             if Nkind (N) = N_Explicit_Dereference
2959               and then Nkind (Prefix (N)) = N_Identifier
2960               and then Nkind (Parent (Entity (Prefix (N)))) =
2961                          N_Object_Declaration
2962             then
2963                Obj_Decl := Parent (Entity (Prefix (N)));
2964
2965                return
2966                  Present (Expression (Obj_Decl))
2967                    and then Nkind (Expression (Obj_Decl)) = N_Allocator
2968                    and then Nkind (Expression (Expression (Obj_Decl))) /=
2969                               N_Qualified_Expression;
2970             end if;
2971
2972             return False;
2973          end Needs_Initialization_Call;
2974
2975       --  Start of processing for Complete_Coextension_Finalization
2976
2977       begin
2978          --  When a coextension root is inside a return statement, we need to
2979          --  use the finalization chain of the function's scope. This does not
2980          --  apply for controlled named access types because in those cases we
2981          --  can use the finalization chain of the type itself.
2982
2983          if Inside_A_Return_Statement (N)
2984            and then
2985              (Ekind (PtrT) = E_Anonymous_Access_Type
2986                 or else
2987                   (Ekind (PtrT) = E_Access_Type
2988                      and then No (Associated_Final_Chain (PtrT))))
2989          then
2990             declare
2991                Decl    : Node_Id;
2992                Outer_S : Entity_Id;
2993                S       : Entity_Id := Current_Scope;
2994
2995             begin
2996                while Present (S) and then S /= Standard_Standard loop
2997                   if Ekind (S) = E_Function then
2998                      Outer_S := Scope (S);
2999
3000                      --  Retrieve the declaration of the body
3001
3002                      Decl := Parent (Parent (
3003                                Corresponding_Body (Parent (Parent (S)))));
3004                      exit;
3005                   end if;
3006
3007                   S := Scope (S);
3008                end loop;
3009
3010                --  Push the scope of the function body since we are inserting
3011                --  the list before the body, but we are currently in the body
3012                --  itself. Override the finalization list of PtrT since the
3013                --  finalization context is now different.
3014
3015                Push_Scope (Outer_S);
3016                Build_Final_List (Decl, PtrT);
3017                Pop_Scope;
3018             end;
3019
3020          --  The root allocator may not be controlled, but it still needs a
3021          --  finalization list for all nested coextensions.
3022
3023          elsif No (Associated_Final_Chain (PtrT)) then
3024             Build_Final_List (N, PtrT);
3025          end if;
3026
3027          Flist :=
3028            Make_Selected_Component (Loc,
3029              Prefix =>
3030                New_Reference_To (Associated_Final_Chain (PtrT), Loc),
3031              Selector_Name =>
3032                Make_Identifier (Loc, Name_F));
3033
3034          Coext_Elmt := First_Elmt (Coextensions (N));
3035          while Present (Coext_Elmt) loop
3036             Coext := Node (Coext_Elmt);
3037
3038             --  Generate:
3039             --    typ! (coext.all)
3040
3041             if Nkind (Coext) = N_Identifier then
3042                Ref :=
3043                  Make_Unchecked_Type_Conversion (Loc,
3044                    Subtype_Mark => New_Reference_To (Etype (Coext), Loc),
3045                    Expression   =>
3046                      Make_Explicit_Dereference (Loc,
3047                        Prefix => New_Copy_Tree (Coext)));
3048             else
3049                Ref := New_Copy_Tree (Coext);
3050             end if;
3051
3052             --  No initialization call if not allowed
3053
3054             Check_Restriction (No_Default_Initialization, N);
3055
3056             if not Restriction_Active (No_Default_Initialization) then
3057
3058                --  Generate:
3059                --    initialize (Ref)
3060                --    attach_to_final_list (Ref, Flist, 2)
3061
3062                if Needs_Initialization_Call (Coext) then
3063                   Insert_Actions (N,
3064                     Make_Init_Call (
3065                       Ref         => Ref,
3066                       Typ         => Etype (Coext),
3067                       Flist_Ref   => Flist,
3068                       With_Attach => Make_Integer_Literal (Loc, Uint_2)));
3069
3070                --  Generate:
3071                --    attach_to_final_list (Ref, Flist, 2)
3072
3073                else
3074                   Insert_Action (N,
3075                     Make_Attach_Call (
3076                       Obj_Ref     => Ref,
3077                       Flist_Ref   => New_Copy_Tree (Flist),
3078                       With_Attach => Make_Integer_Literal (Loc, Uint_2)));
3079                end if;
3080             end if;
3081
3082             Next_Elmt (Coext_Elmt);
3083          end loop;
3084       end Complete_Coextension_Finalization;
3085
3086       -------------------------
3087       -- Rewrite_Coextension --
3088       -------------------------
3089
3090       procedure Rewrite_Coextension (N : Node_Id) is
3091          Temp : constant Node_Id :=
3092                   Make_Defining_Identifier (Loc,
3093                     New_Internal_Name ('C'));
3094
3095          --  Generate:
3096          --    Cnn : aliased Etyp;
3097
3098          Decl : constant Node_Id :=
3099                   Make_Object_Declaration (Loc,
3100                     Defining_Identifier => Temp,
3101                     Aliased_Present     => True,
3102                     Object_Definition   =>
3103                       New_Occurrence_Of (Etyp, Loc));
3104          Nod  : Node_Id;
3105
3106       begin
3107          if Nkind (Expression (N)) = N_Qualified_Expression then
3108             Set_Expression (Decl, Expression (Expression (N)));
3109          end if;
3110
3111          --  Find the proper insertion node for the declaration
3112
3113          Nod := Parent (N);
3114          while Present (Nod) loop
3115             exit when Nkind (Nod) in N_Statement_Other_Than_Procedure_Call
3116               or else Nkind (Nod) = N_Procedure_Call_Statement
3117               or else Nkind (Nod) in N_Declaration;
3118             Nod := Parent (Nod);
3119          end loop;
3120
3121          Insert_Before (Nod, Decl);
3122          Analyze (Decl);
3123
3124          Rewrite (N,
3125            Make_Attribute_Reference (Loc,
3126              Prefix         => New_Occurrence_Of (Temp, Loc),
3127              Attribute_Name => Name_Unrestricted_Access));
3128
3129          Analyze_And_Resolve (N, PtrT);
3130       end Rewrite_Coextension;
3131
3132    --  Start of processing for Expand_N_Allocator
3133
3134    begin
3135       --  RM E.2.3(22). We enforce that the expected type of an allocator
3136       --  shall not be a remote access-to-class-wide-limited-private type
3137
3138       --  Why is this being done at expansion time, seems clearly wrong ???
3139
3140       Validate_Remote_Access_To_Class_Wide_Type (N);
3141
3142       --  Set the Storage Pool
3143
3144       Set_Storage_Pool (N, Associated_Storage_Pool (Root_Type (PtrT)));
3145
3146       if Present (Storage_Pool (N)) then
3147          if Is_RTE (Storage_Pool (N), RE_SS_Pool) then
3148             if VM_Target = No_VM then
3149                Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));
3150             end if;
3151
3152          elsif Is_Class_Wide_Type (Etype (Storage_Pool (N))) then
3153             Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));
3154
3155          else
3156             Set_Procedure_To_Call (N,
3157               Find_Prim_Op (Etype (Storage_Pool (N)), Name_Allocate));
3158          end if;
3159       end if;
3160
3161       --  Under certain circumstances we can replace an allocator by an access
3162       --  to statically allocated storage. The conditions, as noted in AARM
3163       --  3.10 (10c) are as follows:
3164
3165       --    Size and initial value is known at compile time
3166       --    Access type is access-to-constant
3167
3168       --  The allocator is not part of a constraint on a record component,
3169       --  because in that case the inserted actions are delayed until the
3170       --  record declaration is fully analyzed, which is too late for the
3171       --  analysis of the rewritten allocator.
3172
3173       if Is_Access_Constant (PtrT)
3174         and then Nkind (Expression (N)) = N_Qualified_Expression
3175         and then Compile_Time_Known_Value (Expression (Expression (N)))
3176         and then Size_Known_At_Compile_Time (Etype (Expression
3177                                                     (Expression (N))))
3178         and then not Is_Record_Type (Current_Scope)
3179       then
3180          --  Here we can do the optimization. For the allocator
3181
3182          --    new x'(y)
3183
3184          --  We insert an object declaration
3185
3186          --    Tnn : aliased x := y;
3187
3188          --  and replace the allocator by Tnn'Unrestricted_Access. Tnn is
3189          --  marked as requiring static allocation.
3190
3191          Temp :=
3192            Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
3193
3194          Desig := Subtype_Mark (Expression (N));
3195
3196          --  If context is constrained, use constrained subtype directly,
3197          --  so that the constant is not labelled as having a nominally
3198          --  unconstrained subtype.
3199
3200          if Entity (Desig) = Base_Type (Dtyp) then
3201             Desig := New_Occurrence_Of (Dtyp, Loc);
3202          end if;
3203
3204          Insert_Action (N,
3205            Make_Object_Declaration (Loc,
3206              Defining_Identifier => Temp,
3207              Aliased_Present     => True,
3208              Constant_Present    => Is_Access_Constant (PtrT),
3209              Object_Definition   => Desig,
3210              Expression          => Expression (Expression (N))));
3211
3212          Rewrite (N,
3213            Make_Attribute_Reference (Loc,
3214              Prefix => New_Occurrence_Of (Temp, Loc),
3215              Attribute_Name => Name_Unrestricted_Access));
3216
3217          Analyze_And_Resolve (N, PtrT);
3218
3219          --  We set the variable as statically allocated, since we don't want
3220          --  it going on the stack of the current procedure!
3221
3222          Set_Is_Statically_Allocated (Temp);
3223          return;
3224       end if;
3225
3226       --  Same if the allocator is an access discriminant for a local object:
3227       --  instead of an allocator we create a local value and constrain the
3228       --  the enclosing object with the corresponding access attribute.
3229
3230       if Is_Static_Coextension (N) then
3231          Rewrite_Coextension (N);
3232          return;
3233       end if;
3234
3235       --  The current allocator creates an object which may contain nested
3236       --  coextensions. Use the current allocator's finalization list to
3237       --  generate finalization call for all nested coextensions.
3238
3239       if Is_Coextension_Root (N) then
3240          Complete_Coextension_Finalization;
3241       end if;
3242
3243       --  Handle case of qualified expression (other than optimization above)
3244
3245       if Nkind (Expression (N)) = N_Qualified_Expression then
3246          Expand_Allocator_Expression (N);
3247          return;
3248       end if;
3249
3250       --  If the allocator is for a type which requires initialization, and
3251       --  there is no initial value (i.e. operand is a subtype indication
3252       --  rather than a qualified expression), then we must generate a call to
3253       --  the initialization routine using an expressions action node:
3254
3255       --     [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
3256
3257       --  Here ptr_T is the pointer type for the allocator, and T is the
3258       --  subtype of the allocator. A special case arises if the designated
3259       --  type of the access type is a task or contains tasks. In this case
3260       --  the call to Init (Temp.all ...) is replaced by code that ensures
3261       --  that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
3262       --  for details). In addition, if the type T is a task T, then the
3263       --  first argument to Init must be converted to the task record type.
3264
3265       declare
3266          T            : constant Entity_Id := Entity (Expression (N));
3267          Init         : Entity_Id;
3268          Arg1         : Node_Id;
3269          Args         : List_Id;
3270          Decls        : List_Id;
3271          Decl         : Node_Id;
3272          Discr        : Elmt_Id;
3273          Flist        : Node_Id;
3274          Temp_Decl    : Node_Id;
3275          Temp_Type    : Entity_Id;
3276          Attach_Level : Uint;
3277
3278       begin
3279          if No_Initialization (N) then
3280             null;
3281
3282          --  Case of no initialization procedure present
3283
3284          elsif not Has_Non_Null_Base_Init_Proc (T) then
3285
3286             --  Case of simple initialization required
3287
3288             if Needs_Simple_Initialization (T) then
3289                Check_Restriction (No_Default_Initialization, N);
3290                Rewrite (Expression (N),
3291                  Make_Qualified_Expression (Loc,
3292                    Subtype_Mark => New_Occurrence_Of (T, Loc),
3293                    Expression   => Get_Simple_Init_Val (T, N)));
3294
3295                Analyze_And_Resolve (Expression (Expression (N)), T);
3296                Analyze_And_Resolve (Expression (N), T);
3297                Set_Paren_Count     (Expression (Expression (N)), 1);
3298                Expand_N_Allocator  (N);
3299
3300             --  No initialization required
3301
3302             else
3303                null;
3304             end if;
3305
3306          --  Case of initialization procedure present, must be called
3307
3308          else
3309             Check_Restriction (No_Default_Initialization, N);
3310
3311             if not Restriction_Active (No_Default_Initialization) then
3312                Init := Base_Init_Proc (T);
3313                Nod  := N;
3314                Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
3315
3316                --  Construct argument list for the initialization routine call
3317
3318                Arg1 :=
3319                  Make_Explicit_Dereference (Loc,
3320                    Prefix => New_Reference_To (Temp, Loc));
3321                Set_Assignment_OK (Arg1);
3322                Temp_Type := PtrT;
3323
3324                --  The initialization procedure expects a specific type. if the
3325                --  context is access to class wide, indicate that the object
3326                --  being allocated has the right specific type.
3327
3328                if Is_Class_Wide_Type (Dtyp) then
3329                   Arg1 := Unchecked_Convert_To (T, Arg1);
3330                end if;
3331
3332                --  If designated type is a concurrent type or if it is private
3333                --  type whose definition is a concurrent type, the first
3334                --  argument in the Init routine has to be unchecked conversion
3335                --  to the corresponding record type. If the designated type is
3336                --  a derived type, we also convert the argument to its root
3337                --  type.
3338
3339                if Is_Concurrent_Type (T) then
3340                   Arg1 :=
3341                     Unchecked_Convert_To (Corresponding_Record_Type (T), Arg1);
3342
3343                elsif Is_Private_Type (T)
3344                  and then Present (Full_View (T))
3345                  and then Is_Concurrent_Type (Full_View (T))
3346                then
3347                   Arg1 :=
3348                     Unchecked_Convert_To
3349                       (Corresponding_Record_Type (Full_View (T)), Arg1);
3350
3351                elsif Etype (First_Formal (Init)) /= Base_Type (T) then
3352                   declare
3353                      Ftyp : constant Entity_Id := Etype (First_Formal (Init));
3354                   begin
3355                      Arg1 := OK_Convert_To (Etype (Ftyp), Arg1);
3356                      Set_Etype (Arg1, Ftyp);
3357                   end;
3358                end if;
3359
3360                Args := New_List (Arg1);
3361
3362                --  For the task case, pass the Master_Id of the access type as
3363                --  the value of the _Master parameter, and _Chain as the value
3364                --  of the _Chain parameter (_Chain will be defined as part of
3365                --  the generated code for the allocator).
3366
3367                --  In Ada 2005, the context may be a function that returns an
3368                --  anonymous access type. In that case the Master_Id has been
3369                --  created when expanding the function declaration.
3370
3371                if Has_Task (T) then
3372                   if No (Master_Id (Base_Type (PtrT))) then
3373
3374                      --  If we have a non-library level task with restriction
3375                      --  No_Task_Hierarchy set, then no point in expanding.
3376
3377                      if not Is_Library_Level_Entity (T)
3378                        and then Restriction_Active (No_Task_Hierarchy)
3379                      then
3380                         return;
3381                      end if;
3382
3383                      --  The designated type was an incomplete type, and the
3384                      --  access type did not get expanded. Salvage it now.
3385
3386                      pragma Assert (Present (Parent (Base_Type (PtrT))));
3387                      Expand_N_Full_Type_Declaration
3388                        (Parent (Base_Type (PtrT)));
3389                   end if;
3390
3391                   --  If the context of the allocator is a declaration or an
3392                   --  assignment, we can generate a meaningful image for it,
3393                   --  even though subsequent assignments might remove the
3394                   --  connection between task and entity. We build this image
3395                   --  when the left-hand side is a simple variable, a simple
3396                   --  indexed assignment or a simple selected component.
3397
3398                   if Nkind (Parent (N)) = N_Assignment_Statement then
3399                      declare
3400                         Nam : constant Node_Id := Name (Parent (N));
3401
3402                      begin
3403                         if Is_Entity_Name (Nam) then
3404                            Decls :=
3405                              Build_Task_Image_Decls
3406                                (Loc,
3407                                 New_Occurrence_Of
3408                                   (Entity (Nam), Sloc (Nam)), T);
3409
3410                         elsif Nkind_In
3411                           (Nam, N_Indexed_Component, N_Selected_Component)
3412                           and then Is_Entity_Name (Prefix (Nam))
3413                         then
3414                            Decls :=
3415                              Build_Task_Image_Decls
3416                                (Loc, Nam, Etype (Prefix (Nam)));
3417                         else
3418                            Decls := Build_Task_Image_Decls (Loc, T, T);
3419                         end if;
3420                      end;
3421
3422                   elsif Nkind (Parent (N)) = N_Object_Declaration then
3423                      Decls :=
3424                        Build_Task_Image_Decls
3425                          (Loc, Defining_Identifier (Parent (N)), T);
3426
3427                   else
3428                      Decls := Build_Task_Image_Decls (Loc, T, T);
3429                   end if;
3430
3431                   Append_To (Args,
3432                     New_Reference_To
3433                       (Master_Id (Base_Type (Root_Type (PtrT))), Loc));
3434                   Append_To (Args, Make_Identifier (Loc, Name_uChain));
3435
3436                   Decl := Last (Decls);
3437                   Append_To (Args,
3438                     New_Occurrence_Of (Defining_Identifier (Decl), Loc));
3439
3440                   --  Has_Task is false, Decls not used
3441
3442                else
3443                   Decls := No_List;
3444                end if;
3445
3446                --  Add discriminants if discriminated type
3447
3448                declare
3449                   Dis : Boolean := False;
3450                   Typ : Entity_Id;
3451
3452                begin
3453                   if Has_Discriminants (T) then
3454                      Dis := True;
3455                      Typ := T;
3456
3457                   elsif Is_Private_Type (T)
3458                     and then Present (Full_View (T))
3459                     and then Has_Discriminants (Full_View (T))
3460                   then
3461                      Dis := True;
3462                      Typ := Full_View (T);
3463                   end if;
3464
3465                   if Dis then
3466
3467                      --  If the allocated object will be constrained by the
3468                      --  default values for discriminants, then build a subtype
3469                      --  with those defaults, and change the allocated subtype
3470                      --  to that. Note that this happens in fewer cases in Ada
3471                      --  2005 (AI-363).
3472
3473                      if not Is_Constrained (Typ)
3474                        and then Present (Discriminant_Default_Value
3475                                          (First_Discriminant (Typ)))
3476                        and then (Ada_Version < Ada_05
3477                                   or else
3478                                     not Has_Constrained_Partial_View (Typ))
3479                      then
3480                         Typ := Build_Default_Subtype (Typ, N);
3481                         Set_Expression (N, New_Reference_To (Typ, Loc));
3482                      end if;
3483
3484                      Discr := First_Elmt (Discriminant_Constraint (Typ));
3485                      while Present (Discr) loop
3486                         Nod := Node (Discr);
3487                         Append (New_Copy_Tree (Node (Discr)), Args);
3488
3489                         --  AI-416: when the discriminant constraint is an
3490                         --  anonymous access type make sure an accessibility
3491                         --  check is inserted if necessary (3.10.2(22.q/2))
3492
3493                         if Ada_Version >= Ada_05
3494                           and then
3495                             Ekind (Etype (Nod)) = E_Anonymous_Access_Type
3496                         then
3497                            Apply_Accessibility_Check
3498                              (Nod, Typ, Insert_Node => Nod);
3499                         end if;
3500
3501                         Next_Elmt (Discr);
3502                      end loop;
3503                   end if;
3504                end;
3505
3506                --  We set the allocator as analyzed so that when we analyze the
3507                --  expression actions node, we do not get an unwanted recursive
3508                --  expansion of the allocator expression.
3509
3510                Set_Analyzed (N, True);
3511                Nod := Relocate_Node (N);
3512
3513                --  Here is the transformation:
3514                --    input:  new T
3515                --    output: Temp : constant ptr_T := new T;
3516                --            Init (Temp.all, ...);
3517                --    <CTRL>  Attach_To_Final_List (Finalizable (Temp.all));
3518                --    <CTRL>  Initialize (Finalizable (Temp.all));
3519
3520                --  Here ptr_T is the pointer type for the allocator, and is the
3521                --  subtype of the allocator.
3522
3523                Temp_Decl :=
3524                  Make_Object_Declaration (Loc,
3525                    Defining_Identifier => Temp,
3526                    Constant_Present    => True,
3527                    Object_Definition   => New_Reference_To (Temp_Type, Loc),
3528                    Expression          => Nod);
3529
3530                Set_Assignment_OK (Temp_Decl);
3531                Insert_Action (N, Temp_Decl, Suppress => All_Checks);
3532
3533                --  If the designated type is a task type or contains tasks,
3534                --  create block to activate created tasks, and insert
3535                --  declaration for Task_Image variable ahead of call.
3536
3537                if Has_Task (T) then
3538                   declare
3539                      L   : constant List_Id := New_List;
3540                      Blk : Node_Id;
3541                   begin
3542                      Build_Task_Allocate_Block (L, Nod, Args);
3543                      Blk := Last (L);
3544                      Insert_List_Before (First (Declarations (Blk)), Decls);
3545                      Insert_Actions (N, L);
3546                   end;
3547
3548                else
3549                   Insert_Action (N,
3550                     Make_Procedure_Call_Statement (Loc,
3551                       Name                   => New_Reference_To (Init, Loc),
3552                       Parameter_Associations => Args));
3553                end if;
3554
3555                if Needs_Finalization (T) then
3556
3557                   --  Postpone the generation of a finalization call for the
3558                   --  current allocator if it acts as a coextension.
3559
3560                   if Is_Dynamic_Coextension (N) then
3561                      if No (Coextensions (N)) then
3562                         Set_Coextensions (N, New_Elmt_List);
3563                      end if;
3564
3565                      Append_Elmt (New_Copy_Tree (Arg1), Coextensions (N));
3566
3567                   else
3568                      Flist :=
3569                        Get_Allocator_Final_List (N, Base_Type (T), PtrT);
3570
3571                      --  Anonymous access types created for access parameters
3572                      --  are attached to an explicitly constructed controller,
3573                      --  which ensures that they can be finalized properly,
3574                      --  even if their deallocation might not happen. The list
3575                      --  associated with the controller is doubly-linked. For
3576                      --  other anonymous access types, the object may end up
3577                      --  on the global final list which is singly-linked.
3578                      --  Work needed for access discriminants in Ada 2005 ???
3579
3580                      if Ekind (PtrT) = E_Anonymous_Access_Type
3581                        and then
3582                          Nkind (Associated_Node_For_Itype (PtrT))
3583                      not in N_Subprogram_Specification
3584                      then
3585                         Attach_Level := Uint_1;
3586                      else
3587                         Attach_Level := Uint_2;
3588                      end if;
3589
3590                      Insert_Actions (N,
3591                        Make_Init_Call (
3592                          Ref          => New_Copy_Tree (Arg1),
3593                          Typ          => T,
3594                          Flist_Ref    => Flist,
3595                          With_Attach  => Make_Integer_Literal (Loc,
3596                                            Intval => Attach_Level)));
3597                   end if;
3598                end if;
3599
3600                Rewrite (N, New_Reference_To (Temp, Loc));
3601                Analyze_And_Resolve (N, PtrT);
3602             end if;
3603          end if;
3604       end;
3605
3606       --  Ada 2005 (AI-251): If the allocator is for a class-wide interface
3607       --  object that has been rewritten as a reference, we displace "this"
3608       --  to reference properly its secondary dispatch table.
3609
3610       if Nkind (N) = N_Identifier
3611         and then Is_Interface (Dtyp)
3612       then
3613          Displace_Allocator_Pointer (N);
3614       end if;
3615
3616    exception
3617       when RE_Not_Available =>
3618          return;
3619    end Expand_N_Allocator;
3620
3621    -----------------------
3622    -- Expand_N_And_Then --
3623    -----------------------
3624
3625    --  Expand into conditional expression if Actions present, and also deal
3626    --  with optimizing case of arguments being True or False.
3627
3628    procedure Expand_N_And_Then (N : Node_Id) is
3629       Loc     : constant Source_Ptr := Sloc (N);
3630       Typ     : constant Entity_Id  := Etype (N);
3631       Left    : constant Node_Id    := Left_Opnd (N);
3632       Right   : constant Node_Id    := Right_Opnd (N);
3633       Actlist : List_Id;
3634
3635    begin
3636       --  Deal with non-standard booleans
3637
3638       if Is_Boolean_Type (Typ) then
3639          Adjust_Condition (Left);
3640          Adjust_Condition (Right);
3641          Set_Etype (N, Standard_Boolean);
3642       end if;
3643
3644       --  Check for cases where left argument is known to be True or False
3645
3646       if Compile_Time_Known_Value (Left) then
3647
3648          --  If left argument is True, change (True and then Right) to Right.
3649          --  Any actions associated with Right will be executed unconditionally
3650          --  and can thus be inserted into the tree unconditionally.
3651
3652          if Expr_Value_E (Left) = Standard_True then
3653             if Present (Actions (N)) then
3654                Insert_Actions (N, Actions (N));
3655             end if;
3656
3657             Rewrite (N, Right);
3658
3659          --  If left argument is False, change (False and then Right) to False.
3660          --  In this case we can forget the actions associated with Right,
3661          --  since they will never be executed.
3662
3663          else pragma Assert (Expr_Value_E (Left) = Standard_False);
3664             Kill_Dead_Code (Right);
3665             Kill_Dead_Code (Actions (N));
3666             Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
3667          end if;
3668
3669          Adjust_Result_Type (N, Typ);
3670          return;
3671       end if;
3672
3673       --  If Actions are present, we expand
3674
3675       --     left and then right
3676
3677       --  into
3678
3679       --     if left then right else false end
3680
3681       --  with the actions becoming the Then_Actions of the conditional
3682       --  expression. This conditional expression is then further expanded
3683       --  (and will eventually disappear)
3684
3685       if Present (Actions (N)) then
3686          Actlist := Actions (N);
3687          Rewrite (N,
3688             Make_Conditional_Expression (Loc,
3689               Expressions => New_List (
3690                 Left,
3691                 Right,
3692                 New_Occurrence_Of (Standard_False, Loc))));
3693
3694          Set_Then_Actions (N, Actlist);
3695          Analyze_And_Resolve (N, Standard_Boolean);
3696          Adjust_Result_Type (N, Typ);
3697          return;
3698       end if;
3699
3700       --  No actions present, check for cases of right argument True/False
3701
3702       if Compile_Time_Known_Value (Right) then
3703
3704          --  Change (Left and then True) to Left. Note that we know there are
3705          --  no actions associated with the True operand, since we just checked
3706          --  for this case above.
3707
3708          if Expr_Value_E (Right) = Standard_True then
3709             Rewrite (N, Left);
3710
3711          --  Change (Left and then False) to False, making sure to preserve any
3712          --  side effects associated with the Left operand.
3713
3714          else pragma Assert (Expr_Value_E (Right) = Standard_False);
3715             Remove_Side_Effects (Left);
3716             Rewrite
3717               (N, New_Occurrence_Of (Standard_False, Loc));
3718          end if;
3719       end if;
3720
3721       Adjust_Result_Type (N, Typ);
3722    end Expand_N_And_Then;
3723
3724    -------------------------------------
3725    -- Expand_N_Conditional_Expression --
3726    -------------------------------------
3727
3728    --  Expand into expression actions if then/else actions present
3729
3730    procedure Expand_N_Conditional_Expression (N : Node_Id) is
3731       Loc    : constant Source_Ptr := Sloc (N);
3732       Cond   : constant Node_Id    := First (Expressions (N));
3733       Thenx  : constant Node_Id    := Next (Cond);
3734       Elsex  : constant Node_Id    := Next (Thenx);
3735       Typ    : constant Entity_Id  := Etype (N);
3736       Cnn    : Entity_Id;
3737       New_If : Node_Id;
3738
3739    begin
3740       --  If either then or else actions are present, then given:
3741
3742       --     if cond then then-expr else else-expr end
3743
3744       --  we insert the following sequence of actions (using Insert_Actions):
3745
3746       --      Cnn : typ;
3747       --      if cond then
3748       --         <<then actions>>
3749       --         Cnn := then-expr;
3750       --      else
3751       --         <<else actions>>
3752       --         Cnn := else-expr
3753       --      end if;
3754
3755       --  and replace the conditional expression by a reference to Cnn
3756
3757       if Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
3758          Cnn := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
3759
3760          New_If :=
3761            Make_Implicit_If_Statement (N,
3762              Condition => Relocate_Node (Cond),
3763
3764              Then_Statements => New_List (
3765                Make_Assignment_Statement (Sloc (Thenx),
3766                  Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
3767                  Expression => Relocate_Node (Thenx))),
3768
3769              Else_Statements => New_List (
3770                Make_Assignment_Statement (Sloc (Elsex),
3771                  Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
3772                  Expression => Relocate_Node (Elsex))));
3773
3774          Set_Assignment_OK (Name (First (Then_Statements (New_If))));
3775          Set_Assignment_OK (Name (First (Else_Statements (New_If))));
3776
3777          if Present (Then_Actions (N)) then
3778             Insert_List_Before
3779               (First (Then_Statements (New_If)), Then_Actions (N));
3780          end if;
3781
3782          if Present (Else_Actions (N)) then
3783             Insert_List_Before
3784               (First (Else_Statements (New_If)), Else_Actions (N));
3785          end if;
3786
3787          Rewrite (N, New_Occurrence_Of (Cnn, Loc));
3788
3789          Insert_Action (N,
3790            Make_Object_Declaration (Loc,
3791              Defining_Identifier => Cnn,
3792              Object_Definition   => New_Occurrence_Of (Typ, Loc)));
3793
3794          Insert_Action (N, New_If);
3795          Analyze_And_Resolve (N, Typ);
3796       end if;
3797    end Expand_N_Conditional_Expression;
3798
3799    -----------------------------------
3800    -- Expand_N_Explicit_Dereference --
3801    -----------------------------------
3802
3803    procedure Expand_N_Explicit_Dereference (N : Node_Id) is
3804    begin
3805       --  Insert explicit dereference call for the checked storage pool case
3806
3807       Insert_Dereference_Action (Prefix (N));
3808    end Expand_N_Explicit_Dereference;
3809
3810    -----------------
3811    -- Expand_N_In --
3812    -----------------
3813
3814    procedure Expand_N_In (N : Node_Id) is
3815       Loc    : constant Source_Ptr := Sloc (N);
3816       Rtyp   : constant Entity_Id  := Etype (N);
3817       Lop    : constant Node_Id    := Left_Opnd (N);
3818       Rop    : constant Node_Id    := Right_Opnd (N);
3819       Static : constant Boolean    := Is_OK_Static_Expression (N);
3820
3821       procedure Substitute_Valid_Check;
3822       --  Replaces node N by Lop'Valid. This is done when we have an explicit
3823       --  test for the left operand being in range of its subtype.
3824
3825       ----------------------------
3826       -- Substitute_Valid_Check --
3827       ----------------------------
3828
3829       procedure Substitute_Valid_Check is
3830       begin
3831          Rewrite (N,
3832            Make_Attribute_Reference (Loc,
3833              Prefix         => Relocate_Node (Lop),
3834              Attribute_Name => Name_Valid));
3835
3836          Analyze_And_Resolve (N, Rtyp);
3837
3838          Error_Msg_N ("?explicit membership test may be optimized away", N);
3839          Error_Msg_N ("\?use ''Valid attribute instead", N);
3840          return;
3841       end Substitute_Valid_Check;
3842
3843    --  Start of processing for Expand_N_In
3844
3845    begin
3846       --  Check case of explicit test for an expression in range of its
3847       --  subtype. This is suspicious usage and we replace it with a 'Valid
3848       --  test and give a warning.
3849
3850       if Is_Scalar_Type (Etype (Lop))
3851         and then Nkind (Rop) in N_Has_Entity
3852         and then Etype (Lop) = Entity (Rop)
3853         and then Comes_From_Source (N)
3854         and then VM_Target = No_VM
3855       then
3856          Substitute_Valid_Check;
3857          return;
3858       end if;
3859
3860       --  Do validity check on operands
3861
3862       if Validity_Checks_On and Validity_Check_Operands then
3863          Ensure_Valid (Left_Opnd (N));
3864          Validity_Check_Range (Right_Opnd (N));
3865       end if;
3866
3867       --  Case of explicit range
3868
3869       if Nkind (Rop) = N_Range then
3870          declare
3871             Lo : constant Node_Id := Low_Bound (Rop);
3872             Hi : constant Node_Id := High_Bound (Rop);
3873
3874             Ltyp : constant Entity_Id := Etype (Lop);
3875
3876             Lo_Orig : constant Node_Id := Original_Node (Lo);
3877             Hi_Orig : constant Node_Id := Original_Node (Hi);
3878
3879             Lcheck : Compare_Result;
3880             Ucheck : Compare_Result;
3881
3882             Warn1 : constant Boolean :=
3883                       Constant_Condition_Warnings
3884                         and then Comes_From_Source (N)
3885                         and then not In_Instance;
3886             --  This must be true for any of the optimization warnings, we
3887             --  clearly want to give them only for source with the flag on.
3888             --  We also skip these warnings in an instance since it may be
3889             --  the case that different instantiations have different ranges.
3890
3891             Warn2 : constant Boolean :=
3892                       Warn1
3893                         and then Nkind (Original_Node (Rop)) = N_Range
3894                         and then Is_Integer_Type (Etype (Lo));
3895             --  For the case where only one bound warning is elided, we also
3896             --  insist on an explicit range and an integer type. The reason is
3897             --  that the use of enumeration ranges including an end point is
3898             --  common, as is the use of a subtype name, one of whose bounds
3899             --  is the same as the type of the expression.
3900
3901          begin
3902             --  If test is explicit x'first .. x'last, replace by valid check
3903
3904             if Is_Scalar_Type (Ltyp)
3905               and then Nkind (Lo_Orig) = N_Attribute_Reference
3906               and then Attribute_Name (Lo_Orig) = Name_First
3907               and then Nkind (Prefix (Lo_Orig)) in N_Has_Entity
3908               and then Entity (Prefix (Lo_Orig)) = Ltyp
3909               and then Nkind (Hi_Orig) = N_Attribute_Reference
3910               and then Attribute_Name (Hi_Orig) = Name_Last
3911               and then Nkind (Prefix (Hi_Orig)) in N_Has_Entity
3912               and then Entity (Prefix (Hi_Orig)) = Ltyp
3913               and then Comes_From_Source (N)
3914               and then VM_Target = No_VM
3915             then
3916                Substitute_Valid_Check;
3917                return;
3918             end if;
3919
3920             --  If bounds of type are known at compile time, and the end points
3921             --  are known at compile time and identical, this is another case
3922             --  for substituting a valid test. We only do this for discrete
3923             --  types, since it won't arise in practice for float types.
3924
3925             if Comes_From_Source (N)
3926               and then Is_Discrete_Type (Ltyp)
3927               and then Compile_Time_Known_Value (Type_High_Bound (Ltyp))
3928               and then Compile_Time_Known_Value (Type_Low_Bound  (Ltyp))
3929               and then Compile_Time_Known_Value (Lo)
3930               and then Compile_Time_Known_Value (Hi)
3931               and then Expr_Value (Type_High_Bound (Ltyp)) = Expr_Value (Hi)
3932               and then Expr_Value (Type_Low_Bound  (Ltyp)) = Expr_Value (Lo)
3933
3934                --  Kill warnings in instances, since they may be cases where we
3935                --  have a test in the generic that makes sense with some types
3936                --  and not with other types.
3937
3938               and then not In_Instance
3939             then
3940                Substitute_Valid_Check;
3941                return;
3942             end if;
3943
3944             --  If we have an explicit range, do a bit of optimization based
3945             --  on range analysis (we may be able to kill one or both checks).
3946
3947             Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => False);
3948             Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => False);
3949
3950             --  If either check is known to fail, replace result by False since
3951             --  the other check does not matter. Preserve the static flag for
3952             --  legality checks, because we are constant-folding beyond RM 4.9.
3953
3954             if Lcheck = LT or else Ucheck = GT then
3955                if Warn1 then
3956                   Error_Msg_N ("?range test optimized away", N);
3957                   Error_Msg_N ("\?value is known to be out of range", N);
3958                end if;
3959
3960                Rewrite (N,
3961                  New_Reference_To (Standard_False, Loc));
3962                Analyze_And_Resolve (N, Rtyp);
3963                Set_Is_Static_Expression (N, Static);
3964
3965                return;
3966
3967             --  If both checks are known to succeed, replace result by True,
3968             --  since we know we are in range.
3969
3970             elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
3971                if Warn1 then
3972                   Error_Msg_N ("?range test optimized away", N);
3973                   Error_Msg_N ("\?value is known to be in range", N);
3974                end if;
3975
3976                Rewrite (N,
3977                  New_Reference_To (Standard_True, Loc));
3978                Analyze_And_Resolve (N, Rtyp);
3979                Set_Is_Static_Expression (N, Static);
3980
3981                return;
3982
3983             --  If lower bound check succeeds and upper bound check is not
3984             --  known to succeed or fail, then replace the range check with
3985             --  a comparison against the upper bound.
3986
3987             elsif Lcheck in Compare_GE then
3988                if Warn2 and then not In_Instance then
3989                   Error_Msg_N ("?lower bound test optimized away", Lo);
3990                   Error_Msg_N ("\?value is known to be in range", Lo);
3991                end if;
3992
3993                Rewrite (N,
3994                  Make_Op_Le (Loc,
3995                    Left_Opnd  => Lop,
3996                    Right_Opnd => High_Bound (Rop)));
3997                Analyze_And_Resolve (N, Rtyp);
3998
3999                return;
4000
4001             --  If upper bound check succeeds and lower bound check is not
4002             --  known to succeed or fail, then replace the range check with
4003             --  a comparison against the lower bound.
4004
4005             elsif Ucheck in Compare_LE then
4006                if Warn2 and then not In_Instance then
4007                   Error_Msg_N ("?upper bound test optimized away", Hi);
4008                   Error_Msg_N ("\?value is known to be in range", Hi);
4009                end if;
4010
4011                Rewrite (N,
4012                  Make_Op_Ge (Loc,
4013                    Left_Opnd  => Lop,
4014                    Right_Opnd => Low_Bound (Rop)));
4015                Analyze_And_Resolve (N, Rtyp);
4016
4017                return;
4018             end if;
4019
4020             --  We couldn't optimize away the range check, but there is one
4021             --  more issue. If we are checking constant conditionals, then we
4022             --  see if we can determine the outcome assuming everything is
4023             --  valid, and if so give an appropriate warning.
4024
4025             if Warn1 and then not Assume_No_Invalid_Values then
4026                Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => True);
4027                Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => True);
4028
4029                --  Result is out of range for valid value
4030
4031                if Lcheck = LT or else Ucheck = GT then
4032                   Error_Msg_N
4033                     ("?value can only be in range if it is invalid", N);
4034
4035                --  Result is in range for valid value
4036
4037                elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
4038                   Error_Msg_N
4039                     ("?value can only be out of range if it is invalid", N);
4040
4041                --  Lower bound check succeeds if value is valid
4042
4043                elsif Warn2 and then Lcheck in Compare_GE then
4044                   Error_Msg_N
4045                     ("?lower bound check only fails if it is invalid", Lo);
4046
4047                --  Upper bound  check succeeds if value is valid
4048
4049                elsif Warn2 and then Ucheck in Compare_LE then
4050                   Error_Msg_N
4051                     ("?upper bound check only fails for invalid values", Hi);
4052                end if;
4053             end if;
4054          end;
4055
4056          --  For all other cases of an explicit range, nothing to be done
4057
4058          return;
4059
4060       --  Here right operand is a subtype mark
4061
4062       else
4063          declare
4064             Typ    : Entity_Id        := Etype (Rop);
4065             Is_Acc : constant Boolean := Is_Access_Type (Typ);
4066             Obj    : Node_Id          := Lop;
4067             Cond   : Node_Id          := Empty;
4068
4069          begin
4070             Remove_Side_Effects (Obj);
4071
4072             --  For tagged type, do tagged membership operation
4073
4074             if Is_Tagged_Type (Typ) then
4075
4076                --  No expansion will be performed when VM_Target, as the VM
4077                --  back-ends will handle the membership tests directly (tags
4078                --  are not explicitly represented in Java objects, so the
4079                --  normal tagged membership expansion is not what we want).
4080
4081                if VM_Target = No_VM then
4082                   Rewrite (N, Tagged_Membership (N));
4083                   Analyze_And_Resolve (N, Rtyp);
4084                end if;
4085
4086                return;
4087
4088             --  If type is scalar type, rewrite as x in t'first .. t'last.
4089             --  This reason we do this is that the bounds may have the wrong
4090             --  type if they come from the original type definition. Also this
4091             --  way we get all the processing above for an explicit range.
4092
4093             elsif Is_Scalar_Type (Typ) then
4094                Rewrite (Rop,
4095                  Make_Range (Loc,
4096                    Low_Bound =>
4097                      Make_Attribute_Reference (Loc,
4098                        Attribute_Name => Name_First,
4099                        Prefix => New_Reference_To (Typ, Loc)),
4100
4101                    High_Bound =>
4102                      Make_Attribute_Reference (Loc,
4103                        Attribute_Name => Name_Last,
4104                        Prefix => New_Reference_To (Typ, Loc))));
4105                Analyze_And_Resolve (N, Rtyp);
4106                return;
4107
4108             --  Ada 2005 (AI-216): Program_Error is raised when evaluating
4109             --  a membership test if the subtype mark denotes a constrained
4110             --  Unchecked_Union subtype and the expression lacks inferable
4111             --  discriminants.
4112
4113             elsif Is_Unchecked_Union (Base_Type (Typ))
4114               and then Is_Constrained (Typ)
4115               and then not Has_Inferable_Discriminants (Lop)
4116             then
4117                Insert_Action (N,
4118                  Make_Raise_Program_Error (Loc,
4119                    Reason => PE_Unchecked_Union_Restriction));
4120
4121                --  Prevent Gigi from generating incorrect code by rewriting
4122                --  the test as a standard False.
4123
4124                Rewrite (N,
4125                  New_Occurrence_Of (Standard_False, Loc));
4126
4127                return;
4128             end if;
4129
4130             --  Here we have a non-scalar type
4131
4132             if Is_Acc then
4133                Typ := Designated_Type (Typ);
4134             end if;
4135
4136             if not Is_Constrained (Typ) then
4137                Rewrite (N,
4138                  New_Reference_To (Standard_True, Loc));
4139                Analyze_And_Resolve (N, Rtyp);
4140
4141             --  For the constrained array case, we have to check the subscripts
4142             --  for an exact match if the lengths are non-zero (the lengths
4143             --  must match in any case).
4144
4145             elsif Is_Array_Type (Typ) then
4146
4147                Check_Subscripts : declare
4148                   function Construct_Attribute_Reference
4149                     (E   : Node_Id;
4150                      Nam : Name_Id;
4151                      Dim : Nat) return Node_Id;
4152                   --  Build attribute reference E'Nam(Dim)
4153
4154                   -----------------------------------
4155                   -- Construct_Attribute_Reference --
4156                   -----------------------------------
4157
4158                   function Construct_Attribute_Reference
4159                     (E   : Node_Id;
4160                      Nam : Name_Id;
4161                      Dim : Nat) return Node_Id
4162                   is
4163                   begin
4164                      return
4165                        Make_Attribute_Reference (Loc,
4166                          Prefix => E,
4167                          Attribute_Name => Nam,
4168                          Expressions => New_List (
4169                            Make_Integer_Literal (Loc, Dim)));
4170                   end Construct_Attribute_Reference;
4171
4172                --  Start processing for Check_Subscripts
4173
4174                begin
4175                   for J in 1 .. Number_Dimensions (Typ) loop
4176                      Evolve_And_Then (Cond,
4177                        Make_Op_Eq (Loc,
4178                          Left_Opnd  =>
4179                            Construct_Attribute_Reference
4180                              (Duplicate_Subexpr_No_Checks (Obj),
4181                               Name_First, J),
4182                          Right_Opnd =>
4183                            Construct_Attribute_Reference
4184                              (New_Occurrence_Of (Typ, Loc), Name_First, J)));
4185
4186                      Evolve_And_Then (Cond,
4187                        Make_Op_Eq (Loc,
4188                          Left_Opnd  =>
4189                            Construct_Attribute_Reference
4190                              (Duplicate_Subexpr_No_Checks (Obj),
4191                               Name_Last, J),
4192                          Right_Opnd =>
4193                            Construct_Attribute_Reference
4194                              (New_Occurrence_Of (Typ, Loc), Name_Last, J)));
4195                   end loop;
4196
4197                   if Is_Acc then
4198                      Cond :=
4199                        Make_Or_Else (Loc,
4200                          Left_Opnd =>
4201                            Make_Op_Eq (Loc,
4202                              Left_Opnd  => Obj,
4203                              Right_Opnd => Make_Null (Loc)),
4204                          Right_Opnd => Cond);
4205                   end if;
4206
4207                   Rewrite (N, Cond);
4208                   Analyze_And_Resolve (N, Rtyp);
4209                end Check_Subscripts;
4210
4211             --  These are the cases where constraint checks may be required,
4212             --  e.g. records with possible discriminants
4213
4214             else
4215                --  Expand the test into a series of discriminant comparisons.
4216                --  The expression that is built is the negation of the one that
4217                --  is used for checking discriminant constraints.
4218
4219                Obj := Relocate_Node (Left_Opnd (N));
4220
4221                if Has_Discriminants (Typ) then
4222                   Cond := Make_Op_Not (Loc,
4223                     Right_Opnd => Build_Discriminant_Checks (Obj, Typ));
4224
4225                   if Is_Acc then
4226                      Cond := Make_Or_Else (Loc,
4227                        Left_Opnd =>
4228                          Make_Op_Eq (Loc,
4229                            Left_Opnd  => Obj,
4230                            Right_Opnd => Make_Null (Loc)),
4231                        Right_Opnd => Cond);
4232                   end if;
4233
4234                else
4235                   Cond := New_Occurrence_Of (Standard_True, Loc);
4236                end if;
4237
4238                Rewrite (N, Cond);
4239                Analyze_And_Resolve (N, Rtyp);
4240             end if;
4241          end;
4242       end if;
4243    end Expand_N_In;
4244
4245    --------------------------------
4246    -- Expand_N_Indexed_Component --
4247    --------------------------------
4248
4249    procedure Expand_N_Indexed_Component (N : Node_Id) is
4250       Loc : constant Source_Ptr := Sloc (N);
4251       Typ : constant Entity_Id  := Etype (N);
4252       P   : constant Node_Id    := Prefix (N);
4253       T   : constant Entity_Id  := Etype (P);
4254
4255    begin
4256       --  A special optimization, if we have an indexed component that is
4257       --  selecting from a slice, then we can eliminate the slice, since, for
4258       --  example, x (i .. j)(k) is identical to x(k). The only difference is
4259       --  the range check required by the slice. The range check for the slice
4260       --  itself has already been generated. The range check for the
4261       --  subscripting operation is ensured by converting the subject to
4262       --  the subtype of the slice.
4263
4264       --  This optimization not only generates better code, avoiding slice
4265       --  messing especially in the packed case, but more importantly bypasses
4266       --  some problems in handling this peculiar case, for example, the issue
4267       --  of dealing specially with object renamings.
4268
4269       if Nkind (P) = N_Slice then
4270          Rewrite (N,
4271            Make_Indexed_Component (Loc,
4272              Prefix => Prefix (P),
4273              Expressions => New_List (
4274                Convert_To
4275                  (Etype (First_Index (Etype (P))),
4276                   First (Expressions (N))))));
4277          Analyze_And_Resolve (N, Typ);
4278          return;
4279       end if;
4280
4281       --  Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
4282       --  function, then additional actuals must be passed.
4283
4284       if Ada_Version >= Ada_05
4285         and then Is_Build_In_Place_Function_Call (P)
4286       then
4287          Make_Build_In_Place_Call_In_Anonymous_Context (P);
4288       end if;
4289
4290       --  If the prefix is an access type, then we unconditionally rewrite if
4291       --  as an explicit deference. This simplifies processing for several
4292       --  cases, including packed array cases and certain cases in which checks
4293       --  must be generated. We used to try to do this only when it was
4294       --  necessary, but it cleans up the code to do it all the time.
4295
4296       if Is_Access_Type (T) then
4297          Insert_Explicit_Dereference (P);
4298          Analyze_And_Resolve (P, Designated_Type (T));
4299       end if;
4300
4301       --  Generate index and validity checks
4302
4303       Generate_Index_Checks (N);
4304
4305       if Validity_Checks_On and then Validity_Check_Subscripts then
4306          Apply_Subscript_Validity_Checks (N);
4307       end if;
4308
4309       --  All done for the non-packed case
4310
4311       if not Is_Packed (Etype (Prefix (N))) then
4312          return;
4313       end if;
4314
4315       --  For packed arrays that are not bit-packed (i.e. the case of an array
4316       --  with one or more index types with a non-contiguous enumeration type),
4317       --  we can always use the normal packed element get circuit.
4318
4319       if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
4320          Expand_Packed_Element_Reference (N);
4321          return;
4322       end if;
4323
4324       --  For a reference to a component of a bit packed array, we have to
4325       --  convert it to a reference to the corresponding Packed_Array_Type.
4326       --  We only want to do this for simple references, and not for:
4327
4328       --    Left side of assignment, or prefix of left side of assignment, or
4329       --    prefix of the prefix, to handle packed arrays of packed arrays,
4330       --      This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
4331
4332       --    Renaming objects in renaming associations
4333       --      This case is handled when a use of the renamed variable occurs
4334
4335       --    Actual parameters for a procedure call
4336       --      This case is handled in Exp_Ch6.Expand_Actuals
4337
4338       --    The second expression in a 'Read attribute reference
4339
4340       --    The prefix of an address or size attribute reference
4341
4342       --  The following circuit detects these exceptions
4343
4344       declare
4345          Child : Node_Id := N;
4346          Parnt : Node_Id := Parent (N);
4347
4348       begin
4349          loop
4350             if Nkind (Parnt) = N_Unchecked_Expression then
4351                null;
4352
4353             elsif Nkind_In (Parnt, N_Object_Renaming_Declaration,
4354                                    N_Procedure_Call_Statement)
4355               or else (Nkind (Parnt) = N_Parameter_Association
4356                         and then
4357                           Nkind (Parent (Parnt)) =  N_Procedure_Call_Statement)
4358             then
4359                return;
4360
4361             elsif Nkind (Parnt) = N_Attribute_Reference
4362               and then (Attribute_Name (Parnt) = Name_Address
4363                          or else
4364                         Attribute_Name (Parnt) = Name_Size)
4365               and then Prefix (Parnt) = Child
4366             then
4367                return;
4368
4369             elsif Nkind (Parnt) = N_Assignment_Statement
4370               and then Name (Parnt) = Child
4371             then
4372                return;
4373
4374             --  If the expression is an index of an indexed component, it must
4375             --  be expanded regardless of context.
4376
4377             elsif Nkind (Parnt) = N_Indexed_Component
4378               and then Child /= Prefix (Parnt)
4379             then
4380                Expand_Packed_Element_Reference (N);
4381                return;
4382
4383             elsif Nkind (Parent (Parnt)) = N_Assignment_Statement
4384               and then Name (Parent (Parnt)) = Parnt
4385             then
4386                return;
4387
4388             elsif Nkind (Parnt) = N_Attribute_Reference
4389               and then Attribute_Name (Parnt) = Name_Read
4390               and then Next (First (Expressions (Parnt))) = Child
4391             then
4392                return;
4393
4394             elsif Nkind_In (Parnt, N_Indexed_Component, N_Selected_Component)
4395                and then Prefix (Parnt) = Child
4396             then
4397                null;
4398
4399             else
4400                Expand_Packed_Element_Reference (N);
4401                return;
4402             end if;
4403
4404             --  Keep looking up tree for unchecked expression, or if we are the
4405             --  prefix of a possible assignment left side.
4406
4407             Child := Parnt;
4408             Parnt := Parent (Child);
4409          end loop;
4410       end;
4411    end Expand_N_Indexed_Component;
4412
4413    ---------------------
4414    -- Expand_N_Not_In --
4415    ---------------------
4416
4417    --  Replace a not in b by not (a in b) so that the expansions for (a in b)
4418    --  can be done. This avoids needing to duplicate this expansion code.
4419
4420    procedure Expand_N_Not_In (N : Node_Id) is
4421       Loc : constant Source_Ptr := Sloc (N);
4422       Typ : constant Entity_Id  := Etype (N);
4423       Cfs : constant Boolean    := Comes_From_Source (N);
4424
4425    begin
4426       Rewrite (N,
4427         Make_Op_Not (Loc,
4428           Right_Opnd =>
4429             Make_In (Loc,
4430               Left_Opnd  => Left_Opnd (N),
4431               Right_Opnd => Right_Opnd (N))));
4432
4433       --  We want this to appear as coming from source if original does (see
4434       --  transformations in Expand_N_In).
4435
4436       Set_Comes_From_Source (N, Cfs);
4437       Set_Comes_From_Source (Right_Opnd (N), Cfs);
4438
4439       --  Now analyze transformed node
4440
4441       Analyze_And_Resolve (N, Typ);
4442    end Expand_N_Not_In;
4443
4444    -------------------
4445    -- Expand_N_Null --
4446    -------------------
4447
4448    --  The only replacement required is for the case of a null of type that is
4449    --  an access to protected subprogram. We represent such access values as a
4450    --  record, and so we must replace the occurrence of null by the equivalent
4451    --  record (with a null address and a null pointer in it), so that the
4452    --  backend creates the proper value.
4453
4454    procedure Expand_N_Null (N : Node_Id) is
4455       Loc : constant Source_Ptr := Sloc (N);
4456       Typ : constant Entity_Id  := Etype (N);
4457       Agg : Node_Id;
4458
4459    begin
4460       if Is_Access_Protected_Subprogram_Type (Typ) then
4461          Agg :=
4462            Make_Aggregate (Loc,
4463              Expressions => New_List (
4464                New_Occurrence_Of (RTE (RE_Null_Address), Loc),
4465                Make_Null (Loc)));
4466
4467          Rewrite (N, Agg);
4468          Analyze_And_Resolve (N, Equivalent_Type (Typ));
4469
4470          --  For subsequent semantic analysis, the node must retain its type.
4471          --  Gigi in any case replaces this type by the corresponding record
4472          --  type before processing the node.
4473
4474          Set_Etype (N, Typ);
4475       end if;
4476
4477    exception
4478       when RE_Not_Available =>
4479          return;
4480    end Expand_N_Null;
4481
4482    ---------------------
4483    -- Expand_N_Op_Abs --
4484    ---------------------
4485
4486    procedure Expand_N_Op_Abs (N : Node_Id) is
4487       Loc  : constant Source_Ptr := Sloc (N);
4488       Expr : constant Node_Id := Right_Opnd (N);
4489
4490    begin
4491       Unary_Op_Validity_Checks (N);
4492
4493       --  Deal with software overflow checking
4494
4495       if not Backend_Overflow_Checks_On_Target
4496          and then Is_Signed_Integer_Type (Etype (N))
4497          and then Do_Overflow_Check (N)
4498       then
4499          --  The only case to worry about is when the argument is equal to the
4500          --  largest negative number, so what we do is to insert the check:
4501
4502          --     [constraint_error when Expr = typ'Base'First]
4503
4504          --  with the usual Duplicate_Subexpr use coding for expr
4505
4506          Insert_Action (N,
4507            Make_Raise_Constraint_Error (Loc,
4508              Condition =>
4509                Make_Op_Eq (Loc,
4510                  Left_Opnd  => Duplicate_Subexpr (Expr),
4511                  Right_Opnd =>
4512                    Make_Attribute_Reference (Loc,
4513                      Prefix =>
4514                        New_Occurrence_Of (Base_Type (Etype (Expr)), Loc),
4515                      Attribute_Name => Name_First)),
4516              Reason => CE_Overflow_Check_Failed));
4517       end if;
4518
4519       --  Vax floating-point types case
4520
4521       if Vax_Float (Etype (N)) then
4522          Expand_Vax_Arith (N);
4523       end if;
4524    end Expand_N_Op_Abs;
4525
4526    ---------------------
4527    -- Expand_N_Op_Add --
4528    ---------------------
4529
4530    procedure Expand_N_Op_Add (N : Node_Id) is
4531       Typ : constant Entity_Id := Etype (N);
4532
4533    begin
4534       Binary_Op_Validity_Checks (N);
4535
4536       --  N + 0 = 0 + N = N for integer types
4537
4538       if Is_Integer_Type (Typ) then
4539          if Compile_Time_Known_Value (Right_Opnd (N))
4540            and then Expr_Value (Right_Opnd (N)) = Uint_0
4541          then
4542             Rewrite (N, Left_Opnd (N));
4543             return;
4544
4545          elsif Compile_Time_Known_Value (Left_Opnd (N))
4546            and then Expr_Value (Left_Opnd (N)) = Uint_0
4547          then
4548             Rewrite (N, Right_Opnd (N));
4549             return;
4550          end if;
4551       end if;
4552
4553       --  Arithmetic overflow checks for signed integer/fixed point types
4554
4555       if Is_Signed_Integer_Type (Typ)
4556         or else Is_Fixed_Point_Type (Typ)
4557       then
4558          Apply_Arithmetic_Overflow_Check (N);
4559          return;
4560
4561       --  Vax floating-point types case
4562
4563       elsif Vax_Float (Typ) then
4564          Expand_Vax_Arith (N);
4565       end if;
4566    end Expand_N_Op_Add;
4567
4568    ---------------------
4569    -- Expand_N_Op_And --
4570    ---------------------
4571
4572    procedure Expand_N_Op_And (N : Node_Id) is
4573       Typ : constant Entity_Id := Etype (N);
4574
4575    begin
4576       Binary_Op_Validity_Checks (N);
4577
4578       if Is_Array_Type (Etype (N)) then
4579          Expand_Boolean_Operator (N);
4580
4581       elsif Is_Boolean_Type (Etype (N)) then
4582          Adjust_Condition (Left_Opnd (N));
4583          Adjust_Condition (Right_Opnd (N));
4584          Set_Etype (N, Standard_Boolean);
4585          Adjust_Result_Type (N, Typ);
4586       end if;
4587    end Expand_N_Op_And;
4588
4589    ------------------------
4590    -- Expand_N_Op_Concat --
4591    ------------------------
4592
4593    procedure Expand_N_Op_Concat (N : Node_Id) is
4594       Opnds : List_Id;
4595       --  List of operands to be concatenated
4596
4597       Cnode : Node_Id;
4598       --  Node which is to be replaced by the result of concatenating the nodes
4599       --  in the list Opnds.
4600
4601    begin
4602       --  Ensure validity of both operands
4603
4604       Binary_Op_Validity_Checks (N);
4605
4606       --  If we are the left operand of a concatenation higher up the tree,
4607       --  then do nothing for now, since we want to deal with a series of
4608       --  concatenations as a unit.
4609
4610       if Nkind (Parent (N)) = N_Op_Concat
4611         and then N = Left_Opnd (Parent (N))
4612       then
4613          return;
4614       end if;
4615
4616       --  We get here with a concatenation whose left operand may be a
4617       --  concatenation itself with a consistent type. We need to process
4618       --  these concatenation operands from left to right, which means
4619       --  from the deepest node in the tree to the highest node.
4620
4621       Cnode := N;
4622       while Nkind (Left_Opnd (Cnode)) = N_Op_Concat loop
4623          Cnode := Left_Opnd (Cnode);
4624       end loop;
4625
4626       --  Now Opnd is the deepest Opnd, and its parents are the concatenation
4627       --  nodes above, so now we process bottom up, doing the operations. We
4628       --  gather a string that is as long as possible up to five operands
4629
4630       --  The outer loop runs more than once if more than one concatenation
4631       --  type is involved.
4632
4633       Outer : loop
4634          Opnds := New_List (Left_Opnd (Cnode), Right_Opnd (Cnode));
4635          Set_Parent (Opnds, N);
4636
4637          --  The inner loop gathers concatenation operands
4638
4639          Inner : while Cnode /= N
4640                    and then Base_Type (Etype (Cnode)) =
4641                             Base_Type (Etype (Parent (Cnode)))
4642          loop
4643             Cnode := Parent (Cnode);
4644             Append (Right_Opnd (Cnode), Opnds);
4645          end loop Inner;
4646
4647          Expand_Concatenate (Cnode, Opnds);
4648
4649          exit Outer when Cnode = N;
4650          Cnode := Parent (Cnode);
4651       end loop Outer;
4652    end Expand_N_Op_Concat;
4653
4654    ------------------------
4655    -- Expand_N_Op_Divide --
4656    ------------------------
4657
4658    procedure Expand_N_Op_Divide (N : Node_Id) is
4659       Loc   : constant Source_Ptr := Sloc (N);
4660       Lopnd : constant Node_Id    := Left_Opnd (N);
4661       Ropnd : constant Node_Id    := Right_Opnd (N);
4662       Ltyp  : constant Entity_Id  := Etype (Lopnd);
4663       Rtyp  : constant Entity_Id  := Etype (Ropnd);
4664       Typ   : Entity_Id           := Etype (N);
4665       Rknow : constant Boolean    := Is_Integer_Type (Typ)
4666                                        and then
4667                                          Compile_Time_Known_Value (Ropnd);
4668       Rval  : Uint;
4669
4670    begin
4671       Binary_Op_Validity_Checks (N);
4672
4673       if Rknow then
4674          Rval := Expr_Value (Ropnd);
4675       end if;
4676
4677       --  N / 1 = N for integer types
4678
4679       if Rknow and then Rval = Uint_1 then
4680          Rewrite (N, Lopnd);
4681          return;
4682       end if;
4683
4684       --  Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
4685       --  Is_Power_Of_2_For_Shift is set means that we know that our left
4686       --  operand is an unsigned integer, as required for this to work.
4687
4688       if Nkind (Ropnd) = N_Op_Expon
4689         and then Is_Power_Of_2_For_Shift (Ropnd)
4690
4691       --  We cannot do this transformation in configurable run time mode if we
4692       --  have 64-bit --  integers and long shifts are not available.
4693
4694         and then
4695           (Esize (Ltyp) <= 32
4696              or else Support_Long_Shifts_On_Target)
4697       then
4698          Rewrite (N,
4699            Make_Op_Shift_Right (Loc,
4700              Left_Opnd  => Lopnd,
4701              Right_Opnd =>
4702                Convert_To (Standard_Natural, Right_Opnd (Ropnd))));
4703          Analyze_And_Resolve (N, Typ);
4704          return;
4705       end if;
4706
4707       --  Do required fixup of universal fixed operation
4708
4709       if Typ = Universal_Fixed then
4710          Fixup_Universal_Fixed_Operation (N);
4711          Typ := Etype (N);
4712       end if;
4713
4714       --  Divisions with fixed-point results
4715
4716       if Is_Fixed_Point_Type (Typ) then
4717
4718          --  No special processing if Treat_Fixed_As_Integer is set, since
4719          --  from a semantic point of view such operations are simply integer
4720          --  operations and will be treated that way.
4721
4722          if not Treat_Fixed_As_Integer (N) then
4723             if Is_Integer_Type (Rtyp) then
4724                Expand_Divide_Fixed_By_Integer_Giving_Fixed (N);
4725             else
4726                Expand_Divide_Fixed_By_Fixed_Giving_Fixed (N);
4727             end if;
4728          end if;
4729
4730       --  Other cases of division of fixed-point operands. Again we exclude the
4731       --  case where Treat_Fixed_As_Integer is set.
4732
4733       elsif (Is_Fixed_Point_Type (Ltyp) or else
4734              Is_Fixed_Point_Type (Rtyp))
4735         and then not Treat_Fixed_As_Integer (N)
4736       then
4737          if Is_Integer_Type (Typ) then
4738             Expand_Divide_Fixed_By_Fixed_Giving_Integer (N);
4739          else
4740             pragma Assert (Is_Floating_Point_Type (Typ));
4741             Expand_Divide_Fixed_By_Fixed_Giving_Float (N);
4742          end if;
4743
4744       --  Mixed-mode operations can appear in a non-static universal context,
4745       --  in which case the integer argument must be converted explicitly.
4746
4747       elsif Typ = Universal_Real
4748         and then Is_Integer_Type (Rtyp)
4749       then
4750          Rewrite (Ropnd,
4751            Convert_To (Universal_Real, Relocate_Node (Ropnd)));
4752
4753          Analyze_And_Resolve (Ropnd, Universal_Real);
4754
4755       elsif Typ = Universal_Real
4756         and then Is_Integer_Type (Ltyp)
4757       then
4758          Rewrite (Lopnd,
4759            Convert_To (Universal_Real, Relocate_Node (Lopnd)));
4760
4761          Analyze_And_Resolve (Lopnd, Universal_Real);
4762
4763       --  Non-fixed point cases, do integer zero divide and overflow checks
4764
4765       elsif Is_Integer_Type (Typ) then
4766          Apply_Divide_Check (N);
4767
4768          --  Check for 64-bit division available, or long shifts if the divisor
4769          --  is a small power of 2 (since such divides will be converted into
4770          --  long shifts.
4771
4772          if Esize (Ltyp) > 32
4773            and then not Support_64_Bit_Divides_On_Target
4774            and then
4775              (not Rknow
4776                 or else not Support_Long_Shifts_On_Target
4777                 or else (Rval /= Uint_2  and then
4778                          Rval /= Uint_4  and then
4779                          Rval /= Uint_8  and then
4780                          Rval /= Uint_16 and then
4781                          Rval /= Uint_32 and then
4782                          Rval /= Uint_64))
4783          then
4784             Error_Msg_CRT ("64-bit division", N);
4785          end if;
4786
4787       --  Deal with Vax_Float
4788
4789       elsif Vax_Float (Typ) then
4790          Expand_Vax_Arith (N);
4791          return;
4792       end if;
4793    end Expand_N_Op_Divide;
4794
4795    --------------------
4796    -- Expand_N_Op_Eq --
4797    --------------------
4798
4799    procedure Expand_N_Op_Eq (N : Node_Id) is
4800       Loc    : constant Source_Ptr := Sloc (N);
4801       Typ    : constant Entity_Id  := Etype (N);
4802       Lhs    : constant Node_Id    := Left_Opnd (N);
4803       Rhs    : constant Node_Id    := Right_Opnd (N);
4804       Bodies : constant List_Id    := New_List;
4805       A_Typ  : constant Entity_Id  := Etype (Lhs);
4806
4807       Typl    : Entity_Id := A_Typ;
4808       Op_Name : Entity_Id;
4809       Prim    : Elmt_Id;
4810
4811       procedure Build_Equality_Call (Eq : Entity_Id);
4812       --  If a constructed equality exists for the type or for its parent,
4813       --  build and analyze call, adding conversions if the operation is
4814       --  inherited.
4815
4816       function Has_Unconstrained_UU_Component (Typ : Node_Id) return Boolean;
4817       --  Determines whether a type has a subcomponent of an unconstrained
4818       --  Unchecked_Union subtype. Typ is a record type.
4819
4820       -------------------------
4821       -- Build_Equality_Call --
4822       -------------------------
4823
4824       procedure Build_Equality_Call (Eq : Entity_Id) is
4825          Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
4826          L_Exp   : Node_Id := Relocate_Node (Lhs);
4827          R_Exp   : Node_Id := Relocate_Node (Rhs);
4828
4829       begin
4830          if Base_Type (Op_Type) /= Base_Type (A_Typ)
4831            and then not Is_Class_Wide_Type (A_Typ)
4832          then
4833             L_Exp := OK_Convert_To (Op_Type, L_Exp);
4834             R_Exp := OK_Convert_To (Op_Type, R_Exp);
4835          end if;
4836
4837          --  If we have an Unchecked_Union, we need to add the inferred
4838          --  discriminant values as actuals in the function call. At this
4839          --  point, the expansion has determined that both operands have
4840          --  inferable discriminants.
4841
4842          if Is_Unchecked_Union (Op_Type) then
4843             declare
4844                Lhs_Type      : constant Node_Id := Etype (L_Exp);
4845                Rhs_Type      : constant Node_Id := Etype (R_Exp);
4846                Lhs_Discr_Val : Node_Id;
4847                Rhs_Discr_Val : Node_Id;
4848
4849             begin
4850                --  Per-object constrained selected components require special
4851                --  attention. If the enclosing scope of the component is an
4852                --  Unchecked_Union, we cannot reference its discriminants
4853                --  directly. This is why we use the two extra parameters of
4854                --  the equality function of the enclosing Unchecked_Union.
4855
4856                --  type UU_Type (Discr : Integer := 0) is
4857                --     . . .
4858                --  end record;
4859                --  pragma Unchecked_Union (UU_Type);
4860
4861                --  1. Unchecked_Union enclosing record:
4862
4863                --     type Enclosing_UU_Type (Discr : Integer := 0) is record
4864                --        . . .
4865                --        Comp : UU_Type (Discr);
4866                --        . . .
4867                --     end Enclosing_UU_Type;
4868                --     pragma Unchecked_Union (Enclosing_UU_Type);
4869
4870                --     Obj1 : Enclosing_UU_Type;
4871                --     Obj2 : Enclosing_UU_Type (1);
4872
4873                --     [. . .] Obj1 = Obj2 [. . .]
4874
4875                --     Generated code:
4876
4877                --     if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
4878
4879                --  A and B are the formal parameters of the equality function
4880                --  of Enclosing_UU_Type. The function always has two extra
4881                --  formals to capture the inferred discriminant values.
4882
4883                --  2. Non-Unchecked_Union enclosing record:
4884
4885                --     type
4886                --       Enclosing_Non_UU_Type (Discr : Integer := 0)
4887                --     is record
4888                --        . . .
4889                --        Comp : UU_Type (Discr);
4890                --        . . .
4891                --     end Enclosing_Non_UU_Type;
4892
4893                --     Obj1 : Enclosing_Non_UU_Type;
4894                --     Obj2 : Enclosing_Non_UU_Type (1);
4895
4896                --     ...  Obj1 = Obj2 ...
4897
4898                --     Generated code:
4899
4900                --     if not (uu_typeEQ (obj1.comp, obj2.comp,
4901                --                        obj1.discr, obj2.discr)) then
4902
4903                --  In this case we can directly reference the discriminants of
4904                --  the enclosing record.
4905
4906                --  Lhs of equality
4907
4908                if Nkind (Lhs) = N_Selected_Component
4909                  and then Has_Per_Object_Constraint
4910                             (Entity (Selector_Name (Lhs)))
4911                then
4912                   --  Enclosing record is an Unchecked_Union, use formal A
4913
4914                   if Is_Unchecked_Union (Scope
4915                        (Entity (Selector_Name (Lhs))))
4916                   then
4917                      Lhs_Discr_Val :=
4918                        Make_Identifier (Loc,
4919                          Chars => Name_A);
4920
4921                   --  Enclosing record is of a non-Unchecked_Union type, it is
4922                   --  possible to reference the discriminant.
4923
4924                   else
4925                      Lhs_Discr_Val :=
4926                        Make_Selected_Component (Loc,
4927                          Prefix => Prefix (Lhs),
4928                          Selector_Name =>
4929                            New_Copy
4930                              (Get_Discriminant_Value
4931                                 (First_Discriminant (Lhs_Type),
4932                                  Lhs_Type,
4933                                  Stored_Constraint (Lhs_Type))));
4934                   end if;
4935
4936                --  Comment needed here ???
4937
4938                else
4939                   --  Infer the discriminant value
4940
4941                   Lhs_Discr_Val :=
4942                     New_Copy
4943                       (Get_Discriminant_Value
4944                          (First_Discriminant (Lhs_Type),
4945                           Lhs_Type,
4946                           Stored_Constraint (Lhs_Type)));
4947                end if;
4948
4949                --  Rhs of equality
4950
4951                if Nkind (Rhs) = N_Selected_Component
4952                  and then Has_Per_Object_Constraint
4953                             (Entity (Selector_Name (Rhs)))
4954                then
4955                   if Is_Unchecked_Union
4956                        (Scope (Entity (Selector_Name (Rhs))))
4957                   then
4958                      Rhs_Discr_Val :=
4959                        Make_Identifier (Loc,
4960                          Chars => Name_B);
4961
4962                   else
4963                      Rhs_Discr_Val :=
4964                        Make_Selected_Component (Loc,
4965                          Prefix => Prefix (Rhs),
4966                          Selector_Name =>
4967                            New_Copy (Get_Discriminant_Value (
4968                              First_Discriminant (Rhs_Type),
4969                              Rhs_Type,
4970                              Stored_Constraint (Rhs_Type))));
4971
4972                   end if;
4973                else
4974                   Rhs_Discr_Val :=
4975                     New_Copy (Get_Discriminant_Value (
4976                       First_Discriminant (Rhs_Type),
4977                       Rhs_Type,
4978                       Stored_Constraint (Rhs_Type)));
4979
4980                end if;
4981
4982                Rewrite (N,
4983                  Make_Function_Call (Loc,
4984                    Name => New_Reference_To (Eq, Loc),
4985                    Parameter_Associations => New_List (
4986                      L_Exp,
4987                      R_Exp,
4988                      Lhs_Discr_Val,
4989                      Rhs_Discr_Val)));
4990             end;
4991
4992          --  Normal case, not an unchecked union
4993
4994          else
4995             Rewrite (N,
4996               Make_Function_Call (Loc,
4997                 Name => New_Reference_To (Eq, Loc),
4998                 Parameter_Associations => New_List (L_Exp, R_Exp)));
4999          end if;
5000
5001          Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
5002       end Build_Equality_Call;
5003
5004       ------------------------------------
5005       -- Has_Unconstrained_UU_Component --
5006       ------------------------------------
5007
5008       function Has_Unconstrained_UU_Component
5009         (Typ : Node_Id) return Boolean
5010       is
5011          Tdef  : constant Node_Id :=
5012                    Type_Definition (Declaration_Node (Base_Type (Typ)));
5013          Clist : Node_Id;
5014          Vpart : Node_Id;
5015
5016          function Component_Is_Unconstrained_UU
5017            (Comp : Node_Id) return Boolean;
5018          --  Determines whether the subtype of the component is an
5019          --  unconstrained Unchecked_Union.
5020
5021          function Variant_Is_Unconstrained_UU
5022            (Variant : Node_Id) return Boolean;
5023          --  Determines whether a component of the variant has an unconstrained
5024          --  Unchecked_Union subtype.
5025
5026          -----------------------------------
5027          -- Component_Is_Unconstrained_UU --
5028          -----------------------------------
5029
5030          function Component_Is_Unconstrained_UU
5031            (Comp : Node_Id) return Boolean
5032          is
5033          begin
5034             if Nkind (Comp) /= N_Component_Declaration then
5035                return False;
5036             end if;
5037
5038             declare
5039                Sindic : constant Node_Id :=
5040                           Subtype_Indication (Component_Definition (Comp));
5041
5042             begin
5043                --  Unconstrained nominal type. In the case of a constraint
5044                --  present, the node kind would have been N_Subtype_Indication.
5045
5046                if Nkind (Sindic) = N_Identifier then
5047                   return Is_Unchecked_Union (Base_Type (Etype (Sindic)));
5048                end if;
5049
5050                return False;
5051             end;
5052          end Component_Is_Unconstrained_UU;
5053
5054          ---------------------------------
5055          -- Variant_Is_Unconstrained_UU --
5056          ---------------------------------
5057
5058          function Variant_Is_Unconstrained_UU
5059            (Variant : Node_Id) return Boolean
5060          is
5061             Clist : constant Node_Id := Component_List (Variant);
5062
5063          begin
5064             if Is_Empty_List (Component_Items (Clist)) then
5065                return False;
5066             end if;
5067
5068             --  We only need to test one component
5069
5070             declare
5071                Comp : Node_Id := First (Component_Items (Clist));
5072
5073             begin
5074                while Present (Comp) loop
5075                   if Component_Is_Unconstrained_UU (Comp) then
5076                      return True;
5077                   end if;
5078
5079                   Next (Comp);
5080                end loop;
5081             end;
5082
5083             --  None of the components withing the variant were of
5084             --  unconstrained Unchecked_Union type.
5085
5086             return False;
5087          end Variant_Is_Unconstrained_UU;
5088
5089       --  Start of processing for Has_Unconstrained_UU_Component
5090
5091       begin
5092          if Null_Present (Tdef) then
5093             return False;
5094          end if;
5095
5096          Clist := Component_List (Tdef);
5097          Vpart := Variant_Part (Clist);
5098
5099          --  Inspect available components
5100
5101          if Present (Component_Items (Clist)) then
5102             declare
5103                Comp : Node_Id := First (Component_Items (Clist));
5104
5105             begin
5106                while Present (Comp) loop
5107
5108                   --  One component is sufficient
5109
5110                   if Component_Is_Unconstrained_UU (Comp) then
5111                      return True;
5112                   end if;
5113
5114                   Next (Comp);
5115                end loop;
5116             end;
5117          end if;
5118
5119          --  Inspect available components withing variants
5120
5121          if Present (Vpart) then
5122             declare
5123                Variant : Node_Id := First (Variants (Vpart));
5124
5125             begin
5126                while Present (Variant) loop
5127
5128                   --  One component within a variant is sufficient
5129
5130                   if Variant_Is_Unconstrained_UU (Variant) then
5131                      return True;
5132                   end if;
5133
5134                   Next (Variant);
5135                end loop;
5136             end;
5137          end if;
5138
5139          --  Neither the available components, nor the components inside the
5140          --  variant parts were of an unconstrained Unchecked_Union subtype.
5141
5142          return False;
5143       end Has_Unconstrained_UU_Component;
5144
5145    --  Start of processing for Expand_N_Op_Eq
5146
5147    begin
5148       Binary_Op_Validity_Checks (N);
5149
5150       if Ekind (Typl) = E_Private_Type then
5151          Typl := Underlying_Type (Typl);
5152       elsif Ekind (Typl) = E_Private_Subtype then
5153          Typl := Underlying_Type (Base_Type (Typl));
5154       else
5155          null;
5156       end if;
5157
5158       --  It may happen in error situations that the underlying type is not
5159       --  set. The error will be detected later, here we just defend the
5160       --  expander code.
5161
5162       if No (Typl) then
5163          return;
5164       end if;
5165
5166       Typl := Base_Type (Typl);
5167
5168       --  Boolean types (requiring handling of non-standard case)
5169
5170       if Is_Boolean_Type (Typl) then
5171          Adjust_Condition (Left_Opnd (N));
5172          Adjust_Condition (Right_Opnd (N));
5173          Set_Etype (N, Standard_Boolean);
5174          Adjust_Result_Type (N, Typ);
5175
5176       --  Array types
5177
5178       elsif Is_Array_Type (Typl) then
5179
5180          --  If we are doing full validity checking, and it is possible for the
5181          --  array elements to be invalid then expand out array comparisons to
5182          --  make sure that we check the array elements.
5183
5184          if Validity_Check_Operands
5185            and then not Is_Known_Valid (Component_Type (Typl))
5186          then
5187             declare
5188                Save_Force_Validity_Checks : constant Boolean :=
5189                                               Force_Validity_Checks;
5190             begin
5191                Force_Validity_Checks := True;
5192                Rewrite (N,
5193                  Expand_Array_Equality
5194                   (N,
5195                    Relocate_Node (Lhs),
5196                    Relocate_Node (Rhs),
5197                    Bodies,
5198                    Typl));
5199                Insert_Actions (N, Bodies);
5200                Analyze_And_Resolve (N, Standard_Boolean);
5201                Force_Validity_Checks := Save_Force_Validity_Checks;
5202             end;
5203
5204          --  Packed case where both operands are known aligned
5205
5206          elsif Is_Bit_Packed_Array (Typl)
5207            and then not Is_Possibly_Unaligned_Object (Lhs)
5208            and then not Is_Possibly_Unaligned_Object (Rhs)
5209          then
5210             Expand_Packed_Eq (N);
5211
5212          --  Where the component type is elementary we can use a block bit
5213          --  comparison (if supported on the target) exception in the case
5214          --  of floating-point (negative zero issues require element by
5215          --  element comparison), and atomic types (where we must be sure
5216          --  to load elements independently) and possibly unaligned arrays.
5217
5218          elsif Is_Elementary_Type (Component_Type (Typl))
5219            and then not Is_Floating_Point_Type (Component_Type (Typl))
5220            and then not Is_Atomic (Component_Type (Typl))
5221            and then not Is_Possibly_Unaligned_Object (Lhs)
5222            and then not Is_Possibly_Unaligned_Object (Rhs)
5223            and then Support_Composite_Compare_On_Target
5224          then
5225             null;
5226
5227          --  For composite and floating-point cases, expand equality loop to
5228          --  make sure of using proper comparisons for tagged types, and
5229          --  correctly handling the floating-point case.
5230
5231          else
5232             Rewrite (N,
5233               Expand_Array_Equality
5234                 (N,
5235                  Relocate_Node (Lhs),
5236                  Relocate_Node (Rhs),
5237                  Bodies,
5238                  Typl));
5239             Insert_Actions      (N, Bodies,           Suppress => All_Checks);
5240             Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
5241          end if;
5242
5243       --  Record Types
5244
5245       elsif Is_Record_Type (Typl) then
5246
5247          --  For tagged types, use the primitive "="
5248
5249          if Is_Tagged_Type (Typl) then
5250
5251             --  No need to do anything else compiling under restriction
5252             --  No_Dispatching_Calls. During the semantic analysis we
5253             --  already notified such violation.
5254
5255             if Restriction_Active (No_Dispatching_Calls) then
5256                return;
5257             end if;
5258
5259             --  If this is derived from an untagged private type completed with
5260             --  a tagged type, it does not have a full view, so we use the
5261             --  primitive operations of the private type. This check should no
5262             --  longer be necessary when these types get their full views???
5263
5264             if Is_Private_Type (A_Typ)
5265               and then not Is_Tagged_Type (A_Typ)
5266               and then Is_Derived_Type (A_Typ)
5267               and then No (Full_View (A_Typ))
5268             then
5269                --  Search for equality operation, checking that the operands
5270                --  have the same type. Note that we must find a matching entry,
5271                --  or something is very wrong!
5272
5273                Prim := First_Elmt (Collect_Primitive_Operations (A_Typ));
5274
5275                while Present (Prim) loop
5276                   exit when Chars (Node (Prim)) = Name_Op_Eq
5277                     and then Etype (First_Formal (Node (Prim))) =
5278                              Etype (Next_Formal (First_Formal (Node (Prim))))
5279                     and then
5280                       Base_Type (Etype (Node (Prim))) = Standard_Boolean;
5281
5282                   Next_Elmt (Prim);
5283                end loop;
5284
5285                pragma Assert (Present (Prim));
5286                Op_Name := Node (Prim);
5287
5288             --  Find the type's predefined equality or an overriding
5289             --  user- defined equality. The reason for not simply calling
5290             --  Find_Prim_Op here is that there may be a user-defined
5291             --  overloaded equality op that precedes the equality that we want,
5292             --  so we have to explicitly search (e.g., there could be an
5293             --  equality with two different parameter types).
5294
5295             else
5296                if Is_Class_Wide_Type (Typl) then
5297                   Typl := Root_Type (Typl);
5298                end if;
5299
5300                Prim := First_Elmt (Primitive_Operations (Typl));
5301                while Present (Prim) loop
5302                   exit when Chars (Node (Prim)) = Name_Op_Eq
5303                     and then Etype (First_Formal (Node (Prim))) =
5304                              Etype (Next_Formal (First_Formal (Node (Prim))))
5305                     and then
5306                       Base_Type (Etype (Node (Prim))) = Standard_Boolean;
5307
5308                   Next_Elmt (Prim);
5309                end loop;
5310
5311                pragma Assert (Present (Prim));
5312                Op_Name := Node (Prim);
5313             end if;
5314
5315             Build_Equality_Call (Op_Name);
5316
5317          --  Ada 2005 (AI-216): Program_Error is raised when evaluating the
5318          --  predefined equality operator for a type which has a subcomponent
5319          --  of an Unchecked_Union type whose nominal subtype is unconstrained.
5320
5321          elsif Has_Unconstrained_UU_Component (Typl) then
5322             Insert_Action (N,
5323               Make_Raise_Program_Error (Loc,
5324                 Reason => PE_Unchecked_Union_Restriction));
5325
5326             --  Prevent Gigi from generating incorrect code by rewriting the
5327             --  equality as a standard False.
5328
5329             Rewrite (N,
5330               New_Occurrence_Of (Standard_False, Loc));
5331
5332          elsif Is_Unchecked_Union (Typl) then
5333
5334             --  If we can infer the discriminants of the operands, we make a
5335             --  call to the TSS equality function.
5336
5337             if Has_Inferable_Discriminants (Lhs)
5338                  and then
5339                Has_Inferable_Discriminants (Rhs)
5340             then
5341                Build_Equality_Call
5342                  (TSS (Root_Type (Typl), TSS_Composite_Equality));
5343
5344             else
5345                --  Ada 2005 (AI-216): Program_Error is raised when evaluating
5346                --  the predefined equality operator for an Unchecked_Union type
5347                --  if either of the operands lack inferable discriminants.
5348
5349                Insert_Action (N,
5350                  Make_Raise_Program_Error (Loc,
5351                    Reason => PE_Unchecked_Union_Restriction));
5352
5353                --  Prevent Gigi from generating incorrect code by rewriting
5354                --  the equality as a standard False.
5355
5356                Rewrite (N,
5357                  New_Occurrence_Of (Standard_False, Loc));
5358
5359             end if;
5360
5361          --  If a type support function is present (for complex cases), use it
5362
5363          elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
5364             Build_Equality_Call
5365               (TSS (Root_Type (Typl), TSS_Composite_Equality));
5366
5367          --  Otherwise expand the component by component equality. Note that
5368          --  we never use block-bit comparisons for records, because of the
5369          --  problems with gaps. The backend will often be able to recombine
5370          --  the separate comparisons that we generate here.
5371
5372          else
5373             Remove_Side_Effects (Lhs);
5374             Remove_Side_Effects (Rhs);
5375             Rewrite (N,
5376               Expand_Record_Equality (N, Typl, Lhs, Rhs, Bodies));
5377
5378             Insert_Actions      (N, Bodies,           Suppress => All_Checks);
5379             Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
5380          end if;
5381       end if;
5382
5383       --  Test if result is known at compile time
5384
5385       Rewrite_Comparison (N);
5386
5387       --  If we still have comparison for Vax_Float, process it
5388
5389       if Vax_Float (Typl) and then Nkind (N) in N_Op_Compare  then
5390          Expand_Vax_Comparison (N);
5391          return;
5392       end if;
5393    end Expand_N_Op_Eq;
5394
5395    -----------------------
5396    -- Expand_N_Op_Expon --
5397    -----------------------
5398
5399    procedure Expand_N_Op_Expon (N : Node_Id) is
5400       Loc    : constant Source_Ptr := Sloc (N);
5401       Typ    : constant Entity_Id  := Etype (N);
5402       Rtyp   : constant Entity_Id  := Root_Type (Typ);
5403       Base   : constant Node_Id    := Relocate_Node (Left_Opnd (N));
5404       Bastyp : constant Node_Id    := Etype (Base);
5405       Exp    : constant Node_Id    := Relocate_Node (Right_Opnd (N));
5406       Exptyp : constant Entity_Id  := Etype (Exp);
5407       Ovflo  : constant Boolean    := Do_Overflow_Check (N);
5408       Expv   : Uint;
5409       Xnode  : Node_Id;
5410       Temp   : Node_Id;
5411       Rent   : RE_Id;
5412       Ent    : Entity_Id;
5413       Etyp   : Entity_Id;
5414
5415    begin
5416       Binary_Op_Validity_Checks (N);
5417
5418       --  If either operand is of a private type, then we have the use of an
5419       --  intrinsic operator, and we get rid of the privateness, by using root
5420       --  types of underlying types for the actual operation. Otherwise the
5421       --  private types will cause trouble if we expand multiplications or
5422       --  shifts etc. We also do this transformation if the result type is
5423       --  different from the base type.
5424
5425       if Is_Private_Type (Etype (Base))
5426            or else
5427          Is_Private_Type (Typ)
5428            or else
5429          Is_Private_Type (Exptyp)
5430            or else
5431          Rtyp /= Root_Type (Bastyp)
5432       then
5433          declare
5434             Bt : constant Entity_Id := Root_Type (Underlying_Type (Bastyp));
5435             Et : constant Entity_Id := Root_Type (Underlying_Type (Exptyp));
5436
5437          begin
5438             Rewrite (N,
5439               Unchecked_Convert_To (Typ,
5440                 Make_Op_Expon (Loc,
5441                   Left_Opnd  => Unchecked_Convert_To (Bt, Base),
5442                   Right_Opnd => Unchecked_Convert_To (Et, Exp))));
5443             Analyze_And_Resolve (N, Typ);
5444             return;
5445          end;
5446       end if;
5447
5448       --  Test for case of known right argument
5449
5450       if Compile_Time_Known_Value (Exp) then
5451          Expv := Expr_Value (Exp);
5452
5453          --  We only fold small non-negative exponents. You might think we
5454          --  could fold small negative exponents for the real case, but we
5455          --  can't because we are required to raise Constraint_Error for
5456          --  the case of 0.0 ** (negative) even if Machine_Overflows = False.
5457          --  See ACVC test C4A012B.
5458
5459          if Expv >= 0 and then Expv <= 4 then
5460
5461             --  X ** 0 = 1 (or 1.0)
5462
5463             if Expv = 0 then
5464
5465                --  Call Remove_Side_Effects to ensure that any side effects
5466                --  in the ignored left operand (in particular function calls
5467                --  to user defined functions) are properly executed.
5468
5469                Remove_Side_Effects (Base);
5470
5471                if Ekind (Typ) in Integer_Kind then
5472                   Xnode := Make_Integer_Literal (Loc, Intval => 1);
5473                else
5474                   Xnode := Make_Real_Literal (Loc, Ureal_1);
5475                end if;
5476
5477             --  X ** 1 = X
5478
5479             elsif Expv = 1 then
5480                Xnode := Base;
5481
5482             --  X ** 2 = X * X
5483
5484             elsif Expv = 2 then
5485                Xnode :=
5486                  Make_Op_Multiply (Loc,
5487                    Left_Opnd  => Duplicate_Subexpr (Base),
5488                    Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
5489
5490             --  X ** 3 = X * X * X
5491
5492             elsif Expv = 3 then
5493                Xnode :=
5494                  Make_Op_Multiply (Loc,
5495                    Left_Opnd =>
5496                      Make_Op_Multiply (Loc,
5497                        Left_Opnd  => Duplicate_Subexpr (Base),
5498                        Right_Opnd => Duplicate_Subexpr_No_Checks (Base)),
5499                    Right_Opnd  => Duplicate_Subexpr_No_Checks (Base));
5500
5501             --  X ** 4  ->
5502             --    En : constant base'type := base * base;
5503             --    ...
5504             --    En * En
5505
5506             else -- Expv = 4
5507                Temp :=
5508                  Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
5509
5510                Insert_Actions (N, New_List (
5511                  Make_Object_Declaration (Loc,
5512                    Defining_Identifier => Temp,
5513                    Constant_Present    => True,
5514                    Object_Definition   => New_Reference_To (Typ, Loc),
5515                    Expression =>
5516                      Make_Op_Multiply (Loc,
5517                        Left_Opnd  => Duplicate_Subexpr (Base),
5518                        Right_Opnd => Duplicate_Subexpr_No_Checks (Base)))));
5519
5520                Xnode :=
5521                  Make_Op_Multiply (Loc,
5522                    Left_Opnd  => New_Reference_To (Temp, Loc),
5523                    Right_Opnd => New_Reference_To (Temp, Loc));
5524             end if;
5525
5526             Rewrite (N, Xnode);
5527             Analyze_And_Resolve (N, Typ);
5528             return;
5529          end if;
5530       end if;
5531
5532       --  Case of (2 ** expression) appearing as an argument of an integer
5533       --  multiplication, or as the right argument of a division of a non-
5534       --  negative integer. In such cases we leave the node untouched, setting
5535       --  the flag Is_Natural_Power_Of_2_for_Shift set, then the expansion
5536       --  of the higher level node converts it into a shift.
5537
5538       --  Note: this transformation is not applicable for a modular type with
5539       --  a non-binary modulus in the multiplication case, since we get a wrong
5540       --  result if the shift causes an overflow before the modular reduction.
5541
5542       if Nkind (Base) = N_Integer_Literal
5543         and then Intval (Base) = 2
5544         and then Is_Integer_Type (Root_Type (Exptyp))
5545         and then Esize (Root_Type (Exptyp)) <= Esize (Standard_Integer)
5546         and then Is_Unsigned_Type (Exptyp)
5547         and then not Ovflo
5548         and then Nkind (Parent (N)) in N_Binary_Op
5549       then
5550          declare
5551             P : constant Node_Id := Parent (N);
5552             L : constant Node_Id := Left_Opnd (P);
5553             R : constant Node_Id := Right_Opnd (P);
5554
5555          begin
5556             if (Nkind (P) = N_Op_Multiply
5557                  and then not Non_Binary_Modulus (Typ)
5558                  and then
5559                    ((Is_Integer_Type (Etype (L)) and then R = N)
5560                        or else
5561                     (Is_Integer_Type (Etype (R)) and then L = N))
5562                  and then not Do_Overflow_Check (P))
5563
5564               or else
5565                 (Nkind (P) = N_Op_Divide
5566                   and then Is_Integer_Type (Etype (L))
5567                   and then Is_Unsigned_Type (Etype (L))
5568                   and then R = N
5569                   and then not Do_Overflow_Check (P))
5570             then
5571                Set_Is_Power_Of_2_For_Shift (N);
5572                return;
5573             end if;
5574          end;
5575       end if;
5576
5577       --  Fall through if exponentiation must be done using a runtime routine
5578
5579       --  First deal with modular case
5580
5581       if Is_Modular_Integer_Type (Rtyp) then
5582
5583          --  Non-binary case, we call the special exponentiation routine for
5584          --  the non-binary case, converting the argument to Long_Long_Integer
5585          --  and passing the modulus value. Then the result is converted back
5586          --  to the base type.
5587
5588          if Non_Binary_Modulus (Rtyp) then
5589             Rewrite (N,
5590               Convert_To (Typ,
5591                 Make_Function_Call (Loc,
5592                   Name => New_Reference_To (RTE (RE_Exp_Modular), Loc),
5593                   Parameter_Associations => New_List (
5594                     Convert_To (Standard_Integer, Base),
5595                     Make_Integer_Literal (Loc, Modulus (Rtyp)),
5596                     Exp))));
5597
5598          --  Binary case, in this case, we call one of two routines, either the
5599          --  unsigned integer case, or the unsigned long long integer case,
5600          --  with a final "and" operation to do the required mod.
5601
5602          else
5603             if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
5604                Ent := RTE (RE_Exp_Unsigned);
5605             else
5606                Ent := RTE (RE_Exp_Long_Long_Unsigned);
5607             end if;
5608
5609             Rewrite (N,
5610               Convert_To (Typ,
5611                 Make_Op_And (Loc,
5612                   Left_Opnd =>
5613                     Make_Function_Call (Loc,
5614                       Name => New_Reference_To (Ent, Loc),
5615                       Parameter_Associations => New_List (
5616                         Convert_To (Etype (First_Formal (Ent)), Base),
5617                         Exp)),
5618                    Right_Opnd =>
5619                      Make_Integer_Literal (Loc, Modulus (Rtyp) - 1))));
5620
5621          end if;
5622
5623          --  Common exit point for modular type case
5624
5625          Analyze_And_Resolve (N, Typ);
5626          return;
5627
5628       --  Signed integer cases, done using either Integer or Long_Long_Integer.
5629       --  It is not worth having routines for Short_[Short_]Integer, since for
5630       --  most machines it would not help, and it would generate more code that
5631       --  might need certification when a certified run time is required.
5632
5633       --  In the integer cases, we have two routines, one for when overflow
5634       --  checks are required, and one when they are not required, since there
5635       --  is a real gain in omitting checks on many machines.
5636
5637       elsif Rtyp = Base_Type (Standard_Long_Long_Integer)
5638         or else (Rtyp = Base_Type (Standard_Long_Integer)
5639                    and then
5640                      Esize (Standard_Long_Integer) > Esize (Standard_Integer))
5641         or else (Rtyp = Universal_Integer)
5642       then
5643          Etyp := Standard_Long_Long_Integer;
5644
5645          if Ovflo then
5646             Rent := RE_Exp_Long_Long_Integer;
5647          else
5648             Rent := RE_Exn_Long_Long_Integer;
5649          end if;
5650
5651       elsif Is_Signed_Integer_Type (Rtyp) then
5652          Etyp := Standard_Integer;
5653
5654          if Ovflo then
5655             Rent := RE_Exp_Integer;
5656          else
5657             Rent := RE_Exn_Integer;
5658          end if;
5659
5660       --  Floating-point cases, always done using Long_Long_Float. We do not
5661       --  need separate routines for the overflow case here, since in the case
5662       --  of floating-point, we generate infinities anyway as a rule (either
5663       --  that or we automatically trap overflow), and if there is an infinity
5664       --  generated and a range check is required, the check will fail anyway.
5665
5666       else
5667          pragma Assert (Is_Floating_Point_Type (Rtyp));
5668          Etyp := Standard_Long_Long_Float;
5669          Rent := RE_Exn_Long_Long_Float;
5670       end if;
5671
5672       --  Common processing for integer cases and floating-point cases.
5673       --  If we are in the right type, we can call runtime routine directly
5674
5675       if Typ = Etyp
5676         and then Rtyp /= Universal_Integer
5677         and then Rtyp /= Universal_Real
5678       then
5679          Rewrite (N,
5680            Make_Function_Call (Loc,
5681              Name => New_Reference_To (RTE (Rent), Loc),
5682              Parameter_Associations => New_List (Base, Exp)));
5683
5684       --  Otherwise we have to introduce conversions (conversions are also
5685       --  required in the universal cases, since the runtime routine is
5686       --  typed using one of the standard types.
5687
5688       else
5689          Rewrite (N,
5690            Convert_To (Typ,
5691              Make_Function_Call (Loc,
5692                Name => New_Reference_To (RTE (Rent), Loc),
5693                Parameter_Associations => New_List (
5694                  Convert_To (Etyp, Base),
5695                  Exp))));
5696       end if;
5697
5698       Analyze_And_Resolve (N, Typ);
5699       return;
5700
5701    exception
5702       when RE_Not_Available =>
5703          return;
5704    end Expand_N_Op_Expon;
5705
5706    --------------------
5707    -- Expand_N_Op_Ge --
5708    --------------------
5709
5710    procedure Expand_N_Op_Ge (N : Node_Id) is
5711       Typ  : constant Entity_Id := Etype (N);
5712       Op1  : constant Node_Id   := Left_Opnd (N);
5713       Op2  : constant Node_Id   := Right_Opnd (N);
5714       Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5715
5716    begin
5717       Binary_Op_Validity_Checks (N);
5718
5719       if Is_Array_Type (Typ1) then
5720          Expand_Array_Comparison (N);
5721          return;
5722       end if;
5723
5724       if Is_Boolean_Type (Typ1) then
5725          Adjust_Condition (Op1);
5726          Adjust_Condition (Op2);
5727          Set_Etype (N, Standard_Boolean);
5728          Adjust_Result_Type (N, Typ);
5729       end if;
5730
5731       Rewrite_Comparison (N);
5732
5733       --  If we still have comparison, and Vax_Float type, process it
5734
5735       if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5736          Expand_Vax_Comparison (N);
5737          return;
5738       end if;
5739    end Expand_N_Op_Ge;
5740
5741    --------------------
5742    -- Expand_N_Op_Gt --
5743    --------------------
5744
5745    procedure Expand_N_Op_Gt (N : Node_Id) is
5746       Typ  : constant Entity_Id := Etype (N);
5747       Op1  : constant Node_Id   := Left_Opnd (N);
5748       Op2  : constant Node_Id   := Right_Opnd (N);
5749       Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5750
5751    begin
5752       Binary_Op_Validity_Checks (N);
5753
5754       if Is_Array_Type (Typ1) then
5755          Expand_Array_Comparison (N);
5756          return;
5757       end if;
5758
5759       if Is_Boolean_Type (Typ1) then
5760          Adjust_Condition (Op1);
5761          Adjust_Condition (Op2);
5762          Set_Etype (N, Standard_Boolean);
5763          Adjust_Result_Type (N, Typ);
5764       end if;
5765
5766       Rewrite_Comparison (N);
5767
5768       --  If we still have comparison, and Vax_Float type, process it
5769
5770       if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5771          Expand_Vax_Comparison (N);
5772          return;
5773       end if;
5774    end Expand_N_Op_Gt;
5775
5776    --------------------
5777    -- Expand_N_Op_Le --
5778    --------------------
5779
5780    procedure Expand_N_Op_Le (N : Node_Id) is
5781       Typ  : constant Entity_Id := Etype (N);
5782       Op1  : constant Node_Id   := Left_Opnd (N);
5783       Op2  : constant Node_Id   := Right_Opnd (N);
5784       Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5785
5786    begin
5787       Binary_Op_Validity_Checks (N);
5788
5789       if Is_Array_Type (Typ1) then
5790          Expand_Array_Comparison (N);
5791          return;
5792       end if;
5793
5794       if Is_Boolean_Type (Typ1) then
5795          Adjust_Condition (Op1);
5796          Adjust_Condition (Op2);
5797          Set_Etype (N, Standard_Boolean);
5798          Adjust_Result_Type (N, Typ);
5799       end if;
5800
5801       Rewrite_Comparison (N);
5802
5803       --  If we still have comparison, and Vax_Float type, process it
5804
5805       if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5806          Expand_Vax_Comparison (N);
5807          return;
5808       end if;
5809    end Expand_N_Op_Le;
5810
5811    --------------------
5812    -- Expand_N_Op_Lt --
5813    --------------------
5814
5815    procedure Expand_N_Op_Lt (N : Node_Id) is
5816       Typ  : constant Entity_Id := Etype (N);
5817       Op1  : constant Node_Id   := Left_Opnd (N);
5818       Op2  : constant Node_Id   := Right_Opnd (N);
5819       Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5820
5821    begin
5822       Binary_Op_Validity_Checks (N);
5823
5824       if Is_Array_Type (Typ1) then
5825          Expand_Array_Comparison (N);
5826          return;
5827       end if;
5828
5829       if Is_Boolean_Type (Typ1) then
5830          Adjust_Condition (Op1);
5831          Adjust_Condition (Op2);
5832          Set_Etype (N, Standard_Boolean);
5833          Adjust_Result_Type (N, Typ);
5834       end if;
5835
5836       Rewrite_Comparison (N);
5837
5838       --  If we still have comparison, and Vax_Float type, process it
5839
5840       if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5841          Expand_Vax_Comparison (N);
5842          return;
5843       end if;
5844    end Expand_N_Op_Lt;
5845
5846    -----------------------
5847    -- Expand_N_Op_Minus --
5848    -----------------------
5849
5850    procedure Expand_N_Op_Minus (N : Node_Id) is
5851       Loc : constant Source_Ptr := Sloc (N);
5852       Typ : constant Entity_Id  := Etype (N);
5853
5854    begin
5855       Unary_Op_Validity_Checks (N);
5856
5857       if not Backend_Overflow_Checks_On_Target
5858          and then Is_Signed_Integer_Type (Etype (N))
5859          and then Do_Overflow_Check (N)
5860       then
5861          --  Software overflow checking expands -expr into (0 - expr)
5862
5863          Rewrite (N,
5864            Make_Op_Subtract (Loc,
5865              Left_Opnd  => Make_Integer_Literal (Loc, 0),
5866              Right_Opnd => Right_Opnd (N)));
5867
5868          Analyze_And_Resolve (N, Typ);
5869
5870       --  Vax floating-point types case
5871
5872       elsif Vax_Float (Etype (N)) then
5873          Expand_Vax_Arith (N);
5874       end if;
5875    end Expand_N_Op_Minus;
5876
5877    ---------------------
5878    -- Expand_N_Op_Mod --
5879    ---------------------
5880
5881    procedure Expand_N_Op_Mod (N : Node_Id) is
5882       Loc   : constant Source_Ptr := Sloc (N);
5883       Typ   : constant Entity_Id  := Etype (N);
5884       Left  : constant Node_Id    := Left_Opnd (N);
5885       Right : constant Node_Id    := Right_Opnd (N);
5886       DOC   : constant Boolean    := Do_Overflow_Check (N);
5887       DDC   : constant Boolean    := Do_Division_Check (N);
5888
5889       LLB : Uint;
5890       Llo : Uint;
5891       Lhi : Uint;
5892       LOK : Boolean;
5893       Rlo : Uint;
5894       Rhi : Uint;
5895       ROK : Boolean;
5896
5897       pragma Warnings (Off, Lhi);
5898
5899    begin
5900       Binary_Op_Validity_Checks (N);
5901
5902       Determine_Range (Right, ROK, Rlo, Rhi);
5903       Determine_Range (Left,  LOK, Llo, Lhi);
5904
5905       --  Convert mod to rem if operands are known non-negative. We do this
5906       --  since it is quite likely that this will improve the quality of code,
5907       --  (the operation now corresponds to the hardware remainder), and it
5908       --  does not seem likely that it could be harmful.
5909
5910       if LOK and then Llo >= 0
5911            and then
5912          ROK and then Rlo >= 0
5913       then
5914          Rewrite (N,
5915            Make_Op_Rem (Sloc (N),
5916              Left_Opnd  => Left_Opnd (N),
5917              Right_Opnd => Right_Opnd (N)));
5918
5919          --  Instead of reanalyzing the node we do the analysis manually. This
5920          --  avoids anomalies when the replacement is done in an instance and
5921          --  is epsilon more efficient.
5922
5923          Set_Entity            (N, Standard_Entity (S_Op_Rem));
5924          Set_Etype             (N, Typ);
5925          Set_Do_Overflow_Check (N, DOC);
5926          Set_Do_Division_Check (N, DDC);
5927          Expand_N_Op_Rem (N);
5928          Set_Analyzed (N);
5929
5930       --  Otherwise, normal mod processing
5931
5932       else
5933          if Is_Integer_Type (Etype (N)) then
5934             Apply_Divide_Check (N);
5935          end if;
5936
5937          --  Apply optimization x mod 1 = 0. We don't really need that with
5938          --  gcc, but it is useful with other back ends (e.g. AAMP), and is
5939          --  certainly harmless.
5940
5941          if Is_Integer_Type (Etype (N))
5942            and then Compile_Time_Known_Value (Right)
5943            and then Expr_Value (Right) = Uint_1
5944          then
5945             --  Call Remove_Side_Effects to ensure that any side effects in
5946             --  the ignored left operand (in particular function calls to
5947             --  user defined functions) are properly executed.
5948
5949             Remove_Side_Effects (Left);
5950
5951             Rewrite (N, Make_Integer_Literal (Loc, 0));
5952             Analyze_And_Resolve (N, Typ);
5953             return;
5954          end if;
5955
5956          --  Deal with annoying case of largest negative number remainder
5957          --  minus one. Gigi does not handle this case correctly, because
5958          --  it generates a divide instruction which may trap in this case.
5959
5960          --  In fact the check is quite easy, if the right operand is -1, then
5961          --  the mod value is always 0, and we can just ignore the left operand
5962          --  completely in this case.
5963
5964          --  The operand type may be private (e.g. in the expansion of an
5965          --  intrinsic operation) so we must use the underlying type to get the
5966          --  bounds, and convert the literals explicitly.
5967
5968          LLB :=
5969            Expr_Value
5970              (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
5971
5972          if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
5973            and then
5974             ((not LOK) or else (Llo = LLB))
5975          then
5976             Rewrite (N,
5977               Make_Conditional_Expression (Loc,
5978                 Expressions => New_List (
5979                   Make_Op_Eq (Loc,
5980                     Left_Opnd => Duplicate_Subexpr (Right),
5981                     Right_Opnd =>
5982                       Unchecked_Convert_To (Typ,
5983                         Make_Integer_Literal (Loc, -1))),
5984                   Unchecked_Convert_To (Typ,
5985                     Make_Integer_Literal (Loc, Uint_0)),
5986                   Relocate_Node (N))));
5987
5988             Set_Analyzed (Next (Next (First (Expressions (N)))));
5989             Analyze_And_Resolve (N, Typ);
5990          end if;
5991       end if;
5992    end Expand_N_Op_Mod;
5993
5994    --------------------------
5995    -- Expand_N_Op_Multiply --
5996    --------------------------
5997
5998    procedure Expand_N_Op_Multiply (N : Node_Id) is
5999       Loc : constant Source_Ptr := Sloc (N);
6000       Lop : constant Node_Id    := Left_Opnd (N);
6001       Rop : constant Node_Id    := Right_Opnd (N);
6002
6003       Lp2 : constant Boolean :=
6004               Nkind (Lop) = N_Op_Expon
6005                 and then Is_Power_Of_2_For_Shift (Lop);
6006
6007       Rp2 : constant Boolean :=
6008               Nkind (Rop) = N_Op_Expon
6009                 and then Is_Power_Of_2_For_Shift (Rop);
6010
6011       Ltyp : constant Entity_Id  := Etype (Lop);
6012       Rtyp : constant Entity_Id  := Etype (Rop);
6013       Typ  : Entity_Id           := Etype (N);
6014
6015    begin
6016       Binary_Op_Validity_Checks (N);
6017
6018       --  Special optimizations for integer types
6019
6020       if Is_Integer_Type (Typ) then
6021
6022          --  N * 0 = 0 for integer types
6023
6024          if Compile_Time_Known_Value (Rop)
6025            and then Expr_Value (Rop) = Uint_0
6026          then
6027             --  Call Remove_Side_Effects to ensure that any side effects in
6028             --  the ignored left operand (in particular function calls to
6029             --  user defined functions) are properly executed.
6030
6031             Remove_Side_Effects (Lop);
6032
6033             Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
6034             Analyze_And_Resolve (N, Typ);
6035             return;
6036          end if;
6037
6038          --  Similar handling for 0 * N = 0
6039
6040          if Compile_Time_Known_Value (Lop)
6041            and then Expr_Value (Lop) = Uint_0
6042          then
6043             Remove_Side_Effects (Rop);
6044             Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
6045             Analyze_And_Resolve (N, Typ);
6046             return;
6047          end if;
6048
6049          --  N * 1 = 1 * N = N for integer types
6050
6051          --  This optimisation is not done if we are going to
6052          --  rewrite the product 1 * 2 ** N to a shift.
6053
6054          if Compile_Time_Known_Value (Rop)
6055            and then Expr_Value (Rop) = Uint_1
6056            and then not Lp2
6057          then
6058             Rewrite (N, Lop);
6059             return;
6060
6061          elsif Compile_Time_Known_Value (Lop)
6062            and then Expr_Value (Lop) = Uint_1
6063            and then not Rp2
6064          then
6065             Rewrite (N, Rop);
6066             return;
6067          end if;
6068       end if;
6069
6070       --  Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
6071       --  Is_Power_Of_2_For_Shift is set means that we know that our left
6072       --  operand is an integer, as required for this to work.
6073
6074       if Rp2 then
6075          if Lp2 then
6076
6077             --  Convert 2 ** A * 2 ** B into  2 ** (A + B)
6078
6079             Rewrite (N,
6080               Make_Op_Expon (Loc,
6081                 Left_Opnd => Make_Integer_Literal (Loc, 2),
6082                 Right_Opnd =>
6083                   Make_Op_Add (Loc,
6084                     Left_Opnd  => Right_Opnd (Lop),
6085                     Right_Opnd => Right_Opnd (Rop))));
6086             Analyze_And_Resolve (N, Typ);
6087             return;
6088
6089          else
6090             Rewrite (N,
6091               Make_Op_Shift_Left (Loc,
6092                 Left_Opnd  => Lop,
6093                 Right_Opnd =>
6094                   Convert_To (Standard_Natural, Right_Opnd (Rop))));
6095             Analyze_And_Resolve (N, Typ);
6096             return;
6097          end if;
6098
6099       --  Same processing for the operands the other way round
6100
6101       elsif Lp2 then
6102          Rewrite (N,
6103            Make_Op_Shift_Left (Loc,
6104              Left_Opnd  => Rop,
6105              Right_Opnd =>
6106                Convert_To (Standard_Natural, Right_Opnd (Lop))));
6107          Analyze_And_Resolve (N, Typ);
6108          return;
6109       end if;
6110
6111       --  Do required fixup of universal fixed operation
6112
6113       if Typ = Universal_Fixed then
6114          Fixup_Universal_Fixed_Operation (N);
6115          Typ := Etype (N);
6116       end if;
6117
6118       --  Multiplications with fixed-point results
6119
6120       if Is_Fixed_Point_Type (Typ) then
6121
6122          --  No special processing if Treat_Fixed_As_Integer is set, since from
6123          --  a semantic point of view such operations are simply integer
6124          --  operations and will be treated that way.
6125
6126          if not Treat_Fixed_As_Integer (N) then
6127
6128             --  Case of fixed * integer => fixed
6129
6130             if Is_Integer_Type (Rtyp) then
6131                Expand_Multiply_Fixed_By_Integer_Giving_Fixed (N);
6132
6133             --  Case of integer * fixed => fixed
6134
6135             elsif Is_Integer_Type (Ltyp) then
6136                Expand_Multiply_Integer_By_Fixed_Giving_Fixed (N);
6137
6138             --  Case of fixed * fixed => fixed
6139
6140             else
6141                Expand_Multiply_Fixed_By_Fixed_Giving_Fixed (N);
6142             end if;
6143          end if;
6144
6145       --  Other cases of multiplication of fixed-point operands. Again we
6146       --  exclude the cases where Treat_Fixed_As_Integer flag is set.
6147
6148       elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
6149         and then not Treat_Fixed_As_Integer (N)
6150       then
6151          if Is_Integer_Type (Typ) then
6152             Expand_Multiply_Fixed_By_Fixed_Giving_Integer (N);
6153          else
6154             pragma Assert (Is_Floating_Point_Type (Typ));
6155             Expand_Multiply_Fixed_By_Fixed_Giving_Float (N);
6156          end if;
6157
6158       --  Mixed-mode operations can appear in a non-static universal context,
6159       --  in which case the integer argument must be converted explicitly.
6160
6161       elsif Typ = Universal_Real
6162         and then Is_Integer_Type (Rtyp)
6163       then
6164          Rewrite (Rop, Convert_To (Universal_Real, Relocate_Node (Rop)));
6165
6166          Analyze_And_Resolve (Rop, Universal_Real);
6167
6168       elsif Typ = Universal_Real
6169         and then Is_Integer_Type (Ltyp)
6170       then
6171          Rewrite (Lop, Convert_To (Universal_Real, Relocate_Node (Lop)));
6172
6173          Analyze_And_Resolve (Lop, Universal_Real);
6174
6175       --  Non-fixed point cases, check software overflow checking required
6176
6177       elsif Is_Signed_Integer_Type (Etype (N)) then
6178          Apply_Arithmetic_Overflow_Check (N);
6179
6180       --  Deal with VAX float case
6181
6182       elsif Vax_Float (Typ) then
6183          Expand_Vax_Arith (N);
6184          return;
6185       end if;
6186    end Expand_N_Op_Multiply;
6187
6188    --------------------
6189    -- Expand_N_Op_Ne --
6190    --------------------
6191
6192    procedure Expand_N_Op_Ne (N : Node_Id) is
6193       Typ : constant Entity_Id := Etype (Left_Opnd (N));
6194
6195    begin
6196       --  Case of elementary type with standard operator
6197
6198       if Is_Elementary_Type (Typ)
6199         and then Sloc (Entity (N)) = Standard_Location
6200       then
6201          Binary_Op_Validity_Checks (N);
6202
6203          --  Boolean types (requiring handling of non-standard case)
6204
6205          if Is_Boolean_Type (Typ) then
6206             Adjust_Condition (Left_Opnd (N));
6207             Adjust_Condition (Right_Opnd (N));
6208             Set_Etype (N, Standard_Boolean);
6209             Adjust_Result_Type (N, Typ);
6210          end if;
6211
6212          Rewrite_Comparison (N);
6213
6214          --  If we still have comparison for Vax_Float, process it
6215
6216          if Vax_Float (Typ) and then Nkind (N) in N_Op_Compare  then
6217             Expand_Vax_Comparison (N);
6218             return;
6219          end if;
6220
6221       --  For all cases other than elementary types, we rewrite node as the
6222       --  negation of an equality operation, and reanalyze. The equality to be
6223       --  used is defined in the same scope and has the same signature. This
6224       --  signature must be set explicitly since in an instance it may not have
6225       --  the same visibility as in the generic unit. This avoids duplicating
6226       --  or factoring the complex code for record/array equality tests etc.
6227
6228       else
6229          declare
6230             Loc : constant Source_Ptr := Sloc (N);
6231             Neg : Node_Id;
6232             Ne  : constant Entity_Id := Entity (N);
6233
6234          begin
6235             Binary_Op_Validity_Checks (N);
6236
6237             Neg :=
6238               Make_Op_Not (Loc,
6239                 Right_Opnd =>
6240                   Make_Op_Eq (Loc,
6241                     Left_Opnd =>  Left_Opnd (N),
6242                     Right_Opnd => Right_Opnd (N)));
6243             Set_Paren_Count (Right_Opnd (Neg), 1);
6244
6245             if Scope (Ne) /= Standard_Standard then
6246                Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
6247             end if;
6248
6249             --  For navigation purposes, the inequality is treated as an
6250             --  implicit reference to the corresponding equality. Preserve the
6251             --  Comes_From_ source flag so that the proper Xref entry is
6252             --  generated.
6253
6254             Preserve_Comes_From_Source (Neg, N);
6255             Preserve_Comes_From_Source (Right_Opnd (Neg), N);
6256             Rewrite (N, Neg);
6257             Analyze_And_Resolve (N, Standard_Boolean);
6258          end;
6259       end if;
6260    end Expand_N_Op_Ne;
6261
6262    ---------------------
6263    -- Expand_N_Op_Not --
6264    ---------------------
6265
6266    --  If the argument is other than a Boolean array type, there is no special
6267    --  expansion required.
6268
6269    --  For the packed case, we call the special routine in Exp_Pakd, except
6270    --  that if the component size is greater than one, we use the standard
6271    --  routine generating a gruesome loop (it is so peculiar to have packed
6272    --  arrays with non-standard Boolean representations anyway, so it does not
6273    --  matter that we do not handle this case efficiently).
6274
6275    --  For the unpacked case (and for the special packed case where we have non
6276    --  standard Booleans, as discussed above), we generate and insert into the
6277    --  tree the following function definition:
6278
6279    --     function Nnnn (A : arr) is
6280    --       B : arr;
6281    --     begin
6282    --       for J in a'range loop
6283    --          B (J) := not A (J);
6284    --       end loop;
6285    --       return B;
6286    --     end Nnnn;
6287
6288    --  Here arr is the actual subtype of the parameter (and hence always
6289    --  constrained). Then we replace the not with a call to this function.
6290
6291    procedure Expand_N_Op_Not (N : Node_Id) is
6292       Loc  : constant Source_Ptr := Sloc (N);
6293       Typ  : constant Entity_Id  := Etype (N);
6294       Opnd : Node_Id;
6295       Arr  : Entity_Id;
6296       A    : Entity_Id;
6297       B    : Entity_Id;
6298       J    : Entity_Id;
6299       A_J  : Node_Id;
6300       B_J  : Node_Id;
6301
6302       Func_Name      : Entity_Id;
6303       Loop_Statement : Node_Id;
6304
6305    begin
6306       Unary_Op_Validity_Checks (N);
6307
6308       --  For boolean operand, deal with non-standard booleans
6309
6310       if Is_Boolean_Type (Typ) then
6311          Adjust_Condition (Right_Opnd (N));
6312          Set_Etype (N, Standard_Boolean);
6313          Adjust_Result_Type (N, Typ);
6314          return;
6315       end if;
6316
6317       --  Only array types need any other processing
6318
6319       if not Is_Array_Type (Typ) then
6320          return;
6321       end if;
6322
6323       --  Case of array operand. If bit packed with a component size of 1,
6324       --  handle it in Exp_Pakd if the operand is known to be aligned.
6325
6326       if Is_Bit_Packed_Array (Typ)
6327         and then Component_Size (Typ) = 1
6328         and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
6329       then
6330          Expand_Packed_Not (N);
6331          return;
6332       end if;
6333
6334       --  Case of array operand which is not bit-packed. If the context is
6335       --  a safe assignment, call in-place operation, If context is a larger
6336       --  boolean expression in the context of a safe assignment, expansion is
6337       --  done by enclosing operation.
6338
6339       Opnd := Relocate_Node (Right_Opnd (N));
6340       Convert_To_Actual_Subtype (Opnd);
6341       Arr := Etype (Opnd);
6342       Ensure_Defined (Arr, N);
6343       Silly_Boolean_Array_Not_Test (N, Arr);
6344
6345       if Nkind (Parent (N)) = N_Assignment_Statement then
6346          if Safe_In_Place_Array_Op (Name (Parent (N)), N, Empty) then
6347             Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
6348             return;
6349
6350          --  Special case the negation of a binary operation
6351
6352          elsif Nkind_In (Opnd, N_Op_And, N_Op_Or, N_Op_Xor)
6353            and then Safe_In_Place_Array_Op
6354                       (Name (Parent (N)), Left_Opnd (Opnd), Right_Opnd (Opnd))
6355          then
6356             Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
6357             return;
6358          end if;
6359
6360       elsif Nkind (Parent (N)) in N_Binary_Op
6361         and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
6362       then
6363          declare
6364             Op1 : constant Node_Id := Left_Opnd  (Parent (N));
6365             Op2 : constant Node_Id := Right_Opnd (Parent (N));
6366             Lhs : constant Node_Id := Name (Parent (Parent (N)));
6367
6368          begin
6369             if Safe_In_Place_Array_Op (Lhs, Op1, Op2) then
6370                if N = Op1
6371                  and then Nkind (Op2) = N_Op_Not
6372                then
6373                   --  (not A) op (not B) can be reduced to a single call
6374
6375                   return;
6376
6377                elsif N = Op2
6378                  and then Nkind (Parent (N)) = N_Op_Xor
6379                then
6380                   --  A xor (not B) can also be special-cased
6381
6382                   return;
6383                end if;
6384             end if;
6385          end;
6386       end if;
6387
6388       A := Make_Defining_Identifier (Loc, Name_uA);
6389       B := Make_Defining_Identifier (Loc, Name_uB);
6390       J := Make_Defining_Identifier (Loc, Name_uJ);
6391
6392       A_J :=
6393         Make_Indexed_Component (Loc,
6394           Prefix      => New_Reference_To (A, Loc),
6395           Expressions => New_List (New_Reference_To (J, Loc)));
6396
6397       B_J :=
6398         Make_Indexed_Component (Loc,
6399           Prefix      => New_Reference_To (B, Loc),
6400           Expressions => New_List (New_Reference_To (J, Loc)));
6401
6402       Loop_Statement :=
6403         Make_Implicit_Loop_Statement (N,
6404           Identifier => Empty,
6405
6406           Iteration_Scheme =>
6407             Make_Iteration_Scheme (Loc,
6408               Loop_Parameter_Specification =>
6409                 Make_Loop_Parameter_Specification (Loc,
6410                   Defining_Identifier => J,
6411                   Discrete_Subtype_Definition =>
6412                     Make_Attribute_Reference (Loc,
6413                       Prefix => Make_Identifier (Loc, Chars (A)),
6414                       Attribute_Name => Name_Range))),
6415
6416           Statements => New_List (
6417             Make_Assignment_Statement (Loc,
6418               Name       => B_J,
6419               Expression => Make_Op_Not (Loc, A_J))));
6420
6421       Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
6422       Set_Is_Inlined (Func_Name);
6423
6424       Insert_Action (N,
6425         Make_Subprogram_Body (Loc,
6426           Specification =>
6427             Make_Function_Specification (Loc,
6428               Defining_Unit_Name => Func_Name,
6429               Parameter_Specifications => New_List (
6430                 Make_Parameter_Specification (Loc,
6431                   Defining_Identifier => A,
6432                   Parameter_Type      => New_Reference_To (Typ, Loc))),
6433               Result_Definition => New_Reference_To (Typ, Loc)),
6434
6435           Declarations => New_List (
6436             Make_Object_Declaration (Loc,
6437               Defining_Identifier => B,
6438               Object_Definition   => New_Reference_To (Arr, Loc))),
6439
6440           Handled_Statement_Sequence =>
6441             Make_Handled_Sequence_Of_Statements (Loc,
6442               Statements => New_List (
6443                 Loop_Statement,
6444                 Make_Simple_Return_Statement (Loc,
6445                   Expression =>
6446                     Make_Identifier (Loc, Chars (B)))))));
6447
6448       Rewrite (N,
6449         Make_Function_Call (Loc,
6450           Name => New_Reference_To (Func_Name, Loc),
6451           Parameter_Associations => New_List (Opnd)));
6452
6453       Analyze_And_Resolve (N, Typ);
6454    end Expand_N_Op_Not;
6455
6456    --------------------
6457    -- Expand_N_Op_Or --
6458    --------------------
6459
6460    procedure Expand_N_Op_Or (N : Node_Id) is
6461       Typ : constant Entity_Id := Etype (N);
6462
6463    begin
6464       Binary_Op_Validity_Checks (N);
6465
6466       if Is_Array_Type (Etype (N)) then
6467          Expand_Boolean_Operator (N);
6468
6469       elsif Is_Boolean_Type (Etype (N)) then
6470          Adjust_Condition (Left_Opnd (N));
6471          Adjust_Condition (Right_Opnd (N));
6472          Set_Etype (N, Standard_Boolean);
6473          Adjust_Result_Type (N, Typ);
6474       end if;
6475    end Expand_N_Op_Or;
6476
6477    ----------------------
6478    -- Expand_N_Op_Plus --
6479    ----------------------
6480
6481    procedure Expand_N_Op_Plus (N : Node_Id) is
6482    begin
6483       Unary_Op_Validity_Checks (N);
6484    end Expand_N_Op_Plus;
6485
6486    ---------------------
6487    -- Expand_N_Op_Rem --
6488    ---------------------
6489
6490    procedure Expand_N_Op_Rem (N : Node_Id) is
6491       Loc : constant Source_Ptr := Sloc (N);
6492       Typ : constant Entity_Id  := Etype (N);
6493
6494       Left  : constant Node_Id := Left_Opnd (N);
6495       Right : constant Node_Id := Right_Opnd (N);
6496
6497       LLB : Uint;
6498       Llo : Uint;
6499       Lhi : Uint;
6500       LOK : Boolean;
6501       Rlo : Uint;
6502       Rhi : Uint;
6503       ROK : Boolean;
6504
6505       pragma Warnings (Off, Lhi);
6506
6507    begin
6508       Binary_Op_Validity_Checks (N);
6509
6510       if Is_Integer_Type (Etype (N)) then
6511          Apply_Divide_Check (N);
6512       end if;
6513
6514       --  Apply optimization x rem 1 = 0. We don't really need that with gcc,
6515       --  but it is useful with other back ends (e.g. AAMP), and is certainly
6516       --  harmless.
6517
6518       if Is_Integer_Type (Etype (N))
6519         and then Compile_Time_Known_Value (Right)
6520         and then Expr_Value (Right) = Uint_1
6521       then
6522          --  Call Remove_Side_Effects to ensure that any side effects in the
6523          --  ignored left operand (in particular function calls to user defined
6524          --  functions) are properly executed.
6525
6526          Remove_Side_Effects (Left);
6527
6528          Rewrite (N, Make_Integer_Literal (Loc, 0));
6529          Analyze_And_Resolve (N, Typ);
6530          return;
6531       end if;
6532
6533       --  Deal with annoying case of largest negative number remainder minus
6534       --  one. Gigi does not handle this case correctly, because it generates
6535       --  a divide instruction which may trap in this case.
6536
6537       --  In fact the check is quite easy, if the right operand is -1, then
6538       --  the remainder is always 0, and we can just ignore the left operand
6539       --  completely in this case.
6540
6541       Determine_Range (Right, ROK, Rlo, Rhi);
6542       Determine_Range (Left, LOK, Llo, Lhi);
6543
6544       --  The operand type may be private (e.g. in the expansion of an
6545       --  intrinsic operation) so we must use the underlying type to get the
6546       --  bounds, and convert the literals explicitly.
6547
6548       LLB :=
6549         Expr_Value
6550           (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
6551
6552       --  Now perform the test, generating code only if needed
6553
6554       if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
6555         and then
6556          ((not LOK) or else (Llo = LLB))
6557       then
6558          Rewrite (N,
6559            Make_Conditional_Expression (Loc,
6560              Expressions => New_List (
6561                Make_Op_Eq (Loc,
6562                  Left_Opnd => Duplicate_Subexpr (Right),
6563                  Right_Opnd =>
6564                    Unchecked_Convert_To (Typ,
6565                      Make_Integer_Literal (Loc, -1))),
6566
6567                Unchecked_Convert_To (Typ,
6568                  Make_Integer_Literal (Loc, Uint_0)),
6569
6570                Relocate_Node (N))));
6571
6572          Set_Analyzed (Next (Next (First (Expressions (N)))));
6573          Analyze_And_Resolve (N, Typ);
6574       end if;
6575    end Expand_N_Op_Rem;
6576
6577    -----------------------------
6578    -- Expand_N_Op_Rotate_Left --
6579    -----------------------------
6580
6581    procedure Expand_N_Op_Rotate_Left (N : Node_Id) is
6582    begin
6583       Binary_Op_Validity_Checks (N);
6584    end Expand_N_Op_Rotate_Left;
6585
6586    ------------------------------
6587    -- Expand_N_Op_Rotate_Right --
6588    ------------------------------
6589
6590    procedure Expand_N_Op_Rotate_Right (N : Node_Id) is
6591    begin
6592       Binary_Op_Validity_Checks (N);
6593    end Expand_N_Op_Rotate_Right;
6594
6595    ----------------------------
6596    -- Expand_N_Op_Shift_Left --
6597    ----------------------------
6598
6599    procedure Expand_N_Op_Shift_Left (N : Node_Id) is
6600    begin
6601       Binary_Op_Validity_Checks (N);
6602    end Expand_N_Op_Shift_Left;
6603
6604    -----------------------------
6605    -- Expand_N_Op_Shift_Right --
6606    -----------------------------
6607
6608    procedure Expand_N_Op_Shift_Right (N : Node_Id) is
6609    begin
6610       Binary_Op_Validity_Checks (N);
6611    end Expand_N_Op_Shift_Right;
6612
6613    ----------------------------------------
6614    -- Expand_N_Op_Shift_Right_Arithmetic --
6615    ----------------------------------------
6616
6617    procedure Expand_N_Op_Shift_Right_Arithmetic (N : Node_Id) is
6618    begin
6619       Binary_Op_Validity_Checks (N);
6620    end Expand_N_Op_Shift_Right_Arithmetic;
6621
6622    --------------------------
6623    -- Expand_N_Op_Subtract --
6624    --------------------------
6625
6626    procedure Expand_N_Op_Subtract (N : Node_Id) is
6627       Typ : constant Entity_Id := Etype (N);
6628
6629    begin
6630       Binary_Op_Validity_Checks (N);
6631
6632       --  N - 0 = N for integer types
6633
6634       if Is_Integer_Type (Typ)
6635         and then Compile_Time_Known_Value (Right_Opnd (N))
6636         and then Expr_Value (Right_Opnd (N)) = 0
6637       then
6638          Rewrite (N, Left_Opnd (N));
6639          return;
6640       end if;
6641
6642       --  Arithmetic overflow checks for signed integer/fixed point types
6643
6644       if Is_Signed_Integer_Type (Typ)
6645         or else Is_Fixed_Point_Type (Typ)
6646       then
6647          Apply_Arithmetic_Overflow_Check (N);
6648
6649       --  Vax floating-point types case
6650
6651       elsif Vax_Float (Typ) then
6652          Expand_Vax_Arith (N);
6653       end if;
6654    end Expand_N_Op_Subtract;
6655
6656    ---------------------
6657    -- Expand_N_Op_Xor --
6658    ---------------------
6659
6660    procedure Expand_N_Op_Xor (N : Node_Id) is
6661       Typ : constant Entity_Id := Etype (N);
6662
6663    begin
6664       Binary_Op_Validity_Checks (N);
6665
6666       if Is_Array_Type (Etype (N)) then
6667          Expand_Boolean_Operator (N);
6668
6669       elsif Is_Boolean_Type (Etype (N)) then
6670          Adjust_Condition (Left_Opnd (N));
6671          Adjust_Condition (Right_Opnd (N));
6672          Set_Etype (N, Standard_Boolean);
6673          Adjust_Result_Type (N, Typ);
6674       end if;
6675    end Expand_N_Op_Xor;
6676
6677    ----------------------
6678    -- Expand_N_Or_Else --
6679    ----------------------
6680
6681    --  Expand into conditional expression if Actions present, and also
6682    --  deal with optimizing case of arguments being True or False.
6683
6684    procedure Expand_N_Or_Else (N : Node_Id) is
6685       Loc     : constant Source_Ptr := Sloc (N);
6686       Typ     : constant Entity_Id  := Etype (N);
6687       Left    : constant Node_Id    := Left_Opnd (N);
6688       Right   : constant Node_Id    := Right_Opnd (N);
6689       Actlist : List_Id;
6690
6691    begin
6692       --  Deal with non-standard booleans
6693
6694       if Is_Boolean_Type (Typ) then
6695          Adjust_Condition (Left);
6696          Adjust_Condition (Right);
6697          Set_Etype (N, Standard_Boolean);
6698       end if;
6699
6700       --  Check for cases where left argument is known to be True or False
6701
6702       if Compile_Time_Known_Value (Left) then
6703
6704          --  If left argument is False, change (False or else Right) to Right.
6705          --  Any actions associated with Right will be executed unconditionally
6706          --  and can thus be inserted into the tree unconditionally.
6707
6708          if Expr_Value_E (Left) = Standard_False then
6709             if Present (Actions (N)) then
6710                Insert_Actions (N, Actions (N));
6711             end if;
6712
6713             Rewrite (N, Right);
6714
6715          --  If left argument is True, change (True and then Right) to True. In
6716          --  this case we can forget the actions associated with Right, since
6717          --  they will never be executed.
6718
6719          else pragma Assert (Expr_Value_E (Left) = Standard_True);
6720             Kill_Dead_Code (Right);
6721             Kill_Dead_Code (Actions (N));
6722             Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
6723          end if;
6724
6725          Adjust_Result_Type (N, Typ);
6726          return;
6727       end if;
6728
6729       --  If Actions are present, we expand
6730
6731       --     left or else right
6732
6733       --  into
6734
6735       --     if left then True else right end
6736
6737       --  with the actions becoming the Else_Actions of the conditional
6738       --  expression. This conditional expression is then further expanded
6739       --  (and will eventually disappear)
6740
6741       if Present (Actions (N)) then
6742          Actlist := Actions (N);
6743          Rewrite (N,
6744             Make_Conditional_Expression (Loc,
6745               Expressions => New_List (
6746                 Left,
6747                 New_Occurrence_Of (Standard_True, Loc),
6748                 Right)));
6749
6750          Set_Else_Actions (N, Actlist);
6751          Analyze_And_Resolve (N, Standard_Boolean);
6752          Adjust_Result_Type (N, Typ);
6753          return;
6754       end if;
6755
6756       --  No actions present, check for cases of right argument True/False
6757
6758       if Compile_Time_Known_Value (Right) then
6759
6760          --  Change (Left or else False) to Left. Note that we know there are
6761          --  no actions associated with the True operand, since we just checked
6762          --  for this case above.
6763
6764          if Expr_Value_E (Right) = Standard_False then
6765             Rewrite (N, Left);
6766
6767          --  Change (Left or else True) to True, making sure to preserve any
6768          --  side effects associated with the Left operand.
6769
6770          else pragma Assert (Expr_Value_E (Right) = Standard_True);
6771             Remove_Side_Effects (Left);
6772             Rewrite
6773               (N, New_Occurrence_Of (Standard_True, Loc));
6774          end if;
6775       end if;
6776
6777       Adjust_Result_Type (N, Typ);
6778    end Expand_N_Or_Else;
6779
6780    -----------------------------------
6781    -- Expand_N_Qualified_Expression --
6782    -----------------------------------
6783
6784    procedure Expand_N_Qualified_Expression (N : Node_Id) is
6785       Operand     : constant Node_Id   := Expression (N);
6786       Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));
6787
6788    begin
6789       --  Do validity check if validity checking operands
6790
6791       if Validity_Checks_On
6792         and then Validity_Check_Operands
6793       then
6794          Ensure_Valid (Operand);
6795       end if;
6796
6797       --  Apply possible constraint check
6798
6799       Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);
6800    end Expand_N_Qualified_Expression;
6801
6802    ---------------------------------
6803    -- Expand_N_Selected_Component --
6804    ---------------------------------
6805
6806    --  If the selector is a discriminant of a concurrent object, rewrite the
6807    --  prefix to denote the corresponding record type.
6808
6809    procedure Expand_N_Selected_Component (N : Node_Id) is
6810       Loc   : constant Source_Ptr := Sloc (N);
6811       Par   : constant Node_Id    := Parent (N);
6812       P     : constant Node_Id    := Prefix (N);
6813       Ptyp  : Entity_Id           := Underlying_Type (Etype (P));
6814       Disc  : Entity_Id;
6815       New_N : Node_Id;
6816       Dcon  : Elmt_Id;
6817
6818       function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
6819       --  Gigi needs a temporary for prefixes that depend on a discriminant,
6820       --  unless the context of an assignment can provide size information.
6821       --  Don't we have a general routine that does this???
6822
6823       -----------------------
6824       -- In_Left_Hand_Side --
6825       -----------------------
6826
6827       function In_Left_Hand_Side (Comp : Node_Id) return Boolean is
6828       begin
6829          return (Nkind (Parent (Comp)) = N_Assignment_Statement
6830                    and then Comp = Name (Parent (Comp)))
6831            or else (Present (Parent (Comp))
6832                       and then Nkind (Parent (Comp)) in N_Subexpr
6833                       and then In_Left_Hand_Side (Parent (Comp)));
6834       end In_Left_Hand_Side;
6835
6836    --  Start of processing for Expand_N_Selected_Component
6837
6838    begin
6839       --  Insert explicit dereference if required
6840
6841       if Is_Access_Type (Ptyp) then
6842          Insert_Explicit_Dereference (P);
6843          Analyze_And_Resolve (P, Designated_Type (Ptyp));
6844
6845          if Ekind (Etype (P)) = E_Private_Subtype
6846            and then Is_For_Access_Subtype (Etype (P))
6847          then
6848             Set_Etype (P, Base_Type (Etype (P)));
6849          end if;
6850
6851          Ptyp := Etype (P);
6852       end if;
6853
6854       --  Deal with discriminant check required
6855
6856       if Do_Discriminant_Check (N) then
6857
6858          --  Present the discriminant checking function to the backend, so that
6859          --  it can inline the call to the function.
6860
6861          Add_Inlined_Body
6862            (Discriminant_Checking_Func
6863              (Original_Record_Component (Entity (Selector_Name (N)))));
6864
6865          --  Now reset the flag and generate the call
6866
6867          Set_Do_Discriminant_Check (N, False);
6868          Generate_Discriminant_Check (N);
6869       end if;
6870
6871       --  Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
6872       --  function, then additional actuals must be passed.
6873
6874       if Ada_Version >= Ada_05
6875         and then Is_Build_In_Place_Function_Call (P)
6876       then
6877          Make_Build_In_Place_Call_In_Anonymous_Context (P);
6878       end if;
6879
6880       --  Gigi cannot handle unchecked conversions that are the prefix of a
6881       --  selected component with discriminants. This must be checked during
6882       --  expansion, because during analysis the type of the selector is not
6883       --  known at the point the prefix is analyzed. If the conversion is the
6884       --  target of an assignment, then we cannot force the evaluation.
6885
6886       if Nkind (Prefix (N)) = N_Unchecked_Type_Conversion
6887         and then Has_Discriminants (Etype (N))
6888         and then not In_Left_Hand_Side (N)
6889       then
6890          Force_Evaluation (Prefix (N));
6891       end if;
6892
6893       --  Remaining processing applies only if selector is a discriminant
6894
6895       if Ekind (Entity (Selector_Name (N))) = E_Discriminant then
6896
6897          --  If the selector is a discriminant of a constrained record type,
6898          --  we may be able to rewrite the expression with the actual value
6899          --  of the discriminant, a useful optimization in some cases.
6900
6901          if Is_Record_Type (Ptyp)
6902            and then Has_Discriminants (Ptyp)
6903            and then Is_Constrained (Ptyp)
6904          then
6905             --  Do this optimization for discrete types only, and not for
6906             --  access types (access discriminants get us into trouble!)
6907
6908             if not Is_Discrete_Type (Etype (N)) then
6909                null;
6910
6911             --  Don't do this on the left hand of an assignment statement.
6912             --  Normally one would think that references like this would
6913             --  not occur, but they do in generated code, and mean that
6914             --  we really do want to assign the discriminant!
6915
6916             elsif Nkind (Par) = N_Assignment_Statement
6917               and then Name (Par) = N
6918             then
6919                null;
6920
6921             --  Don't do this optimization for the prefix of an attribute or
6922             --  the operand of an object renaming declaration since these are
6923             --  contexts where we do not want the value anyway.
6924
6925             elsif (Nkind (Par) = N_Attribute_Reference
6926                      and then Prefix (Par) = N)
6927               or else Is_Renamed_Object (N)
6928             then
6929                null;
6930
6931             --  Don't do this optimization if we are within the code for a
6932             --  discriminant check, since the whole point of such a check may
6933             --  be to verify the condition on which the code below depends!
6934
6935             elsif Is_In_Discriminant_Check (N) then
6936                null;
6937
6938             --  Green light to see if we can do the optimization. There is
6939             --  still one condition that inhibits the optimization below but
6940             --  now is the time to check the particular discriminant.
6941
6942             else
6943                --  Loop through discriminants to find the matching discriminant
6944                --  constraint to see if we can copy it.
6945
6946                Disc := First_Discriminant (Ptyp);
6947                Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
6948                Discr_Loop : while Present (Dcon) loop
6949
6950                   --  Check if this is the matching discriminant
6951
6952                   if Disc = Entity (Selector_Name (N)) then
6953
6954                      --  Here we have the matching discriminant. Check for
6955                      --  the case of a discriminant of a component that is
6956                      --  constrained by an outer discriminant, which cannot
6957                      --  be optimized away.
6958
6959                      if
6960                        Denotes_Discriminant
6961                         (Node (Dcon), Check_Concurrent => True)
6962                      then
6963                         exit Discr_Loop;
6964
6965                      --  In the context of a case statement, the expression may
6966                      --  have the base type of the discriminant, and we need to
6967                      --  preserve the constraint to avoid spurious errors on
6968                      --  missing cases.
6969
6970                      elsif Nkind (Parent (N)) = N_Case_Statement
6971                        and then Etype (Node (Dcon)) /= Etype (Disc)
6972                      then
6973                         Rewrite (N,
6974                           Make_Qualified_Expression (Loc,
6975                             Subtype_Mark =>
6976                               New_Occurrence_Of (Etype (Disc), Loc),
6977                             Expression   =>
6978                               New_Copy_Tree (Node (Dcon))));
6979                         Analyze_And_Resolve (N, Etype (Disc));
6980
6981                         --  In case that comes out as a static expression,
6982                         --  reset it (a selected component is never static).
6983
6984                         Set_Is_Static_Expression (N, False);
6985                         return;
6986
6987                      --  Otherwise we can just copy the constraint, but the
6988                      --  result is certainly not static! In some cases the
6989                      --  discriminant constraint has been analyzed in the
6990                      --  context of the original subtype indication, but for
6991                      --  itypes the constraint might not have been analyzed
6992                      --  yet, and this must be done now.
6993
6994                      else
6995                         Rewrite (N, New_Copy_Tree (Node (Dcon)));
6996                         Analyze_And_Resolve (N);
6997                         Set_Is_Static_Expression (N, False);
6998                         return;
6999                      end if;
7000                   end if;
7001
7002                   Next_Elmt (Dcon);
7003                   Next_Discriminant (Disc);
7004                end loop Discr_Loop;
7005
7006                --  Note: the above loop should always find a matching
7007                --  discriminant, but if it does not, we just missed an
7008                --  optimization due to some glitch (perhaps a previous error),
7009                --  so ignore.
7010
7011             end if;
7012          end if;
7013
7014          --  The only remaining processing is in the case of a discriminant of
7015          --  a concurrent object, where we rewrite the prefix to denote the
7016          --  corresponding record type. If the type is derived and has renamed
7017          --  discriminants, use corresponding discriminant, which is the one
7018          --  that appears in the corresponding record.
7019
7020          if not Is_Concurrent_Type (Ptyp) then
7021             return;
7022          end if;
7023
7024          Disc := Entity (Selector_Name (N));
7025
7026          if Is_Derived_Type (Ptyp)
7027            and then Present (Corresponding_Discriminant (Disc))
7028          then
7029             Disc := Corresponding_Discriminant (Disc);
7030          end if;
7031
7032          New_N :=
7033            Make_Selected_Component (Loc,
7034              Prefix =>
7035                Unchecked_Convert_To (Corresponding_Record_Type (Ptyp),
7036                  New_Copy_Tree (P)),
7037              Selector_Name => Make_Identifier (Loc, Chars (Disc)));
7038
7039          Rewrite (N, New_N);
7040          Analyze (N);
7041       end if;
7042    end Expand_N_Selected_Component;
7043
7044    --------------------
7045    -- Expand_N_Slice --
7046    --------------------
7047
7048    procedure Expand_N_Slice (N : Node_Id) is
7049       Loc  : constant Source_Ptr := Sloc (N);
7050       Typ  : constant Entity_Id  := Etype (N);
7051       Pfx  : constant Node_Id    := Prefix (N);
7052       Ptp  : Entity_Id           := Etype (Pfx);
7053
7054       function Is_Procedure_Actual (N : Node_Id) return Boolean;
7055       --  Check whether the argument is an actual for a procedure call, in
7056       --  which case the expansion of a bit-packed slice is deferred until the
7057       --  call itself is expanded. The reason this is required is that we might
7058       --  have an IN OUT or OUT parameter, and the copy out is essential, and
7059       --  that copy out would be missed if we created a temporary here in
7060       --  Expand_N_Slice. Note that we don't bother to test specifically for an
7061       --  IN OUT or OUT mode parameter, since it is a bit tricky to do, and it
7062       --  is harmless to defer expansion in the IN case, since the call
7063       --  processing will still generate the appropriate copy in operation,
7064       --  which will take care of the slice.
7065
7066       procedure Make_Temporary;
7067       --  Create a named variable for the value of the slice, in cases where
7068       --  the back-end cannot handle it properly, e.g. when packed types or
7069       --  unaligned slices are involved.
7070
7071       -------------------------
7072       -- Is_Procedure_Actual --
7073       -------------------------
7074
7075       function Is_Procedure_Actual (N : Node_Id) return Boolean is
7076          Par : Node_Id := Parent (N);
7077
7078       begin
7079          loop
7080             --  If our parent is a procedure call we can return
7081
7082             if Nkind (Par) = N_Procedure_Call_Statement then
7083                return True;
7084
7085             --  If our parent is a type conversion, keep climbing the tree,
7086             --  since a type conversion can be a procedure actual. Also keep
7087             --  climbing if parameter association or a qualified expression,
7088             --  since these are additional cases that do can appear on
7089             --  procedure actuals.
7090
7091             elsif Nkind_In (Par, N_Type_Conversion,
7092                                  N_Parameter_Association,
7093                                  N_Qualified_Expression)
7094             then
7095                Par := Parent (Par);
7096
7097                --  Any other case is not what we are looking for
7098
7099             else
7100                return False;
7101             end if;
7102          end loop;
7103       end Is_Procedure_Actual;
7104
7105       --------------------
7106       -- Make_Temporary --
7107       --------------------
7108
7109       procedure Make_Temporary is
7110          Decl : Node_Id;
7111          Ent  : constant Entity_Id :=
7112                   Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
7113       begin
7114          Decl :=
7115            Make_Object_Declaration (Loc,
7116              Defining_Identifier => Ent,
7117              Object_Definition   => New_Occurrence_Of (Typ, Loc));
7118
7119          Set_No_Initialization (Decl);
7120
7121          Insert_Actions (N, New_List (
7122            Decl,
7123            Make_Assignment_Statement (Loc,
7124              Name => New_Occurrence_Of (Ent, Loc),
7125              Expression => Relocate_Node (N))));
7126
7127          Rewrite (N, New_Occurrence_Of (Ent, Loc));
7128          Analyze_And_Resolve (N, Typ);
7129       end Make_Temporary;
7130
7131    --  Start of processing for Expand_N_Slice
7132
7133    begin
7134       --  Special handling for access types
7135
7136       if Is_Access_Type (Ptp) then
7137
7138          Ptp := Designated_Type (Ptp);
7139
7140          Rewrite (Pfx,
7141            Make_Explicit_Dereference (Sloc (N),
7142             Prefix => Relocate_Node (Pfx)));
7143
7144          Analyze_And_Resolve (Pfx, Ptp);
7145       end if;
7146
7147       --  Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
7148       --  function, then additional actuals must be passed.
7149
7150       if Ada_Version >= Ada_05
7151         and then Is_Build_In_Place_Function_Call (Pfx)
7152       then
7153          Make_Build_In_Place_Call_In_Anonymous_Context (Pfx);
7154       end if;
7155
7156       --  Range checks are potentially also needed for cases involving a slice
7157       --  indexed by a subtype indication, but Do_Range_Check can currently
7158       --  only be set for expressions ???
7159
7160       if not Index_Checks_Suppressed (Ptp)
7161         and then (not Is_Entity_Name (Pfx)
7162                    or else not Index_Checks_Suppressed (Entity (Pfx)))
7163         and then Nkind (Discrete_Range (N)) /= N_Subtype_Indication
7164
7165          --  Do not enable range check to nodes associated with the frontend
7166          --  expansion of the dispatch table. We first check if Ada.Tags is
7167          --  already loaded to avoid the addition of an undesired dependence
7168          --  on such run-time unit.
7169
7170         and then
7171           (VM_Target /= No_VM
7172             or else not
7173              (RTU_Loaded (Ada_Tags)
7174                and then Nkind (Prefix (N)) = N_Selected_Component
7175                and then Present (Entity (Selector_Name (Prefix (N))))
7176                and then Entity (Selector_Name (Prefix (N))) =
7177                                   RTE_Record_Component (RE_Prims_Ptr)))
7178       then
7179          Enable_Range_Check (Discrete_Range (N));
7180       end if;
7181
7182       --  The remaining case to be handled is packed slices. We can leave
7183       --  packed slices as they are in the following situations:
7184
7185       --    1. Right or left side of an assignment (we can handle this
7186       --       situation correctly in the assignment statement expansion).
7187
7188       --    2. Prefix of indexed component (the slide is optimized away in this
7189       --       case, see the start of Expand_N_Slice.)
7190
7191       --    3. Object renaming declaration, since we want the name of the
7192       --       slice, not the value.
7193
7194       --    4. Argument to procedure call, since copy-in/copy-out handling may
7195       --       be required, and this is handled in the expansion of call
7196       --       itself.
7197
7198       --    5. Prefix of an address attribute (this is an error which is caught
7199       --       elsewhere, and the expansion would interfere with generating the
7200       --       error message).
7201
7202       if not Is_Packed (Typ) then
7203
7204          --  Apply transformation for actuals of a function call, where
7205          --  Expand_Actuals is not used.
7206
7207          if Nkind (Parent (N)) = N_Function_Call
7208            and then Is_Possibly_Unaligned_Slice (N)
7209          then
7210             Make_Temporary;
7211          end if;
7212
7213       elsif Nkind (Parent (N)) = N_Assignment_Statement
7214         or else (Nkind (Parent (Parent (N))) = N_Assignment_Statement
7215                    and then Parent (N) = Name (Parent (Parent (N))))
7216       then
7217          return;
7218
7219       elsif Nkind (Parent (N)) = N_Indexed_Component
7220         or else Is_Renamed_Object (N)
7221         or else Is_Procedure_Actual (N)
7222       then
7223          return;
7224
7225       elsif Nkind (Parent (N)) = N_Attribute_Reference
7226         and then Attribute_Name (Parent (N)) = Name_Address
7227       then
7228          return;
7229
7230       else
7231          Make_Temporary;
7232       end if;
7233    end Expand_N_Slice;
7234
7235    ------------------------------
7236    -- Expand_N_Type_Conversion --
7237    ------------------------------
7238
7239    procedure Expand_N_Type_Conversion (N : Node_Id) is
7240       Loc          : constant Source_Ptr := Sloc (N);
7241       Operand      : constant Node_Id    := Expression (N);
7242       Target_Type  : constant Entity_Id  := Etype (N);
7243       Operand_Type : Entity_Id           := Etype (Operand);
7244
7245       procedure Handle_Changed_Representation;
7246       --  This is called in the case of record and array type conversions to
7247       --  see if there is a change of representation to be handled. Change of
7248       --  representation is actually handled at the assignment statement level,
7249       --  and what this procedure does is rewrite node N conversion as an
7250       --  assignment to temporary. If there is no change of representation,
7251       --  then the conversion node is unchanged.
7252
7253       procedure Real_Range_Check;
7254       --  Handles generation of range check for real target value
7255
7256       -----------------------------------
7257       -- Handle_Changed_Representation --
7258       -----------------------------------
7259
7260       procedure Handle_Changed_Representation is
7261          Temp : Entity_Id;
7262          Decl : Node_Id;
7263          Odef : Node_Id;
7264          Disc : Node_Id;
7265          N_Ix : Node_Id;
7266          Cons : List_Id;
7267
7268       begin
7269          --  Nothing else to do if no change of representation
7270
7271          if Same_Representation (Operand_Type, Target_Type) then
7272             return;
7273
7274          --  The real change of representation work is done by the assignment
7275          --  statement processing. So if this type conversion is appearing as
7276          --  the expression of an assignment statement, nothing needs to be
7277          --  done to the conversion.
7278
7279          elsif Nkind (Parent (N)) = N_Assignment_Statement then
7280             return;
7281
7282          --  Otherwise we need to generate a temporary variable, and do the
7283          --  change of representation assignment into that temporary variable.
7284          --  The conversion is then replaced by a reference to this variable.
7285
7286          else
7287             Cons := No_List;
7288
7289             --  If type is unconstrained we have to add a constraint, copied
7290             --  from the actual value of the left hand side.
7291
7292             if not Is_Constrained (Target_Type) then
7293                if Has_Discriminants (Operand_Type) then
7294                   Disc := First_Discriminant (Operand_Type);
7295
7296                   if Disc /= First_Stored_Discriminant (Operand_Type) then
7297                      Disc := First_Stored_Discriminant (Operand_Type);
7298                   end if;
7299
7300                   Cons := New_List;
7301                   while Present (Disc) loop
7302                      Append_To (Cons,
7303                        Make_Selected_Component (Loc,
7304                          Prefix => Duplicate_Subexpr_Move_Checks (Operand),
7305                          Selector_Name =>
7306                            Make_Identifier (Loc, Chars (Disc))));
7307                      Next_Discriminant (Disc);
7308                   end loop;
7309
7310                elsif Is_Array_Type (Operand_Type) then
7311                   N_Ix := First_Index (Target_Type);
7312                   Cons := New_List;
7313
7314                   for J in 1 .. Number_Dimensions (Operand_Type) loop
7315
7316                      --  We convert the bounds explicitly. We use an unchecked
7317                      --  conversion because bounds checks are done elsewhere.
7318
7319                      Append_To (Cons,
7320                        Make_Range (Loc,
7321                          Low_Bound =>
7322                            Unchecked_Convert_To (Etype (N_Ix),
7323                              Make_Attribute_Reference (Loc,
7324                                Prefix =>
7325                                  Duplicate_Subexpr_No_Checks
7326                                    (Operand, Name_Req => True),
7327                                Attribute_Name => Name_First,
7328                                Expressions    => New_List (
7329                                  Make_Integer_Literal (Loc, J)))),
7330
7331                          High_Bound =>
7332                            Unchecked_Convert_To (Etype (N_Ix),
7333                              Make_Attribute_Reference (Loc,
7334                                Prefix =>
7335                                  Duplicate_Subexpr_No_Checks
7336                                    (Operand, Name_Req => True),
7337                                Attribute_Name => Name_Last,
7338                                Expressions    => New_List (
7339                                  Make_Integer_Literal (Loc, J))))));
7340
7341                      Next_Index (N_Ix);
7342                   end loop;
7343                end if;
7344             end if;
7345
7346             Odef := New_Occurrence_Of (Target_Type, Loc);
7347
7348             if Present (Cons) then
7349                Odef :=
7350                  Make_Subtype_Indication (Loc,
7351                    Subtype_Mark => Odef,
7352                    Constraint =>
7353                      Make_Index_Or_Discriminant_Constraint (Loc,
7354                        Constraints => Cons));
7355             end if;
7356
7357             Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
7358             Decl :=
7359               Make_Object_Declaration (Loc,
7360                 Defining_Identifier => Temp,
7361                 Object_Definition   => Odef);
7362
7363             Set_No_Initialization (Decl, True);
7364
7365             --  Insert required actions. It is essential to suppress checks
7366             --  since we have suppressed default initialization, which means
7367             --  that the variable we create may have no discriminants.
7368
7369             Insert_Actions (N,
7370               New_List (
7371                 Decl,
7372                 Make_Assignment_Statement (Loc,
7373                   Name => New_Occurrence_Of (Temp, Loc),
7374                   Expression => Relocate_Node (N))),
7375                 Suppress => All_Checks);
7376
7377             Rewrite (N, New_Occurrence_Of (Temp, Loc));
7378             return;
7379          end if;
7380       end Handle_Changed_Representation;
7381
7382       ----------------------
7383       -- Real_Range_Check --
7384       ----------------------
7385
7386       --  Case of conversions to floating-point or fixed-point. If range checks
7387       --  are enabled and the target type has a range constraint, we convert:
7388
7389       --     typ (x)
7390
7391       --       to
7392
7393       --     Tnn : typ'Base := typ'Base (x);
7394       --     [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
7395       --     Tnn
7396
7397       --  This is necessary when there is a conversion of integer to float or
7398       --  to fixed-point to ensure that the correct checks are made. It is not
7399       --  necessary for float to float where it is enough to simply set the
7400       --  Do_Range_Check flag.
7401
7402       procedure Real_Range_Check is
7403          Btyp : constant Entity_Id := Base_Type (Target_Type);
7404          Lo   : constant Node_Id   := Type_Low_Bound  (Target_Type);
7405          Hi   : constant Node_Id   := Type_High_Bound (Target_Type);
7406          Xtyp : constant Entity_Id := Etype (Operand);
7407          Conv : Node_Id;
7408          Tnn  : Entity_Id;
7409
7410       begin
7411          --  Nothing to do if conversion was rewritten
7412
7413          if Nkind (N) /= N_Type_Conversion then
7414             return;
7415          end if;
7416
7417          --  Nothing to do if range checks suppressed, or target has the same
7418          --  range as the base type (or is the base type).
7419
7420          if Range_Checks_Suppressed (Target_Type)
7421            or else (Lo = Type_Low_Bound (Btyp)
7422                       and then
7423                     Hi = Type_High_Bound (Btyp))
7424          then
7425             return;
7426          end if;
7427
7428          --  Nothing to do if expression is an entity on which checks have been
7429          --  suppressed.
7430
7431          if Is_Entity_Name (Operand)
7432            and then Range_Checks_Suppressed (Entity (Operand))
7433          then
7434             return;
7435          end if;
7436
7437          --  Nothing to do if bounds are all static and we can tell that the
7438          --  expression is within the bounds of the target. Note that if the
7439          --  operand is of an unconstrained floating-point type, then we do
7440          --  not trust it to be in range (might be infinite)
7441
7442          declare
7443             S_Lo : constant Node_Id := Type_Low_Bound (Xtyp);
7444             S_Hi : constant Node_Id := Type_High_Bound (Xtyp);
7445
7446          begin
7447             if (not Is_Floating_Point_Type (Xtyp)
7448                  or else Is_Constrained (Xtyp))
7449               and then Compile_Time_Known_Value (S_Lo)
7450               and then Compile_Time_Known_Value (S_Hi)
7451               and then Compile_Time_Known_Value (Hi)
7452               and then Compile_Time_Known_Value (Lo)
7453             then
7454                declare
7455                   D_Lov : constant Ureal := Expr_Value_R (Lo);
7456                   D_Hiv : constant Ureal := Expr_Value_R (Hi);
7457                   S_Lov : Ureal;
7458                   S_Hiv : Ureal;
7459
7460                begin
7461                   if Is_Real_Type (Xtyp) then
7462                      S_Lov := Expr_Value_R (S_Lo);
7463                      S_Hiv := Expr_Value_R (S_Hi);
7464                   else
7465                      S_Lov := UR_From_Uint (Expr_Value (S_Lo));
7466                      S_Hiv := UR_From_Uint (Expr_Value (S_Hi));
7467                   end if;
7468
7469                   if D_Hiv > D_Lov
7470                     and then S_Lov >= D_Lov
7471                     and then S_Hiv <= D_Hiv
7472                   then
7473                      Set_Do_Range_Check (Operand, False);
7474                      return;
7475                   end if;
7476                end;
7477             end if;
7478          end;
7479
7480          --  For float to float conversions, we are done
7481
7482          if Is_Floating_Point_Type (Xtyp)
7483               and then
7484             Is_Floating_Point_Type (Btyp)
7485          then
7486             return;
7487          end if;
7488
7489          --  Otherwise rewrite the conversion as described above
7490
7491          Conv := Relocate_Node (N);
7492          Rewrite
7493            (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc));
7494          Set_Etype (Conv, Btyp);
7495
7496          --  Enable overflow except for case of integer to float conversions,
7497          --  where it is never required, since we can never have overflow in
7498          --  this case.
7499
7500          if not Is_Integer_Type (Etype (Operand)) then
7501             Enable_Overflow_Check (Conv);
7502          end if;
7503
7504          Tnn :=
7505            Make_Defining_Identifier (Loc,
7506              Chars => New_Internal_Name ('T'));
7507
7508          Insert_Actions (N, New_List (
7509            Make_Object_Declaration (Loc,
7510              Defining_Identifier => Tnn,
7511              Object_Definition   => New_Occurrence_Of (Btyp, Loc),
7512              Expression => Conv),
7513
7514            Make_Raise_Constraint_Error (Loc,
7515              Condition =>
7516               Make_Or_Else (Loc,
7517                 Left_Opnd =>
7518                   Make_Op_Lt (Loc,
7519                     Left_Opnd  => New_Occurrence_Of (Tnn, Loc),
7520                     Right_Opnd =>
7521                       Make_Attribute_Reference (Loc,
7522                         Attribute_Name => Name_First,
7523                         Prefix =>
7524                           New_Occurrence_Of (Target_Type, Loc))),
7525
7526                 Right_Opnd =>
7527                   Make_Op_Gt (Loc,
7528                     Left_Opnd  => New_Occurrence_Of (Tnn, Loc),
7529                     Right_Opnd =>
7530                       Make_Attribute_Reference (Loc,
7531                         Attribute_Name => Name_Last,
7532                         Prefix =>
7533                           New_Occurrence_Of (Target_Type, Loc)))),
7534              Reason => CE_Range_Check_Failed)));
7535
7536          Rewrite (N, New_Occurrence_Of (Tnn, Loc));
7537          Analyze_And_Resolve (N, Btyp);
7538       end Real_Range_Check;
7539
7540    --  Start of processing for Expand_N_Type_Conversion
7541
7542    begin
7543       --  Nothing at all to do if conversion is to the identical type so remove
7544       --  the conversion completely, it is useless.
7545
7546       if Operand_Type = Target_Type then
7547          Rewrite (N, Relocate_Node (Operand));
7548          return;
7549       end if;
7550
7551       --  Nothing to do if this is the second argument of read. This is a
7552       --  "backwards" conversion that will be handled by the specialized code
7553       --  in attribute processing.
7554
7555       if Nkind (Parent (N)) = N_Attribute_Reference
7556         and then Attribute_Name (Parent (N)) = Name_Read
7557         and then Next (First (Expressions (Parent (N)))) = N
7558       then
7559          return;
7560       end if;
7561
7562       --  Here if we may need to expand conversion
7563
7564       --  Do validity check if validity checking operands
7565
7566       if Validity_Checks_On
7567         and then Validity_Check_Operands
7568       then
7569          Ensure_Valid (Operand);
7570       end if;
7571
7572       --  Special case of converting from non-standard boolean type
7573
7574       if Is_Boolean_Type (Operand_Type)
7575         and then (Nonzero_Is_True (Operand_Type))
7576       then
7577          Adjust_Condition (Operand);
7578          Set_Etype (Operand, Standard_Boolean);
7579          Operand_Type := Standard_Boolean;
7580       end if;
7581
7582       --  Case of converting to an access type
7583
7584       if Is_Access_Type (Target_Type) then
7585
7586          --  Apply an accessibility check when the conversion operand is an
7587          --  access parameter (or a renaming thereof), unless conversion was
7588          --  expanded from an Unchecked_ or Unrestricted_Access attribute.
7589          --  Note that other checks may still need to be applied below (such
7590          --  as tagged type checks).
7591
7592          if Is_Entity_Name (Operand)
7593            and then
7594              (Is_Formal (Entity (Operand))
7595                or else
7596                  (Present (Renamed_Object (Entity (Operand)))
7597                    and then Is_Entity_Name (Renamed_Object (Entity (Operand)))
7598                    and then Is_Formal
7599                               (Entity (Renamed_Object (Entity (Operand))))))
7600            and then Ekind (Etype (Operand)) = E_Anonymous_Access_Type
7601            and then (Nkind (Original_Node (N)) /= N_Attribute_Reference
7602                       or else Attribute_Name (Original_Node (N)) = Name_Access)
7603          then
7604             Apply_Accessibility_Check
7605               (Operand, Target_Type, Insert_Node => Operand);
7606
7607          --  If the level of the operand type is statically deeper than the
7608          --  level of the target type, then force Program_Error. Note that this
7609          --  can only occur for cases where the attribute is within the body of
7610          --  an instantiation (otherwise the conversion will already have been
7611          --  rejected as illegal). Note: warnings are issued by the analyzer
7612          --  for the instance cases.
7613
7614          elsif In_Instance_Body
7615            and then Type_Access_Level (Operand_Type) >
7616                     Type_Access_Level (Target_Type)
7617          then
7618             Rewrite (N,
7619               Make_Raise_Program_Error (Sloc (N),
7620                 Reason => PE_Accessibility_Check_Failed));
7621             Set_Etype (N, Target_Type);
7622
7623          --  When the operand is a selected access discriminant the check needs
7624          --  to be made against the level of the object denoted by the prefix
7625          --  of the selected name. Force Program_Error for this case as well
7626          --  (this accessibility violation can only happen if within the body
7627          --  of an instantiation).
7628
7629          elsif In_Instance_Body
7630            and then Ekind (Operand_Type) = E_Anonymous_Access_Type
7631            and then Nkind (Operand) = N_Selected_Component
7632            and then Object_Access_Level (Operand) >
7633                       Type_Access_Level (Target_Type)
7634          then
7635             Rewrite (N,
7636               Make_Raise_Program_Error (Sloc (N),
7637                 Reason => PE_Accessibility_Check_Failed));
7638             Set_Etype (N, Target_Type);
7639          end if;
7640       end if;
7641
7642       --  Case of conversions of tagged types and access to tagged types
7643
7644       --  When needed, that is to say when the expression is class-wide, Add
7645       --  runtime a tag check for (strict) downward conversion by using the
7646       --  membership test, generating:
7647
7648       --      [constraint_error when Operand not in Target_Type'Class]
7649
7650       --  or in the access type case
7651
7652       --      [constraint_error
7653       --        when Operand /= null
7654       --          and then Operand.all not in
7655       --            Designated_Type (Target_Type)'Class]
7656
7657       if (Is_Access_Type (Target_Type)
7658            and then Is_Tagged_Type (Designated_Type (Target_Type)))
7659         or else Is_Tagged_Type (Target_Type)
7660       then
7661          --  Do not do any expansion in the access type case if the parent is a
7662          --  renaming, since this is an error situation which will be caught by
7663          --  Sem_Ch8, and the expansion can interfere with this error check.
7664
7665          if Is_Access_Type (Target_Type)
7666            and then Is_Renamed_Object (N)
7667          then
7668             return;
7669          end if;
7670
7671          --  Otherwise, proceed with processing tagged conversion
7672
7673          declare
7674             Actual_Op_Typ   : Entity_Id;
7675             Actual_Targ_Typ : Entity_Id;
7676             Make_Conversion : Boolean := False;
7677             Root_Op_Typ     : Entity_Id;
7678
7679             procedure Make_Tag_Check (Targ_Typ : Entity_Id);
7680             --  Create a membership check to test whether Operand is a member
7681             --  of Targ_Typ. If the original Target_Type is an access, include
7682             --  a test for null value. The check is inserted at N.
7683
7684             --------------------
7685             -- Make_Tag_Check --
7686             --------------------
7687
7688             procedure Make_Tag_Check (Targ_Typ : Entity_Id) is
7689                Cond : Node_Id;
7690
7691             begin
7692                --  Generate:
7693                --    [Constraint_Error
7694                --       when Operand /= null
7695                --         and then Operand.all not in Targ_Typ]
7696
7697                if Is_Access_Type (Target_Type) then
7698                   Cond :=
7699                     Make_And_Then (Loc,
7700                       Left_Opnd =>
7701                         Make_Op_Ne (Loc,
7702                           Left_Opnd  => Duplicate_Subexpr_No_Checks (Operand),
7703                           Right_Opnd => Make_Null (Loc)),
7704
7705                       Right_Opnd =>
7706                         Make_Not_In (Loc,
7707                           Left_Opnd  =>
7708                             Make_Explicit_Dereference (Loc,
7709                               Prefix => Duplicate_Subexpr_No_Checks (Operand)),
7710                           Right_Opnd => New_Reference_To (Targ_Typ, Loc)));
7711
7712                --  Generate:
7713                --    [Constraint_Error when Operand not in Targ_Typ]
7714
7715                else
7716                   Cond :=
7717                     Make_Not_In (Loc,
7718                       Left_Opnd  => Duplicate_Subexpr_No_Checks (Operand),
7719                       Right_Opnd => New_Reference_To (Targ_Typ, Loc));
7720                end if;
7721
7722                Insert_Action (N,
7723                  Make_Raise_Constraint_Error (Loc,
7724                    Condition => Cond,
7725                    Reason    => CE_Tag_Check_Failed));
7726             end Make_Tag_Check;
7727
7728          --  Start of processing
7729
7730          begin
7731             if Is_Access_Type (Target_Type) then
7732                Actual_Op_Typ   := Designated_Type (Operand_Type);
7733                Actual_Targ_Typ := Designated_Type (Target_Type);
7734
7735             else
7736                Actual_Op_Typ   := Operand_Type;
7737                Actual_Targ_Typ := Target_Type;
7738             end if;
7739
7740             Root_Op_Typ := Root_Type (Actual_Op_Typ);
7741
7742             --  Ada 2005 (AI-251): Handle interface type conversion
7743
7744             if Is_Interface (Actual_Op_Typ) then
7745                Expand_Interface_Conversion (N, Is_Static => False);
7746                return;
7747             end if;
7748
7749             if not Tag_Checks_Suppressed (Actual_Targ_Typ) then
7750
7751                --  Create a runtime tag check for a downward class-wide type
7752                --  conversion.
7753
7754                if Is_Class_Wide_Type (Actual_Op_Typ)
7755                  and then Root_Op_Typ /= Actual_Targ_Typ
7756                  and then Is_Ancestor (Root_Op_Typ, Actual_Targ_Typ)
7757                then
7758                   Make_Tag_Check (Class_Wide_Type (Actual_Targ_Typ));
7759                   Make_Conversion := True;
7760                end if;
7761
7762                --  AI05-0073: If the result subtype of the function is defined
7763                --  by an access_definition designating a specific tagged type
7764                --  T, a check is made that the result value is null or the tag
7765                --  of the object designated by the result value identifies T.
7766                --  Constraint_Error is raised if this check fails.
7767
7768                if Nkind (Parent (N)) = Sinfo.N_Return_Statement then
7769                   declare
7770                      Func     : Entity_Id;
7771                      Func_Typ : Entity_Id;
7772
7773                   begin
7774                      --  Climb scope stack looking for the enclosing function
7775
7776                      Func := Current_Scope;
7777                      while Present (Func)
7778                        and then Ekind (Func) /= E_Function
7779                      loop
7780                         Func := Scope (Func);
7781                      end loop;
7782
7783                      --  The function's return subtype must be defined using
7784                      --  an access definition.
7785
7786                      if Nkind (Result_Definition (Parent (Func))) =
7787                           N_Access_Definition
7788                      then
7789                         Func_Typ := Directly_Designated_Type (Etype (Func));
7790
7791                         --  The return subtype denotes a specific tagged type,
7792                         --  in other words, a non class-wide type.
7793
7794                         if Is_Tagged_Type (Func_Typ)
7795                           and then not Is_Class_Wide_Type (Func_Typ)
7796                         then
7797                            Make_Tag_Check (Actual_Targ_Typ);
7798                            Make_Conversion := True;
7799                         end if;
7800                      end if;
7801                   end;
7802                end if;
7803
7804                --  We have generated a tag check for either a class-wide type
7805                --  conversion or for AI05-0073.
7806
7807                if Make_Conversion then
7808                   declare
7809                      Conv : Node_Id;
7810                   begin
7811                      Conv :=
7812                        Make_Unchecked_Type_Conversion (Loc,
7813                          Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
7814                          Expression   => Relocate_Node (Expression (N)));
7815                      Rewrite (N, Conv);
7816                      Analyze_And_Resolve (N, Target_Type);
7817                   end;
7818                end if;
7819             end if;
7820          end;
7821
7822       --  Case of other access type conversions
7823
7824       elsif Is_Access_Type (Target_Type) then
7825          Apply_Constraint_Check (Operand, Target_Type);
7826
7827       --  Case of conversions from a fixed-point type
7828
7829       --  These conversions require special expansion and processing, found in
7830       --  the Exp_Fixd package. We ignore cases where Conversion_OK is set,
7831       --  since from a semantic point of view, these are simple integer
7832       --  conversions, which do not need further processing.
7833
7834       elsif Is_Fixed_Point_Type (Operand_Type)
7835         and then not Conversion_OK (N)
7836       then
7837          --  We should never see universal fixed at this case, since the
7838          --  expansion of the constituent divide or multiply should have
7839          --  eliminated the explicit mention of universal fixed.
7840
7841          pragma Assert (Operand_Type /= Universal_Fixed);
7842
7843          --  Check for special case of the conversion to universal real that
7844          --  occurs as a result of the use of a round attribute. In this case,
7845          --  the real type for the conversion is taken from the target type of
7846          --  the Round attribute and the result must be marked as rounded.
7847
7848          if Target_Type = Universal_Real
7849            and then Nkind (Parent (N)) = N_Attribute_Reference
7850            and then Attribute_Name (Parent (N)) = Name_Round
7851          then
7852             Set_Rounded_Result (N);
7853             Set_Etype (N, Etype (Parent (N)));
7854          end if;
7855
7856          --  Otherwise do correct fixed-conversion, but skip these if the
7857          --  Conversion_OK flag is set, because from a semantic point of
7858          --  view these are simple integer conversions needing no further
7859          --  processing (the backend will simply treat them as integers)
7860
7861          if not Conversion_OK (N) then
7862             if Is_Fixed_Point_Type (Etype (N)) then
7863                Expand_Convert_Fixed_To_Fixed (N);
7864                Real_Range_Check;
7865
7866             elsif Is_Integer_Type (Etype (N)) then
7867                Expand_Convert_Fixed_To_Integer (N);
7868
7869             else
7870                pragma Assert (Is_Floating_Point_Type (Etype (N)));
7871                Expand_Convert_Fixed_To_Float (N);
7872                Real_Range_Check;
7873             end if;
7874          end if;
7875
7876       --  Case of conversions to a fixed-point type
7877
7878       --  These conversions require special expansion and processing, found in
7879       --  the Exp_Fixd package. Again, ignore cases where Conversion_OK is set,
7880       --  since from a semantic point of view, these are simple integer
7881       --  conversions, which do not need further processing.
7882
7883       elsif Is_Fixed_Point_Type (Target_Type)
7884         and then not Conversion_OK (N)
7885       then
7886          if Is_Integer_Type (Operand_Type) then
7887             Expand_Convert_Integer_To_Fixed (N);
7888             Real_Range_Check;
7889          else
7890             pragma Assert (Is_Floating_Point_Type (Operand_Type));
7891             Expand_Convert_Float_To_Fixed (N);
7892             Real_Range_Check;
7893          end if;
7894
7895       --  Case of float-to-integer conversions
7896
7897       --  We also handle float-to-fixed conversions with Conversion_OK set
7898       --  since semantically the fixed-point target is treated as though it
7899       --  were an integer in such cases.
7900
7901       elsif Is_Floating_Point_Type (Operand_Type)
7902         and then
7903           (Is_Integer_Type (Target_Type)
7904             or else
7905           (Is_Fixed_Point_Type (Target_Type) and then Conversion_OK (N)))
7906       then
7907          --  One more check here, gcc is still not able to do conversions of
7908          --  this type with proper overflow checking, and so gigi is doing an
7909          --  approximation of what is required by doing floating-point compares
7910          --  with the end-point. But that can lose precision in some cases, and
7911          --  give a wrong result. Converting the operand to Universal_Real is
7912          --  helpful, but still does not catch all cases with 64-bit integers
7913          --  on targets with only 64-bit floats
7914
7915          --  The above comment seems obsoleted by Apply_Float_Conversion_Check
7916          --  Can this code be removed ???
7917
7918          if Do_Range_Check (Operand) then
7919             Rewrite (Operand,
7920               Make_Type_Conversion (Loc,
7921                 Subtype_Mark =>
7922                   New_Occurrence_Of (Universal_Real, Loc),
7923                 Expression =>
7924                   Relocate_Node (Operand)));
7925
7926             Set_Etype (Operand, Universal_Real);
7927             Enable_Range_Check (Operand);
7928             Set_Do_Range_Check (Expression (Operand), False);
7929          end if;
7930
7931       --  Case of array conversions
7932
7933       --  Expansion of array conversions, add required length/range checks but
7934       --  only do this if there is no change of representation. For handling of
7935       --  this case, see Handle_Changed_Representation.
7936
7937       elsif Is_Array_Type (Target_Type) then
7938
7939          if Is_Constrained (Target_Type) then
7940             Apply_Length_Check (Operand, Target_Type);
7941          else
7942             Apply_Range_Check (Operand, Target_Type);
7943          end if;
7944
7945          Handle_Changed_Representation;
7946
7947       --  Case of conversions of discriminated types
7948
7949       --  Add required discriminant checks if target is constrained. Again this
7950       --  change is skipped if we have a change of representation.
7951
7952       elsif Has_Discriminants (Target_Type)
7953         and then Is_Constrained (Target_Type)
7954       then
7955          Apply_Discriminant_Check (Operand, Target_Type);
7956          Handle_Changed_Representation;
7957
7958       --  Case of all other record conversions. The only processing required
7959       --  is to check for a change of representation requiring the special
7960       --  assignment processing.
7961
7962       elsif Is_Record_Type (Target_Type) then
7963
7964          --  Ada 2005 (AI-216): Program_Error is raised when converting from
7965          --  a derived Unchecked_Union type to an unconstrained type that is
7966          --  not Unchecked_Union if the operand lacks inferable discriminants.
7967
7968          if Is_Derived_Type (Operand_Type)
7969            and then Is_Unchecked_Union (Base_Type (Operand_Type))
7970            and then not Is_Constrained (Target_Type)
7971            and then not Is_Unchecked_Union (Base_Type (Target_Type))
7972            and then not Has_Inferable_Discriminants (Operand)
7973          then
7974             --  To prevent Gigi from generating illegal code, we generate a
7975             --  Program_Error node, but we give it the target type of the
7976             --  conversion.
7977
7978             declare
7979                PE : constant Node_Id := Make_Raise_Program_Error (Loc,
7980                       Reason => PE_Unchecked_Union_Restriction);
7981
7982             begin
7983                Set_Etype (PE, Target_Type);
7984                Rewrite (N, PE);
7985
7986             end;
7987          else
7988             Handle_Changed_Representation;
7989          end if;
7990
7991       --  Case of conversions of enumeration types
7992
7993       elsif Is_Enumeration_Type (Target_Type) then
7994
7995          --  Special processing is required if there is a change of
7996          --  representation (from enumeration representation clauses)
7997
7998          if not Same_Representation (Target_Type, Operand_Type) then
7999
8000             --  Convert: x(y) to x'val (ytyp'val (y))
8001
8002             Rewrite (N,
8003                Make_Attribute_Reference (Loc,
8004                  Prefix => New_Occurrence_Of (Target_Type, Loc),
8005                  Attribute_Name => Name_Val,
8006                  Expressions => New_List (
8007                    Make_Attribute_Reference (Loc,
8008                      Prefix => New_Occurrence_Of (Operand_Type, Loc),
8009                      Attribute_Name => Name_Pos,
8010                      Expressions => New_List (Operand)))));
8011
8012             Analyze_And_Resolve (N, Target_Type);
8013          end if;
8014
8015       --  Case of conversions to floating-point
8016
8017       elsif Is_Floating_Point_Type (Target_Type) then
8018          Real_Range_Check;
8019       end if;
8020
8021       --  At this stage, either the conversion node has been transformed into
8022       --  some other equivalent expression, or left as a conversion that can
8023       --  be handled by Gigi. The conversions that Gigi can handle are the
8024       --  following:
8025
8026       --    Conversions with no change of representation or type
8027
8028       --    Numeric conversions involving integer, floating- and fixed-point
8029       --    values. Fixed-point values are allowed only if Conversion_OK is
8030       --    set, i.e. if the fixed-point values are to be treated as integers.
8031
8032       --  No other conversions should be passed to Gigi
8033
8034       --  Check: are these rules stated in sinfo??? if so, why restate here???
8035
8036       --  The only remaining step is to generate a range check if we still have
8037       --  a type conversion at this stage and Do_Range_Check is set. For now we
8038       --  do this only for conversions of discrete types.
8039
8040       if Nkind (N) = N_Type_Conversion
8041         and then Is_Discrete_Type (Etype (N))
8042       then
8043          declare
8044             Expr : constant Node_Id := Expression (N);
8045             Ftyp : Entity_Id;
8046             Ityp : Entity_Id;
8047
8048          begin
8049             if Do_Range_Check (Expr)
8050               and then Is_Discrete_Type (Etype (Expr))
8051             then
8052                Set_Do_Range_Check (Expr, False);
8053
8054                --  Before we do a range check, we have to deal with treating a
8055                --  fixed-point operand as an integer. The way we do this is
8056                --  simply to do an unchecked conversion to an appropriate
8057                --  integer type large enough to hold the result.
8058
8059                --  This code is not active yet, because we are only dealing
8060                --  with discrete types so far ???
8061
8062                if Nkind (Expr) in N_Has_Treat_Fixed_As_Integer
8063                  and then Treat_Fixed_As_Integer (Expr)
8064                then
8065                   Ftyp := Base_Type (Etype (Expr));
8066
8067                   if Esize (Ftyp) >= Esize (Standard_Integer) then
8068                      Ityp := Standard_Long_Long_Integer;
8069                   else
8070                      Ityp := Standard_Integer;
8071                   end if;
8072
8073                   Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
8074                end if;
8075
8076                --  Reset overflow flag, since the range check will include
8077                --  dealing with possible overflow, and generate the check If
8078                --  Address is either a source type or target type, suppress
8079                --  range check to avoid typing anomalies when it is a visible
8080                --  integer type.
8081
8082                Set_Do_Overflow_Check (N, False);
8083                if not Is_Descendent_Of_Address (Etype (Expr))
8084                  and then not Is_Descendent_Of_Address (Target_Type)
8085                then
8086                   Generate_Range_Check
8087                     (Expr, Target_Type, CE_Range_Check_Failed);
8088                end if;
8089             end if;
8090          end;
8091       end if;
8092
8093       --  Final step, if the result is a type conversion involving Vax_Float
8094       --  types, then it is subject for further special processing.
8095
8096       if Nkind (N) = N_Type_Conversion
8097         and then (Vax_Float (Operand_Type) or else Vax_Float (Target_Type))
8098       then
8099          Expand_Vax_Conversion (N);
8100          return;
8101       end if;
8102    end Expand_N_Type_Conversion;
8103
8104    -----------------------------------
8105    -- Expand_N_Unchecked_Expression --
8106    -----------------------------------
8107
8108    --  Remove the unchecked expression node from the tree. It's job was simply
8109    --  to make sure that its constituent expression was handled with checks
8110    --  off, and now that that is done, we can remove it from the tree, and
8111    --  indeed must, since gigi does not expect to see these nodes.
8112
8113    procedure Expand_N_Unchecked_Expression (N : Node_Id) is
8114       Exp : constant Node_Id := Expression (N);
8115
8116    begin
8117       Set_Assignment_OK (Exp, Assignment_OK (N) or Assignment_OK (Exp));
8118       Rewrite (N, Exp);
8119    end Expand_N_Unchecked_Expression;
8120
8121    ----------------------------------------
8122    -- Expand_N_Unchecked_Type_Conversion --
8123    ----------------------------------------
8124
8125    --  If this cannot be handled by Gigi and we haven't already made a
8126    --  temporary for it, do it now.
8127
8128    procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id) is
8129       Target_Type  : constant Entity_Id := Etype (N);
8130       Operand      : constant Node_Id   := Expression (N);
8131       Operand_Type : constant Entity_Id := Etype (Operand);
8132
8133    begin
8134       --  If we have a conversion of a compile time known value to a target
8135       --  type and the value is in range of the target type, then we can simply
8136       --  replace the construct by an integer literal of the correct type. We
8137       --  only apply this to integer types being converted. Possibly it may
8138       --  apply in other cases, but it is too much trouble to worry about.
8139
8140       --  Note that we do not do this transformation if the Kill_Range_Check
8141       --  flag is set, since then the value may be outside the expected range.
8142       --  This happens in the Normalize_Scalars case.
8143
8144       --  We also skip this if either the target or operand type is biased
8145       --  because in this case, the unchecked conversion is supposed to
8146       --  preserve the bit pattern, not the integer value.
8147
8148       if Is_Integer_Type (Target_Type)
8149         and then not Has_Biased_Representation (Target_Type)
8150         and then Is_Integer_Type (Operand_Type)
8151         and then not Has_Biased_Representation (Operand_Type)
8152         and then Compile_Time_Known_Value (Operand)
8153         and then not Kill_Range_Check (N)
8154       then
8155          declare
8156             Val : constant Uint := Expr_Value (Operand);
8157
8158          begin
8159             if Compile_Time_Known_Value (Type_Low_Bound (Target_Type))
8160                  and then
8161                Compile_Time_Known_Value (Type_High_Bound (Target_Type))
8162                  and then
8163                Val >= Expr_Value (Type_Low_Bound (Target_Type))
8164                  and then
8165                Val <= Expr_Value (Type_High_Bound (Target_Type))
8166             then
8167                Rewrite (N, Make_Integer_Literal (Sloc (N), Val));
8168
8169                --  If Address is the target type, just set the type to avoid a
8170                --  spurious type error on the literal when Address is a visible
8171                --  integer type.
8172
8173                if Is_Descendent_Of_Address (Target_Type) then
8174                   Set_Etype (N, Target_Type);
8175                else
8176                   Analyze_And_Resolve (N, Target_Type);
8177                end if;
8178
8179                return;
8180             end if;
8181          end;
8182       end if;
8183
8184       --  Nothing to do if conversion is safe
8185
8186       if Safe_Unchecked_Type_Conversion (N) then
8187          return;
8188       end if;
8189
8190       --  Otherwise force evaluation unless Assignment_OK flag is set (this
8191       --  flag indicates ??? -- more comments needed here)
8192
8193       if Assignment_OK (N) then
8194          null;
8195       else
8196          Force_Evaluation (N);
8197       end if;
8198    end Expand_N_Unchecked_Type_Conversion;
8199
8200    ----------------------------
8201    -- Expand_Record_Equality --
8202    ----------------------------
8203
8204    --  For non-variant records, Equality is expanded when needed into:
8205
8206    --      and then Lhs.Discr1 = Rhs.Discr1
8207    --      and then ...
8208    --      and then Lhs.Discrn = Rhs.Discrn
8209    --      and then Lhs.Cmp1 = Rhs.Cmp1
8210    --      and then ...
8211    --      and then Lhs.Cmpn = Rhs.Cmpn
8212
8213    --  The expression is folded by the back-end for adjacent fields. This
8214    --  function is called for tagged record in only one occasion: for imple-
8215    --  menting predefined primitive equality (see Predefined_Primitives_Bodies)
8216    --  otherwise the primitive "=" is used directly.
8217
8218    function Expand_Record_Equality
8219      (Nod    : Node_Id;
8220       Typ    : Entity_Id;
8221       Lhs    : Node_Id;
8222       Rhs    : Node_Id;
8223       Bodies : List_Id) return Node_Id
8224    is
8225       Loc : constant Source_Ptr := Sloc (Nod);
8226
8227       Result : Node_Id;
8228       C      : Entity_Id;
8229
8230       First_Time : Boolean := True;
8231
8232       function Suitable_Element (C : Entity_Id) return Entity_Id;
8233       --  Return the first field to compare beginning with C, skipping the
8234       --  inherited components.
8235
8236       ----------------------
8237       -- Suitable_Element --
8238       ----------------------
8239
8240       function Suitable_Element (C : Entity_Id) return Entity_Id is
8241       begin
8242          if No (C) then
8243             return Empty;
8244
8245          elsif Ekind (C) /= E_Discriminant
8246            and then Ekind (C) /= E_Component
8247          then
8248             return Suitable_Element (Next_Entity (C));
8249
8250          elsif Is_Tagged_Type (Typ)
8251            and then C /= Original_Record_Component (C)
8252          then
8253             return Suitable_Element (Next_Entity (C));
8254
8255          elsif Chars (C) = Name_uController
8256            or else Chars (C) = Name_uTag
8257          then
8258             return Suitable_Element (Next_Entity (C));
8259
8260          elsif Is_Interface (Etype (C)) then
8261             return Suitable_Element (Next_Entity (C));
8262
8263          else
8264             return C;
8265          end if;
8266       end Suitable_Element;
8267
8268    --  Start of processing for Expand_Record_Equality
8269
8270    begin
8271       --  Generates the following code: (assuming that Typ has one Discr and
8272       --  component C2 is also a record)
8273
8274       --   True
8275       --     and then Lhs.Discr1 = Rhs.Discr1
8276       --     and then Lhs.C1 = Rhs.C1
8277       --     and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
8278       --     and then ...
8279       --     and then Lhs.Cmpn = Rhs.Cmpn
8280
8281       Result := New_Reference_To (Standard_True, Loc);
8282       C := Suitable_Element (First_Entity (Typ));
8283
8284       while Present (C) loop
8285          declare
8286             New_Lhs : Node_Id;
8287             New_Rhs : Node_Id;
8288             Check   : Node_Id;
8289
8290          begin
8291             if First_Time then
8292                First_Time := False;
8293                New_Lhs := Lhs;
8294                New_Rhs := Rhs;
8295             else
8296                New_Lhs := New_Copy_Tree (Lhs);
8297                New_Rhs := New_Copy_Tree (Rhs);
8298             end if;
8299
8300             Check :=
8301               Expand_Composite_Equality (Nod, Etype (C),
8302                Lhs =>
8303                  Make_Selected_Component (Loc,
8304                    Prefix => New_Lhs,
8305                    Selector_Name => New_Reference_To (C, Loc)),
8306                Rhs =>
8307                  Make_Selected_Component (Loc,
8308                    Prefix => New_Rhs,
8309                    Selector_Name => New_Reference_To (C, Loc)),
8310                Bodies => Bodies);
8311
8312             --  If some (sub)component is an unchecked_union, the whole
8313             --  operation will raise program error.
8314
8315             if Nkind (Check) = N_Raise_Program_Error then
8316                Result := Check;
8317                Set_Etype (Result, Standard_Boolean);
8318                exit;
8319             else
8320                Result :=
8321                  Make_And_Then (Loc,
8322                    Left_Opnd  => Result,
8323                    Right_Opnd => Check);
8324             end if;
8325          end;
8326
8327          C := Suitable_Element (Next_Entity (C));
8328       end loop;
8329
8330       return Result;
8331    end Expand_Record_Equality;
8332
8333    -------------------------------------
8334    -- Fixup_Universal_Fixed_Operation --
8335    -------------------------------------
8336
8337    procedure Fixup_Universal_Fixed_Operation (N : Node_Id) is
8338       Conv : constant Node_Id := Parent (N);
8339
8340    begin
8341       --  We must have a type conversion immediately above us
8342
8343       pragma Assert (Nkind (Conv) = N_Type_Conversion);
8344
8345       --  Normally the type conversion gives our target type. The exception
8346       --  occurs in the case of the Round attribute, where the conversion
8347       --  will be to universal real, and our real type comes from the Round
8348       --  attribute (as well as an indication that we must round the result)
8349
8350       if Nkind (Parent (Conv)) = N_Attribute_Reference
8351         and then Attribute_Name (Parent (Conv)) = Name_Round
8352       then
8353          Set_Etype (N, Etype (Parent (Conv)));
8354          Set_Rounded_Result (N);
8355
8356       --  Normal case where type comes from conversion above us
8357
8358       else
8359          Set_Etype (N, Etype (Conv));
8360       end if;
8361    end Fixup_Universal_Fixed_Operation;
8362
8363    ------------------------------
8364    -- Get_Allocator_Final_List --
8365    ------------------------------
8366
8367    function Get_Allocator_Final_List
8368      (N    : Node_Id;
8369       T    : Entity_Id;
8370       PtrT : Entity_Id) return Entity_Id
8371    is
8372       Loc : constant Source_Ptr := Sloc (N);
8373
8374       Owner : Entity_Id := PtrT;
8375       --  The entity whose finalization list must be used to attach the
8376       --  allocated object.
8377
8378    begin
8379       if Ekind (PtrT) = E_Anonymous_Access_Type then
8380
8381          --  If the context is an access parameter, we need to create a
8382          --  non-anonymous access type in order to have a usable final list,
8383          --  because there is otherwise no pool to which the allocated object
8384          --  can belong. We create both the type and the finalization chain
8385          --  here, because freezing an internal type does not create such a
8386          --  chain. The Final_Chain that is thus created is shared by the
8387          --  access parameter. The access type is tested against the result
8388          --  type of the function to exclude allocators whose type is an
8389          --  anonymous access result type. We freeze the type at once to
8390          --  ensure that it is properly decorated for the back-end, even
8391          --  if the context and current scope is a loop.
8392
8393          if Nkind (Associated_Node_For_Itype (PtrT))
8394               in N_Subprogram_Specification
8395            and then
8396              PtrT /=
8397                Etype (Defining_Unit_Name (Associated_Node_For_Itype (PtrT)))
8398          then
8399             Owner := Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
8400             Insert_Action (N,
8401               Make_Full_Type_Declaration (Loc,
8402                 Defining_Identifier => Owner,
8403                 Type_Definition =>
8404                    Make_Access_To_Object_Definition (Loc,
8405                      Subtype_Indication =>
8406                        New_Occurrence_Of (T, Loc))));
8407
8408             Freeze_Before (N, Owner);
8409             Build_Final_List (N, Owner);
8410             Set_Associated_Final_Chain (PtrT, Associated_Final_Chain (Owner));
8411
8412          --  Ada 2005 (AI-318-02): If the context is a return object
8413          --  declaration, then the anonymous return subtype is defined to have
8414          --  the same accessibility level as that of the function's result
8415          --  subtype, which means that we want the scope where the function is
8416          --  declared.
8417
8418          elsif Nkind (Associated_Node_For_Itype (PtrT)) = N_Object_Declaration
8419            and then Ekind (Scope (PtrT)) = E_Return_Statement
8420          then
8421             Owner := Scope (Return_Applies_To (Scope (PtrT)));
8422
8423          --  Case of an access discriminant, or (Ada 2005), of an anonymous
8424          --  access component or anonymous access function result: find the
8425          --  final list associated with the scope of the type. (In the
8426          --  anonymous access component kind, a list controller will have
8427          --  been allocated when freezing the record type, and PtrT has an
8428          --  Associated_Final_Chain attribute designating it.)
8429
8430          elsif No (Associated_Final_Chain (PtrT)) then
8431             Owner := Scope (PtrT);
8432          end if;
8433       end if;
8434
8435       return Find_Final_List (Owner);
8436    end Get_Allocator_Final_List;
8437
8438    ---------------------------------
8439    -- Has_Inferable_Discriminants --
8440    ---------------------------------
8441
8442    function Has_Inferable_Discriminants (N : Node_Id) return Boolean is
8443
8444       function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean;
8445       --  Determines whether the left-most prefix of a selected component is a
8446       --  formal parameter in a subprogram. Assumes N is a selected component.
8447
8448       --------------------------------
8449       -- Prefix_Is_Formal_Parameter --
8450       --------------------------------
8451
8452       function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean is
8453          Sel_Comp : Node_Id := N;
8454
8455       begin
8456          --  Move to the left-most prefix by climbing up the tree
8457
8458          while Present (Parent (Sel_Comp))
8459            and then Nkind (Parent (Sel_Comp)) = N_Selected_Component
8460          loop
8461             Sel_Comp := Parent (Sel_Comp);
8462          end loop;
8463
8464          return Ekind (Entity (Prefix (Sel_Comp))) in Formal_Kind;
8465       end Prefix_Is_Formal_Parameter;
8466
8467    --  Start of processing for Has_Inferable_Discriminants
8468
8469    begin
8470       --  For identifiers and indexed components, it is sufficient to have a
8471       --  constrained Unchecked_Union nominal subtype.
8472
8473       if Nkind_In (N, N_Identifier, N_Indexed_Component) then
8474          return Is_Unchecked_Union (Base_Type (Etype (N)))
8475                   and then
8476                 Is_Constrained (Etype (N));
8477
8478       --  For selected components, the subtype of the selector must be a
8479       --  constrained Unchecked_Union. If the component is subject to a
8480       --  per-object constraint, then the enclosing object must have inferable
8481       --  discriminants.
8482
8483       elsif Nkind (N) = N_Selected_Component then
8484          if Has_Per_Object_Constraint (Entity (Selector_Name (N))) then
8485
8486             --  A small hack. If we have a per-object constrained selected
8487             --  component of a formal parameter, return True since we do not
8488             --  know the actual parameter association yet.
8489
8490             if Prefix_Is_Formal_Parameter (N) then
8491                return True;
8492             end if;
8493
8494             --  Otherwise, check the enclosing object and the selector
8495
8496             return Has_Inferable_Discriminants (Prefix (N))
8497                      and then
8498                    Has_Inferable_Discriminants (Selector_Name (N));
8499          end if;
8500
8501          --  The call to Has_Inferable_Discriminants will determine whether
8502          --  the selector has a constrained Unchecked_Union nominal type.
8503
8504          return Has_Inferable_Discriminants (Selector_Name (N));
8505
8506       --  A qualified expression has inferable discriminants if its subtype
8507       --  mark is a constrained Unchecked_Union subtype.
8508
8509       elsif Nkind (N) = N_Qualified_Expression then
8510          return Is_Unchecked_Union (Subtype_Mark (N))
8511                   and then
8512                 Is_Constrained (Subtype_Mark (N));
8513
8514       end if;
8515
8516       return False;
8517    end Has_Inferable_Discriminants;
8518
8519    -------------------------------
8520    -- Insert_Dereference_Action --
8521    -------------------------------
8522
8523    procedure Insert_Dereference_Action (N : Node_Id) is
8524       Loc  : constant Source_Ptr := Sloc (N);
8525       Typ  : constant Entity_Id  := Etype (N);
8526       Pool : constant Entity_Id  := Associated_Storage_Pool (Typ);
8527       Pnod : constant Node_Id    := Parent (N);
8528
8529       function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
8530       --  Return true if type of P is derived from Checked_Pool;
8531
8532       -----------------------------
8533       -- Is_Checked_Storage_Pool --
8534       -----------------------------
8535
8536       function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean is
8537          T : Entity_Id;
8538
8539       begin
8540          if No (P) then
8541             return False;
8542          end if;
8543
8544          T := Etype (P);
8545          while T /= Etype (T) loop
8546             if Is_RTE (T, RE_Checked_Pool) then
8547                return True;
8548             else
8549                T := Etype (T);
8550             end if;
8551          end loop;
8552
8553          return False;
8554       end Is_Checked_Storage_Pool;
8555
8556    --  Start of processing for Insert_Dereference_Action
8557
8558    begin
8559       pragma Assert (Nkind (Pnod) = N_Explicit_Dereference);
8560
8561       if not (Is_Checked_Storage_Pool (Pool)
8562               and then Comes_From_Source (Original_Node (Pnod)))
8563       then
8564          return;
8565       end if;
8566
8567       Insert_Action (N,
8568         Make_Procedure_Call_Statement (Loc,
8569           Name => New_Reference_To (
8570             Find_Prim_Op (Etype (Pool), Name_Dereference), Loc),
8571
8572           Parameter_Associations => New_List (
8573
8574             --  Pool
8575
8576              New_Reference_To (Pool, Loc),
8577
8578             --  Storage_Address. We use the attribute Pool_Address, which uses
8579             --  the pointer itself to find the address of the object, and which
8580             --  handles unconstrained arrays properly by computing the address
8581             --  of the template. i.e. the correct address of the corresponding
8582             --  allocation.
8583
8584              Make_Attribute_Reference (Loc,
8585                Prefix         => Duplicate_Subexpr_Move_Checks (N),
8586                Attribute_Name => Name_Pool_Address),
8587
8588             --  Size_In_Storage_Elements
8589
8590              Make_Op_Divide (Loc,
8591                Left_Opnd  =>
8592                 Make_Attribute_Reference (Loc,
8593                   Prefix         =>
8594                     Make_Explicit_Dereference (Loc,
8595                       Duplicate_Subexpr_Move_Checks (N)),
8596                   Attribute_Name => Name_Size),
8597                Right_Opnd =>
8598                  Make_Integer_Literal (Loc, System_Storage_Unit)),
8599
8600             --  Alignment
8601
8602              Make_Attribute_Reference (Loc,
8603                Prefix         =>
8604                  Make_Explicit_Dereference (Loc,
8605                    Duplicate_Subexpr_Move_Checks (N)),
8606                Attribute_Name => Name_Alignment))));
8607
8608    exception
8609       when RE_Not_Available =>
8610          return;
8611    end Insert_Dereference_Action;
8612
8613    ------------------------------
8614    -- Make_Array_Comparison_Op --
8615    ------------------------------
8616
8617    --  This is a hand-coded expansion of the following generic function:
8618
8619    --  generic
8620    --    type elem is  (<>);
8621    --    type index is (<>);
8622    --    type a is array (index range <>) of elem;
8623
8624    --  function Gnnn (X : a; Y: a) return boolean is
8625    --    J : index := Y'first;
8626
8627    --  begin
8628    --    if X'length = 0 then
8629    --       return false;
8630
8631    --    elsif Y'length = 0 then
8632    --       return true;
8633
8634    --    else
8635    --      for I in X'range loop
8636    --        if X (I) = Y (J) then
8637    --          if J = Y'last then
8638    --            exit;
8639    --          else
8640    --            J := index'succ (J);
8641    --          end if;
8642
8643    --        else
8644    --           return X (I) > Y (J);
8645    --        end if;
8646    --      end loop;
8647
8648    --      return X'length > Y'length;
8649    --    end if;
8650    --  end Gnnn;
8651
8652    --  Note that since we are essentially doing this expansion by hand, we
8653    --  do not need to generate an actual or formal generic part, just the
8654    --  instantiated function itself.
8655
8656    function Make_Array_Comparison_Op
8657      (Typ : Entity_Id;
8658       Nod : Node_Id) return Node_Id
8659    is
8660       Loc : constant Source_Ptr := Sloc (Nod);
8661
8662       X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uX);
8663       Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uY);
8664       I : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uI);
8665       J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
8666
8667       Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ)));
8668
8669       Loop_Statement : Node_Id;
8670       Loop_Body      : Node_Id;
8671       If_Stat        : Node_Id;
8672       Inner_If       : Node_Id;
8673       Final_Expr     : Node_Id;
8674       Func_Body      : Node_Id;
8675       Func_Name      : Entity_Id;
8676       Formals        : List_Id;
8677       Length1        : Node_Id;
8678       Length2        : Node_Id;
8679
8680    begin
8681       --  if J = Y'last then
8682       --     exit;
8683       --  else
8684       --     J := index'succ (J);
8685       --  end if;
8686
8687       Inner_If :=
8688         Make_Implicit_If_Statement (Nod,
8689           Condition =>
8690             Make_Op_Eq (Loc,
8691               Left_Opnd => New_Reference_To (J, Loc),
8692               Right_Opnd =>
8693                 Make_Attribute_Reference (Loc,
8694                   Prefix => New_Reference_To (Y, Loc),
8695                   Attribute_Name => Name_Last)),
8696
8697           Then_Statements => New_List (
8698                 Make_Exit_Statement (Loc)),
8699
8700           Else_Statements =>
8701             New_List (
8702               Make_Assignment_Statement (Loc,
8703                 Name => New_Reference_To (J, Loc),
8704                 Expression =>
8705                   Make_Attribute_Reference (Loc,
8706                     Prefix => New_Reference_To (Index, Loc),
8707                     Attribute_Name => Name_Succ,
8708                     Expressions => New_List (New_Reference_To (J, Loc))))));
8709
8710       --  if X (I) = Y (J) then
8711       --     if ... end if;
8712       --  else
8713       --     return X (I) > Y (J);
8714       --  end if;
8715
8716       Loop_Body :=
8717         Make_Implicit_If_Statement (Nod,
8718           Condition =>
8719             Make_Op_Eq (Loc,
8720               Left_Opnd =>
8721                 Make_Indexed_Component (Loc,
8722                   Prefix      => New_Reference_To (X, Loc),
8723                   Expressions => New_List (New_Reference_To (I, Loc))),
8724
8725               Right_Opnd =>
8726                 Make_Indexed_Component (Loc,
8727                   Prefix      => New_Reference_To (Y, Loc),
8728                   Expressions => New_List (New_Reference_To (J, Loc)))),
8729
8730           Then_Statements => New_List (Inner_If),
8731
8732           Else_Statements => New_List (
8733             Make_Simple_Return_Statement (Loc,
8734               Expression =>
8735                 Make_Op_Gt (Loc,
8736                   Left_Opnd =>
8737                     Make_Indexed_Component (Loc,
8738                       Prefix      => New_Reference_To (X, Loc),
8739                       Expressions => New_List (New_Reference_To (I, Loc))),
8740
8741                   Right_Opnd =>
8742                     Make_Indexed_Component (Loc,
8743                       Prefix      => New_Reference_To (Y, Loc),
8744                       Expressions => New_List (
8745                         New_Reference_To (J, Loc)))))));
8746
8747       --  for I in X'range loop
8748       --     if ... end if;
8749       --  end loop;
8750
8751       Loop_Statement :=
8752         Make_Implicit_Loop_Statement (Nod,
8753           Identifier => Empty,
8754
8755           Iteration_Scheme =>
8756             Make_Iteration_Scheme (Loc,
8757               Loop_Parameter_Specification =>
8758                 Make_Loop_Parameter_Specification (Loc,
8759                   Defining_Identifier => I,
8760                   Discrete_Subtype_Definition =>
8761                     Make_Attribute_Reference (Loc,
8762                       Prefix => New_Reference_To (X, Loc),
8763                       Attribute_Name => Name_Range))),
8764
8765           Statements => New_List (Loop_Body));
8766
8767       --    if X'length = 0 then
8768       --       return false;
8769       --    elsif Y'length = 0 then
8770       --       return true;
8771       --    else
8772       --      for ... loop ... end loop;
8773       --      return X'length > Y'length;
8774       --    end if;
8775
8776       Length1 :=
8777         Make_Attribute_Reference (Loc,
8778           Prefix => New_Reference_To (X, Loc),
8779           Attribute_Name => Name_Length);
8780
8781       Length2 :=
8782         Make_Attribute_Reference (Loc,
8783           Prefix => New_Reference_To (Y, Loc),
8784           Attribute_Name => Name_Length);
8785
8786       Final_Expr :=
8787         Make_Op_Gt (Loc,
8788           Left_Opnd  => Length1,
8789           Right_Opnd => Length2);
8790
8791       If_Stat :=
8792         Make_Implicit_If_Statement (Nod,
8793           Condition =>
8794             Make_Op_Eq (Loc,
8795               Left_Opnd =>
8796                 Make_Attribute_Reference (Loc,
8797                   Prefix => New_Reference_To (X, Loc),
8798                   Attribute_Name => Name_Length),
8799               Right_Opnd =>
8800                 Make_Integer_Literal (Loc, 0)),
8801
8802           Then_Statements =>
8803             New_List (
8804               Make_Simple_Return_Statement (Loc,
8805                 Expression => New_Reference_To (Standard_False, Loc))),
8806
8807           Elsif_Parts => New_List (
8808             Make_Elsif_Part (Loc,
8809               Condition =>
8810                 Make_Op_Eq (Loc,
8811                   Left_Opnd =>
8812                     Make_Attribute_Reference (Loc,
8813                       Prefix => New_Reference_To (Y, Loc),
8814                       Attribute_Name => Name_Length),
8815                   Right_Opnd =>
8816                     Make_Integer_Literal (Loc, 0)),
8817
8818               Then_Statements =>
8819                 New_List (
8820                   Make_Simple_Return_Statement (Loc,
8821                      Expression => New_Reference_To (Standard_True, Loc))))),
8822
8823           Else_Statements => New_List (
8824             Loop_Statement,
8825             Make_Simple_Return_Statement (Loc,
8826               Expression => Final_Expr)));
8827
8828       --  (X : a; Y: a)
8829
8830       Formals := New_List (
8831         Make_Parameter_Specification (Loc,
8832           Defining_Identifier => X,
8833           Parameter_Type      => New_Reference_To (Typ, Loc)),
8834
8835         Make_Parameter_Specification (Loc,
8836           Defining_Identifier => Y,
8837           Parameter_Type      => New_Reference_To (Typ, Loc)));
8838
8839       --  function Gnnn (...) return boolean is
8840       --    J : index := Y'first;
8841       --  begin
8842       --    if ... end if;
8843       --  end Gnnn;
8844
8845       Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('G'));
8846
8847       Func_Body :=
8848         Make_Subprogram_Body (Loc,
8849           Specification =>
8850             Make_Function_Specification (Loc,
8851               Defining_Unit_Name       => Func_Name,
8852               Parameter_Specifications => Formals,
8853               Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
8854
8855           Declarations => New_List (
8856             Make_Object_Declaration (Loc,
8857               Defining_Identifier => J,
8858               Object_Definition   => New_Reference_To (Index, Loc),
8859               Expression =>
8860                 Make_Attribute_Reference (Loc,
8861                   Prefix => New_Reference_To (Y, Loc),
8862                   Attribute_Name => Name_First))),
8863
8864           Handled_Statement_Sequence =>
8865             Make_Handled_Sequence_Of_Statements (Loc,
8866               Statements => New_List (If_Stat)));
8867
8868       return Func_Body;
8869    end Make_Array_Comparison_Op;
8870
8871    ---------------------------
8872    -- Make_Boolean_Array_Op --
8873    ---------------------------
8874
8875    --  For logical operations on boolean arrays, expand in line the following,
8876    --  replacing 'and' with 'or' or 'xor' where needed:
8877
8878    --    function Annn (A : typ; B: typ) return typ is
8879    --       C : typ;
8880    --    begin
8881    --       for J in A'range loop
8882    --          C (J) := A (J) op B (J);
8883    --       end loop;
8884    --       return C;
8885    --    end Annn;
8886
8887    --  Here typ is the boolean array type
8888
8889    function Make_Boolean_Array_Op
8890      (Typ : Entity_Id;
8891       N   : Node_Id) return Node_Id
8892    is
8893       Loc : constant Source_Ptr := Sloc (N);
8894
8895       A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
8896       B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
8897       C : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uC);
8898       J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
8899
8900       A_J : Node_Id;
8901       B_J : Node_Id;
8902       C_J : Node_Id;
8903       Op  : Node_Id;
8904
8905       Formals        : List_Id;
8906       Func_Name      : Entity_Id;
8907       Func_Body      : Node_Id;
8908       Loop_Statement : Node_Id;
8909
8910    begin
8911       A_J :=
8912         Make_Indexed_Component (Loc,
8913           Prefix      => New_Reference_To (A, Loc),
8914           Expressions => New_List (New_Reference_To (J, Loc)));
8915
8916       B_J :=
8917         Make_Indexed_Component (Loc,
8918           Prefix      => New_Reference_To (B, Loc),
8919           Expressions => New_List (New_Reference_To (J, Loc)));
8920
8921       C_J :=
8922         Make_Indexed_Component (Loc,
8923           Prefix      => New_Reference_To (C, Loc),
8924           Expressions => New_List (New_Reference_To (J, Loc)));
8925
8926       if Nkind (N) = N_Op_And then
8927          Op :=
8928            Make_Op_And (Loc,
8929              Left_Opnd  => A_J,
8930              Right_Opnd => B_J);
8931
8932       elsif Nkind (N) = N_Op_Or then
8933          Op :=
8934            Make_Op_Or (Loc,
8935              Left_Opnd  => A_J,
8936              Right_Opnd => B_J);
8937
8938       else
8939          Op :=
8940            Make_Op_Xor (Loc,
8941              Left_Opnd  => A_J,
8942              Right_Opnd => B_J);
8943       end if;
8944
8945       Loop_Statement :=
8946         Make_Implicit_Loop_Statement (N,
8947           Identifier => Empty,
8948
8949           Iteration_Scheme =>
8950             Make_Iteration_Scheme (Loc,
8951               Loop_Parameter_Specification =>
8952                 Make_Loop_Parameter_Specification (Loc,
8953                   Defining_Identifier => J,
8954                   Discrete_Subtype_Definition =>
8955                     Make_Attribute_Reference (Loc,
8956                       Prefix => New_Reference_To (A, Loc),
8957                       Attribute_Name => Name_Range))),
8958
8959           Statements => New_List (
8960             Make_Assignment_Statement (Loc,
8961               Name       => C_J,
8962               Expression => Op)));
8963
8964       Formals := New_List (
8965         Make_Parameter_Specification (Loc,
8966           Defining_Identifier => A,
8967           Parameter_Type      => New_Reference_To (Typ, Loc)),
8968
8969         Make_Parameter_Specification (Loc,
8970           Defining_Identifier => B,
8971           Parameter_Type      => New_Reference_To (Typ, Loc)));
8972
8973       Func_Name :=
8974         Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
8975       Set_Is_Inlined (Func_Name);
8976
8977       Func_Body :=
8978         Make_Subprogram_Body (Loc,
8979           Specification =>
8980             Make_Function_Specification (Loc,
8981               Defining_Unit_Name       => Func_Name,
8982               Parameter_Specifications => Formals,
8983               Result_Definition        => New_Reference_To (Typ, Loc)),
8984
8985           Declarations => New_List (
8986             Make_Object_Declaration (Loc,
8987               Defining_Identifier => C,
8988               Object_Definition   => New_Reference_To (Typ, Loc))),
8989
8990           Handled_Statement_Sequence =>
8991             Make_Handled_Sequence_Of_Statements (Loc,
8992               Statements => New_List (
8993                 Loop_Statement,
8994                 Make_Simple_Return_Statement (Loc,
8995                   Expression => New_Reference_To (C, Loc)))));
8996
8997       return Func_Body;
8998    end Make_Boolean_Array_Op;
8999
9000    ------------------------
9001    -- Rewrite_Comparison --
9002    ------------------------
9003
9004    procedure Rewrite_Comparison (N : Node_Id) is
9005       Warning_Generated : Boolean := False;
9006       --  Set to True if first pass with Assume_Valid generates a warning in
9007       --  which case we skip the second pass to avoid warning overloaded.
9008
9009       Result : Node_Id;
9010       --  Set to Standard_True or Standard_False
9011
9012    begin
9013       if Nkind (N) = N_Type_Conversion then
9014          Rewrite_Comparison (Expression (N));
9015          return;
9016
9017       elsif Nkind (N) not in N_Op_Compare then
9018          return;
9019       end if;
9020
9021       --  Now start looking at the comparison in detail. We potentially go
9022       --  through this loop twice. The first time, Assume_Valid is set False
9023       --  in the call to Compile_Time_Compare. If this call results in a
9024       --  clear result of always True or Always False, that's decisive and
9025       --  we are done. Otherwise we repeat the processing with Assume_Valid
9026       --  set to True to generate additional warnings. We can stil that step
9027       --  if Constant_Condition_Warnings is False.
9028
9029       for AV in False .. True loop
9030          declare
9031             Typ : constant Entity_Id := Etype (N);
9032             Op1 : constant Node_Id   := Left_Opnd (N);
9033             Op2 : constant Node_Id   := Right_Opnd (N);
9034
9035             Res : constant Compare_Result :=
9036                     Compile_Time_Compare (Op1, Op2, Assume_Valid => AV);
9037             --  Res indicates if compare outcome can be compile time determined
9038
9039             True_Result  : Boolean;
9040             False_Result : Boolean;
9041
9042          begin
9043             case N_Op_Compare (Nkind (N)) is
9044             when N_Op_Eq =>
9045                True_Result  := Res = EQ;
9046                False_Result := Res = LT or else Res = GT or else Res = NE;
9047
9048             when N_Op_Ge =>
9049                True_Result  := Res in Compare_GE;
9050                False_Result := Res = LT;
9051
9052                if Res = LE
9053                  and then Constant_Condition_Warnings
9054                  and then Comes_From_Source (Original_Node (N))
9055                  and then Nkind (Original_Node (N)) = N_Op_Ge
9056                  and then not In_Instance
9057                  and then Is_Integer_Type (Etype (Left_Opnd (N)))
9058                  and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
9059                then
9060                   Error_Msg_N
9061                     ("can never be greater than, could replace by ""'=""?", N);
9062                   Warning_Generated := True;
9063                end if;
9064
9065             when N_Op_Gt =>
9066                True_Result  := Res = GT;
9067                False_Result := Res in Compare_LE;
9068
9069             when N_Op_Lt =>
9070                True_Result  := Res = LT;
9071                False_Result := Res in Compare_GE;
9072
9073             when N_Op_Le =>
9074                True_Result  := Res in Compare_LE;
9075                False_Result := Res = GT;
9076
9077                if Res = GE
9078                  and then Constant_Condition_Warnings
9079                  and then Comes_From_Source (Original_Node (N))
9080                  and then Nkind (Original_Node (N)) = N_Op_Le
9081                  and then not In_Instance
9082                  and then Is_Integer_Type (Etype (Left_Opnd (N)))
9083                  and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
9084                then
9085                   Error_Msg_N
9086                     ("can never be less than, could replace by ""'=""?", N);
9087                   Warning_Generated := True;
9088                end if;
9089
9090             when N_Op_Ne =>
9091                True_Result  := Res = NE or else Res = GT or else Res = LT;
9092                False_Result := Res = EQ;
9093             end case;
9094
9095             --  If this is the first iteration, then we actually convert the
9096             --  comparison into True or False, if the result is certain.
9097
9098             if AV = False then
9099                if True_Result or False_Result then
9100                   if True_Result then
9101                      Result := Standard_True;
9102                   else
9103                      Result := Standard_False;
9104                   end if;
9105
9106                   Rewrite (N,
9107                     Convert_To (Typ,
9108                       New_Occurrence_Of (Result, Sloc (N))));
9109                   Analyze_And_Resolve (N, Typ);
9110                   Warn_On_Known_Condition (N);
9111                   return;
9112                end if;
9113
9114             --  If this is the second iteration (AV = True), and the original
9115             --  node comes from source and we are not in an instance, then
9116             --  give a warning if we know result would be True or False. Note
9117             --  we know Constant_Condition_Warnings is set if we get here.
9118
9119             elsif Comes_From_Source (Original_Node (N))
9120               and then not In_Instance
9121             then
9122                if True_Result then
9123                   Error_Msg_N
9124                     ("condition can only be False if invalid values present?",
9125                      N);
9126                elsif False_Result then
9127                   Error_Msg_N
9128                     ("condition can only be True if invalid values present?",
9129                      N);
9130                end if;
9131             end if;
9132          end;
9133
9134          --  Skip second iteration if not warning on constant conditions or
9135          --  if the first iteration already generated a warning of some kind
9136          --  or if we are in any case assuming all values are valid (so that
9137          --  the first iteration took care of the valid case).
9138
9139          exit when not Constant_Condition_Warnings;
9140          exit when Warning_Generated;
9141          exit when Assume_No_Invalid_Values;
9142       end loop;
9143    end Rewrite_Comparison;
9144
9145    ----------------------------
9146    -- Safe_In_Place_Array_Op --
9147    ----------------------------
9148
9149    function Safe_In_Place_Array_Op
9150      (Lhs : Node_Id;
9151       Op1 : Node_Id;
9152       Op2 : Node_Id) return Boolean
9153    is
9154       Target : Entity_Id;
9155
9156       function Is_Safe_Operand (Op : Node_Id) return Boolean;
9157       --  Operand is safe if it cannot overlap part of the target of the
9158       --  operation. If the operand and the target are identical, the operand
9159       --  is safe. The operand can be empty in the case of negation.
9160
9161       function Is_Unaliased (N : Node_Id) return Boolean;
9162       --  Check that N is a stand-alone entity
9163
9164       ------------------
9165       -- Is_Unaliased --
9166       ------------------
9167
9168       function Is_Unaliased (N : Node_Id) return Boolean is
9169       begin
9170          return
9171            Is_Entity_Name (N)
9172              and then No (Address_Clause (Entity (N)))
9173              and then No (Renamed_Object (Entity (N)));
9174       end Is_Unaliased;
9175
9176       ---------------------
9177       -- Is_Safe_Operand --
9178       ---------------------
9179
9180       function Is_Safe_Operand (Op : Node_Id) return Boolean is
9181       begin
9182          if No (Op) then
9183             return True;
9184
9185          elsif Is_Entity_Name (Op) then
9186             return Is_Unaliased (Op);
9187
9188          elsif Nkind_In (Op, N_Indexed_Component, N_Selected_Component) then
9189             return Is_Unaliased (Prefix (Op));
9190
9191          elsif Nkind (Op) = N_Slice then
9192             return
9193               Is_Unaliased (Prefix (Op))
9194                 and then Entity (Prefix (Op)) /= Target;
9195
9196          elsif Nkind (Op) = N_Op_Not then
9197             return Is_Safe_Operand (Right_Opnd (Op));
9198
9199          else
9200             return False;
9201          end if;
9202       end Is_Safe_Operand;
9203
9204       --  Start of processing for Is_Safe_In_Place_Array_Op
9205
9206    begin
9207       --  Skip this processing if the component size is different from system
9208       --  storage unit (since at least for NOT this would cause problems).
9209
9210       if Component_Size (Etype (Lhs)) /= System_Storage_Unit then
9211          return False;
9212
9213       --  Cannot do in place stuff on VM_Target since cannot pass addresses
9214
9215       elsif VM_Target /= No_VM then
9216          return False;
9217
9218       --  Cannot do in place stuff if non-standard Boolean representation
9219
9220       elsif Has_Non_Standard_Rep (Component_Type (Etype (Lhs))) then
9221          return False;
9222
9223       elsif not Is_Unaliased (Lhs) then
9224          return False;
9225       else
9226          Target := Entity (Lhs);
9227
9228          return
9229            Is_Safe_Operand (Op1)
9230              and then Is_Safe_Operand (Op2);
9231       end if;
9232    end Safe_In_Place_Array_Op;
9233
9234    -----------------------
9235    -- Tagged_Membership --
9236    -----------------------
9237
9238    --  There are two different cases to consider depending on whether the right
9239    --  operand is a class-wide type or not. If not we just compare the actual
9240    --  tag of the left expr to the target type tag:
9241    --
9242    --     Left_Expr.Tag = Right_Type'Tag;
9243    --
9244    --  If it is a class-wide type we use the RT function CW_Membership which is
9245    --  usually implemented by looking in the ancestor tables contained in the
9246    --  dispatch table pointed by Left_Expr.Tag for Typ'Tag
9247
9248    --  Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
9249    --  function IW_Membership which is usually implemented by looking in the
9250    --  table of abstract interface types plus the ancestor table contained in
9251    --  the dispatch table pointed by Left_Expr.Tag for Typ'Tag
9252
9253    function Tagged_Membership (N : Node_Id) return Node_Id is
9254       Left  : constant Node_Id    := Left_Opnd  (N);
9255       Right : constant Node_Id    := Right_Opnd (N);
9256       Loc   : constant Source_Ptr := Sloc (N);
9257
9258       Left_Type  : Entity_Id;
9259       Right_Type : Entity_Id;
9260       Obj_Tag    : Node_Id;
9261
9262    begin
9263       Left_Type  := Etype (Left);
9264       Right_Type := Etype (Right);
9265
9266       if Is_Class_Wide_Type (Left_Type) then
9267          Left_Type := Root_Type (Left_Type);
9268       end if;
9269
9270       Obj_Tag :=
9271         Make_Selected_Component (Loc,
9272           Prefix        => Relocate_Node (Left),
9273           Selector_Name =>
9274             New_Reference_To (First_Tag_Component (Left_Type), Loc));
9275
9276       if Is_Class_Wide_Type (Right_Type) then
9277
9278          --  No need to issue a run-time check if we statically know that the
9279          --  result of this membership test is always true. For example,
9280          --  considering the following declarations:
9281
9282          --    type Iface is interface;
9283          --    type T     is tagged null record;
9284          --    type DT    is new T and Iface with null record;
9285
9286          --    Obj1 : T;
9287          --    Obj2 : DT;
9288
9289          --  These membership tests are always true:
9290
9291          --    Obj1 in T'Class
9292          --    Obj2 in T'Class;
9293          --    Obj2 in Iface'Class;
9294
9295          --  We do not need to handle cases where the membership is illegal.
9296          --  For example:
9297
9298          --    Obj1 in DT'Class;     --  Compile time error
9299          --    Obj1 in Iface'Class;  --  Compile time error
9300
9301          if not Is_Class_Wide_Type (Left_Type)
9302            and then (Is_Ancestor (Etype (Right_Type), Left_Type)
9303                        or else (Is_Interface (Etype (Right_Type))
9304                                  and then Interface_Present_In_Ancestor
9305                                            (Typ   => Left_Type,
9306                                             Iface => Etype (Right_Type))))
9307          then
9308             return New_Reference_To (Standard_True, Loc);
9309          end if;
9310
9311          --  Ada 2005 (AI-251): Class-wide applied to interfaces
9312
9313          if Is_Interface (Etype (Class_Wide_Type (Right_Type)))
9314
9315             --   Support to: "Iface_CW_Typ in Typ'Class"
9316
9317            or else Is_Interface (Left_Type)
9318          then
9319             --  Issue error if IW_Membership operation not available in a
9320             --  configurable run time setting.
9321
9322             if not RTE_Available (RE_IW_Membership) then
9323                Error_Msg_CRT
9324                  ("dynamic membership test on interface types", N);
9325                return Empty;
9326             end if;
9327
9328             return
9329               Make_Function_Call (Loc,
9330                  Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
9331                  Parameter_Associations => New_List (
9332                    Make_Attribute_Reference (Loc,
9333                      Prefix => Obj_Tag,
9334                      Attribute_Name => Name_Address),
9335                    New_Reference_To (
9336                      Node (First_Elmt
9337                             (Access_Disp_Table (Root_Type (Right_Type)))),
9338                      Loc)));
9339
9340          --  Ada 95: Normal case
9341
9342          else
9343             return
9344               Build_CW_Membership (Loc,
9345                 Obj_Tag_Node => Obj_Tag,
9346                 Typ_Tag_Node =>
9347                    New_Reference_To (
9348                      Node (First_Elmt
9349                             (Access_Disp_Table (Root_Type (Right_Type)))),
9350                      Loc));
9351          end if;
9352
9353       --  Right_Type is not a class-wide type
9354
9355       else
9356          --  No need to check the tag of the object if Right_Typ is abstract
9357
9358          if Is_Abstract_Type (Right_Type) then
9359             return New_Reference_To (Standard_False, Loc);
9360
9361          else
9362             return
9363               Make_Op_Eq (Loc,
9364                 Left_Opnd  => Obj_Tag,
9365                 Right_Opnd =>
9366                   New_Reference_To
9367                     (Node (First_Elmt (Access_Disp_Table (Right_Type))), Loc));
9368          end if;
9369       end if;
9370    end Tagged_Membership;
9371
9372    ------------------------------
9373    -- Unary_Op_Validity_Checks --
9374    ------------------------------
9375
9376    procedure Unary_Op_Validity_Checks (N : Node_Id) is
9377    begin
9378       if Validity_Checks_On and Validity_Check_Operands then
9379          Ensure_Valid (Right_Opnd (N));
9380       end if;
9381    end Unary_Op_Validity_Checks;
9382
9383 end Exp_Ch4;