OSDN Git Service

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