OSDN Git Service

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