[multiple changes]
[platform/upstream/gcc.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       Istyp : constant Entity_Id := Etype (First_Index (Atyp));
2150       --  Index subtype
2151
2152       Ityp : constant Entity_Id := Base_Type (Istyp);
2153       --  Index type. This is the base type of the index subtype, and is used
2154       --  for all computed bounds (which may be out of range of Istyp in the
2155       --  case of null ranges).
2156
2157       Artyp : Entity_Id;
2158       --  This is the type we use to do arithmetic to compute the bounds and
2159       --  lengths of operands. The choice of this type is a little subtle and
2160       --  is discussed in a separate section at the start of the body code.
2161
2162       Concatenation_Error : exception;
2163       --  Raised if concatenation is sure to raise a CE
2164
2165       Result_May_Be_Null : Boolean := True;
2166       --  Reset to False if at least one operand is encountered which is known
2167       --  at compile time to be non-null. Used for handling the special case
2168       --  of setting the high bound to the last operand high bound for a null
2169       --  result, thus ensuring a proper high bound in the super-flat case.
2170
2171       N : constant Nat := List_Length (Opnds);
2172       --  Number of concatenation operands including possibly null operands
2173
2174       NN : Nat := 0;
2175       --  Number of operands excluding any known to be null, except that the
2176       --  last operand is always retained, in case it provides the bounds for
2177       --  a null result.
2178
2179       Opnd : Node_Id;
2180       --  Current operand being processed in the loop through operands. After
2181       --  this loop is complete, always contains the last operand (which is not
2182       --  the same as Operands (NN), since null operands are skipped).
2183
2184       --  Arrays describing the operands, only the first NN entries of each
2185       --  array are set (NN < N when we exclude known null operands).
2186
2187       Is_Fixed_Length : array (1 .. N) of Boolean;
2188       --  True if length of corresponding operand known at compile time
2189
2190       Operands : array (1 .. N) of Node_Id;
2191       --  Set to the corresponding entry in the Opnds list (but note that null
2192       --  operands are excluded, so not all entries in the list are stored).
2193
2194       Fixed_Length : array (1 .. N) of Uint;
2195       --  Set to length of operand. Entries in this array are set only if the
2196       --  corresponding entry in Is_Fixed_Length is True.
2197
2198       Opnd_Low_Bound : array (1 .. N) of Node_Id;
2199       --  Set to lower bound of operand. Either an integer literal in the case
2200       --  where the bound is known at compile time, else actual lower bound.
2201       --  The operand low bound is of type Ityp.
2202
2203       Var_Length : array (1 .. N) of Entity_Id;
2204       --  Set to an entity of type Natural that contains the length of an
2205       --  operand whose length is not known at compile time. Entries in this
2206       --  array are set only if the corresponding entry in Is_Fixed_Length
2207       --  is False. The entity is of type Artyp.
2208
2209       Aggr_Length : array (0 .. N) of Node_Id;
2210       --  The J'th entry in an expression node that represents the total length
2211       --  of operands 1 through J. It is either an integer literal node, or a
2212       --  reference to a constant entity with the right value, so it is fine
2213       --  to just do a Copy_Node to get an appropriate copy. The extra zero'th
2214       --  entry always is set to zero. The length is of type Artyp.
2215
2216       Low_Bound : Node_Id;
2217       --  A tree node representing the low bound of the result (of type Ityp).
2218       --  This is either an integer literal node, or an identifier reference to
2219       --  a constant entity initialized to the appropriate value.
2220
2221       Last_Opnd_High_Bound : Node_Id;
2222       --  A tree node representing the high bound of the last operand. This
2223       --  need only be set if the result could be null. It is used for the
2224       --  special case of setting the right high bound for a null result.
2225       --  This is of type Ityp.
2226
2227       High_Bound : Node_Id;
2228       --  A tree node representing the high bound of the result (of type Ityp)
2229
2230       Result : Node_Id;
2231       --  Result of the concatenation (of type Ityp)
2232
2233       function To_Artyp (X : Node_Id) return Node_Id;
2234       --  Given a node of type Ityp, returns the corresponding value of type
2235       --  Artyp. For non-enumeration types, this is a plain integer conversion.
2236       --  For enum types, the Pos of the value is returned.
2237
2238       function To_Ityp (X : Node_Id) return Node_Id;
2239       --  The inverse function (uses Val in the case of enumeration types)
2240
2241       Known_Non_Null_Operand_Seen : Boolean;
2242       --  Set True during generation of the assignements of operands into
2243       --  result once an operand known to be non-null has been seen.
2244
2245       --------------
2246       -- To_Artyp --
2247       --------------
2248
2249       function To_Artyp (X : Node_Id) return Node_Id is
2250       begin
2251          if Ityp = Base_Type (Artyp) then
2252             return X;
2253
2254          elsif Is_Enumeration_Type (Ityp) then
2255             return
2256               Make_Attribute_Reference (Loc,
2257                 Prefix         => New_Occurrence_Of (Ityp, Loc),
2258                 Attribute_Name => Name_Pos,
2259                 Expressions    => New_List (X));
2260
2261          else
2262             return Convert_To (Artyp, X);
2263          end if;
2264       end To_Artyp;
2265
2266       -------------
2267       -- To_Ityp --
2268       -------------
2269
2270       function To_Ityp (X : Node_Id) return Node_Id is
2271       begin
2272          if Is_Enumeration_Type (Ityp) then
2273             return
2274               Make_Attribute_Reference (Loc,
2275                 Prefix         => New_Occurrence_Of (Ityp, Loc),
2276                 Attribute_Name => Name_Val,
2277                 Expressions    => New_List (X));
2278
2279          --  Case where we will do a type conversion
2280
2281          else
2282             if Ityp = Base_Type (Artyp) then
2283                return X;
2284             else
2285                return Convert_To (Ityp, X);
2286             end if;
2287          end if;
2288       end To_Ityp;
2289
2290       --  Local Declarations
2291
2292       Opnd_Typ : Entity_Id;
2293       Ent      : Entity_Id;
2294       Len      : Uint;
2295       J        : Nat;
2296       Clen     : Node_Id;
2297       Set      : Boolean;
2298
2299       Saved_In_Inlined_Body : Boolean;
2300
2301    begin
2302       Aggr_Length (0) := Make_Integer_Literal (Loc, 0);
2303
2304       --  Choose an appropriate computational type
2305
2306       --  We will be doing calculations of lengths and bounds in this routine
2307       --  and computing one from the other in some cases, e.g. getting the high
2308       --  bound by adding the length-1 to the low bound.
2309
2310       --  We can't just use the index type, or even its base type for this
2311       --  purpose for two reasons. First it might be an enumeration type which
2312       --  is not suitable fo computations of any kind, and second it may simply
2313       --  not have enough range. For example if the index type is -128..+127
2314       --  then lengths can be up to 256, which is out of range of the type.
2315
2316       --  For enumeration types, we can simply use Standard_Integer, this is
2317       --  sufficient since the actual number of enumeration literals cannot
2318       --  possibly exceed the range of integer (remember we will be doing the
2319       --  arithmetic with POS values, not representation values).
2320
2321       if Is_Enumeration_Type (Ityp) then
2322          Artyp := Standard_Integer;
2323
2324       --  For modular types, we use a 32-bit modular type for types whose size
2325       --  is in the range 1-31 bits. For 32-bit unsigned types, we use the
2326       --  identity type, and for larger unsigned types we use 64-bits.
2327
2328       elsif Is_Modular_Integer_Type (Ityp) then
2329          if RM_Size (Ityp) < RM_Size (Standard_Unsigned) then
2330             Artyp := Standard_Unsigned;
2331          elsif RM_Size (Ityp) = RM_Size (Standard_Unsigned) then
2332             Artyp := Ityp;
2333          else
2334             Artyp := RTE (RE_Long_Long_Unsigned);
2335          end if;
2336
2337       --  Similar treatment for signed types
2338
2339       else
2340          if RM_Size (Ityp) < RM_Size (Standard_Integer) then
2341             Artyp := Standard_Integer;
2342          elsif RM_Size (Ityp) = RM_Size (Standard_Integer) then
2343             Artyp := Ityp;
2344          else
2345             Artyp := Standard_Long_Long_Integer;
2346          end if;
2347       end if;
2348
2349       --  Go through operands setting up the above arrays
2350
2351       J := 1;
2352       while J <= N loop
2353          Opnd := Remove_Head (Opnds);
2354          Opnd_Typ := Etype (Opnd);
2355
2356          --  The parent got messed up when we put the operands in a list,
2357          --  so now put back the proper parent for the saved operand.
2358
2359          Set_Parent (Opnd, Parent (Cnode));
2360
2361          --  Set will be True when we have setup one entry in the array
2362
2363          Set := False;
2364
2365          --  Singleton element (or character literal) case
2366
2367          if Base_Type (Opnd_Typ) = Ctyp then
2368             NN := NN + 1;
2369             Operands (NN) := Opnd;
2370             Is_Fixed_Length (NN) := True;
2371             Fixed_Length (NN) := Uint_1;
2372             Result_May_Be_Null := False;
2373
2374             --  Set low bound of operand (no need to set Last_Opnd_High_Bound
2375             --  since we know that the result cannot be null).
2376
2377             Opnd_Low_Bound (NN) :=
2378               Make_Attribute_Reference (Loc,
2379                 Prefix         => New_Reference_To (Istyp, Loc),
2380                 Attribute_Name => Name_First);
2381
2382             Set := True;
2383
2384          --  String literal case (can only occur for strings of course)
2385
2386          elsif Nkind (Opnd) = N_String_Literal then
2387             Len := String_Literal_Length (Opnd_Typ);
2388
2389             if Len /= 0 then
2390                Result_May_Be_Null := False;
2391             end if;
2392
2393             --  Capture last operand high bound if result could be null
2394
2395             if J = N and then Result_May_Be_Null then
2396                Last_Opnd_High_Bound :=
2397                  Make_Op_Add (Loc,
2398                    Left_Opnd  =>
2399                      New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)),
2400                    Right_Opnd => Make_Integer_Literal (Loc, 1));
2401             end if;
2402
2403             --  Skip null string literal
2404
2405             if J < N and then Len = 0 then
2406                goto Continue;
2407             end if;
2408
2409             NN := NN + 1;
2410             Operands (NN) := Opnd;
2411             Is_Fixed_Length (NN) := True;
2412
2413             --  Set length and bounds
2414
2415             Fixed_Length (NN) := Len;
2416
2417             Opnd_Low_Bound (NN) :=
2418               New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));
2419
2420             Set := True;
2421
2422          --  All other cases
2423
2424          else
2425             --  Check constrained case with known bounds
2426
2427             if Is_Constrained (Opnd_Typ) then
2428                declare
2429                   Index    : constant Node_Id   := First_Index (Opnd_Typ);
2430                   Indx_Typ : constant Entity_Id := Etype (Index);
2431                   Lo       : constant Node_Id   := Type_Low_Bound  (Indx_Typ);
2432                   Hi       : constant Node_Id   := Type_High_Bound (Indx_Typ);
2433
2434                begin
2435                   --  Fixed length constrained array type with known at compile
2436                   --  time bounds is last case of fixed length operand.
2437
2438                   if Compile_Time_Known_Value (Lo)
2439                        and then
2440                      Compile_Time_Known_Value (Hi)
2441                   then
2442                      declare
2443                         Loval : constant Uint := Expr_Value (Lo);
2444                         Hival : constant Uint := Expr_Value (Hi);
2445                         Len   : constant Uint :=
2446                                   UI_Max (Hival - Loval + 1, Uint_0);
2447
2448                      begin
2449                         if Len > 0 then
2450                            Result_May_Be_Null := False;
2451                         end if;
2452
2453                         --  Capture last operand bound if result could be null
2454
2455                         if J = N and then Result_May_Be_Null then
2456                            Last_Opnd_High_Bound :=
2457                              Convert_To (Ityp,
2458                                Make_Integer_Literal (Loc,
2459                                  Intval => Expr_Value (Hi)));
2460                         end if;
2461
2462                         --  Exclude null length case unless last operand
2463
2464                         if J < N and then Len = 0 then
2465                            goto Continue;
2466                         end if;
2467
2468                         NN := NN + 1;
2469                         Operands (NN) := Opnd;
2470                         Is_Fixed_Length (NN) := True;
2471                         Fixed_Length (NN)    := Len;
2472
2473                         Opnd_Low_Bound (NN) := To_Ityp (
2474                           Make_Integer_Literal (Loc,
2475                             Intval => Expr_Value (Lo)));
2476
2477                         Set := True;
2478                      end;
2479                   end if;
2480                end;
2481             end if;
2482
2483             --  All cases where the length is not known at compile time, or the
2484             --  special case of an operand which is known to be null but has a
2485             --  lower bound other than 1 or is other than a string type.
2486
2487             if not Set then
2488                NN := NN + 1;
2489
2490                --  Capture operand bounds
2491
2492                Opnd_Low_Bound (NN) :=
2493                  Make_Attribute_Reference (Loc,
2494                    Prefix         =>
2495                      Duplicate_Subexpr (Opnd, Name_Req => True),
2496                    Attribute_Name => Name_First);
2497
2498                if J = N and Result_May_Be_Null then
2499                   Last_Opnd_High_Bound :=
2500                     Convert_To (Ityp,
2501                       Make_Attribute_Reference (Loc,
2502                         Prefix         =>
2503                           Duplicate_Subexpr (Opnd, Name_Req => True),
2504                         Attribute_Name => Name_Last));
2505                end if;
2506
2507                --  Capture length of operand in entity
2508
2509                Operands (NN) := Opnd;
2510                Is_Fixed_Length (NN) := False;
2511
2512                Var_Length (NN) :=
2513                  Make_Defining_Identifier (Loc,
2514                    Chars => New_Internal_Name ('L'));
2515
2516                Insert_Action (Cnode,
2517                  Make_Object_Declaration (Loc,
2518                    Defining_Identifier => Var_Length (NN),
2519                    Constant_Present    => True,
2520
2521                    Object_Definition   =>
2522                      New_Occurrence_Of (Artyp, Loc),
2523
2524                    Expression          =>
2525                      Make_Attribute_Reference (Loc,
2526                        Prefix         =>
2527                          Duplicate_Subexpr (Opnd, Name_Req => True),
2528                        Attribute_Name => Name_Length)),
2529
2530                  Suppress => All_Checks);
2531             end if;
2532          end if;
2533
2534          --  Set next entry in aggregate length array
2535
2536          --  For first entry, make either integer literal for fixed length
2537          --  or a reference to the saved length for variable length.
2538
2539          if NN = 1 then
2540             if Is_Fixed_Length (1) then
2541                Aggr_Length (1) :=
2542                  Make_Integer_Literal (Loc,
2543                    Intval => Fixed_Length (1));
2544             else
2545                Aggr_Length (1) :=
2546                  New_Reference_To (Var_Length (1), Loc);
2547             end if;
2548
2549          --  If entry is fixed length and only fixed lengths so far, make
2550          --  appropriate new integer literal adding new length.
2551
2552          elsif Is_Fixed_Length (NN)
2553            and then Nkind (Aggr_Length (NN - 1)) = N_Integer_Literal
2554          then
2555             Aggr_Length (NN) :=
2556               Make_Integer_Literal (Loc,
2557                 Intval => Fixed_Length (NN) + Intval (Aggr_Length (NN - 1)));
2558
2559             --  All other cases, construct an addition node for the length and
2560             --  create an entity initialized to this length.
2561
2562          else
2563             Ent :=
2564               Make_Defining_Identifier (Loc,
2565                 Chars => New_Internal_Name ('L'));
2566
2567             if Is_Fixed_Length (NN) then
2568                Clen := Make_Integer_Literal (Loc, Fixed_Length (NN));
2569             else
2570                Clen := New_Reference_To (Var_Length (NN), Loc);
2571             end if;
2572
2573             Insert_Action (Cnode,
2574               Make_Object_Declaration (Loc,
2575                 Defining_Identifier => Ent,
2576                 Constant_Present    => True,
2577
2578                 Object_Definition   =>
2579                   New_Occurrence_Of (Artyp, Loc),
2580
2581                 Expression          =>
2582                   Make_Op_Add (Loc,
2583                     Left_Opnd  => New_Copy (Aggr_Length (NN - 1)),
2584                     Right_Opnd => Clen)),
2585
2586               Suppress => All_Checks);
2587
2588             Aggr_Length (NN) := Make_Identifier (Loc, Chars => Chars (Ent));
2589          end if;
2590
2591       <<Continue>>
2592          J := J + 1;
2593       end loop;
2594
2595       --  If we have only skipped null operands, return the last operand
2596
2597       if NN = 0 then
2598          Result := Opnd;
2599          goto Done;
2600       end if;
2601
2602       --  If we have only one non-null operand, return it and we are done.
2603       --  There is one case in which this cannot be done, and that is when
2604       --  the sole operand is of the element type, in which case it must be
2605       --  converted to an array, and the easiest way of doing that is to go
2606       --  through the normal general circuit.
2607
2608       if NN = 1
2609         and then Base_Type (Etype (Operands (1))) /= Ctyp
2610       then
2611          Result := Operands (1);
2612          goto Done;
2613       end if;
2614
2615       --  Cases where we have a real concatenation
2616
2617       --  Next step is to find the low bound for the result array that we
2618       --  will allocate. The rules for this are in (RM 4.5.6(5-7)).
2619
2620       --  If the ultimate ancestor of the index subtype is a constrained array
2621       --  definition, then the lower bound is that of the index subtype as
2622       --  specified by (RM 4.5.3(6)).
2623
2624       --  The right test here is to go to the root type, and then the ultimate
2625       --  ancestor is the first subtype of this root type.
2626
2627       if Is_Constrained (First_Subtype (Root_Type (Atyp))) then
2628          Low_Bound :=
2629            Make_Attribute_Reference (Loc,
2630              Prefix         =>
2631                New_Occurrence_Of (First_Subtype (Root_Type (Atyp)), Loc),
2632              Attribute_Name => Name_First);
2633
2634       --  If the first operand in the list has known length we know that
2635       --  the lower bound of the result is the lower bound of this operand.
2636
2637       elsif Is_Fixed_Length (1) then
2638          Low_Bound := Opnd_Low_Bound (1);
2639
2640       --  OK, we don't know the lower bound, we have to build a horrible
2641       --  expression actions node of the form
2642
2643       --     if Cond1'Length /= 0 then
2644       --        Opnd1 low bound
2645       --     else
2646       --        if Opnd2'Length /= 0 then
2647       --          Opnd2 low bound
2648       --        else
2649       --           ...
2650
2651       --  The nesting ends either when we hit an operand whose length is known
2652       --  at compile time, or on reaching the last operand, whose low bound we
2653       --  take unconditionally whether or not it is null. It's easiest to do
2654       --  this with a recursive procedure:
2655
2656       else
2657          declare
2658             function Get_Known_Bound (J : Nat) return Node_Id;
2659             --  Returns the lower bound determined by operands J .. NN
2660
2661             ---------------------
2662             -- Get_Known_Bound --
2663             ---------------------
2664
2665             function Get_Known_Bound (J : Nat) return Node_Id is
2666             begin
2667                if Is_Fixed_Length (J) or else J = NN then
2668                   return New_Copy (Opnd_Low_Bound (J));
2669
2670                else
2671                   return
2672                     Make_Conditional_Expression (Loc,
2673                       Expressions => New_List (
2674
2675                         Make_Op_Ne (Loc,
2676                           Left_Opnd  => New_Reference_To (Var_Length (J), Loc),
2677                           Right_Opnd => Make_Integer_Literal (Loc, 0)),
2678
2679                         New_Copy (Opnd_Low_Bound (J)),
2680                         Get_Known_Bound (J + 1)));
2681                end if;
2682             end Get_Known_Bound;
2683
2684          begin
2685             Ent :=
2686               Make_Defining_Identifier (Loc, Chars => New_Internal_Name ('L'));
2687
2688             Insert_Action (Cnode,
2689               Make_Object_Declaration (Loc,
2690                 Defining_Identifier => Ent,
2691                 Constant_Present    => True,
2692                 Object_Definition   => New_Occurrence_Of (Ityp, Loc),
2693                 Expression          => Get_Known_Bound (1)),
2694               Suppress => All_Checks);
2695
2696             Low_Bound := New_Reference_To (Ent, Loc);
2697          end;
2698       end if;
2699
2700       --  Now we can safely compute the upper bound, normally
2701       --  Low_Bound + Length - 1.
2702
2703       High_Bound :=
2704         To_Ityp (
2705           Make_Op_Add (Loc,
2706             Left_Opnd  => To_Artyp (New_Copy (Low_Bound)),
2707             Right_Opnd =>
2708               Make_Op_Subtract (Loc,
2709                 Left_Opnd  => New_Copy (Aggr_Length (NN)),
2710                 Right_Opnd => Make_Integer_Literal (Loc, 1))));
2711
2712       --  Now force overflow checking on High_Bound
2713
2714       Activate_Overflow_Check (High_Bound);
2715
2716       --  Handle the exceptional case where the result is null, in which case
2717       --  case the bounds come from the last operand (so that we get the proper
2718       --  bounds if the last operand is super-flat).
2719
2720       if Result_May_Be_Null then
2721          High_Bound :=
2722            Make_Conditional_Expression (Loc,
2723              Expressions => New_List (
2724                Make_Op_Eq (Loc,
2725                  Left_Opnd  => New_Copy (Aggr_Length (NN)),
2726                  Right_Opnd => Make_Integer_Literal (Loc, 0)),
2727                Last_Opnd_High_Bound,
2728                High_Bound));
2729       end if;
2730
2731       --  Now we construct an array object with appropriate bounds
2732
2733       Ent :=
2734         Make_Defining_Identifier (Loc,
2735           Chars => New_Internal_Name ('S'));
2736
2737       --  Kludge! Kludge! ???
2738       --  If the bound is statically known to be out of range, we do not want
2739       --  to abort, we want a warning and a runtime constraint error, so we
2740       --  pretend this comes from an inlined body (otherwise a static out
2741       --  of range value would be an illegality).
2742
2743       --  This is horrible, we really must find a better way ???
2744
2745       Saved_In_Inlined_Body := In_Inlined_Body;
2746       In_Inlined_Body := True;
2747
2748       Insert_Action (Cnode,
2749         Make_Object_Declaration (Loc,
2750           Defining_Identifier => Ent,
2751           Object_Definition   =>
2752             Make_Subtype_Indication (Loc,
2753               Subtype_Mark => New_Occurrence_Of (Atyp, Loc),
2754               Constraint   =>
2755                 Make_Index_Or_Discriminant_Constraint (Loc,
2756                   Constraints => New_List (
2757                     Make_Range (Loc,
2758                       Low_Bound  => Low_Bound,
2759                       High_Bound => High_Bound))))),
2760         Suppress => All_Checks);
2761
2762       In_Inlined_Body := Saved_In_Inlined_Body;
2763
2764       --  Catch the static out of range case now
2765
2766       if Raises_Constraint_Error (High_Bound) then
2767          raise Concatenation_Error;
2768       end if;
2769
2770       --  Now we will generate the assignments to do the actual concatenation
2771
2772       Known_Non_Null_Operand_Seen := False;
2773
2774       for J in 1 .. NN loop
2775          declare
2776             Lo : constant Node_Id :=
2777                    Make_Op_Add (Loc,
2778                      Left_Opnd  => To_Artyp (New_Copy (Low_Bound)),
2779                      Right_Opnd => Aggr_Length (J - 1));
2780
2781             Hi : constant Node_Id :=
2782                    Make_Op_Add (Loc,
2783                      Left_Opnd  => To_Artyp (New_Copy (Low_Bound)),
2784                      Right_Opnd =>
2785                        Make_Op_Subtract (Loc,
2786                          Left_Opnd  => Aggr_Length (J),
2787                          Right_Opnd => Make_Integer_Literal (Loc, 1)));
2788
2789          begin
2790             --  Singleton case, simple assignment
2791
2792             if Base_Type (Etype (Operands (J))) = Ctyp then
2793                Known_Non_Null_Operand_Seen := True;
2794                Insert_Action (Cnode,
2795                  Make_Assignment_Statement (Loc,
2796                    Name       =>
2797                      Make_Indexed_Component (Loc,
2798                        Prefix      => New_Occurrence_Of (Ent, Loc),
2799                        Expressions => New_List (To_Ityp (Lo))),
2800                    Expression => Operands (J)),
2801                  Suppress => All_Checks);
2802
2803             --  Array case, slice assignment, skipped when argument is fixed
2804             --  length and known to be null.
2805
2806             elsif (not Is_Fixed_Length (J)) or else (Fixed_Length (J) > 0) then
2807                declare
2808                   Assign : Node_Id :=
2809                              Make_Assignment_Statement (Loc,
2810                                Name       =>
2811                                  Make_Slice (Loc,
2812                                    Prefix         =>
2813                                      New_Occurrence_Of (Ent, Loc),
2814                                    Discrete_Range =>
2815                                      Make_Range (Loc,
2816                                        Low_Bound  => To_Ityp (Lo),
2817                                        High_Bound => To_Ityp (Hi))),
2818                                Expression => Operands (J));
2819                begin
2820                   if Is_Fixed_Length (J) then
2821                      Known_Non_Null_Operand_Seen := True;
2822
2823                   elsif not Known_Non_Null_Operand_Seen then
2824
2825                      --  Here if operand length is not statically known and no
2826                      --  operand known to be non-null has been processed yet.
2827                      --  If operand length is 0, we do not need to perform the
2828                      --  assignment, and we must avoid the evaluation of the
2829                      --  high bound of the slice, since it may underflow if the
2830                      --  low bound is Ityp'First.
2831
2832                      Assign :=
2833                        Make_Implicit_If_Statement (Cnode,
2834                          Condition =>
2835                            Make_Op_Ne (Loc,
2836                              Left_Opnd =>
2837                                New_Occurrence_Of (Var_Length (J), Loc),
2838                              Right_Opnd => Make_Integer_Literal (Loc, 0)),
2839                          Then_Statements =>
2840                            New_List (Assign));
2841                   end if;
2842                   Insert_Action (Cnode, Assign, Suppress => All_Checks);
2843                end;
2844             end if;
2845          end;
2846       end loop;
2847
2848       --  Finally we build the result, which is a reference to the array object
2849
2850       Result := New_Reference_To (Ent, Loc);
2851
2852    <<Done>>
2853       Rewrite (Cnode, Result);
2854       Analyze_And_Resolve (Cnode, Atyp);
2855
2856    exception
2857       when Concatenation_Error =>
2858
2859          --  Kill warning generated for the declaration of the static out of
2860          --  range high bound, and instead generate a Constraint_Error with
2861          --  an appropriate specific message.
2862
2863          Kill_Dead_Code (Declaration_Node (Entity (High_Bound)));
2864          Apply_Compile_Time_Constraint_Error
2865            (N      => Cnode,
2866             Msg    => "concatenation result upper bound out of range?",
2867             Reason => CE_Range_Check_Failed);
2868          --  Set_Etype (Cnode, Atyp);
2869    end Expand_Concatenate;
2870
2871    ------------------------
2872    -- Expand_N_Allocator --
2873    ------------------------
2874
2875    procedure Expand_N_Allocator (N : Node_Id) is
2876       PtrT  : constant Entity_Id  := Etype (N);
2877       Dtyp  : constant Entity_Id  := Designated_Type (PtrT);
2878       Etyp  : constant Entity_Id  := Etype (Expression (N));
2879       Loc   : constant Source_Ptr := Sloc (N);
2880       Desig : Entity_Id;
2881       Temp  : Entity_Id;
2882       Nod   : Node_Id;
2883
2884       procedure Complete_Coextension_Finalization;
2885       --  Generate finalization calls for all nested coextensions of N. This
2886       --  routine may allocate list controllers if necessary.
2887
2888       procedure Rewrite_Coextension (N : Node_Id);
2889       --  Static coextensions have the same lifetime as the entity they
2890       --  constrain. Such occurrences can be rewritten as aliased objects
2891       --  and their unrestricted access used instead of the coextension.
2892
2893       ---------------------------------------
2894       -- Complete_Coextension_Finalization --
2895       ---------------------------------------
2896
2897       procedure Complete_Coextension_Finalization is
2898          Coext      : Node_Id;
2899          Coext_Elmt : Elmt_Id;
2900          Flist      : Node_Id;
2901          Ref        : Node_Id;
2902
2903          function Inside_A_Return_Statement (N : Node_Id) return Boolean;
2904          --  Determine whether node N is part of a return statement
2905
2906          function Needs_Initialization_Call (N : Node_Id) return Boolean;
2907          --  Determine whether node N is a subtype indicator allocator which
2908          --  acts a coextension. Such coextensions need initialization.
2909
2910          -------------------------------
2911          -- Inside_A_Return_Statement --
2912          -------------------------------
2913
2914          function Inside_A_Return_Statement (N : Node_Id) return Boolean is
2915             P : Node_Id;
2916
2917          begin
2918             P := Parent (N);
2919             while Present (P) loop
2920                if Nkind_In
2921                    (P, N_Extended_Return_Statement, N_Simple_Return_Statement)
2922                then
2923                   return True;
2924
2925                --  Stop the traversal when we reach a subprogram body
2926
2927                elsif Nkind (P) = N_Subprogram_Body then
2928                   return False;
2929                end if;
2930
2931                P := Parent (P);
2932             end loop;
2933
2934             return False;
2935          end Inside_A_Return_Statement;
2936
2937          -------------------------------
2938          -- Needs_Initialization_Call --
2939          -------------------------------
2940
2941          function Needs_Initialization_Call (N : Node_Id) return Boolean is
2942             Obj_Decl : Node_Id;
2943
2944          begin
2945             if Nkind (N) = N_Explicit_Dereference
2946               and then Nkind (Prefix (N)) = N_Identifier
2947               and then Nkind (Parent (Entity (Prefix (N)))) =
2948                          N_Object_Declaration
2949             then
2950                Obj_Decl := Parent (Entity (Prefix (N)));
2951
2952                return
2953                  Present (Expression (Obj_Decl))
2954                    and then Nkind (Expression (Obj_Decl)) = N_Allocator
2955                    and then Nkind (Expression (Expression (Obj_Decl))) /=
2956                               N_Qualified_Expression;
2957             end if;
2958
2959             return False;
2960          end Needs_Initialization_Call;
2961
2962       --  Start of processing for Complete_Coextension_Finalization
2963
2964       begin
2965          --  When a coextension root is inside a return statement, we need to
2966          --  use the finalization chain of the function's scope. This does not
2967          --  apply for controlled named access types because in those cases we
2968          --  can use the finalization chain of the type itself.
2969
2970          if Inside_A_Return_Statement (N)
2971            and then
2972              (Ekind (PtrT) = E_Anonymous_Access_Type
2973                 or else
2974                   (Ekind (PtrT) = E_Access_Type
2975                      and then No (Associated_Final_Chain (PtrT))))
2976          then
2977             declare
2978                Decl    : Node_Id;
2979                Outer_S : Entity_Id;
2980                S       : Entity_Id := Current_Scope;
2981
2982             begin
2983                while Present (S) and then S /= Standard_Standard loop
2984                   if Ekind (S) = E_Function then
2985                      Outer_S := Scope (S);
2986
2987                      --  Retrieve the declaration of the body
2988
2989                      Decl := Parent (Parent (
2990                                Corresponding_Body (Parent (Parent (S)))));
2991                      exit;
2992                   end if;
2993
2994                   S := Scope (S);
2995                end loop;
2996
2997                --  Push the scope of the function body since we are inserting
2998                --  the list before the body, but we are currently in the body
2999                --  itself. Override the finalization list of PtrT since the
3000                --  finalization context is now different.
3001
3002                Push_Scope (Outer_S);
3003                Build_Final_List (Decl, PtrT);
3004                Pop_Scope;
3005             end;
3006
3007          --  The root allocator may not be controlled, but it still needs a
3008          --  finalization list for all nested coextensions.
3009
3010          elsif No (Associated_Final_Chain (PtrT)) then
3011             Build_Final_List (N, PtrT);
3012          end if;
3013
3014          Flist :=
3015            Make_Selected_Component (Loc,
3016              Prefix =>
3017                New_Reference_To (Associated_Final_Chain (PtrT), Loc),
3018              Selector_Name =>
3019                Make_Identifier (Loc, Name_F));
3020
3021          Coext_Elmt := First_Elmt (Coextensions (N));
3022          while Present (Coext_Elmt) loop
3023             Coext := Node (Coext_Elmt);
3024
3025             --  Generate:
3026             --    typ! (coext.all)
3027
3028             if Nkind (Coext) = N_Identifier then
3029                Ref :=
3030                  Make_Unchecked_Type_Conversion (Loc,
3031                    Subtype_Mark => New_Reference_To (Etype (Coext), Loc),
3032                    Expression   =>
3033                      Make_Explicit_Dereference (Loc,
3034                        Prefix => New_Copy_Tree (Coext)));
3035             else
3036                Ref := New_Copy_Tree (Coext);
3037             end if;
3038
3039             --  No initialization call if not allowed
3040
3041             Check_Restriction (No_Default_Initialization, N);
3042
3043             if not Restriction_Active (No_Default_Initialization) then
3044
3045                --  Generate:
3046                --    initialize (Ref)
3047                --    attach_to_final_list (Ref, Flist, 2)
3048
3049                if Needs_Initialization_Call (Coext) then
3050                   Insert_Actions (N,
3051                     Make_Init_Call (
3052                       Ref         => Ref,
3053                       Typ         => Etype (Coext),
3054                       Flist_Ref   => Flist,
3055                       With_Attach => Make_Integer_Literal (Loc, Uint_2)));
3056
3057                --  Generate:
3058                --    attach_to_final_list (Ref, Flist, 2)
3059
3060                else
3061                   Insert_Action (N,
3062                     Make_Attach_Call (
3063                       Obj_Ref     => Ref,
3064                       Flist_Ref   => New_Copy_Tree (Flist),
3065                       With_Attach => Make_Integer_Literal (Loc, Uint_2)));
3066                end if;
3067             end if;
3068
3069             Next_Elmt (Coext_Elmt);
3070          end loop;
3071       end Complete_Coextension_Finalization;
3072
3073       -------------------------
3074       -- Rewrite_Coextension --
3075       -------------------------
3076
3077       procedure Rewrite_Coextension (N : Node_Id) is
3078          Temp : constant Node_Id :=
3079                   Make_Defining_Identifier (Loc,
3080                     New_Internal_Name ('C'));
3081
3082          --  Generate:
3083          --    Cnn : aliased Etyp;
3084
3085          Decl : constant Node_Id :=
3086                   Make_Object_Declaration (Loc,
3087                     Defining_Identifier => Temp,
3088                     Aliased_Present     => True,
3089                     Object_Definition   =>
3090                       New_Occurrence_Of (Etyp, Loc));
3091          Nod  : Node_Id;
3092
3093       begin
3094          if Nkind (Expression (N)) = N_Qualified_Expression then
3095             Set_Expression (Decl, Expression (Expression (N)));
3096          end if;
3097
3098          --  Find the proper insertion node for the declaration
3099
3100          Nod := Parent (N);
3101          while Present (Nod) loop
3102             exit when Nkind (Nod) in N_Statement_Other_Than_Procedure_Call
3103               or else Nkind (Nod) = N_Procedure_Call_Statement
3104               or else Nkind (Nod) in N_Declaration;
3105             Nod := Parent (Nod);
3106          end loop;
3107
3108          Insert_Before (Nod, Decl);
3109          Analyze (Decl);
3110
3111          Rewrite (N,
3112            Make_Attribute_Reference (Loc,
3113              Prefix         => New_Occurrence_Of (Temp, Loc),
3114              Attribute_Name => Name_Unrestricted_Access));
3115
3116          Analyze_And_Resolve (N, PtrT);
3117       end Rewrite_Coextension;
3118
3119    --  Start of processing for Expand_N_Allocator
3120
3121    begin
3122       --  RM E.2.3(22). We enforce that the expected type of an allocator
3123       --  shall not be a remote access-to-class-wide-limited-private type
3124
3125       --  Why is this being done at expansion time, seems clearly wrong ???
3126
3127       Validate_Remote_Access_To_Class_Wide_Type (N);
3128
3129       --  Set the Storage Pool
3130
3131       Set_Storage_Pool (N, Associated_Storage_Pool (Root_Type (PtrT)));
3132
3133       if Present (Storage_Pool (N)) then
3134          if Is_RTE (Storage_Pool (N), RE_SS_Pool) then
3135             if VM_Target = No_VM then
3136                Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));
3137             end if;
3138
3139          elsif Is_Class_Wide_Type (Etype (Storage_Pool (N))) then
3140             Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));
3141
3142          else
3143             Set_Procedure_To_Call (N,
3144               Find_Prim_Op (Etype (Storage_Pool (N)), Name_Allocate));
3145          end if;
3146       end if;
3147
3148       --  Under certain circumstances we can replace an allocator by an access
3149       --  to statically allocated storage. The conditions, as noted in AARM
3150       --  3.10 (10c) are as follows:
3151
3152       --    Size and initial value is known at compile time
3153       --    Access type is access-to-constant
3154
3155       --  The allocator is not part of a constraint on a record component,
3156       --  because in that case the inserted actions are delayed until the
3157       --  record declaration is fully analyzed, which is too late for the
3158       --  analysis of the rewritten allocator.
3159
3160       if Is_Access_Constant (PtrT)
3161         and then Nkind (Expression (N)) = N_Qualified_Expression
3162         and then Compile_Time_Known_Value (Expression (Expression (N)))
3163         and then Size_Known_At_Compile_Time (Etype (Expression
3164                                                     (Expression (N))))
3165         and then not Is_Record_Type (Current_Scope)
3166       then
3167          --  Here we can do the optimization. For the allocator
3168
3169          --    new x'(y)
3170
3171          --  We insert an object declaration
3172
3173          --    Tnn : aliased x := y;
3174
3175          --  and replace the allocator by Tnn'Unrestricted_Access. Tnn is
3176          --  marked as requiring static allocation.
3177
3178          Temp :=
3179            Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
3180
3181          Desig := Subtype_Mark (Expression (N));
3182
3183          --  If context is constrained, use constrained subtype directly,
3184          --  so that the constant is not labelled as having a nominally
3185          --  unconstrained subtype.
3186
3187          if Entity (Desig) = Base_Type (Dtyp) then
3188             Desig := New_Occurrence_Of (Dtyp, Loc);
3189          end if;
3190
3191          Insert_Action (N,
3192            Make_Object_Declaration (Loc,
3193              Defining_Identifier => Temp,
3194              Aliased_Present     => True,
3195              Constant_Present    => Is_Access_Constant (PtrT),
3196              Object_Definition   => Desig,
3197              Expression          => Expression (Expression (N))));
3198
3199          Rewrite (N,
3200            Make_Attribute_Reference (Loc,
3201              Prefix => New_Occurrence_Of (Temp, Loc),
3202              Attribute_Name => Name_Unrestricted_Access));
3203
3204          Analyze_And_Resolve (N, PtrT);
3205
3206          --  We set the variable as statically allocated, since we don't want
3207          --  it going on the stack of the current procedure!
3208
3209          Set_Is_Statically_Allocated (Temp);
3210          return;
3211       end if;
3212
3213       --  Same if the allocator is an access discriminant for a local object:
3214       --  instead of an allocator we create a local value and constrain the
3215       --  the enclosing object with the corresponding access attribute.
3216
3217       if Is_Static_Coextension (N) then
3218          Rewrite_Coextension (N);
3219          return;
3220       end if;
3221
3222       --  The current allocator creates an object which may contain nested
3223       --  coextensions. Use the current allocator's finalization list to
3224       --  generate finalization call for all nested coextensions.
3225
3226       if Is_Coextension_Root (N) then
3227          Complete_Coextension_Finalization;
3228       end if;
3229
3230       --  Handle case of qualified expression (other than optimization above)
3231
3232       if Nkind (Expression (N)) = N_Qualified_Expression then
3233          Expand_Allocator_Expression (N);
3234          return;
3235       end if;
3236
3237       --  If the allocator is for a type which requires initialization, and
3238       --  there is no initial value (i.e. operand is a subtype indication
3239       --  rather than a qualified expression), then we must generate a call to
3240       --  the initialization routine using an expressions action node:
3241
3242       --     [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
3243
3244       --  Here ptr_T is the pointer type for the allocator, and T is the
3245       --  subtype of the allocator. A special case arises if the designated
3246       --  type of the access type is a task or contains tasks. In this case
3247       --  the call to Init (Temp.all ...) is replaced by code that ensures
3248       --  that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
3249       --  for details). In addition, if the type T is a task T, then the
3250       --  first argument to Init must be converted to the task record type.
3251
3252       declare
3253          T            : constant Entity_Id := Entity (Expression (N));
3254          Init         : Entity_Id;
3255          Arg1         : Node_Id;
3256          Args         : List_Id;
3257          Decls        : List_Id;
3258          Decl         : Node_Id;
3259          Discr        : Elmt_Id;
3260          Flist        : Node_Id;
3261          Temp_Decl    : Node_Id;
3262          Temp_Type    : Entity_Id;
3263          Attach_Level : Uint;
3264
3265       begin
3266          if No_Initialization (N) then
3267             null;
3268
3269          --  Case of no initialization procedure present
3270
3271          elsif not Has_Non_Null_Base_Init_Proc (T) then
3272
3273             --  Case of simple initialization required
3274
3275             if Needs_Simple_Initialization (T) then
3276                Check_Restriction (No_Default_Initialization, N);
3277                Rewrite (Expression (N),
3278                  Make_Qualified_Expression (Loc,
3279                    Subtype_Mark => New_Occurrence_Of (T, Loc),
3280                    Expression   => Get_Simple_Init_Val (T, N)));
3281
3282                Analyze_And_Resolve (Expression (Expression (N)), T);
3283                Analyze_And_Resolve (Expression (N), T);
3284                Set_Paren_Count     (Expression (Expression (N)), 1);
3285                Expand_N_Allocator  (N);
3286
3287             --  No initialization required
3288
3289             else
3290                null;
3291             end if;
3292
3293          --  Case of initialization procedure present, must be called
3294
3295          else
3296             Check_Restriction (No_Default_Initialization, N);
3297
3298             if not Restriction_Active (No_Default_Initialization) then
3299                Init := Base_Init_Proc (T);
3300                Nod  := N;
3301                Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
3302
3303                --  Construct argument list for the initialization routine call
3304
3305                Arg1 :=
3306                  Make_Explicit_Dereference (Loc,
3307                    Prefix => New_Reference_To (Temp, Loc));
3308                Set_Assignment_OK (Arg1);
3309                Temp_Type := PtrT;
3310
3311                --  The initialization procedure expects a specific type. if the
3312                --  context is access to class wide, indicate that the object
3313                --  being allocated has the right specific type.
3314
3315                if Is_Class_Wide_Type (Dtyp) then
3316                   Arg1 := Unchecked_Convert_To (T, Arg1);
3317                end if;
3318
3319                --  If designated type is a concurrent type or if it is private
3320                --  type whose definition is a concurrent type, the first
3321                --  argument in the Init routine has to be unchecked conversion
3322                --  to the corresponding record type. If the designated type is
3323                --  a derived type, we also convert the argument to its root
3324                --  type.
3325
3326                if Is_Concurrent_Type (T) then
3327                   Arg1 :=
3328                     Unchecked_Convert_To (Corresponding_Record_Type (T), Arg1);
3329
3330                elsif Is_Private_Type (T)
3331                  and then Present (Full_View (T))
3332                  and then Is_Concurrent_Type (Full_View (T))
3333                then
3334                   Arg1 :=
3335                     Unchecked_Convert_To
3336                       (Corresponding_Record_Type (Full_View (T)), Arg1);
3337
3338                elsif Etype (First_Formal (Init)) /= Base_Type (T) then
3339                   declare
3340                      Ftyp : constant Entity_Id := Etype (First_Formal (Init));
3341                   begin
3342                      Arg1 := OK_Convert_To (Etype (Ftyp), Arg1);
3343                      Set_Etype (Arg1, Ftyp);
3344                   end;
3345                end if;
3346
3347                Args := New_List (Arg1);
3348
3349                --  For the task case, pass the Master_Id of the access type as
3350                --  the value of the _Master parameter, and _Chain as the value
3351                --  of the _Chain parameter (_Chain will be defined as part of
3352                --  the generated code for the allocator).
3353
3354                --  In Ada 2005, the context may be a function that returns an
3355                --  anonymous access type. In that case the Master_Id has been
3356                --  created when expanding the function declaration.
3357
3358                if Has_Task (T) then
3359                   if No (Master_Id (Base_Type (PtrT))) then
3360
3361                      --  If we have a non-library level task with restriction
3362                      --  No_Task_Hierarchy set, then no point in expanding.
3363
3364                      if not Is_Library_Level_Entity (T)
3365                        and then Restriction_Active (No_Task_Hierarchy)
3366                      then
3367                         return;
3368                      end if;
3369
3370                      --  The designated type was an incomplete type, and the
3371                      --  access type did not get expanded. Salvage it now.
3372
3373                      pragma Assert (Present (Parent (Base_Type (PtrT))));
3374                      Expand_N_Full_Type_Declaration
3375                        (Parent (Base_Type (PtrT)));
3376                   end if;
3377
3378                   --  If the context of the allocator is a declaration or an
3379                   --  assignment, we can generate a meaningful image for it,
3380                   --  even though subsequent assignments might remove the
3381                   --  connection between task and entity. We build this image
3382                   --  when the left-hand side is a simple variable, a simple
3383                   --  indexed assignment or a simple selected component.
3384
3385                   if Nkind (Parent (N)) = N_Assignment_Statement then
3386                      declare
3387                         Nam : constant Node_Id := Name (Parent (N));
3388
3389                      begin
3390                         if Is_Entity_Name (Nam) then
3391                            Decls :=
3392                              Build_Task_Image_Decls
3393                                (Loc,
3394                                 New_Occurrence_Of
3395                                   (Entity (Nam), Sloc (Nam)), T);
3396
3397                         elsif Nkind_In
3398                           (Nam, N_Indexed_Component, N_Selected_Component)
3399                           and then Is_Entity_Name (Prefix (Nam))
3400                         then
3401                            Decls :=
3402                              Build_Task_Image_Decls
3403                                (Loc, Nam, Etype (Prefix (Nam)));
3404                         else
3405                            Decls := Build_Task_Image_Decls (Loc, T, T);
3406                         end if;
3407                      end;
3408
3409                   elsif Nkind (Parent (N)) = N_Object_Declaration then
3410                      Decls :=
3411                        Build_Task_Image_Decls
3412                          (Loc, Defining_Identifier (Parent (N)), T);
3413
3414                   else
3415                      Decls := Build_Task_Image_Decls (Loc, T, T);
3416                   end if;
3417
3418                   Append_To (Args,
3419                     New_Reference_To
3420                       (Master_Id (Base_Type (Root_Type (PtrT))), Loc));
3421                   Append_To (Args, Make_Identifier (Loc, Name_uChain));
3422
3423                   Decl := Last (Decls);
3424                   Append_To (Args,
3425                     New_Occurrence_Of (Defining_Identifier (Decl), Loc));
3426
3427                   --  Has_Task is false, Decls not used
3428
3429                else
3430                   Decls := No_List;
3431                end if;
3432
3433                --  Add discriminants if discriminated type
3434
3435                declare
3436                   Dis : Boolean := False;
3437                   Typ : Entity_Id;
3438
3439                begin
3440                   if Has_Discriminants (T) then
3441                      Dis := True;
3442                      Typ := T;
3443
3444                   elsif Is_Private_Type (T)
3445                     and then Present (Full_View (T))
3446                     and then Has_Discriminants (Full_View (T))
3447                   then
3448                      Dis := True;
3449                      Typ := Full_View (T);
3450                   end if;
3451
3452                   if Dis then
3453
3454                      --  If the allocated object will be constrained by the
3455                      --  default values for discriminants, then build a subtype
3456                      --  with those defaults, and change the allocated subtype
3457                      --  to that. Note that this happens in fewer cases in Ada
3458                      --  2005 (AI-363).
3459
3460                      if not Is_Constrained (Typ)
3461                        and then Present (Discriminant_Default_Value
3462                                          (First_Discriminant (Typ)))
3463                        and then (Ada_Version < Ada_05
3464                                   or else
3465                                     not Has_Constrained_Partial_View (Typ))
3466                      then
3467                         Typ := Build_Default_Subtype (Typ, N);
3468                         Set_Expression (N, New_Reference_To (Typ, Loc));
3469                      end if;
3470
3471                      Discr := First_Elmt (Discriminant_Constraint (Typ));
3472                      while Present (Discr) loop
3473                         Nod := Node (Discr);
3474                         Append (New_Copy_Tree (Node (Discr)), Args);
3475
3476                         --  AI-416: when the discriminant constraint is an
3477                         --  anonymous access type make sure an accessibility
3478                         --  check is inserted if necessary (3.10.2(22.q/2))
3479
3480                         if Ada_Version >= Ada_05
3481                           and then
3482                             Ekind (Etype (Nod)) = E_Anonymous_Access_Type
3483                         then
3484                            Apply_Accessibility_Check
3485                              (Nod, Typ, Insert_Node => Nod);
3486                         end if;
3487
3488                         Next_Elmt (Discr);
3489                      end loop;
3490                   end if;
3491                end;
3492
3493                --  We set the allocator as analyzed so that when we analyze the
3494                --  expression actions node, we do not get an unwanted recursive
3495                --  expansion of the allocator expression.
3496
3497                Set_Analyzed (N, True);
3498                Nod := Relocate_Node (N);
3499
3500                --  Here is the transformation:
3501                --    input:  new T
3502                --    output: Temp : constant ptr_T := new T;
3503                --            Init (Temp.all, ...);
3504                --    <CTRL>  Attach_To_Final_List (Finalizable (Temp.all));
3505                --    <CTRL>  Initialize (Finalizable (Temp.all));
3506
3507                --  Here ptr_T is the pointer type for the allocator, and is the
3508                --  subtype of the allocator.
3509
3510                Temp_Decl :=
3511                  Make_Object_Declaration (Loc,
3512                    Defining_Identifier => Temp,
3513                    Constant_Present    => True,
3514                    Object_Definition   => New_Reference_To (Temp_Type, Loc),
3515                    Expression          => Nod);
3516
3517                Set_Assignment_OK (Temp_Decl);
3518                Insert_Action (N, Temp_Decl, Suppress => All_Checks);
3519
3520                --  If the designated type is a task type or contains tasks,
3521                --  create block to activate created tasks, and insert
3522                --  declaration for Task_Image variable ahead of call.
3523
3524                if Has_Task (T) then
3525                   declare
3526                      L   : constant List_Id := New_List;
3527                      Blk : Node_Id;
3528                   begin
3529                      Build_Task_Allocate_Block (L, Nod, Args);
3530                      Blk := Last (L);
3531                      Insert_List_Before (First (Declarations (Blk)), Decls);
3532                      Insert_Actions (N, L);
3533                   end;
3534
3535                else
3536                   Insert_Action (N,
3537                     Make_Procedure_Call_Statement (Loc,
3538                       Name                   => New_Reference_To (Init, Loc),
3539                       Parameter_Associations => Args));
3540                end if;
3541
3542                if Needs_Finalization (T) then
3543
3544                   --  Postpone the generation of a finalization call for the
3545                   --  current allocator if it acts as a coextension.
3546
3547                   if Is_Dynamic_Coextension (N) then
3548                      if No (Coextensions (N)) then
3549                         Set_Coextensions (N, New_Elmt_List);
3550                      end if;
3551
3552                      Append_Elmt (New_Copy_Tree (Arg1), Coextensions (N));
3553
3554                   else
3555                      Flist :=
3556                        Get_Allocator_Final_List (N, Base_Type (T), PtrT);
3557
3558                      --  Anonymous access types created for access parameters
3559                      --  are attached to an explicitly constructed controller,
3560                      --  which ensures that they can be finalized properly,
3561                      --  even if their deallocation might not happen. The list
3562                      --  associated with the controller is doubly-linked. For
3563                      --  other anonymous access types, the object may end up
3564                      --  on the global final list which is singly-linked.
3565                      --  Work needed for access discriminants in Ada 2005 ???
3566
3567                      if Ekind (PtrT) = E_Anonymous_Access_Type
3568                        and then
3569                          Nkind (Associated_Node_For_Itype (PtrT))
3570                      not in N_Subprogram_Specification
3571                      then
3572                         Attach_Level := Uint_1;
3573                      else
3574                         Attach_Level := Uint_2;
3575                      end if;
3576
3577                      Insert_Actions (N,
3578                        Make_Init_Call (
3579                          Ref          => New_Copy_Tree (Arg1),
3580                          Typ          => T,
3581                          Flist_Ref    => Flist,
3582                          With_Attach  => Make_Integer_Literal (Loc,
3583                                            Intval => Attach_Level)));
3584                   end if;
3585                end if;
3586
3587                Rewrite (N, New_Reference_To (Temp, Loc));
3588                Analyze_And_Resolve (N, PtrT);
3589             end if;
3590          end if;
3591       end;
3592
3593       --  Ada 2005 (AI-251): If the allocator is for a class-wide interface
3594       --  object that has been rewritten as a reference, we displace "this"
3595       --  to reference properly its secondary dispatch table.
3596
3597       if Nkind (N) = N_Identifier
3598         and then Is_Interface (Dtyp)
3599       then
3600          Displace_Allocator_Pointer (N);
3601       end if;
3602
3603    exception
3604       when RE_Not_Available =>
3605          return;
3606    end Expand_N_Allocator;
3607
3608    -----------------------
3609    -- Expand_N_And_Then --
3610    -----------------------
3611
3612    --  Expand into conditional expression if Actions present, and also deal
3613    --  with optimizing case of arguments being True or False.
3614
3615    procedure Expand_N_And_Then (N : Node_Id) is
3616       Loc     : constant Source_Ptr := Sloc (N);
3617       Typ     : constant Entity_Id  := Etype (N);
3618       Left    : constant Node_Id    := Left_Opnd (N);
3619       Right   : constant Node_Id    := Right_Opnd (N);
3620       Actlist : List_Id;
3621
3622    begin
3623       --  Deal with non-standard booleans
3624
3625       if Is_Boolean_Type (Typ) then
3626          Adjust_Condition (Left);
3627          Adjust_Condition (Right);
3628          Set_Etype (N, Standard_Boolean);
3629       end if;
3630
3631       --  Check for cases where left argument is known to be True or False
3632
3633       if Compile_Time_Known_Value (Left) then
3634
3635          --  If left argument is True, change (True and then Right) to Right.
3636          --  Any actions associated with Right will be executed unconditionally
3637          --  and can thus be inserted into the tree unconditionally.
3638
3639          if Expr_Value_E (Left) = Standard_True then
3640             if Present (Actions (N)) then
3641                Insert_Actions (N, Actions (N));
3642             end if;
3643
3644             Rewrite (N, Right);
3645
3646          --  If left argument is False, change (False and then Right) to False.
3647          --  In this case we can forget the actions associated with Right,
3648          --  since they will never be executed.
3649
3650          else pragma Assert (Expr_Value_E (Left) = Standard_False);
3651             Kill_Dead_Code (Right);
3652             Kill_Dead_Code (Actions (N));
3653             Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
3654          end if;
3655
3656          Adjust_Result_Type (N, Typ);
3657          return;
3658       end if;
3659
3660       --  If Actions are present, we expand
3661
3662       --     left and then right
3663
3664       --  into
3665
3666       --     if left then right else false end
3667
3668       --  with the actions becoming the Then_Actions of the conditional
3669       --  expression. This conditional expression is then further expanded
3670       --  (and will eventually disappear)
3671
3672       if Present (Actions (N)) then
3673          Actlist := Actions (N);
3674          Rewrite (N,
3675             Make_Conditional_Expression (Loc,
3676               Expressions => New_List (
3677                 Left,
3678                 Right,
3679                 New_Occurrence_Of (Standard_False, Loc))));
3680
3681          Set_Then_Actions (N, Actlist);
3682          Analyze_And_Resolve (N, Standard_Boolean);
3683          Adjust_Result_Type (N, Typ);
3684          return;
3685       end if;
3686
3687       --  No actions present, check for cases of right argument True/False
3688
3689       if Compile_Time_Known_Value (Right) then
3690
3691          --  Change (Left and then True) to Left. Note that we know there are
3692          --  no actions associated with the True operand, since we just checked
3693          --  for this case above.
3694
3695          if Expr_Value_E (Right) = Standard_True then
3696             Rewrite (N, Left);
3697
3698          --  Change (Left and then False) to False, making sure to preserve any
3699          --  side effects associated with the Left operand.
3700
3701          else pragma Assert (Expr_Value_E (Right) = Standard_False);
3702             Remove_Side_Effects (Left);
3703             Rewrite
3704               (N, New_Occurrence_Of (Standard_False, Loc));
3705          end if;
3706       end if;
3707
3708       Adjust_Result_Type (N, Typ);
3709    end Expand_N_And_Then;
3710
3711    -------------------------------------
3712    -- Expand_N_Conditional_Expression --
3713    -------------------------------------
3714
3715    --  Expand into expression actions if then/else actions present
3716
3717    procedure Expand_N_Conditional_Expression (N : Node_Id) is
3718       Loc    : constant Source_Ptr := Sloc (N);
3719       Cond   : constant Node_Id    := First (Expressions (N));
3720       Thenx  : constant Node_Id    := Next (Cond);
3721       Elsex  : constant Node_Id    := Next (Thenx);
3722       Typ    : constant Entity_Id  := Etype (N);
3723       Cnn    : Entity_Id;
3724       New_If : Node_Id;
3725
3726    begin
3727       --  If either then or else actions are present, then given:
3728
3729       --     if cond then then-expr else else-expr end
3730
3731       --  we insert the following sequence of actions (using Insert_Actions):
3732
3733       --      Cnn : typ;
3734       --      if cond then
3735       --         <<then actions>>
3736       --         Cnn := then-expr;
3737       --      else
3738       --         <<else actions>>
3739       --         Cnn := else-expr
3740       --      end if;
3741
3742       --  and replace the conditional expression by a reference to Cnn
3743
3744       if Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
3745          Cnn := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
3746
3747          New_If :=
3748            Make_Implicit_If_Statement (N,
3749              Condition => Relocate_Node (Cond),
3750
3751              Then_Statements => New_List (
3752                Make_Assignment_Statement (Sloc (Thenx),
3753                  Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
3754                  Expression => Relocate_Node (Thenx))),
3755
3756              Else_Statements => New_List (
3757                Make_Assignment_Statement (Sloc (Elsex),
3758                  Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
3759                  Expression => Relocate_Node (Elsex))));
3760
3761          Set_Assignment_OK (Name (First (Then_Statements (New_If))));
3762          Set_Assignment_OK (Name (First (Else_Statements (New_If))));
3763
3764          if Present (Then_Actions (N)) then
3765             Insert_List_Before
3766               (First (Then_Statements (New_If)), Then_Actions (N));
3767          end if;
3768
3769          if Present (Else_Actions (N)) then
3770             Insert_List_Before
3771               (First (Else_Statements (New_If)), Else_Actions (N));
3772          end if;
3773
3774          Rewrite (N, New_Occurrence_Of (Cnn, Loc));
3775
3776          Insert_Action (N,
3777            Make_Object_Declaration (Loc,
3778              Defining_Identifier => Cnn,
3779              Object_Definition   => New_Occurrence_Of (Typ, Loc)));
3780
3781          Insert_Action (N, New_If);
3782          Analyze_And_Resolve (N, Typ);
3783       end if;
3784    end Expand_N_Conditional_Expression;
3785
3786    -----------------------------------
3787    -- Expand_N_Explicit_Dereference --
3788    -----------------------------------
3789
3790    procedure Expand_N_Explicit_Dereference (N : Node_Id) is
3791    begin
3792       --  Insert explicit dereference call for the checked storage pool case
3793
3794       Insert_Dereference_Action (Prefix (N));
3795    end Expand_N_Explicit_Dereference;
3796
3797    -----------------
3798    -- Expand_N_In --
3799    -----------------
3800
3801    procedure Expand_N_In (N : Node_Id) is
3802       Loc    : constant Source_Ptr := Sloc (N);
3803       Rtyp   : constant Entity_Id  := Etype (N);
3804       Lop    : constant Node_Id    := Left_Opnd (N);
3805       Rop    : constant Node_Id    := Right_Opnd (N);
3806       Static : constant Boolean    := Is_OK_Static_Expression (N);
3807
3808       procedure Substitute_Valid_Check;
3809       --  Replaces node N by Lop'Valid. This is done when we have an explicit
3810       --  test for the left operand being in range of its subtype.
3811
3812       ----------------------------
3813       -- Substitute_Valid_Check --
3814       ----------------------------
3815
3816       procedure Substitute_Valid_Check is
3817       begin
3818          Rewrite (N,
3819            Make_Attribute_Reference (Loc,
3820              Prefix         => Relocate_Node (Lop),
3821              Attribute_Name => Name_Valid));
3822
3823          Analyze_And_Resolve (N, Rtyp);
3824
3825          Error_Msg_N ("?explicit membership test may be optimized away", N);
3826          Error_Msg_N ("\?use ''Valid attribute instead", N);
3827          return;
3828       end Substitute_Valid_Check;
3829
3830    --  Start of processing for Expand_N_In
3831
3832    begin
3833       --  Check case of explicit test for an expression in range of its
3834       --  subtype. This is suspicious usage and we replace it with a 'Valid
3835       --  test and give a warning.
3836
3837       if Is_Scalar_Type (Etype (Lop))
3838         and then Nkind (Rop) in N_Has_Entity
3839         and then Etype (Lop) = Entity (Rop)
3840         and then Comes_From_Source (N)
3841         and then VM_Target = No_VM
3842       then
3843          Substitute_Valid_Check;
3844          return;
3845       end if;
3846
3847       --  Do validity check on operands
3848
3849       if Validity_Checks_On and Validity_Check_Operands then
3850          Ensure_Valid (Left_Opnd (N));
3851          Validity_Check_Range (Right_Opnd (N));
3852       end if;
3853
3854       --  Case of explicit range
3855
3856       if Nkind (Rop) = N_Range then
3857          declare
3858             Lo : constant Node_Id := Low_Bound (Rop);
3859             Hi : constant Node_Id := High_Bound (Rop);
3860
3861             Ltyp : constant Entity_Id := Etype (Lop);
3862
3863             Lo_Orig : constant Node_Id := Original_Node (Lo);
3864             Hi_Orig : constant Node_Id := Original_Node (Hi);
3865
3866             Lcheck : Compare_Result;
3867             Ucheck : Compare_Result;
3868
3869             Warn1 : constant Boolean :=
3870                       Constant_Condition_Warnings
3871                         and then Comes_From_Source (N)
3872                         and then not In_Instance;
3873             --  This must be true for any of the optimization warnings, we
3874             --  clearly want to give them only for source with the flag on.
3875             --  We also skip these warnings in an instance since it may be
3876             --  the case that different instantiations have different ranges.
3877
3878             Warn2 : constant Boolean :=
3879                       Warn1
3880                         and then Nkind (Original_Node (Rop)) = N_Range
3881                         and then Is_Integer_Type (Etype (Lo));
3882             --  For the case where only one bound warning is elided, we also
3883             --  insist on an explicit range and an integer type. The reason is
3884             --  that the use of enumeration ranges including an end point is
3885             --  common, as is the use of a subtype name, one of whose bounds
3886             --  is the same as the type of the expression.
3887
3888          begin
3889             --  If test is explicit x'first .. x'last, replace by valid check
3890
3891             if Is_Scalar_Type (Ltyp)
3892               and then Nkind (Lo_Orig) = N_Attribute_Reference
3893               and then Attribute_Name (Lo_Orig) = Name_First
3894               and then Nkind (Prefix (Lo_Orig)) in N_Has_Entity
3895               and then Entity (Prefix (Lo_Orig)) = Ltyp
3896               and then Nkind (Hi_Orig) = N_Attribute_Reference
3897               and then Attribute_Name (Hi_Orig) = Name_Last
3898               and then Nkind (Prefix (Hi_Orig)) in N_Has_Entity
3899               and then Entity (Prefix (Hi_Orig)) = Ltyp
3900               and then Comes_From_Source (N)
3901               and then VM_Target = No_VM
3902             then
3903                Substitute_Valid_Check;
3904                return;
3905             end if;
3906
3907             --  If bounds of type are known at compile time, and the end points
3908             --  are known at compile time and identical, this is another case
3909             --  for substituting a valid test. We only do this for discrete
3910             --  types, since it won't arise in practice for float types.
3911
3912             if Comes_From_Source (N)
3913               and then Is_Discrete_Type (Ltyp)
3914               and then Compile_Time_Known_Value (Type_High_Bound (Ltyp))
3915               and then Compile_Time_Known_Value (Type_Low_Bound  (Ltyp))
3916               and then Compile_Time_Known_Value (Lo)
3917               and then Compile_Time_Known_Value (Hi)
3918               and then Expr_Value (Type_High_Bound (Ltyp)) = Expr_Value (Hi)
3919               and then Expr_Value (Type_Low_Bound  (Ltyp)) = Expr_Value (Lo)
3920
3921                --  Kill warnings in instances, since they may be cases where we
3922                --  have a test in the generic that makes sense with some types
3923                --  and not with other types.
3924
3925               and then not In_Instance
3926             then
3927                Substitute_Valid_Check;
3928                return;
3929             end if;
3930
3931             --  If we have an explicit range, do a bit of optimization based
3932             --  on range analysis (we may be able to kill one or both checks).
3933
3934             Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => False);
3935             Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => False);
3936
3937             --  If either check is known to fail, replace result by False since
3938             --  the other check does not matter. Preserve the static flag for
3939             --  legality checks, because we are constant-folding beyond RM 4.9.
3940
3941             if Lcheck = LT or else Ucheck = GT then
3942                if Warn1 then
3943                   Error_Msg_N ("?range test optimized away", N);
3944                   Error_Msg_N ("\?value is known to be out of range", N);
3945                end if;
3946
3947                Rewrite (N,
3948                  New_Reference_To (Standard_False, Loc));
3949                Analyze_And_Resolve (N, Rtyp);
3950                Set_Is_Static_Expression (N, Static);
3951
3952                return;
3953
3954             --  If both checks are known to succeed, replace result by True,
3955             --  since we know we are in range.
3956
3957             elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
3958                if Warn1 then
3959                   Error_Msg_N ("?range test optimized away", N);
3960                   Error_Msg_N ("\?value is known to be in range", N);
3961                end if;
3962
3963                Rewrite (N,
3964                  New_Reference_To (Standard_True, Loc));
3965                Analyze_And_Resolve (N, Rtyp);
3966                Set_Is_Static_Expression (N, Static);
3967
3968                return;
3969
3970             --  If lower bound check succeeds and upper bound check is not
3971             --  known to succeed or fail, then replace the range check with
3972             --  a comparison against the upper bound.
3973
3974             elsif Lcheck in Compare_GE then
3975                if Warn2 and then not In_Instance then
3976                   Error_Msg_N ("?lower bound test optimized away", Lo);
3977                   Error_Msg_N ("\?value is known to be in range", Lo);
3978                end if;
3979
3980                Rewrite (N,
3981                  Make_Op_Le (Loc,
3982                    Left_Opnd  => Lop,
3983                    Right_Opnd => High_Bound (Rop)));
3984                Analyze_And_Resolve (N, Rtyp);
3985
3986                return;
3987
3988             --  If upper bound check succeeds and lower bound check is not
3989             --  known to succeed or fail, then replace the range check with
3990             --  a comparison against the lower bound.
3991
3992             elsif Ucheck in Compare_LE then
3993                if Warn2 and then not In_Instance then
3994                   Error_Msg_N ("?upper bound test optimized away", Hi);
3995                   Error_Msg_N ("\?value is known to be in range", Hi);
3996                end if;
3997
3998                Rewrite (N,
3999                  Make_Op_Ge (Loc,
4000                    Left_Opnd  => Lop,
4001                    Right_Opnd => Low_Bound (Rop)));
4002                Analyze_And_Resolve (N, Rtyp);
4003
4004                return;
4005             end if;
4006
4007             --  We couldn't optimize away the range check, but there is one
4008             --  more issue. If we are checking constant conditionals, then we
4009             --  see if we can determine the outcome assuming everything is
4010             --  valid, and if so give an appropriate warning.
4011
4012             if Warn1 and then not Assume_No_Invalid_Values then
4013                Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => True);
4014                Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => True);
4015
4016                --  Result is out of range for valid value
4017
4018                if Lcheck = LT or else Ucheck = GT then
4019                   Error_Msg_N
4020                     ("?value can only be in range if it is invalid", N);
4021
4022                --  Result is in range for valid value
4023
4024                elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
4025                   Error_Msg_N
4026                     ("?value can only be out of range if it is invalid", N);
4027
4028                --  Lower bound check succeeds if value is valid
4029
4030                elsif Warn2 and then Lcheck in Compare_GE then
4031                   Error_Msg_N
4032                     ("?lower bound check only fails if it is invalid", Lo);
4033
4034                --  Upper bound  check succeeds if value is valid
4035
4036                elsif Warn2 and then Ucheck in Compare_LE then
4037                   Error_Msg_N
4038                     ("?upper bound check only fails for invalid values", Hi);
4039                end if;
4040             end if;
4041          end;
4042
4043          --  For all other cases of an explicit range, nothing to be done
4044
4045          return;
4046
4047       --  Here right operand is a subtype mark
4048
4049       else
4050          declare
4051             Typ    : Entity_Id        := Etype (Rop);
4052             Is_Acc : constant Boolean := Is_Access_Type (Typ);
4053             Obj    : Node_Id          := Lop;
4054             Cond   : Node_Id          := Empty;
4055
4056          begin
4057             Remove_Side_Effects (Obj);
4058
4059             --  For tagged type, do tagged membership operation
4060
4061             if Is_Tagged_Type (Typ) then
4062
4063                --  No expansion will be performed when VM_Target, as the VM
4064                --  back-ends will handle the membership tests directly (tags
4065                --  are not explicitly represented in Java objects, so the
4066                --  normal tagged membership expansion is not what we want).
4067
4068                if VM_Target = No_VM then
4069                   Rewrite (N, Tagged_Membership (N));
4070                   Analyze_And_Resolve (N, Rtyp);
4071                end if;
4072
4073                return;
4074
4075             --  If type is scalar type, rewrite as x in t'first .. t'last.
4076             --  This reason we do this is that the bounds may have the wrong
4077             --  type if they come from the original type definition. Also this
4078             --  way we get all the processing above for an explicit range.
4079
4080             elsif Is_Scalar_Type (Typ) then
4081                Rewrite (Rop,
4082                  Make_Range (Loc,
4083                    Low_Bound =>
4084                      Make_Attribute_Reference (Loc,
4085                        Attribute_Name => Name_First,
4086                        Prefix => New_Reference_To (Typ, Loc)),
4087
4088                    High_Bound =>
4089                      Make_Attribute_Reference (Loc,
4090                        Attribute_Name => Name_Last,
4091                        Prefix => New_Reference_To (Typ, Loc))));
4092                Analyze_And_Resolve (N, Rtyp);
4093                return;
4094
4095             --  Ada 2005 (AI-216): Program_Error is raised when evaluating
4096             --  a membership test if the subtype mark denotes a constrained
4097             --  Unchecked_Union subtype and the expression lacks inferable
4098             --  discriminants.
4099
4100             elsif Is_Unchecked_Union (Base_Type (Typ))
4101               and then Is_Constrained (Typ)
4102               and then not Has_Inferable_Discriminants (Lop)
4103             then
4104                Insert_Action (N,
4105                  Make_Raise_Program_Error (Loc,
4106                    Reason => PE_Unchecked_Union_Restriction));
4107
4108                --  Prevent Gigi from generating incorrect code by rewriting
4109                --  the test as a standard False.
4110
4111                Rewrite (N,
4112                  New_Occurrence_Of (Standard_False, Loc));
4113
4114                return;
4115             end if;
4116
4117             --  Here we have a non-scalar type
4118
4119             if Is_Acc then
4120                Typ := Designated_Type (Typ);
4121             end if;
4122
4123             if not Is_Constrained (Typ) then
4124                Rewrite (N,
4125                  New_Reference_To (Standard_True, Loc));
4126                Analyze_And_Resolve (N, Rtyp);
4127
4128             --  For the constrained array case, we have to check the subscripts
4129             --  for an exact match if the lengths are non-zero (the lengths
4130             --  must match in any case).
4131
4132             elsif Is_Array_Type (Typ) then
4133
4134                Check_Subscripts : declare
4135                   function Construct_Attribute_Reference
4136                     (E   : Node_Id;
4137                      Nam : Name_Id;
4138                      Dim : Nat) return Node_Id;
4139                   --  Build attribute reference E'Nam(Dim)
4140
4141                   -----------------------------------
4142                   -- Construct_Attribute_Reference --
4143                   -----------------------------------
4144
4145                   function Construct_Attribute_Reference
4146                     (E   : Node_Id;
4147                      Nam : Name_Id;
4148                      Dim : Nat) return Node_Id
4149                   is
4150                   begin
4151                      return
4152                        Make_Attribute_Reference (Loc,
4153                          Prefix => E,
4154                          Attribute_Name => Nam,
4155                          Expressions => New_List (
4156                            Make_Integer_Literal (Loc, Dim)));
4157                   end Construct_Attribute_Reference;
4158
4159                --  Start processing for Check_Subscripts
4160
4161                begin
4162                   for J in 1 .. Number_Dimensions (Typ) loop
4163                      Evolve_And_Then (Cond,
4164                        Make_Op_Eq (Loc,
4165                          Left_Opnd  =>
4166                            Construct_Attribute_Reference
4167                              (Duplicate_Subexpr_No_Checks (Obj),
4168                               Name_First, J),
4169                          Right_Opnd =>
4170                            Construct_Attribute_Reference
4171                              (New_Occurrence_Of (Typ, Loc), Name_First, J)));
4172
4173                      Evolve_And_Then (Cond,
4174                        Make_Op_Eq (Loc,
4175                          Left_Opnd  =>
4176                            Construct_Attribute_Reference
4177                              (Duplicate_Subexpr_No_Checks (Obj),
4178                               Name_Last, J),
4179                          Right_Opnd =>
4180                            Construct_Attribute_Reference
4181                              (New_Occurrence_Of (Typ, Loc), Name_Last, J)));
4182                   end loop;
4183
4184                   if Is_Acc then
4185                      Cond :=
4186                        Make_Or_Else (Loc,
4187                          Left_Opnd =>
4188                            Make_Op_Eq (Loc,
4189                              Left_Opnd  => Obj,
4190                              Right_Opnd => Make_Null (Loc)),
4191                          Right_Opnd => Cond);
4192                   end if;
4193
4194                   Rewrite (N, Cond);
4195                   Analyze_And_Resolve (N, Rtyp);
4196                end Check_Subscripts;
4197
4198             --  These are the cases where constraint checks may be required,
4199             --  e.g. records with possible discriminants
4200
4201             else
4202                --  Expand the test into a series of discriminant comparisons.
4203                --  The expression that is built is the negation of the one that
4204                --  is used for checking discriminant constraints.
4205
4206                Obj := Relocate_Node (Left_Opnd (N));
4207
4208                if Has_Discriminants (Typ) then
4209                   Cond := Make_Op_Not (Loc,
4210                     Right_Opnd => Build_Discriminant_Checks (Obj, Typ));
4211
4212                   if Is_Acc then
4213                      Cond := Make_Or_Else (Loc,
4214                        Left_Opnd =>
4215                          Make_Op_Eq (Loc,
4216                            Left_Opnd  => Obj,
4217                            Right_Opnd => Make_Null (Loc)),
4218                        Right_Opnd => Cond);
4219                   end if;
4220
4221                else
4222                   Cond := New_Occurrence_Of (Standard_True, Loc);
4223                end if;
4224
4225                Rewrite (N, Cond);
4226                Analyze_And_Resolve (N, Rtyp);
4227             end if;
4228          end;
4229       end if;
4230    end Expand_N_In;
4231
4232    --------------------------------
4233    -- Expand_N_Indexed_Component --
4234    --------------------------------
4235
4236    procedure Expand_N_Indexed_Component (N : Node_Id) is
4237       Loc : constant Source_Ptr := Sloc (N);
4238       Typ : constant Entity_Id  := Etype (N);
4239       P   : constant Node_Id    := Prefix (N);
4240       T   : constant Entity_Id  := Etype (P);
4241
4242    begin
4243       --  A special optimization, if we have an indexed component that is
4244       --  selecting from a slice, then we can eliminate the slice, since, for
4245       --  example, x (i .. j)(k) is identical to x(k). The only difference is
4246       --  the range check required by the slice. The range check for the slice
4247       --  itself has already been generated. The range check for the
4248       --  subscripting operation is ensured by converting the subject to
4249       --  the subtype of the slice.
4250
4251       --  This optimization not only generates better code, avoiding slice
4252       --  messing especially in the packed case, but more importantly bypasses
4253       --  some problems in handling this peculiar case, for example, the issue
4254       --  of dealing specially with object renamings.
4255
4256       if Nkind (P) = N_Slice then
4257          Rewrite (N,
4258            Make_Indexed_Component (Loc,
4259              Prefix => Prefix (P),
4260              Expressions => New_List (
4261                Convert_To
4262                  (Etype (First_Index (Etype (P))),
4263                   First (Expressions (N))))));
4264          Analyze_And_Resolve (N, Typ);
4265          return;
4266       end if;
4267
4268       --  Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
4269       --  function, then additional actuals must be passed.
4270
4271       if Ada_Version >= Ada_05
4272         and then Is_Build_In_Place_Function_Call (P)
4273       then
4274          Make_Build_In_Place_Call_In_Anonymous_Context (P);
4275       end if;
4276
4277       --  If the prefix is an access type, then we unconditionally rewrite if
4278       --  as an explicit deference. This simplifies processing for several
4279       --  cases, including packed array cases and certain cases in which checks
4280       --  must be generated. We used to try to do this only when it was
4281       --  necessary, but it cleans up the code to do it all the time.
4282
4283       if Is_Access_Type (T) then
4284          Insert_Explicit_Dereference (P);
4285          Analyze_And_Resolve (P, Designated_Type (T));
4286       end if;
4287
4288       --  Generate index and validity checks
4289
4290       Generate_Index_Checks (N);
4291
4292       if Validity_Checks_On and then Validity_Check_Subscripts then
4293          Apply_Subscript_Validity_Checks (N);
4294       end if;
4295
4296       --  All done for the non-packed case
4297
4298       if not Is_Packed (Etype (Prefix (N))) then
4299          return;
4300       end if;
4301
4302       --  For packed arrays that are not bit-packed (i.e. the case of an array
4303       --  with one or more index types with a non-contiguous enumeration type),
4304       --  we can always use the normal packed element get circuit.
4305
4306       if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
4307          Expand_Packed_Element_Reference (N);
4308          return;
4309       end if;
4310
4311       --  For a reference to a component of a bit packed array, we have to
4312       --  convert it to a reference to the corresponding Packed_Array_Type.
4313       --  We only want to do this for simple references, and not for:
4314
4315       --    Left side of assignment, or prefix of left side of assignment, or
4316       --    prefix of the prefix, to handle packed arrays of packed arrays,
4317       --      This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
4318
4319       --    Renaming objects in renaming associations
4320       --      This case is handled when a use of the renamed variable occurs
4321
4322       --    Actual parameters for a procedure call
4323       --      This case is handled in Exp_Ch6.Expand_Actuals
4324
4325       --    The second expression in a 'Read attribute reference
4326
4327       --    The prefix of an address or size attribute reference
4328
4329       --  The following circuit detects these exceptions
4330
4331       declare
4332          Child : Node_Id := N;
4333          Parnt : Node_Id := Parent (N);
4334
4335       begin
4336          loop
4337             if Nkind (Parnt) = N_Unchecked_Expression then
4338                null;
4339
4340             elsif Nkind_In (Parnt, N_Object_Renaming_Declaration,
4341                                    N_Procedure_Call_Statement)
4342               or else (Nkind (Parnt) = N_Parameter_Association
4343                         and then
4344                           Nkind (Parent (Parnt)) =  N_Procedure_Call_Statement)
4345             then
4346                return;
4347
4348             elsif Nkind (Parnt) = N_Attribute_Reference
4349               and then (Attribute_Name (Parnt) = Name_Address
4350                          or else
4351                         Attribute_Name (Parnt) = Name_Size)
4352               and then Prefix (Parnt) = Child
4353             then
4354                return;
4355
4356             elsif Nkind (Parnt) = N_Assignment_Statement
4357               and then Name (Parnt) = Child
4358             then
4359                return;
4360
4361             --  If the expression is an index of an indexed component, it must
4362             --  be expanded regardless of context.
4363
4364             elsif Nkind (Parnt) = N_Indexed_Component
4365               and then Child /= Prefix (Parnt)
4366             then
4367                Expand_Packed_Element_Reference (N);
4368                return;
4369
4370             elsif Nkind (Parent (Parnt)) = N_Assignment_Statement
4371               and then Name (Parent (Parnt)) = Parnt
4372             then
4373                return;
4374
4375             elsif Nkind (Parnt) = N_Attribute_Reference
4376               and then Attribute_Name (Parnt) = Name_Read
4377               and then Next (First (Expressions (Parnt))) = Child
4378             then
4379                return;
4380
4381             elsif Nkind_In (Parnt, N_Indexed_Component, N_Selected_Component)
4382                and then Prefix (Parnt) = Child
4383             then
4384                null;
4385
4386             else
4387                Expand_Packed_Element_Reference (N);
4388                return;
4389             end if;
4390
4391             --  Keep looking up tree for unchecked expression, or if we are the
4392             --  prefix of a possible assignment left side.
4393
4394             Child := Parnt;
4395             Parnt := Parent (Child);
4396          end loop;
4397       end;
4398    end Expand_N_Indexed_Component;
4399
4400    ---------------------
4401    -- Expand_N_Not_In --
4402    ---------------------
4403
4404    --  Replace a not in b by not (a in b) so that the expansions for (a in b)
4405    --  can be done. This avoids needing to duplicate this expansion code.
4406
4407    procedure Expand_N_Not_In (N : Node_Id) is
4408       Loc : constant Source_Ptr := Sloc (N);
4409       Typ : constant Entity_Id  := Etype (N);
4410       Cfs : constant Boolean    := Comes_From_Source (N);
4411
4412    begin
4413       Rewrite (N,
4414         Make_Op_Not (Loc,
4415           Right_Opnd =>
4416             Make_In (Loc,
4417               Left_Opnd  => Left_Opnd (N),
4418               Right_Opnd => Right_Opnd (N))));
4419
4420       --  We want this to appear as coming from source if original does (see
4421       --  transformations in Expand_N_In).
4422
4423       Set_Comes_From_Source (N, Cfs);
4424       Set_Comes_From_Source (Right_Opnd (N), Cfs);
4425
4426       --  Now analyze transformed node
4427
4428       Analyze_And_Resolve (N, Typ);
4429    end Expand_N_Not_In;
4430
4431    -------------------
4432    -- Expand_N_Null --
4433    -------------------
4434
4435    --  The only replacement required is for the case of a null of type that is
4436    --  an access to protected subprogram. We represent such access values as a
4437    --  record, and so we must replace the occurrence of null by the equivalent
4438    --  record (with a null address and a null pointer in it), so that the
4439    --  backend creates the proper value.
4440
4441    procedure Expand_N_Null (N : Node_Id) is
4442       Loc : constant Source_Ptr := Sloc (N);
4443       Typ : constant Entity_Id  := Etype (N);
4444       Agg : Node_Id;
4445
4446    begin
4447       if Is_Access_Protected_Subprogram_Type (Typ) then
4448          Agg :=
4449            Make_Aggregate (Loc,
4450              Expressions => New_List (
4451                New_Occurrence_Of (RTE (RE_Null_Address), Loc),
4452                Make_Null (Loc)));
4453
4454          Rewrite (N, Agg);
4455          Analyze_And_Resolve (N, Equivalent_Type (Typ));
4456
4457          --  For subsequent semantic analysis, the node must retain its type.
4458          --  Gigi in any case replaces this type by the corresponding record
4459          --  type before processing the node.
4460
4461          Set_Etype (N, Typ);
4462       end if;
4463
4464    exception
4465       when RE_Not_Available =>
4466          return;
4467    end Expand_N_Null;
4468
4469    ---------------------
4470    -- Expand_N_Op_Abs --
4471    ---------------------
4472
4473    procedure Expand_N_Op_Abs (N : Node_Id) is
4474       Loc  : constant Source_Ptr := Sloc (N);
4475       Expr : constant Node_Id := Right_Opnd (N);
4476
4477    begin
4478       Unary_Op_Validity_Checks (N);
4479
4480       --  Deal with software overflow checking
4481
4482       if not Backend_Overflow_Checks_On_Target
4483          and then Is_Signed_Integer_Type (Etype (N))
4484          and then Do_Overflow_Check (N)
4485       then
4486          --  The only case to worry about is when the argument is equal to the
4487          --  largest negative number, so what we do is to insert the check:
4488
4489          --     [constraint_error when Expr = typ'Base'First]
4490
4491          --  with the usual Duplicate_Subexpr use coding for expr
4492
4493          Insert_Action (N,
4494            Make_Raise_Constraint_Error (Loc,
4495              Condition =>
4496                Make_Op_Eq (Loc,
4497                  Left_Opnd  => Duplicate_Subexpr (Expr),
4498                  Right_Opnd =>
4499                    Make_Attribute_Reference (Loc,
4500                      Prefix =>
4501                        New_Occurrence_Of (Base_Type (Etype (Expr)), Loc),
4502                      Attribute_Name => Name_First)),
4503              Reason => CE_Overflow_Check_Failed));
4504       end if;
4505
4506       --  Vax floating-point types case
4507
4508       if Vax_Float (Etype (N)) then
4509          Expand_Vax_Arith (N);
4510       end if;
4511    end Expand_N_Op_Abs;
4512
4513    ---------------------
4514    -- Expand_N_Op_Add --
4515    ---------------------
4516
4517    procedure Expand_N_Op_Add (N : Node_Id) is
4518       Typ : constant Entity_Id := Etype (N);
4519
4520    begin
4521       Binary_Op_Validity_Checks (N);
4522
4523       --  N + 0 = 0 + N = N for integer types
4524
4525       if Is_Integer_Type (Typ) then
4526          if Compile_Time_Known_Value (Right_Opnd (N))
4527            and then Expr_Value (Right_Opnd (N)) = Uint_0
4528          then
4529             Rewrite (N, Left_Opnd (N));
4530             return;
4531
4532          elsif Compile_Time_Known_Value (Left_Opnd (N))
4533            and then Expr_Value (Left_Opnd (N)) = Uint_0
4534          then
4535             Rewrite (N, Right_Opnd (N));
4536             return;
4537          end if;
4538       end if;
4539
4540       --  Arithmetic overflow checks for signed integer/fixed point types
4541
4542       if Is_Signed_Integer_Type (Typ)
4543         or else Is_Fixed_Point_Type (Typ)
4544       then
4545          Apply_Arithmetic_Overflow_Check (N);
4546          return;
4547
4548       --  Vax floating-point types case
4549
4550       elsif Vax_Float (Typ) then
4551          Expand_Vax_Arith (N);
4552       end if;
4553    end Expand_N_Op_Add;
4554
4555    ---------------------
4556    -- Expand_N_Op_And --
4557    ---------------------
4558
4559    procedure Expand_N_Op_And (N : Node_Id) is
4560       Typ : constant Entity_Id := Etype (N);
4561
4562    begin
4563       Binary_Op_Validity_Checks (N);
4564
4565       if Is_Array_Type (Etype (N)) then
4566          Expand_Boolean_Operator (N);
4567
4568       elsif Is_Boolean_Type (Etype (N)) then
4569          Adjust_Condition (Left_Opnd (N));
4570          Adjust_Condition (Right_Opnd (N));
4571          Set_Etype (N, Standard_Boolean);
4572          Adjust_Result_Type (N, Typ);
4573       end if;
4574    end Expand_N_Op_And;
4575
4576    ------------------------
4577    -- Expand_N_Op_Concat --
4578    ------------------------
4579
4580    procedure Expand_N_Op_Concat (N : Node_Id) is
4581       Opnds : List_Id;
4582       --  List of operands to be concatenated
4583
4584       Cnode : Node_Id;
4585       --  Node which is to be replaced by the result of concatenating the nodes
4586       --  in the list Opnds.
4587
4588    begin
4589       --  Ensure validity of both operands
4590
4591       Binary_Op_Validity_Checks (N);
4592
4593       --  If we are the left operand of a concatenation higher up the tree,
4594       --  then do nothing for now, since we want to deal with a series of
4595       --  concatenations as a unit.
4596
4597       if Nkind (Parent (N)) = N_Op_Concat
4598         and then N = Left_Opnd (Parent (N))
4599       then
4600          return;
4601       end if;
4602
4603       --  We get here with a concatenation whose left operand may be a
4604       --  concatenation itself with a consistent type. We need to process
4605       --  these concatenation operands from left to right, which means
4606       --  from the deepest node in the tree to the highest node.
4607
4608       Cnode := N;
4609       while Nkind (Left_Opnd (Cnode)) = N_Op_Concat loop
4610          Cnode := Left_Opnd (Cnode);
4611       end loop;
4612
4613       --  Now Opnd is the deepest Opnd, and its parents are the concatenation
4614       --  nodes above, so now we process bottom up, doing the operations. We
4615       --  gather a string that is as long as possible up to five operands
4616
4617       --  The outer loop runs more than once if more than one concatenation
4618       --  type is involved.
4619
4620       Outer : loop
4621          Opnds := New_List (Left_Opnd (Cnode), Right_Opnd (Cnode));
4622          Set_Parent (Opnds, N);
4623
4624          --  The inner loop gathers concatenation operands
4625
4626          Inner : while Cnode /= N
4627                    and then Base_Type (Etype (Cnode)) =
4628                             Base_Type (Etype (Parent (Cnode)))
4629          loop
4630             Cnode := Parent (Cnode);
4631             Append (Right_Opnd (Cnode), Opnds);
4632          end loop Inner;
4633
4634          Expand_Concatenate (Cnode, Opnds);
4635
4636          exit Outer when Cnode = N;
4637          Cnode := Parent (Cnode);
4638       end loop Outer;
4639    end Expand_N_Op_Concat;
4640
4641    ------------------------
4642    -- Expand_N_Op_Divide --
4643    ------------------------
4644
4645    procedure Expand_N_Op_Divide (N : Node_Id) is
4646       Loc   : constant Source_Ptr := Sloc (N);
4647       Lopnd : constant Node_Id    := Left_Opnd (N);
4648       Ropnd : constant Node_Id    := Right_Opnd (N);
4649       Ltyp  : constant Entity_Id  := Etype (Lopnd);
4650       Rtyp  : constant Entity_Id  := Etype (Ropnd);
4651       Typ   : Entity_Id           := Etype (N);
4652       Rknow : constant Boolean    := Is_Integer_Type (Typ)
4653                                        and then
4654                                          Compile_Time_Known_Value (Ropnd);
4655       Rval  : Uint;
4656
4657    begin
4658       Binary_Op_Validity_Checks (N);
4659
4660       if Rknow then
4661          Rval := Expr_Value (Ropnd);
4662       end if;
4663
4664       --  N / 1 = N for integer types
4665
4666       if Rknow and then Rval = Uint_1 then
4667          Rewrite (N, Lopnd);
4668          return;
4669       end if;
4670
4671       --  Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
4672       --  Is_Power_Of_2_For_Shift is set means that we know that our left
4673       --  operand is an unsigned integer, as required for this to work.
4674
4675       if Nkind (Ropnd) = N_Op_Expon
4676         and then Is_Power_Of_2_For_Shift (Ropnd)
4677
4678       --  We cannot do this transformation in configurable run time mode if we
4679       --  have 64-bit --  integers and long shifts are not available.
4680
4681         and then
4682           (Esize (Ltyp) <= 32
4683              or else Support_Long_Shifts_On_Target)
4684       then
4685          Rewrite (N,
4686            Make_Op_Shift_Right (Loc,
4687              Left_Opnd  => Lopnd,
4688              Right_Opnd =>
4689                Convert_To (Standard_Natural, Right_Opnd (Ropnd))));
4690          Analyze_And_Resolve (N, Typ);
4691          return;
4692       end if;
4693
4694       --  Do required fixup of universal fixed operation
4695
4696       if Typ = Universal_Fixed then
4697          Fixup_Universal_Fixed_Operation (N);
4698          Typ := Etype (N);
4699       end if;
4700
4701       --  Divisions with fixed-point results
4702
4703       if Is_Fixed_Point_Type (Typ) then
4704
4705          --  No special processing if Treat_Fixed_As_Integer is set, since
4706          --  from a semantic point of view such operations are simply integer
4707          --  operations and will be treated that way.
4708
4709          if not Treat_Fixed_As_Integer (N) then
4710             if Is_Integer_Type (Rtyp) then
4711                Expand_Divide_Fixed_By_Integer_Giving_Fixed (N);
4712             else
4713                Expand_Divide_Fixed_By_Fixed_Giving_Fixed (N);
4714             end if;
4715          end if;
4716
4717       --  Other cases of division of fixed-point operands. Again we exclude the
4718       --  case where Treat_Fixed_As_Integer is set.
4719
4720       elsif (Is_Fixed_Point_Type (Ltyp) or else
4721              Is_Fixed_Point_Type (Rtyp))
4722         and then not Treat_Fixed_As_Integer (N)
4723       then
4724          if Is_Integer_Type (Typ) then
4725             Expand_Divide_Fixed_By_Fixed_Giving_Integer (N);
4726          else
4727             pragma Assert (Is_Floating_Point_Type (Typ));
4728             Expand_Divide_Fixed_By_Fixed_Giving_Float (N);
4729          end if;
4730
4731       --  Mixed-mode operations can appear in a non-static universal context,
4732       --  in which case the integer argument must be converted explicitly.
4733
4734       elsif Typ = Universal_Real
4735         and then Is_Integer_Type (Rtyp)
4736       then
4737          Rewrite (Ropnd,
4738            Convert_To (Universal_Real, Relocate_Node (Ropnd)));
4739
4740          Analyze_And_Resolve (Ropnd, Universal_Real);
4741
4742       elsif Typ = Universal_Real
4743         and then Is_Integer_Type (Ltyp)
4744       then
4745          Rewrite (Lopnd,
4746            Convert_To (Universal_Real, Relocate_Node (Lopnd)));
4747
4748          Analyze_And_Resolve (Lopnd, Universal_Real);
4749
4750       --  Non-fixed point cases, do integer zero divide and overflow checks
4751
4752       elsif Is_Integer_Type (Typ) then
4753          Apply_Divide_Check (N);
4754
4755          --  Check for 64-bit division available, or long shifts if the divisor
4756          --  is a small power of 2 (since such divides will be converted into
4757          --  long shifts.
4758
4759          if Esize (Ltyp) > 32
4760            and then not Support_64_Bit_Divides_On_Target
4761            and then
4762              (not Rknow
4763                 or else not Support_Long_Shifts_On_Target
4764                 or else (Rval /= Uint_2  and then
4765                          Rval /= Uint_4  and then
4766                          Rval /= Uint_8  and then
4767                          Rval /= Uint_16 and then
4768                          Rval /= Uint_32 and then
4769                          Rval /= Uint_64))
4770          then
4771             Error_Msg_CRT ("64-bit division", N);
4772          end if;
4773
4774       --  Deal with Vax_Float
4775
4776       elsif Vax_Float (Typ) then
4777          Expand_Vax_Arith (N);
4778          return;
4779       end if;
4780    end Expand_N_Op_Divide;
4781
4782    --------------------
4783    -- Expand_N_Op_Eq --
4784    --------------------
4785
4786    procedure Expand_N_Op_Eq (N : Node_Id) is
4787       Loc    : constant Source_Ptr := Sloc (N);
4788       Typ    : constant Entity_Id  := Etype (N);
4789       Lhs    : constant Node_Id    := Left_Opnd (N);
4790       Rhs    : constant Node_Id    := Right_Opnd (N);
4791       Bodies : constant List_Id    := New_List;
4792       A_Typ  : constant Entity_Id  := Etype (Lhs);
4793
4794       Typl    : Entity_Id := A_Typ;
4795       Op_Name : Entity_Id;
4796       Prim    : Elmt_Id;
4797
4798       procedure Build_Equality_Call (Eq : Entity_Id);
4799       --  If a constructed equality exists for the type or for its parent,
4800       --  build and analyze call, adding conversions if the operation is
4801       --  inherited.
4802
4803       function Has_Unconstrained_UU_Component (Typ : Node_Id) return Boolean;
4804       --  Determines whether a type has a subcomponent of an unconstrained
4805       --  Unchecked_Union subtype. Typ is a record type.
4806
4807       -------------------------
4808       -- Build_Equality_Call --
4809       -------------------------
4810
4811       procedure Build_Equality_Call (Eq : Entity_Id) is
4812          Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
4813          L_Exp   : Node_Id := Relocate_Node (Lhs);
4814          R_Exp   : Node_Id := Relocate_Node (Rhs);
4815
4816       begin
4817          if Base_Type (Op_Type) /= Base_Type (A_Typ)
4818            and then not Is_Class_Wide_Type (A_Typ)
4819          then
4820             L_Exp := OK_Convert_To (Op_Type, L_Exp);
4821             R_Exp := OK_Convert_To (Op_Type, R_Exp);
4822          end if;
4823
4824          --  If we have an Unchecked_Union, we need to add the inferred
4825          --  discriminant values as actuals in the function call. At this
4826          --  point, the expansion has determined that both operands have
4827          --  inferable discriminants.
4828
4829          if Is_Unchecked_Union (Op_Type) then
4830             declare
4831                Lhs_Type      : constant Node_Id := Etype (L_Exp);
4832                Rhs_Type      : constant Node_Id := Etype (R_Exp);
4833                Lhs_Discr_Val : Node_Id;
4834                Rhs_Discr_Val : Node_Id;
4835
4836             begin
4837                --  Per-object constrained selected components require special
4838                --  attention. If the enclosing scope of the component is an
4839                --  Unchecked_Union, we cannot reference its discriminants
4840                --  directly. This is why we use the two extra parameters of
4841                --  the equality function of the enclosing Unchecked_Union.
4842
4843                --  type UU_Type (Discr : Integer := 0) is
4844                --     . . .
4845                --  end record;
4846                --  pragma Unchecked_Union (UU_Type);
4847
4848                --  1. Unchecked_Union enclosing record:
4849
4850                --     type Enclosing_UU_Type (Discr : Integer := 0) is record
4851                --        . . .
4852                --        Comp : UU_Type (Discr);
4853                --        . . .
4854                --     end Enclosing_UU_Type;
4855                --     pragma Unchecked_Union (Enclosing_UU_Type);
4856
4857                --     Obj1 : Enclosing_UU_Type;
4858                --     Obj2 : Enclosing_UU_Type (1);
4859
4860                --     [. . .] Obj1 = Obj2 [. . .]
4861
4862                --     Generated code:
4863
4864                --     if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
4865
4866                --  A and B are the formal parameters of the equality function
4867                --  of Enclosing_UU_Type. The function always has two extra
4868                --  formals to capture the inferred discriminant values.
4869
4870                --  2. Non-Unchecked_Union enclosing record:
4871
4872                --     type
4873                --       Enclosing_Non_UU_Type (Discr : Integer := 0)
4874                --     is record
4875                --        . . .
4876                --        Comp : UU_Type (Discr);
4877                --        . . .
4878                --     end Enclosing_Non_UU_Type;
4879
4880                --     Obj1 : Enclosing_Non_UU_Type;
4881                --     Obj2 : Enclosing_Non_UU_Type (1);
4882
4883                --     ...  Obj1 = Obj2 ...
4884
4885                --     Generated code:
4886
4887                --     if not (uu_typeEQ (obj1.comp, obj2.comp,
4888                --                        obj1.discr, obj2.discr)) then
4889
4890                --  In this case we can directly reference the discriminants of
4891                --  the enclosing record.
4892
4893                --  Lhs of equality
4894
4895                if Nkind (Lhs) = N_Selected_Component
4896                  and then Has_Per_Object_Constraint
4897                             (Entity (Selector_Name (Lhs)))
4898                then
4899                   --  Enclosing record is an Unchecked_Union, use formal A
4900
4901                   if Is_Unchecked_Union (Scope
4902                        (Entity (Selector_Name (Lhs))))
4903                   then
4904                      Lhs_Discr_Val :=
4905                        Make_Identifier (Loc,
4906                          Chars => Name_A);
4907
4908                   --  Enclosing record is of a non-Unchecked_Union type, it is
4909                   --  possible to reference the discriminant.
4910
4911                   else
4912                      Lhs_Discr_Val :=
4913                        Make_Selected_Component (Loc,
4914                          Prefix => Prefix (Lhs),
4915                          Selector_Name =>
4916                            New_Copy
4917                              (Get_Discriminant_Value
4918                                 (First_Discriminant (Lhs_Type),
4919                                  Lhs_Type,
4920                                  Stored_Constraint (Lhs_Type))));
4921                   end if;
4922
4923                --  Comment needed here ???
4924
4925                else
4926                   --  Infer the discriminant value
4927
4928                   Lhs_Discr_Val :=
4929                     New_Copy
4930                       (Get_Discriminant_Value
4931                          (First_Discriminant (Lhs_Type),
4932                           Lhs_Type,
4933                           Stored_Constraint (Lhs_Type)));
4934                end if;
4935
4936                --  Rhs of equality
4937
4938                if Nkind (Rhs) = N_Selected_Component
4939                  and then Has_Per_Object_Constraint
4940                             (Entity (Selector_Name (Rhs)))
4941                then
4942                   if Is_Unchecked_Union
4943                        (Scope (Entity (Selector_Name (Rhs))))
4944                   then
4945                      Rhs_Discr_Val :=
4946                        Make_Identifier (Loc,
4947                          Chars => Name_B);
4948
4949                   else
4950                      Rhs_Discr_Val :=
4951                        Make_Selected_Component (Loc,
4952                          Prefix => Prefix (Rhs),
4953                          Selector_Name =>
4954                            New_Copy (Get_Discriminant_Value (
4955                              First_Discriminant (Rhs_Type),
4956                              Rhs_Type,
4957                              Stored_Constraint (Rhs_Type))));
4958
4959                   end if;
4960                else
4961                   Rhs_Discr_Val :=
4962                     New_Copy (Get_Discriminant_Value (
4963                       First_Discriminant (Rhs_Type),
4964                       Rhs_Type,
4965                       Stored_Constraint (Rhs_Type)));
4966
4967                end if;
4968
4969                Rewrite (N,
4970                  Make_Function_Call (Loc,
4971                    Name => New_Reference_To (Eq, Loc),
4972                    Parameter_Associations => New_List (
4973                      L_Exp,
4974                      R_Exp,
4975                      Lhs_Discr_Val,
4976                      Rhs_Discr_Val)));
4977             end;
4978
4979          --  Normal case, not an unchecked union
4980
4981          else
4982             Rewrite (N,
4983               Make_Function_Call (Loc,
4984                 Name => New_Reference_To (Eq, Loc),
4985                 Parameter_Associations => New_List (L_Exp, R_Exp)));
4986          end if;
4987
4988          Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
4989       end Build_Equality_Call;
4990
4991       ------------------------------------
4992       -- Has_Unconstrained_UU_Component --
4993       ------------------------------------
4994
4995       function Has_Unconstrained_UU_Component
4996         (Typ : Node_Id) return Boolean
4997       is
4998          Tdef  : constant Node_Id :=
4999                    Type_Definition (Declaration_Node (Base_Type (Typ)));
5000          Clist : Node_Id;
5001          Vpart : Node_Id;
5002
5003          function Component_Is_Unconstrained_UU
5004            (Comp : Node_Id) return Boolean;
5005          --  Determines whether the subtype of the component is an
5006          --  unconstrained Unchecked_Union.
5007
5008          function Variant_Is_Unconstrained_UU
5009            (Variant : Node_Id) return Boolean;
5010          --  Determines whether a component of the variant has an unconstrained
5011          --  Unchecked_Union subtype.
5012
5013          -----------------------------------
5014          -- Component_Is_Unconstrained_UU --
5015          -----------------------------------
5016
5017          function Component_Is_Unconstrained_UU
5018            (Comp : Node_Id) return Boolean
5019          is
5020          begin
5021             if Nkind (Comp) /= N_Component_Declaration then
5022                return False;
5023             end if;
5024
5025             declare
5026                Sindic : constant Node_Id :=
5027                           Subtype_Indication (Component_Definition (Comp));
5028
5029             begin
5030                --  Unconstrained nominal type. In the case of a constraint
5031                --  present, the node kind would have been N_Subtype_Indication.
5032
5033                if Nkind (Sindic) = N_Identifier then
5034                   return Is_Unchecked_Union (Base_Type (Etype (Sindic)));
5035                end if;
5036
5037                return False;
5038             end;
5039          end Component_Is_Unconstrained_UU;
5040
5041          ---------------------------------
5042          -- Variant_Is_Unconstrained_UU --
5043          ---------------------------------
5044
5045          function Variant_Is_Unconstrained_UU
5046            (Variant : Node_Id) return Boolean
5047          is
5048             Clist : constant Node_Id := Component_List (Variant);
5049
5050          begin
5051             if Is_Empty_List (Component_Items (Clist)) then
5052                return False;
5053             end if;
5054
5055             --  We only need to test one component
5056
5057             declare
5058                Comp : Node_Id := First (Component_Items (Clist));
5059
5060             begin
5061                while Present (Comp) loop
5062                   if Component_Is_Unconstrained_UU (Comp) then
5063                      return True;
5064                   end if;
5065
5066                   Next (Comp);
5067                end loop;
5068             end;
5069
5070             --  None of the components withing the variant were of
5071             --  unconstrained Unchecked_Union type.
5072
5073             return False;
5074          end Variant_Is_Unconstrained_UU;
5075
5076       --  Start of processing for Has_Unconstrained_UU_Component
5077
5078       begin
5079          if Null_Present (Tdef) then
5080             return False;
5081          end if;
5082
5083          Clist := Component_List (Tdef);
5084          Vpart := Variant_Part (Clist);
5085
5086          --  Inspect available components
5087
5088          if Present (Component_Items (Clist)) then
5089             declare
5090                Comp : Node_Id := First (Component_Items (Clist));
5091
5092             begin
5093                while Present (Comp) loop
5094
5095                   --  One component is sufficient
5096
5097                   if Component_Is_Unconstrained_UU (Comp) then
5098                      return True;
5099                   end if;
5100
5101                   Next (Comp);
5102                end loop;
5103             end;
5104          end if;
5105
5106          --  Inspect available components withing variants
5107
5108          if Present (Vpart) then
5109             declare
5110                Variant : Node_Id := First (Variants (Vpart));
5111
5112             begin
5113                while Present (Variant) loop
5114
5115                   --  One component within a variant is sufficient
5116
5117                   if Variant_Is_Unconstrained_UU (Variant) then
5118                      return True;
5119                   end if;
5120
5121                   Next (Variant);
5122                end loop;
5123             end;
5124          end if;
5125
5126          --  Neither the available components, nor the components inside the
5127          --  variant parts were of an unconstrained Unchecked_Union subtype.
5128
5129          return False;
5130       end Has_Unconstrained_UU_Component;
5131
5132    --  Start of processing for Expand_N_Op_Eq
5133
5134    begin
5135       Binary_Op_Validity_Checks (N);
5136
5137       if Ekind (Typl) = E_Private_Type then
5138          Typl := Underlying_Type (Typl);
5139       elsif Ekind (Typl) = E_Private_Subtype then
5140          Typl := Underlying_Type (Base_Type (Typl));
5141       else
5142          null;
5143       end if;
5144
5145       --  It may happen in error situations that the underlying type is not
5146       --  set. The error will be detected later, here we just defend the
5147       --  expander code.
5148
5149       if No (Typl) then
5150          return;
5151       end if;
5152
5153       Typl := Base_Type (Typl);
5154
5155       --  Boolean types (requiring handling of non-standard case)
5156
5157       if Is_Boolean_Type (Typl) then
5158          Adjust_Condition (Left_Opnd (N));
5159          Adjust_Condition (Right_Opnd (N));
5160          Set_Etype (N, Standard_Boolean);
5161          Adjust_Result_Type (N, Typ);
5162
5163       --  Array types
5164
5165       elsif Is_Array_Type (Typl) then
5166
5167          --  If we are doing full validity checking, and it is possible for the
5168          --  array elements to be invalid then expand out array comparisons to
5169          --  make sure that we check the array elements.
5170
5171          if Validity_Check_Operands
5172            and then not Is_Known_Valid (Component_Type (Typl))
5173          then
5174             declare
5175                Save_Force_Validity_Checks : constant Boolean :=
5176                                               Force_Validity_Checks;
5177             begin
5178                Force_Validity_Checks := True;
5179                Rewrite (N,
5180                  Expand_Array_Equality
5181                   (N,
5182                    Relocate_Node (Lhs),
5183                    Relocate_Node (Rhs),
5184                    Bodies,
5185                    Typl));
5186                Insert_Actions (N, Bodies);
5187                Analyze_And_Resolve (N, Standard_Boolean);
5188                Force_Validity_Checks := Save_Force_Validity_Checks;
5189             end;
5190
5191          --  Packed case where both operands are known aligned
5192
5193          elsif Is_Bit_Packed_Array (Typl)
5194            and then not Is_Possibly_Unaligned_Object (Lhs)
5195            and then not Is_Possibly_Unaligned_Object (Rhs)
5196          then
5197             Expand_Packed_Eq (N);
5198
5199          --  Where the component type is elementary we can use a block bit
5200          --  comparison (if supported on the target) exception in the case
5201          --  of floating-point (negative zero issues require element by
5202          --  element comparison), and atomic types (where we must be sure
5203          --  to load elements independently) and possibly unaligned arrays.
5204
5205          elsif Is_Elementary_Type (Component_Type (Typl))
5206            and then not Is_Floating_Point_Type (Component_Type (Typl))
5207            and then not Is_Atomic (Component_Type (Typl))
5208            and then not Is_Possibly_Unaligned_Object (Lhs)
5209            and then not Is_Possibly_Unaligned_Object (Rhs)
5210            and then Support_Composite_Compare_On_Target
5211          then
5212             null;
5213
5214          --  For composite and floating-point cases, expand equality loop to
5215          --  make sure of using proper comparisons for tagged types, and
5216          --  correctly handling the floating-point case.
5217
5218          else
5219             Rewrite (N,
5220               Expand_Array_Equality
5221                 (N,
5222                  Relocate_Node (Lhs),
5223                  Relocate_Node (Rhs),
5224                  Bodies,
5225                  Typl));
5226             Insert_Actions      (N, Bodies,           Suppress => All_Checks);
5227             Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
5228          end if;
5229
5230       --  Record Types
5231
5232       elsif Is_Record_Type (Typl) then
5233
5234          --  For tagged types, use the primitive "="
5235
5236          if Is_Tagged_Type (Typl) then
5237
5238             --  No need to do anything else compiling under restriction
5239             --  No_Dispatching_Calls. During the semantic analysis we
5240             --  already notified such violation.
5241
5242             if Restriction_Active (No_Dispatching_Calls) then
5243                return;
5244             end if;
5245
5246             --  If this is derived from an untagged private type completed with
5247             --  a tagged type, it does not have a full view, so we use the
5248             --  primitive operations of the private type. This check should no
5249             --  longer be necessary when these types get their full views???
5250
5251             if Is_Private_Type (A_Typ)
5252               and then not Is_Tagged_Type (A_Typ)
5253               and then Is_Derived_Type (A_Typ)
5254               and then No (Full_View (A_Typ))
5255             then
5256                --  Search for equality operation, checking that the operands
5257                --  have the same type. Note that we must find a matching entry,
5258                --  or something is very wrong!
5259
5260                Prim := First_Elmt (Collect_Primitive_Operations (A_Typ));
5261
5262                while Present (Prim) loop
5263                   exit when Chars (Node (Prim)) = Name_Op_Eq
5264                     and then Etype (First_Formal (Node (Prim))) =
5265                              Etype (Next_Formal (First_Formal (Node (Prim))))
5266                     and then
5267                       Base_Type (Etype (Node (Prim))) = Standard_Boolean;
5268
5269                   Next_Elmt (Prim);
5270                end loop;
5271
5272                pragma Assert (Present (Prim));
5273                Op_Name := Node (Prim);
5274
5275             --  Find the type's predefined equality or an overriding
5276             --  user- defined equality. The reason for not simply calling
5277             --  Find_Prim_Op here is that there may be a user-defined
5278             --  overloaded equality op that precedes the equality that we want,
5279             --  so we have to explicitly search (e.g., there could be an
5280             --  equality with two different parameter types).
5281
5282             else
5283                if Is_Class_Wide_Type (Typl) then
5284                   Typl := Root_Type (Typl);
5285                end if;
5286
5287                Prim := First_Elmt (Primitive_Operations (Typl));
5288                while Present (Prim) loop
5289                   exit when Chars (Node (Prim)) = Name_Op_Eq
5290                     and then Etype (First_Formal (Node (Prim))) =
5291                              Etype (Next_Formal (First_Formal (Node (Prim))))
5292                     and then
5293                       Base_Type (Etype (Node (Prim))) = Standard_Boolean;
5294
5295                   Next_Elmt (Prim);
5296                end loop;
5297
5298                pragma Assert (Present (Prim));
5299                Op_Name := Node (Prim);
5300             end if;
5301
5302             Build_Equality_Call (Op_Name);
5303
5304          --  Ada 2005 (AI-216): Program_Error is raised when evaluating the
5305          --  predefined equality operator for a type which has a subcomponent
5306          --  of an Unchecked_Union type whose nominal subtype is unconstrained.
5307
5308          elsif Has_Unconstrained_UU_Component (Typl) then
5309             Insert_Action (N,
5310               Make_Raise_Program_Error (Loc,
5311                 Reason => PE_Unchecked_Union_Restriction));
5312
5313             --  Prevent Gigi from generating incorrect code by rewriting the
5314             --  equality as a standard False.
5315
5316             Rewrite (N,
5317               New_Occurrence_Of (Standard_False, Loc));
5318
5319          elsif Is_Unchecked_Union (Typl) then
5320
5321             --  If we can infer the discriminants of the operands, we make a
5322             --  call to the TSS equality function.
5323
5324             if Has_Inferable_Discriminants (Lhs)
5325                  and then
5326                Has_Inferable_Discriminants (Rhs)
5327             then
5328                Build_Equality_Call
5329                  (TSS (Root_Type (Typl), TSS_Composite_Equality));
5330
5331             else
5332                --  Ada 2005 (AI-216): Program_Error is raised when evaluating
5333                --  the predefined equality operator for an Unchecked_Union type
5334                --  if either of the operands lack inferable discriminants.
5335
5336                Insert_Action (N,
5337                  Make_Raise_Program_Error (Loc,
5338                    Reason => PE_Unchecked_Union_Restriction));
5339
5340                --  Prevent Gigi from generating incorrect code by rewriting
5341                --  the equality as a standard False.
5342
5343                Rewrite (N,
5344                  New_Occurrence_Of (Standard_False, Loc));
5345
5346             end if;
5347
5348          --  If a type support function is present (for complex cases), use it
5349
5350          elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
5351             Build_Equality_Call
5352               (TSS (Root_Type (Typl), TSS_Composite_Equality));
5353
5354          --  Otherwise expand the component by component equality. Note that
5355          --  we never use block-bit comparisons for records, because of the
5356          --  problems with gaps. The backend will often be able to recombine
5357          --  the separate comparisons that we generate here.
5358
5359          else
5360             Remove_Side_Effects (Lhs);
5361             Remove_Side_Effects (Rhs);
5362             Rewrite (N,
5363               Expand_Record_Equality (N, Typl, Lhs, Rhs, Bodies));
5364
5365             Insert_Actions      (N, Bodies,           Suppress => All_Checks);
5366             Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
5367          end if;
5368       end if;
5369
5370       --  Test if result is known at compile time
5371
5372       Rewrite_Comparison (N);
5373
5374       --  If we still have comparison for Vax_Float, process it
5375
5376       if Vax_Float (Typl) and then Nkind (N) in N_Op_Compare  then
5377          Expand_Vax_Comparison (N);
5378          return;
5379       end if;
5380    end Expand_N_Op_Eq;
5381
5382    -----------------------
5383    -- Expand_N_Op_Expon --
5384    -----------------------
5385
5386    procedure Expand_N_Op_Expon (N : Node_Id) is
5387       Loc    : constant Source_Ptr := Sloc (N);
5388       Typ    : constant Entity_Id  := Etype (N);
5389       Rtyp   : constant Entity_Id  := Root_Type (Typ);
5390       Base   : constant Node_Id    := Relocate_Node (Left_Opnd (N));
5391       Bastyp : constant Node_Id    := Etype (Base);
5392       Exp    : constant Node_Id    := Relocate_Node (Right_Opnd (N));
5393       Exptyp : constant Entity_Id  := Etype (Exp);
5394       Ovflo  : constant Boolean    := Do_Overflow_Check (N);
5395       Expv   : Uint;
5396       Xnode  : Node_Id;
5397       Temp   : Node_Id;
5398       Rent   : RE_Id;
5399       Ent    : Entity_Id;
5400       Etyp   : Entity_Id;
5401
5402    begin
5403       Binary_Op_Validity_Checks (N);
5404
5405       --  If either operand is of a private type, then we have the use of an
5406       --  intrinsic operator, and we get rid of the privateness, by using root
5407       --  types of underlying types for the actual operation. Otherwise the
5408       --  private types will cause trouble if we expand multiplications or
5409       --  shifts etc. We also do this transformation if the result type is
5410       --  different from the base type.
5411
5412       if Is_Private_Type (Etype (Base))
5413            or else
5414          Is_Private_Type (Typ)
5415            or else
5416          Is_Private_Type (Exptyp)
5417            or else
5418          Rtyp /= Root_Type (Bastyp)
5419       then
5420          declare
5421             Bt : constant Entity_Id := Root_Type (Underlying_Type (Bastyp));
5422             Et : constant Entity_Id := Root_Type (Underlying_Type (Exptyp));
5423
5424          begin
5425             Rewrite (N,
5426               Unchecked_Convert_To (Typ,
5427                 Make_Op_Expon (Loc,
5428                   Left_Opnd  => Unchecked_Convert_To (Bt, Base),
5429                   Right_Opnd => Unchecked_Convert_To (Et, Exp))));
5430             Analyze_And_Resolve (N, Typ);
5431             return;
5432          end;
5433       end if;
5434
5435       --  Test for case of known right argument
5436
5437       if Compile_Time_Known_Value (Exp) then
5438          Expv := Expr_Value (Exp);
5439
5440          --  We only fold small non-negative exponents. You might think we
5441          --  could fold small negative exponents for the real case, but we
5442          --  can't because we are required to raise Constraint_Error for
5443          --  the case of 0.0 ** (negative) even if Machine_Overflows = False.
5444          --  See ACVC test C4A012B.
5445
5446          if Expv >= 0 and then Expv <= 4 then
5447
5448             --  X ** 0 = 1 (or 1.0)
5449
5450             if Expv = 0 then
5451
5452                --  Call Remove_Side_Effects to ensure that any side effects
5453                --  in the ignored left operand (in particular function calls
5454                --  to user defined functions) are properly executed.
5455
5456                Remove_Side_Effects (Base);
5457
5458                if Ekind (Typ) in Integer_Kind then
5459                   Xnode := Make_Integer_Literal (Loc, Intval => 1);
5460                else
5461                   Xnode := Make_Real_Literal (Loc, Ureal_1);
5462                end if;
5463
5464             --  X ** 1 = X
5465
5466             elsif Expv = 1 then
5467                Xnode := Base;
5468
5469             --  X ** 2 = X * X
5470
5471             elsif Expv = 2 then
5472                Xnode :=
5473                  Make_Op_Multiply (Loc,
5474                    Left_Opnd  => Duplicate_Subexpr (Base),
5475                    Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
5476
5477             --  X ** 3 = X * X * X
5478
5479             elsif Expv = 3 then
5480                Xnode :=
5481                  Make_Op_Multiply (Loc,
5482                    Left_Opnd =>
5483                      Make_Op_Multiply (Loc,
5484                        Left_Opnd  => Duplicate_Subexpr (Base),
5485                        Right_Opnd => Duplicate_Subexpr_No_Checks (Base)),
5486                    Right_Opnd  => Duplicate_Subexpr_No_Checks (Base));
5487
5488             --  X ** 4  ->
5489             --    En : constant base'type := base * base;
5490             --    ...
5491             --    En * En
5492
5493             else -- Expv = 4
5494                Temp :=
5495                  Make_Defining_Identifier (Loc, New_Internal_Name ('E'));
5496
5497                Insert_Actions (N, New_List (
5498                  Make_Object_Declaration (Loc,
5499                    Defining_Identifier => Temp,
5500                    Constant_Present    => True,
5501                    Object_Definition   => New_Reference_To (Typ, Loc),
5502                    Expression =>
5503                      Make_Op_Multiply (Loc,
5504                        Left_Opnd  => Duplicate_Subexpr (Base),
5505                        Right_Opnd => Duplicate_Subexpr_No_Checks (Base)))));
5506
5507                Xnode :=
5508                  Make_Op_Multiply (Loc,
5509                    Left_Opnd  => New_Reference_To (Temp, Loc),
5510                    Right_Opnd => New_Reference_To (Temp, Loc));
5511             end if;
5512
5513             Rewrite (N, Xnode);
5514             Analyze_And_Resolve (N, Typ);
5515             return;
5516          end if;
5517       end if;
5518
5519       --  Case of (2 ** expression) appearing as an argument of an integer
5520       --  multiplication, or as the right argument of a division of a non-
5521       --  negative integer. In such cases we leave the node untouched, setting
5522       --  the flag Is_Natural_Power_Of_2_for_Shift set, then the expansion
5523       --  of the higher level node converts it into a shift.
5524
5525       --  Note: this transformation is not applicable for a modular type with
5526       --  a non-binary modulus in the multiplication case, since we get a wrong
5527       --  result if the shift causes an overflow before the modular reduction.
5528
5529       if Nkind (Base) = N_Integer_Literal
5530         and then Intval (Base) = 2
5531         and then Is_Integer_Type (Root_Type (Exptyp))
5532         and then Esize (Root_Type (Exptyp)) <= Esize (Standard_Integer)
5533         and then Is_Unsigned_Type (Exptyp)
5534         and then not Ovflo
5535         and then Nkind (Parent (N)) in N_Binary_Op
5536       then
5537          declare
5538             P : constant Node_Id := Parent (N);
5539             L : constant Node_Id := Left_Opnd (P);
5540             R : constant Node_Id := Right_Opnd (P);
5541
5542          begin
5543             if (Nkind (P) = N_Op_Multiply
5544                  and then not Non_Binary_Modulus (Typ)
5545                  and then
5546                    ((Is_Integer_Type (Etype (L)) and then R = N)
5547                        or else
5548                     (Is_Integer_Type (Etype (R)) and then L = N))
5549                  and then not Do_Overflow_Check (P))
5550
5551               or else
5552                 (Nkind (P) = N_Op_Divide
5553                   and then Is_Integer_Type (Etype (L))
5554                   and then Is_Unsigned_Type (Etype (L))
5555                   and then R = N
5556                   and then not Do_Overflow_Check (P))
5557             then
5558                Set_Is_Power_Of_2_For_Shift (N);
5559                return;
5560             end if;
5561          end;
5562       end if;
5563
5564       --  Fall through if exponentiation must be done using a runtime routine
5565
5566       --  First deal with modular case
5567
5568       if Is_Modular_Integer_Type (Rtyp) then
5569
5570          --  Non-binary case, we call the special exponentiation routine for
5571          --  the non-binary case, converting the argument to Long_Long_Integer
5572          --  and passing the modulus value. Then the result is converted back
5573          --  to the base type.
5574
5575          if Non_Binary_Modulus (Rtyp) then
5576             Rewrite (N,
5577               Convert_To (Typ,
5578                 Make_Function_Call (Loc,
5579                   Name => New_Reference_To (RTE (RE_Exp_Modular), Loc),
5580                   Parameter_Associations => New_List (
5581                     Convert_To (Standard_Integer, Base),
5582                     Make_Integer_Literal (Loc, Modulus (Rtyp)),
5583                     Exp))));
5584
5585          --  Binary case, in this case, we call one of two routines, either the
5586          --  unsigned integer case, or the unsigned long long integer case,
5587          --  with a final "and" operation to do the required mod.
5588
5589          else
5590             if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
5591                Ent := RTE (RE_Exp_Unsigned);
5592             else
5593                Ent := RTE (RE_Exp_Long_Long_Unsigned);
5594             end if;
5595
5596             Rewrite (N,
5597               Convert_To (Typ,
5598                 Make_Op_And (Loc,
5599                   Left_Opnd =>
5600                     Make_Function_Call (Loc,
5601                       Name => New_Reference_To (Ent, Loc),
5602                       Parameter_Associations => New_List (
5603                         Convert_To (Etype (First_Formal (Ent)), Base),
5604                         Exp)),
5605                    Right_Opnd =>
5606                      Make_Integer_Literal (Loc, Modulus (Rtyp) - 1))));
5607
5608          end if;
5609
5610          --  Common exit point for modular type case
5611
5612          Analyze_And_Resolve (N, Typ);
5613          return;
5614
5615       --  Signed integer cases, done using either Integer or Long_Long_Integer.
5616       --  It is not worth having routines for Short_[Short_]Integer, since for
5617       --  most machines it would not help, and it would generate more code that
5618       --  might need certification when a certified run time is required.
5619
5620       --  In the integer cases, we have two routines, one for when overflow
5621       --  checks are required, and one when they are not required, since there
5622       --  is a real gain in omitting checks on many machines.
5623
5624       elsif Rtyp = Base_Type (Standard_Long_Long_Integer)
5625         or else (Rtyp = Base_Type (Standard_Long_Integer)
5626                    and then
5627                      Esize (Standard_Long_Integer) > Esize (Standard_Integer))
5628         or else (Rtyp = Universal_Integer)
5629       then
5630          Etyp := Standard_Long_Long_Integer;
5631
5632          if Ovflo then
5633             Rent := RE_Exp_Long_Long_Integer;
5634          else
5635             Rent := RE_Exn_Long_Long_Integer;
5636          end if;
5637
5638       elsif Is_Signed_Integer_Type (Rtyp) then
5639          Etyp := Standard_Integer;
5640
5641          if Ovflo then
5642             Rent := RE_Exp_Integer;
5643          else
5644             Rent := RE_Exn_Integer;
5645          end if;
5646
5647       --  Floating-point cases, always done using Long_Long_Float. We do not
5648       --  need separate routines for the overflow case here, since in the case
5649       --  of floating-point, we generate infinities anyway as a rule (either
5650       --  that or we automatically trap overflow), and if there is an infinity
5651       --  generated and a range check is required, the check will fail anyway.
5652
5653       else
5654          pragma Assert (Is_Floating_Point_Type (Rtyp));
5655          Etyp := Standard_Long_Long_Float;
5656          Rent := RE_Exn_Long_Long_Float;
5657       end if;
5658
5659       --  Common processing for integer cases and floating-point cases.
5660       --  If we are in the right type, we can call runtime routine directly
5661
5662       if Typ = Etyp
5663         and then Rtyp /= Universal_Integer
5664         and then Rtyp /= Universal_Real
5665       then
5666          Rewrite (N,
5667            Make_Function_Call (Loc,
5668              Name => New_Reference_To (RTE (Rent), Loc),
5669              Parameter_Associations => New_List (Base, Exp)));
5670
5671       --  Otherwise we have to introduce conversions (conversions are also
5672       --  required in the universal cases, since the runtime routine is
5673       --  typed using one of the standard types.
5674
5675       else
5676          Rewrite (N,
5677            Convert_To (Typ,
5678              Make_Function_Call (Loc,
5679                Name => New_Reference_To (RTE (Rent), Loc),
5680                Parameter_Associations => New_List (
5681                  Convert_To (Etyp, Base),
5682                  Exp))));
5683       end if;
5684
5685       Analyze_And_Resolve (N, Typ);
5686       return;
5687
5688    exception
5689       when RE_Not_Available =>
5690          return;
5691    end Expand_N_Op_Expon;
5692
5693    --------------------
5694    -- Expand_N_Op_Ge --
5695    --------------------
5696
5697    procedure Expand_N_Op_Ge (N : Node_Id) is
5698       Typ  : constant Entity_Id := Etype (N);
5699       Op1  : constant Node_Id   := Left_Opnd (N);
5700       Op2  : constant Node_Id   := Right_Opnd (N);
5701       Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5702
5703    begin
5704       Binary_Op_Validity_Checks (N);
5705
5706       if Is_Array_Type (Typ1) then
5707          Expand_Array_Comparison (N);
5708          return;
5709       end if;
5710
5711       if Is_Boolean_Type (Typ1) then
5712          Adjust_Condition (Op1);
5713          Adjust_Condition (Op2);
5714          Set_Etype (N, Standard_Boolean);
5715          Adjust_Result_Type (N, Typ);
5716       end if;
5717
5718       Rewrite_Comparison (N);
5719
5720       --  If we still have comparison, and Vax_Float type, process it
5721
5722       if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5723          Expand_Vax_Comparison (N);
5724          return;
5725       end if;
5726    end Expand_N_Op_Ge;
5727
5728    --------------------
5729    -- Expand_N_Op_Gt --
5730    --------------------
5731
5732    procedure Expand_N_Op_Gt (N : Node_Id) is
5733       Typ  : constant Entity_Id := Etype (N);
5734       Op1  : constant Node_Id   := Left_Opnd (N);
5735       Op2  : constant Node_Id   := Right_Opnd (N);
5736       Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5737
5738    begin
5739       Binary_Op_Validity_Checks (N);
5740
5741       if Is_Array_Type (Typ1) then
5742          Expand_Array_Comparison (N);
5743          return;
5744       end if;
5745
5746       if Is_Boolean_Type (Typ1) then
5747          Adjust_Condition (Op1);
5748          Adjust_Condition (Op2);
5749          Set_Etype (N, Standard_Boolean);
5750          Adjust_Result_Type (N, Typ);
5751       end if;
5752
5753       Rewrite_Comparison (N);
5754
5755       --  If we still have comparison, and Vax_Float type, process it
5756
5757       if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5758          Expand_Vax_Comparison (N);
5759          return;
5760       end if;
5761    end Expand_N_Op_Gt;
5762
5763    --------------------
5764    -- Expand_N_Op_Le --
5765    --------------------
5766
5767    procedure Expand_N_Op_Le (N : Node_Id) is
5768       Typ  : constant Entity_Id := Etype (N);
5769       Op1  : constant Node_Id   := Left_Opnd (N);
5770       Op2  : constant Node_Id   := Right_Opnd (N);
5771       Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5772
5773    begin
5774       Binary_Op_Validity_Checks (N);
5775
5776       if Is_Array_Type (Typ1) then
5777          Expand_Array_Comparison (N);
5778          return;
5779       end if;
5780
5781       if Is_Boolean_Type (Typ1) then
5782          Adjust_Condition (Op1);
5783          Adjust_Condition (Op2);
5784          Set_Etype (N, Standard_Boolean);
5785          Adjust_Result_Type (N, Typ);
5786       end if;
5787
5788       Rewrite_Comparison (N);
5789
5790       --  If we still have comparison, and Vax_Float type, process it
5791
5792       if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5793          Expand_Vax_Comparison (N);
5794          return;
5795       end if;
5796    end Expand_N_Op_Le;
5797
5798    --------------------
5799    -- Expand_N_Op_Lt --
5800    --------------------
5801
5802    procedure Expand_N_Op_Lt (N : Node_Id) is
5803       Typ  : constant Entity_Id := Etype (N);
5804       Op1  : constant Node_Id   := Left_Opnd (N);
5805       Op2  : constant Node_Id   := Right_Opnd (N);
5806       Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
5807
5808    begin
5809       Binary_Op_Validity_Checks (N);
5810
5811       if Is_Array_Type (Typ1) then
5812          Expand_Array_Comparison (N);
5813          return;
5814       end if;
5815
5816       if Is_Boolean_Type (Typ1) then
5817          Adjust_Condition (Op1);
5818          Adjust_Condition (Op2);
5819          Set_Etype (N, Standard_Boolean);
5820          Adjust_Result_Type (N, Typ);
5821       end if;
5822
5823       Rewrite_Comparison (N);
5824
5825       --  If we still have comparison, and Vax_Float type, process it
5826
5827       if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
5828          Expand_Vax_Comparison (N);
5829          return;
5830       end if;
5831    end Expand_N_Op_Lt;
5832
5833    -----------------------
5834    -- Expand_N_Op_Minus --
5835    -----------------------
5836
5837    procedure Expand_N_Op_Minus (N : Node_Id) is
5838       Loc : constant Source_Ptr := Sloc (N);
5839       Typ : constant Entity_Id  := Etype (N);
5840
5841    begin
5842       Unary_Op_Validity_Checks (N);
5843
5844       if not Backend_Overflow_Checks_On_Target
5845          and then Is_Signed_Integer_Type (Etype (N))
5846          and then Do_Overflow_Check (N)
5847       then
5848          --  Software overflow checking expands -expr into (0 - expr)
5849
5850          Rewrite (N,
5851            Make_Op_Subtract (Loc,
5852              Left_Opnd  => Make_Integer_Literal (Loc, 0),
5853              Right_Opnd => Right_Opnd (N)));
5854
5855          Analyze_And_Resolve (N, Typ);
5856
5857       --  Vax floating-point types case
5858
5859       elsif Vax_Float (Etype (N)) then
5860          Expand_Vax_Arith (N);
5861       end if;
5862    end Expand_N_Op_Minus;
5863
5864    ---------------------
5865    -- Expand_N_Op_Mod --
5866    ---------------------
5867
5868    procedure Expand_N_Op_Mod (N : Node_Id) is
5869       Loc   : constant Source_Ptr := Sloc (N);
5870       Typ   : constant Entity_Id  := Etype (N);
5871       Left  : constant Node_Id    := Left_Opnd (N);
5872       Right : constant Node_Id    := Right_Opnd (N);
5873       DOC   : constant Boolean    := Do_Overflow_Check (N);
5874       DDC   : constant Boolean    := Do_Division_Check (N);
5875
5876       LLB : Uint;
5877       Llo : Uint;
5878       Lhi : Uint;
5879       LOK : Boolean;
5880       Rlo : Uint;
5881       Rhi : Uint;
5882       ROK : Boolean;
5883
5884       pragma Warnings (Off, Lhi);
5885
5886    begin
5887       Binary_Op_Validity_Checks (N);
5888
5889       Determine_Range (Right, ROK, Rlo, Rhi);
5890       Determine_Range (Left,  LOK, Llo, Lhi);
5891
5892       --  Convert mod to rem if operands are known non-negative. We do this
5893       --  since it is quite likely that this will improve the quality of code,
5894       --  (the operation now corresponds to the hardware remainder), and it
5895       --  does not seem likely that it could be harmful.
5896
5897       if LOK and then Llo >= 0
5898            and then
5899          ROK and then Rlo >= 0
5900       then
5901          Rewrite (N,
5902            Make_Op_Rem (Sloc (N),
5903              Left_Opnd  => Left_Opnd (N),
5904              Right_Opnd => Right_Opnd (N)));
5905
5906          --  Instead of reanalyzing the node we do the analysis manually. This
5907          --  avoids anomalies when the replacement is done in an instance and
5908          --  is epsilon more efficient.
5909
5910          Set_Entity            (N, Standard_Entity (S_Op_Rem));
5911          Set_Etype             (N, Typ);
5912          Set_Do_Overflow_Check (N, DOC);
5913          Set_Do_Division_Check (N, DDC);
5914          Expand_N_Op_Rem (N);
5915          Set_Analyzed (N);
5916
5917       --  Otherwise, normal mod processing
5918
5919       else
5920          if Is_Integer_Type (Etype (N)) then
5921             Apply_Divide_Check (N);
5922          end if;
5923
5924          --  Apply optimization x mod 1 = 0. We don't really need that with
5925          --  gcc, but it is useful with other back ends (e.g. AAMP), and is
5926          --  certainly harmless.
5927
5928          if Is_Integer_Type (Etype (N))
5929            and then Compile_Time_Known_Value (Right)
5930            and then Expr_Value (Right) = Uint_1
5931          then
5932             --  Call Remove_Side_Effects to ensure that any side effects in
5933             --  the ignored left operand (in particular function calls to
5934             --  user defined functions) are properly executed.
5935
5936             Remove_Side_Effects (Left);
5937
5938             Rewrite (N, Make_Integer_Literal (Loc, 0));
5939             Analyze_And_Resolve (N, Typ);
5940             return;
5941          end if;
5942
5943          --  Deal with annoying case of largest negative number remainder
5944          --  minus one. Gigi does not handle this case correctly, because
5945          --  it generates a divide instruction which may trap in this case.
5946
5947          --  In fact the check is quite easy, if the right operand is -1, then
5948          --  the mod value is always 0, and we can just ignore the left operand
5949          --  completely in this case.
5950
5951          --  The operand type may be private (e.g. in the expansion of an
5952          --  intrinsic operation) so we must use the underlying type to get the
5953          --  bounds, and convert the literals explicitly.
5954
5955          LLB :=
5956            Expr_Value
5957              (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
5958
5959          if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
5960            and then
5961             ((not LOK) or else (Llo = LLB))
5962          then
5963             Rewrite (N,
5964               Make_Conditional_Expression (Loc,
5965                 Expressions => New_List (
5966                   Make_Op_Eq (Loc,
5967                     Left_Opnd => Duplicate_Subexpr (Right),
5968                     Right_Opnd =>
5969                       Unchecked_Convert_To (Typ,
5970                         Make_Integer_Literal (Loc, -1))),
5971                   Unchecked_Convert_To (Typ,
5972                     Make_Integer_Literal (Loc, Uint_0)),
5973                   Relocate_Node (N))));
5974
5975             Set_Analyzed (Next (Next (First (Expressions (N)))));
5976             Analyze_And_Resolve (N, Typ);
5977          end if;
5978       end if;
5979    end Expand_N_Op_Mod;
5980
5981    --------------------------
5982    -- Expand_N_Op_Multiply --
5983    --------------------------
5984
5985    procedure Expand_N_Op_Multiply (N : Node_Id) is
5986       Loc : constant Source_Ptr := Sloc (N);
5987       Lop : constant Node_Id    := Left_Opnd (N);
5988       Rop : constant Node_Id    := Right_Opnd (N);
5989
5990       Lp2 : constant Boolean :=
5991               Nkind (Lop) = N_Op_Expon
5992                 and then Is_Power_Of_2_For_Shift (Lop);
5993
5994       Rp2 : constant Boolean :=
5995               Nkind (Rop) = N_Op_Expon
5996                 and then Is_Power_Of_2_For_Shift (Rop);
5997
5998       Ltyp : constant Entity_Id  := Etype (Lop);
5999       Rtyp : constant Entity_Id  := Etype (Rop);
6000       Typ  : Entity_Id           := Etype (N);
6001
6002    begin
6003       Binary_Op_Validity_Checks (N);
6004
6005       --  Special optimizations for integer types
6006
6007       if Is_Integer_Type (Typ) then
6008
6009          --  N * 0 = 0 for integer types
6010
6011          if Compile_Time_Known_Value (Rop)
6012            and then Expr_Value (Rop) = Uint_0
6013          then
6014             --  Call Remove_Side_Effects to ensure that any side effects in
6015             --  the ignored left operand (in particular function calls to
6016             --  user defined functions) are properly executed.
6017
6018             Remove_Side_Effects (Lop);
6019
6020             Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
6021             Analyze_And_Resolve (N, Typ);
6022             return;
6023          end if;
6024
6025          --  Similar handling for 0 * N = 0
6026
6027          if Compile_Time_Known_Value (Lop)
6028            and then Expr_Value (Lop) = Uint_0
6029          then
6030             Remove_Side_Effects (Rop);
6031             Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
6032             Analyze_And_Resolve (N, Typ);
6033             return;
6034          end if;
6035
6036          --  N * 1 = 1 * N = N for integer types
6037
6038          --  This optimisation is not done if we are going to
6039          --  rewrite the product 1 * 2 ** N to a shift.
6040
6041          if Compile_Time_Known_Value (Rop)
6042            and then Expr_Value (Rop) = Uint_1
6043            and then not Lp2
6044          then
6045             Rewrite (N, Lop);
6046             return;
6047
6048          elsif Compile_Time_Known_Value (Lop)
6049            and then Expr_Value (Lop) = Uint_1
6050            and then not Rp2
6051          then
6052             Rewrite (N, Rop);
6053             return;
6054          end if;
6055       end if;
6056
6057       --  Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
6058       --  Is_Power_Of_2_For_Shift is set means that we know that our left
6059       --  operand is an integer, as required for this to work.
6060
6061       if Rp2 then
6062          if Lp2 then
6063
6064             --  Convert 2 ** A * 2 ** B into  2 ** (A + B)
6065
6066             Rewrite (N,
6067               Make_Op_Expon (Loc,
6068                 Left_Opnd => Make_Integer_Literal (Loc, 2),
6069                 Right_Opnd =>
6070                   Make_Op_Add (Loc,
6071                     Left_Opnd  => Right_Opnd (Lop),
6072                     Right_Opnd => Right_Opnd (Rop))));
6073             Analyze_And_Resolve (N, Typ);
6074             return;
6075
6076          else
6077             Rewrite (N,
6078               Make_Op_Shift_Left (Loc,
6079                 Left_Opnd  => Lop,
6080                 Right_Opnd =>
6081                   Convert_To (Standard_Natural, Right_Opnd (Rop))));
6082             Analyze_And_Resolve (N, Typ);
6083             return;
6084          end if;
6085
6086       --  Same processing for the operands the other way round
6087
6088       elsif Lp2 then
6089          Rewrite (N,
6090            Make_Op_Shift_Left (Loc,
6091              Left_Opnd  => Rop,
6092              Right_Opnd =>
6093                Convert_To (Standard_Natural, Right_Opnd (Lop))));
6094          Analyze_And_Resolve (N, Typ);
6095          return;
6096       end if;
6097
6098       --  Do required fixup of universal fixed operation
6099
6100       if Typ = Universal_Fixed then
6101          Fixup_Universal_Fixed_Operation (N);
6102          Typ := Etype (N);
6103       end if;
6104
6105       --  Multiplications with fixed-point results
6106
6107       if Is_Fixed_Point_Type (Typ) then
6108
6109          --  No special processing if Treat_Fixed_As_Integer is set, since from
6110          --  a semantic point of view such operations are simply integer
6111          --  operations and will be treated that way.
6112
6113          if not Treat_Fixed_As_Integer (N) then
6114
6115             --  Case of fixed * integer => fixed
6116
6117             if Is_Integer_Type (Rtyp) then
6118                Expand_Multiply_Fixed_By_Integer_Giving_Fixed (N);
6119
6120             --  Case of integer * fixed => fixed
6121
6122             elsif Is_Integer_Type (Ltyp) then
6123                Expand_Multiply_Integer_By_Fixed_Giving_Fixed (N);
6124
6125             --  Case of fixed * fixed => fixed
6126
6127             else
6128                Expand_Multiply_Fixed_By_Fixed_Giving_Fixed (N);
6129             end if;
6130          end if;
6131
6132       --  Other cases of multiplication of fixed-point operands. Again we
6133       --  exclude the cases where Treat_Fixed_As_Integer flag is set.
6134
6135       elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
6136         and then not Treat_Fixed_As_Integer (N)
6137       then
6138          if Is_Integer_Type (Typ) then
6139             Expand_Multiply_Fixed_By_Fixed_Giving_Integer (N);
6140          else
6141             pragma Assert (Is_Floating_Point_Type (Typ));
6142             Expand_Multiply_Fixed_By_Fixed_Giving_Float (N);
6143          end if;
6144
6145       --  Mixed-mode operations can appear in a non-static universal context,
6146       --  in which case the integer argument must be converted explicitly.
6147
6148       elsif Typ = Universal_Real
6149         and then Is_Integer_Type (Rtyp)
6150       then
6151          Rewrite (Rop, Convert_To (Universal_Real, Relocate_Node (Rop)));
6152
6153          Analyze_And_Resolve (Rop, Universal_Real);
6154
6155       elsif Typ = Universal_Real
6156         and then Is_Integer_Type (Ltyp)
6157       then
6158          Rewrite (Lop, Convert_To (Universal_Real, Relocate_Node (Lop)));
6159
6160          Analyze_And_Resolve (Lop, Universal_Real);
6161
6162       --  Non-fixed point cases, check software overflow checking required
6163
6164       elsif Is_Signed_Integer_Type (Etype (N)) then
6165          Apply_Arithmetic_Overflow_Check (N);
6166
6167       --  Deal with VAX float case
6168
6169       elsif Vax_Float (Typ) then
6170          Expand_Vax_Arith (N);
6171          return;
6172       end if;
6173    end Expand_N_Op_Multiply;
6174
6175    --------------------
6176    -- Expand_N_Op_Ne --
6177    --------------------
6178
6179    procedure Expand_N_Op_Ne (N : Node_Id) is
6180       Typ : constant Entity_Id := Etype (Left_Opnd (N));
6181
6182    begin
6183       --  Case of elementary type with standard operator
6184
6185       if Is_Elementary_Type (Typ)
6186         and then Sloc (Entity (N)) = Standard_Location
6187       then
6188          Binary_Op_Validity_Checks (N);
6189
6190          --  Boolean types (requiring handling of non-standard case)
6191
6192          if Is_Boolean_Type (Typ) then
6193             Adjust_Condition (Left_Opnd (N));
6194             Adjust_Condition (Right_Opnd (N));
6195             Set_Etype (N, Standard_Boolean);
6196             Adjust_Result_Type (N, Typ);
6197          end if;
6198
6199          Rewrite_Comparison (N);
6200
6201          --  If we still have comparison for Vax_Float, process it
6202
6203          if Vax_Float (Typ) and then Nkind (N) in N_Op_Compare  then
6204             Expand_Vax_Comparison (N);
6205             return;
6206          end if;
6207
6208       --  For all cases other than elementary types, we rewrite node as the
6209       --  negation of an equality operation, and reanalyze. The equality to be
6210       --  used is defined in the same scope and has the same signature. This
6211       --  signature must be set explicitly since in an instance it may not have
6212       --  the same visibility as in the generic unit. This avoids duplicating
6213       --  or factoring the complex code for record/array equality tests etc.
6214
6215       else
6216          declare
6217             Loc : constant Source_Ptr := Sloc (N);
6218             Neg : Node_Id;
6219             Ne  : constant Entity_Id := Entity (N);
6220
6221          begin
6222             Binary_Op_Validity_Checks (N);
6223
6224             Neg :=
6225               Make_Op_Not (Loc,
6226                 Right_Opnd =>
6227                   Make_Op_Eq (Loc,
6228                     Left_Opnd =>  Left_Opnd (N),
6229                     Right_Opnd => Right_Opnd (N)));
6230             Set_Paren_Count (Right_Opnd (Neg), 1);
6231
6232             if Scope (Ne) /= Standard_Standard then
6233                Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
6234             end if;
6235
6236             --  For navigation purposes, the inequality is treated as an
6237             --  implicit reference to the corresponding equality. Preserve the
6238             --  Comes_From_ source flag so that the proper Xref entry is
6239             --  generated.
6240
6241             Preserve_Comes_From_Source (Neg, N);
6242             Preserve_Comes_From_Source (Right_Opnd (Neg), N);
6243             Rewrite (N, Neg);
6244             Analyze_And_Resolve (N, Standard_Boolean);
6245          end;
6246       end if;
6247    end Expand_N_Op_Ne;
6248
6249    ---------------------
6250    -- Expand_N_Op_Not --
6251    ---------------------
6252
6253    --  If the argument is other than a Boolean array type, there is no special
6254    --  expansion required.
6255
6256    --  For the packed case, we call the special routine in Exp_Pakd, except
6257    --  that if the component size is greater than one, we use the standard
6258    --  routine generating a gruesome loop (it is so peculiar to have packed
6259    --  arrays with non-standard Boolean representations anyway, so it does not
6260    --  matter that we do not handle this case efficiently).
6261
6262    --  For the unpacked case (and for the special packed case where we have non
6263    --  standard Booleans, as discussed above), we generate and insert into the
6264    --  tree the following function definition:
6265
6266    --     function Nnnn (A : arr) is
6267    --       B : arr;
6268    --     begin
6269    --       for J in a'range loop
6270    --          B (J) := not A (J);
6271    --       end loop;
6272    --       return B;
6273    --     end Nnnn;
6274
6275    --  Here arr is the actual subtype of the parameter (and hence always
6276    --  constrained). Then we replace the not with a call to this function.
6277
6278    procedure Expand_N_Op_Not (N : Node_Id) is
6279       Loc  : constant Source_Ptr := Sloc (N);
6280       Typ  : constant Entity_Id  := Etype (N);
6281       Opnd : Node_Id;
6282       Arr  : Entity_Id;
6283       A    : Entity_Id;
6284       B    : Entity_Id;
6285       J    : Entity_Id;
6286       A_J  : Node_Id;
6287       B_J  : Node_Id;
6288
6289       Func_Name      : Entity_Id;
6290       Loop_Statement : Node_Id;
6291
6292    begin
6293       Unary_Op_Validity_Checks (N);
6294
6295       --  For boolean operand, deal with non-standard booleans
6296
6297       if Is_Boolean_Type (Typ) then
6298          Adjust_Condition (Right_Opnd (N));
6299          Set_Etype (N, Standard_Boolean);
6300          Adjust_Result_Type (N, Typ);
6301          return;
6302       end if;
6303
6304       --  Only array types need any other processing
6305
6306       if not Is_Array_Type (Typ) then
6307          return;
6308       end if;
6309
6310       --  Case of array operand. If bit packed with a component size of 1,
6311       --  handle it in Exp_Pakd if the operand is known to be aligned.
6312
6313       if Is_Bit_Packed_Array (Typ)
6314         and then Component_Size (Typ) = 1
6315         and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
6316       then
6317          Expand_Packed_Not (N);
6318          return;
6319       end if;
6320
6321       --  Case of array operand which is not bit-packed. If the context is
6322       --  a safe assignment, call in-place operation, If context is a larger
6323       --  boolean expression in the context of a safe assignment, expansion is
6324       --  done by enclosing operation.
6325
6326       Opnd := Relocate_Node (Right_Opnd (N));
6327       Convert_To_Actual_Subtype (Opnd);
6328       Arr := Etype (Opnd);
6329       Ensure_Defined (Arr, N);
6330       Silly_Boolean_Array_Not_Test (N, Arr);
6331
6332       if Nkind (Parent (N)) = N_Assignment_Statement then
6333          if Safe_In_Place_Array_Op (Name (Parent (N)), N, Empty) then
6334             Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
6335             return;
6336
6337          --  Special case the negation of a binary operation
6338
6339          elsif Nkind_In (Opnd, N_Op_And, N_Op_Or, N_Op_Xor)
6340            and then Safe_In_Place_Array_Op
6341                       (Name (Parent (N)), Left_Opnd (Opnd), Right_Opnd (Opnd))
6342          then
6343             Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
6344             return;
6345          end if;
6346
6347       elsif Nkind (Parent (N)) in N_Binary_Op
6348         and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
6349       then
6350          declare
6351             Op1 : constant Node_Id := Left_Opnd  (Parent (N));
6352             Op2 : constant Node_Id := Right_Opnd (Parent (N));
6353             Lhs : constant Node_Id := Name (Parent (Parent (N)));
6354
6355          begin
6356             if Safe_In_Place_Array_Op (Lhs, Op1, Op2) then
6357                if N = Op1
6358                  and then Nkind (Op2) = N_Op_Not
6359                then
6360                   --  (not A) op (not B) can be reduced to a single call
6361
6362                   return;
6363
6364                elsif N = Op2
6365                  and then Nkind (Parent (N)) = N_Op_Xor
6366                then
6367                   --  A xor (not B) can also be special-cased
6368
6369                   return;
6370                end if;
6371             end if;
6372          end;
6373       end if;
6374
6375       A := Make_Defining_Identifier (Loc, Name_uA);
6376       B := Make_Defining_Identifier (Loc, Name_uB);
6377       J := Make_Defining_Identifier (Loc, Name_uJ);
6378
6379       A_J :=
6380         Make_Indexed_Component (Loc,
6381           Prefix      => New_Reference_To (A, Loc),
6382           Expressions => New_List (New_Reference_To (J, Loc)));
6383
6384       B_J :=
6385         Make_Indexed_Component (Loc,
6386           Prefix      => New_Reference_To (B, Loc),
6387           Expressions => New_List (New_Reference_To (J, Loc)));
6388
6389       Loop_Statement :=
6390         Make_Implicit_Loop_Statement (N,
6391           Identifier => Empty,
6392
6393           Iteration_Scheme =>
6394             Make_Iteration_Scheme (Loc,
6395               Loop_Parameter_Specification =>
6396                 Make_Loop_Parameter_Specification (Loc,
6397                   Defining_Identifier => J,
6398                   Discrete_Subtype_Definition =>
6399                     Make_Attribute_Reference (Loc,
6400                       Prefix => Make_Identifier (Loc, Chars (A)),
6401                       Attribute_Name => Name_Range))),
6402
6403           Statements => New_List (
6404             Make_Assignment_Statement (Loc,
6405               Name       => B_J,
6406               Expression => Make_Op_Not (Loc, A_J))));
6407
6408       Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('N'));
6409       Set_Is_Inlined (Func_Name);
6410
6411       Insert_Action (N,
6412         Make_Subprogram_Body (Loc,
6413           Specification =>
6414             Make_Function_Specification (Loc,
6415               Defining_Unit_Name => Func_Name,
6416               Parameter_Specifications => New_List (
6417                 Make_Parameter_Specification (Loc,
6418                   Defining_Identifier => A,
6419                   Parameter_Type      => New_Reference_To (Typ, Loc))),
6420               Result_Definition => New_Reference_To (Typ, Loc)),
6421
6422           Declarations => New_List (
6423             Make_Object_Declaration (Loc,
6424               Defining_Identifier => B,
6425               Object_Definition   => New_Reference_To (Arr, Loc))),
6426
6427           Handled_Statement_Sequence =>
6428             Make_Handled_Sequence_Of_Statements (Loc,
6429               Statements => New_List (
6430                 Loop_Statement,
6431                 Make_Simple_Return_Statement (Loc,
6432                   Expression =>
6433                     Make_Identifier (Loc, Chars (B)))))));
6434
6435       Rewrite (N,
6436         Make_Function_Call (Loc,
6437           Name => New_Reference_To (Func_Name, Loc),
6438           Parameter_Associations => New_List (Opnd)));
6439
6440       Analyze_And_Resolve (N, Typ);
6441    end Expand_N_Op_Not;
6442
6443    --------------------
6444    -- Expand_N_Op_Or --
6445    --------------------
6446
6447    procedure Expand_N_Op_Or (N : Node_Id) is
6448       Typ : constant Entity_Id := Etype (N);
6449
6450    begin
6451       Binary_Op_Validity_Checks (N);
6452
6453       if Is_Array_Type (Etype (N)) then
6454          Expand_Boolean_Operator (N);
6455
6456       elsif Is_Boolean_Type (Etype (N)) then
6457          Adjust_Condition (Left_Opnd (N));
6458          Adjust_Condition (Right_Opnd (N));
6459          Set_Etype (N, Standard_Boolean);
6460          Adjust_Result_Type (N, Typ);
6461       end if;
6462    end Expand_N_Op_Or;
6463
6464    ----------------------
6465    -- Expand_N_Op_Plus --
6466    ----------------------
6467
6468    procedure Expand_N_Op_Plus (N : Node_Id) is
6469    begin
6470       Unary_Op_Validity_Checks (N);
6471    end Expand_N_Op_Plus;
6472
6473    ---------------------
6474    -- Expand_N_Op_Rem --
6475    ---------------------
6476
6477    procedure Expand_N_Op_Rem (N : Node_Id) is
6478       Loc : constant Source_Ptr := Sloc (N);
6479       Typ : constant Entity_Id  := Etype (N);
6480
6481       Left  : constant Node_Id := Left_Opnd (N);
6482       Right : constant Node_Id := Right_Opnd (N);
6483
6484       LLB : Uint;
6485       Llo : Uint;
6486       Lhi : Uint;
6487       LOK : Boolean;
6488       Rlo : Uint;
6489       Rhi : Uint;
6490       ROK : Boolean;
6491
6492       pragma Warnings (Off, Lhi);
6493
6494    begin
6495       Binary_Op_Validity_Checks (N);
6496
6497       if Is_Integer_Type (Etype (N)) then
6498          Apply_Divide_Check (N);
6499       end if;
6500
6501       --  Apply optimization x rem 1 = 0. We don't really need that with gcc,
6502       --  but it is useful with other back ends (e.g. AAMP), and is certainly
6503       --  harmless.
6504
6505       if Is_Integer_Type (Etype (N))
6506         and then Compile_Time_Known_Value (Right)
6507         and then Expr_Value (Right) = Uint_1
6508       then
6509          --  Call Remove_Side_Effects to ensure that any side effects in the
6510          --  ignored left operand (in particular function calls to user defined
6511          --  functions) are properly executed.
6512
6513          Remove_Side_Effects (Left);
6514
6515          Rewrite (N, Make_Integer_Literal (Loc, 0));
6516          Analyze_And_Resolve (N, Typ);
6517          return;
6518       end if;
6519
6520       --  Deal with annoying case of largest negative number remainder minus
6521       --  one. Gigi does not handle this case correctly, because it generates
6522       --  a divide instruction which may trap in this case.
6523
6524       --  In fact the check is quite easy, if the right operand is -1, then
6525       --  the remainder is always 0, and we can just ignore the left operand
6526       --  completely in this case.
6527
6528       Determine_Range (Right, ROK, Rlo, Rhi);
6529       Determine_Range (Left, LOK, Llo, Lhi);
6530
6531       --  The operand type may be private (e.g. in the expansion of an
6532       --  intrinsic operation) so we must use the underlying type to get the
6533       --  bounds, and convert the literals explicitly.
6534
6535       LLB :=
6536         Expr_Value
6537           (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
6538
6539       --  Now perform the test, generating code only if needed
6540
6541       if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
6542         and then
6543          ((not LOK) or else (Llo = LLB))
6544       then
6545          Rewrite (N,
6546            Make_Conditional_Expression (Loc,
6547              Expressions => New_List (
6548                Make_Op_Eq (Loc,
6549                  Left_Opnd => Duplicate_Subexpr (Right),
6550                  Right_Opnd =>
6551                    Unchecked_Convert_To (Typ,
6552                      Make_Integer_Literal (Loc, -1))),
6553
6554                Unchecked_Convert_To (Typ,
6555                  Make_Integer_Literal (Loc, Uint_0)),
6556
6557                Relocate_Node (N))));
6558
6559          Set_Analyzed (Next (Next (First (Expressions (N)))));
6560          Analyze_And_Resolve (N, Typ);
6561       end if;
6562    end Expand_N_Op_Rem;
6563
6564    -----------------------------
6565    -- Expand_N_Op_Rotate_Left --
6566    -----------------------------
6567
6568    procedure Expand_N_Op_Rotate_Left (N : Node_Id) is
6569    begin
6570       Binary_Op_Validity_Checks (N);
6571    end Expand_N_Op_Rotate_Left;
6572
6573    ------------------------------
6574    -- Expand_N_Op_Rotate_Right --
6575    ------------------------------
6576
6577    procedure Expand_N_Op_Rotate_Right (N : Node_Id) is
6578    begin
6579       Binary_Op_Validity_Checks (N);
6580    end Expand_N_Op_Rotate_Right;
6581
6582    ----------------------------
6583    -- Expand_N_Op_Shift_Left --
6584    ----------------------------
6585
6586    procedure Expand_N_Op_Shift_Left (N : Node_Id) is
6587    begin
6588       Binary_Op_Validity_Checks (N);
6589    end Expand_N_Op_Shift_Left;
6590
6591    -----------------------------
6592    -- Expand_N_Op_Shift_Right --
6593    -----------------------------
6594
6595    procedure Expand_N_Op_Shift_Right (N : Node_Id) is
6596    begin
6597       Binary_Op_Validity_Checks (N);
6598    end Expand_N_Op_Shift_Right;
6599
6600    ----------------------------------------
6601    -- Expand_N_Op_Shift_Right_Arithmetic --
6602    ----------------------------------------
6603
6604    procedure Expand_N_Op_Shift_Right_Arithmetic (N : Node_Id) is
6605    begin
6606       Binary_Op_Validity_Checks (N);
6607    end Expand_N_Op_Shift_Right_Arithmetic;
6608
6609    --------------------------
6610    -- Expand_N_Op_Subtract --
6611    --------------------------
6612
6613    procedure Expand_N_Op_Subtract (N : Node_Id) is
6614       Typ : constant Entity_Id := Etype (N);
6615
6616    begin
6617       Binary_Op_Validity_Checks (N);
6618
6619       --  N - 0 = N for integer types
6620
6621       if Is_Integer_Type (Typ)
6622         and then Compile_Time_Known_Value (Right_Opnd (N))
6623         and then Expr_Value (Right_Opnd (N)) = 0
6624       then
6625          Rewrite (N, Left_Opnd (N));
6626          return;
6627       end if;
6628
6629       --  Arithmetic overflow checks for signed integer/fixed point types
6630
6631       if Is_Signed_Integer_Type (Typ)
6632         or else Is_Fixed_Point_Type (Typ)
6633       then
6634          Apply_Arithmetic_Overflow_Check (N);
6635
6636       --  Vax floating-point types case
6637
6638       elsif Vax_Float (Typ) then
6639          Expand_Vax_Arith (N);
6640       end if;
6641    end Expand_N_Op_Subtract;
6642
6643    ---------------------
6644    -- Expand_N_Op_Xor --
6645    ---------------------
6646
6647    procedure Expand_N_Op_Xor (N : Node_Id) is
6648       Typ : constant Entity_Id := Etype (N);
6649
6650    begin
6651       Binary_Op_Validity_Checks (N);
6652
6653       if Is_Array_Type (Etype (N)) then
6654          Expand_Boolean_Operator (N);
6655
6656       elsif Is_Boolean_Type (Etype (N)) then
6657          Adjust_Condition (Left_Opnd (N));
6658          Adjust_Condition (Right_Opnd (N));
6659          Set_Etype (N, Standard_Boolean);
6660          Adjust_Result_Type (N, Typ);
6661       end if;
6662    end Expand_N_Op_Xor;
6663
6664    ----------------------
6665    -- Expand_N_Or_Else --
6666    ----------------------
6667
6668    --  Expand into conditional expression if Actions present, and also
6669    --  deal with optimizing case of arguments being True or False.
6670
6671    procedure Expand_N_Or_Else (N : Node_Id) is
6672       Loc     : constant Source_Ptr := Sloc (N);
6673       Typ     : constant Entity_Id  := Etype (N);
6674       Left    : constant Node_Id    := Left_Opnd (N);
6675       Right   : constant Node_Id    := Right_Opnd (N);
6676       Actlist : List_Id;
6677
6678    begin
6679       --  Deal with non-standard booleans
6680
6681       if Is_Boolean_Type (Typ) then
6682          Adjust_Condition (Left);
6683          Adjust_Condition (Right);
6684          Set_Etype (N, Standard_Boolean);
6685       end if;
6686
6687       --  Check for cases where left argument is known to be True or False
6688
6689       if Compile_Time_Known_Value (Left) then
6690
6691          --  If left argument is False, change (False or else Right) to Right.
6692          --  Any actions associated with Right will be executed unconditionally
6693          --  and can thus be inserted into the tree unconditionally.
6694
6695          if Expr_Value_E (Left) = Standard_False then
6696             if Present (Actions (N)) then
6697                Insert_Actions (N, Actions (N));
6698             end if;
6699
6700             Rewrite (N, Right);
6701
6702          --  If left argument is True, change (True and then Right) to True. In
6703          --  this case we can forget the actions associated with Right, since
6704          --  they will never be executed.
6705
6706          else pragma Assert (Expr_Value_E (Left) = Standard_True);
6707             Kill_Dead_Code (Right);
6708             Kill_Dead_Code (Actions (N));
6709             Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
6710          end if;
6711
6712          Adjust_Result_Type (N, Typ);
6713          return;
6714       end if;
6715
6716       --  If Actions are present, we expand
6717
6718       --     left or else right
6719
6720       --  into
6721
6722       --     if left then True else right end
6723
6724       --  with the actions becoming the Else_Actions of the conditional
6725       --  expression. This conditional expression is then further expanded
6726       --  (and will eventually disappear)
6727
6728       if Present (Actions (N)) then
6729          Actlist := Actions (N);
6730          Rewrite (N,
6731             Make_Conditional_Expression (Loc,
6732               Expressions => New_List (
6733                 Left,
6734                 New_Occurrence_Of (Standard_True, Loc),
6735                 Right)));
6736
6737          Set_Else_Actions (N, Actlist);
6738          Analyze_And_Resolve (N, Standard_Boolean);
6739          Adjust_Result_Type (N, Typ);
6740          return;
6741       end if;
6742
6743       --  No actions present, check for cases of right argument True/False
6744
6745       if Compile_Time_Known_Value (Right) then
6746
6747          --  Change (Left or else False) to Left. Note that we know there are
6748          --  no actions associated with the True operand, since we just checked
6749          --  for this case above.
6750
6751          if Expr_Value_E (Right) = Standard_False then
6752             Rewrite (N, Left);
6753
6754          --  Change (Left or else True) to True, making sure to preserve any
6755          --  side effects associated with the Left operand.
6756
6757          else pragma Assert (Expr_Value_E (Right) = Standard_True);
6758             Remove_Side_Effects (Left);
6759             Rewrite
6760               (N, New_Occurrence_Of (Standard_True, Loc));
6761          end if;
6762       end if;
6763
6764       Adjust_Result_Type (N, Typ);
6765    end Expand_N_Or_Else;
6766
6767    -----------------------------------
6768    -- Expand_N_Qualified_Expression --
6769    -----------------------------------
6770
6771    procedure Expand_N_Qualified_Expression (N : Node_Id) is
6772       Operand     : constant Node_Id   := Expression (N);
6773       Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));
6774
6775    begin
6776       --  Do validity check if validity checking operands
6777
6778       if Validity_Checks_On
6779         and then Validity_Check_Operands
6780       then
6781          Ensure_Valid (Operand);
6782       end if;
6783
6784       --  Apply possible constraint check
6785
6786       Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);
6787    end Expand_N_Qualified_Expression;
6788
6789    ---------------------------------
6790    -- Expand_N_Selected_Component --
6791    ---------------------------------
6792
6793    --  If the selector is a discriminant of a concurrent object, rewrite the
6794    --  prefix to denote the corresponding record type.
6795
6796    procedure Expand_N_Selected_Component (N : Node_Id) is
6797       Loc   : constant Source_Ptr := Sloc (N);
6798       Par   : constant Node_Id    := Parent (N);
6799       P     : constant Node_Id    := Prefix (N);
6800       Ptyp  : Entity_Id           := Underlying_Type (Etype (P));
6801       Disc  : Entity_Id;
6802       New_N : Node_Id;
6803       Dcon  : Elmt_Id;
6804
6805       function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
6806       --  Gigi needs a temporary for prefixes that depend on a discriminant,
6807       --  unless the context of an assignment can provide size information.
6808       --  Don't we have a general routine that does this???
6809
6810       -----------------------
6811       -- In_Left_Hand_Side --
6812       -----------------------
6813
6814       function In_Left_Hand_Side (Comp : Node_Id) return Boolean is
6815       begin
6816          return (Nkind (Parent (Comp)) = N_Assignment_Statement
6817                    and then Comp = Name (Parent (Comp)))
6818            or else (Present (Parent (Comp))
6819                       and then Nkind (Parent (Comp)) in N_Subexpr
6820                       and then In_Left_Hand_Side (Parent (Comp)));
6821       end In_Left_Hand_Side;
6822
6823    --  Start of processing for Expand_N_Selected_Component
6824
6825    begin
6826       --  Insert explicit dereference if required
6827
6828       if Is_Access_Type (Ptyp) then
6829          Insert_Explicit_Dereference (P);
6830          Analyze_And_Resolve (P, Designated_Type (Ptyp));
6831
6832          if Ekind (Etype (P)) = E_Private_Subtype
6833            and then Is_For_Access_Subtype (Etype (P))
6834          then
6835             Set_Etype (P, Base_Type (Etype (P)));
6836          end if;
6837
6838          Ptyp := Etype (P);
6839       end if;
6840
6841       --  Deal with discriminant check required
6842
6843       if Do_Discriminant_Check (N) then
6844
6845          --  Present the discriminant checking function to the backend, so that
6846          --  it can inline the call to the function.
6847
6848          Add_Inlined_Body
6849            (Discriminant_Checking_Func
6850              (Original_Record_Component (Entity (Selector_Name (N)))));
6851
6852          --  Now reset the flag and generate the call
6853
6854          Set_Do_Discriminant_Check (N, False);
6855          Generate_Discriminant_Check (N);
6856       end if;
6857
6858       --  Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
6859       --  function, then additional actuals must be passed.
6860
6861       if Ada_Version >= Ada_05
6862         and then Is_Build_In_Place_Function_Call (P)
6863       then
6864          Make_Build_In_Place_Call_In_Anonymous_Context (P);
6865       end if;
6866
6867       --  Gigi cannot handle unchecked conversions that are the prefix of a
6868       --  selected component with discriminants. This must be checked during
6869       --  expansion, because during analysis the type of the selector is not
6870       --  known at the point the prefix is analyzed. If the conversion is the
6871       --  target of an assignment, then we cannot force the evaluation.
6872
6873       if Nkind (Prefix (N)) = N_Unchecked_Type_Conversion
6874         and then Has_Discriminants (Etype (N))
6875         and then not In_Left_Hand_Side (N)
6876       then
6877          Force_Evaluation (Prefix (N));
6878       end if;
6879
6880       --  Remaining processing applies only if selector is a discriminant
6881
6882       if Ekind (Entity (Selector_Name (N))) = E_Discriminant then
6883
6884          --  If the selector is a discriminant of a constrained record type,
6885          --  we may be able to rewrite the expression with the actual value
6886          --  of the discriminant, a useful optimization in some cases.
6887
6888          if Is_Record_Type (Ptyp)
6889            and then Has_Discriminants (Ptyp)
6890            and then Is_Constrained (Ptyp)
6891          then
6892             --  Do this optimization for discrete types only, and not for
6893             --  access types (access discriminants get us into trouble!)
6894
6895             if not Is_Discrete_Type (Etype (N)) then
6896                null;
6897
6898             --  Don't do this on the left hand of an assignment statement.
6899             --  Normally one would think that references like this would
6900             --  not occur, but they do in generated code, and mean that
6901             --  we really do want to assign the discriminant!
6902
6903             elsif Nkind (Par) = N_Assignment_Statement
6904               and then Name (Par) = N
6905             then
6906                null;
6907
6908             --  Don't do this optimization for the prefix of an attribute or
6909             --  the operand of an object renaming declaration since these are
6910             --  contexts where we do not want the value anyway.
6911
6912             elsif (Nkind (Par) = N_Attribute_Reference
6913                      and then Prefix (Par) = N)
6914               or else Is_Renamed_Object (N)
6915             then
6916                null;
6917
6918             --  Don't do this optimization if we are within the code for a
6919             --  discriminant check, since the whole point of such a check may
6920             --  be to verify the condition on which the code below depends!
6921
6922             elsif Is_In_Discriminant_Check (N) then
6923                null;
6924
6925             --  Green light to see if we can do the optimization. There is
6926             --  still one condition that inhibits the optimization below but
6927             --  now is the time to check the particular discriminant.
6928
6929             else
6930                --  Loop through discriminants to find the matching discriminant
6931                --  constraint to see if we can copy it.
6932
6933                Disc := First_Discriminant (Ptyp);
6934                Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
6935                Discr_Loop : while Present (Dcon) loop
6936
6937                   --  Check if this is the matching discriminant
6938
6939                   if Disc = Entity (Selector_Name (N)) then
6940
6941                      --  Here we have the matching discriminant. Check for
6942                      --  the case of a discriminant of a component that is
6943                      --  constrained by an outer discriminant, which cannot
6944                      --  be optimized away.
6945
6946                      if
6947                        Denotes_Discriminant
6948                         (Node (Dcon), Check_Concurrent => True)
6949                      then
6950                         exit Discr_Loop;
6951
6952                      --  In the context of a case statement, the expression may
6953                      --  have the base type of the discriminant, and we need to
6954                      --  preserve the constraint to avoid spurious errors on
6955                      --  missing cases.
6956
6957                      elsif Nkind (Parent (N)) = N_Case_Statement
6958                        and then Etype (Node (Dcon)) /= Etype (Disc)
6959                      then
6960                         Rewrite (N,
6961                           Make_Qualified_Expression (Loc,
6962                             Subtype_Mark =>
6963                               New_Occurrence_Of (Etype (Disc), Loc),
6964                             Expression   =>
6965                               New_Copy_Tree (Node (Dcon))));
6966                         Analyze_And_Resolve (N, Etype (Disc));
6967
6968                         --  In case that comes out as a static expression,
6969                         --  reset it (a selected component is never static).
6970
6971                         Set_Is_Static_Expression (N, False);
6972                         return;
6973
6974                      --  Otherwise we can just copy the constraint, but the
6975                      --  result is certainly not static! In some cases the
6976                      --  discriminant constraint has been analyzed in the
6977                      --  context of the original subtype indication, but for
6978                      --  itypes the constraint might not have been analyzed
6979                      --  yet, and this must be done now.
6980
6981                      else
6982                         Rewrite (N, New_Copy_Tree (Node (Dcon)));
6983                         Analyze_And_Resolve (N);
6984                         Set_Is_Static_Expression (N, False);
6985                         return;
6986                      end if;
6987                   end if;
6988
6989                   Next_Elmt (Dcon);
6990                   Next_Discriminant (Disc);
6991                end loop Discr_Loop;
6992
6993                --  Note: the above loop should always find a matching
6994                --  discriminant, but if it does not, we just missed an
6995                --  optimization due to some glitch (perhaps a previous error),
6996                --  so ignore.
6997
6998             end if;
6999          end if;
7000
7001          --  The only remaining processing is in the case of a discriminant of
7002          --  a concurrent object, where we rewrite the prefix to denote the
7003          --  corresponding record type. If the type is derived and has renamed
7004          --  discriminants, use corresponding discriminant, which is the one
7005          --  that appears in the corresponding record.
7006
7007          if not Is_Concurrent_Type (Ptyp) then
7008             return;
7009          end if;
7010
7011          Disc := Entity (Selector_Name (N));
7012
7013          if Is_Derived_Type (Ptyp)
7014            and then Present (Corresponding_Discriminant (Disc))
7015          then
7016             Disc := Corresponding_Discriminant (Disc);
7017          end if;
7018
7019          New_N :=
7020            Make_Selected_Component (Loc,
7021              Prefix =>
7022                Unchecked_Convert_To (Corresponding_Record_Type (Ptyp),
7023                  New_Copy_Tree (P)),
7024              Selector_Name => Make_Identifier (Loc, Chars (Disc)));
7025
7026          Rewrite (N, New_N);
7027          Analyze (N);
7028       end if;
7029    end Expand_N_Selected_Component;
7030
7031    --------------------
7032    -- Expand_N_Slice --
7033    --------------------
7034
7035    procedure Expand_N_Slice (N : Node_Id) is
7036       Loc  : constant Source_Ptr := Sloc (N);
7037       Typ  : constant Entity_Id  := Etype (N);
7038       Pfx  : constant Node_Id    := Prefix (N);
7039       Ptp  : Entity_Id           := Etype (Pfx);
7040
7041       function Is_Procedure_Actual (N : Node_Id) return Boolean;
7042       --  Check whether the argument is an actual for a procedure call, in
7043       --  which case the expansion of a bit-packed slice is deferred until the
7044       --  call itself is expanded. The reason this is required is that we might
7045       --  have an IN OUT or OUT parameter, and the copy out is essential, and
7046       --  that copy out would be missed if we created a temporary here in
7047       --  Expand_N_Slice. Note that we don't bother to test specifically for an
7048       --  IN OUT or OUT mode parameter, since it is a bit tricky to do, and it
7049       --  is harmless to defer expansion in the IN case, since the call
7050       --  processing will still generate the appropriate copy in operation,
7051       --  which will take care of the slice.
7052
7053       procedure Make_Temporary;
7054       --  Create a named variable for the value of the slice, in cases where
7055       --  the back-end cannot handle it properly, e.g. when packed types or
7056       --  unaligned slices are involved.
7057
7058       -------------------------
7059       -- Is_Procedure_Actual --
7060       -------------------------
7061
7062       function Is_Procedure_Actual (N : Node_Id) return Boolean is
7063          Par : Node_Id := Parent (N);
7064
7065       begin
7066          loop
7067             --  If our parent is a procedure call we can return
7068
7069             if Nkind (Par) = N_Procedure_Call_Statement then
7070                return True;
7071
7072             --  If our parent is a type conversion, keep climbing the tree,
7073             --  since a type conversion can be a procedure actual. Also keep
7074             --  climbing if parameter association or a qualified expression,
7075             --  since these are additional cases that do can appear on
7076             --  procedure actuals.
7077
7078             elsif Nkind_In (Par, N_Type_Conversion,
7079                                  N_Parameter_Association,
7080                                  N_Qualified_Expression)
7081             then
7082                Par := Parent (Par);
7083
7084                --  Any other case is not what we are looking for
7085
7086             else
7087                return False;
7088             end if;
7089          end loop;
7090       end Is_Procedure_Actual;
7091
7092       --------------------
7093       -- Make_Temporary --
7094       --------------------
7095
7096       procedure Make_Temporary is
7097          Decl : Node_Id;
7098          Ent  : constant Entity_Id :=
7099                   Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
7100       begin
7101          Decl :=
7102            Make_Object_Declaration (Loc,
7103              Defining_Identifier => Ent,
7104              Object_Definition   => New_Occurrence_Of (Typ, Loc));
7105
7106          Set_No_Initialization (Decl);
7107
7108          Insert_Actions (N, New_List (
7109            Decl,
7110            Make_Assignment_Statement (Loc,
7111              Name => New_Occurrence_Of (Ent, Loc),
7112              Expression => Relocate_Node (N))));
7113
7114          Rewrite (N, New_Occurrence_Of (Ent, Loc));
7115          Analyze_And_Resolve (N, Typ);
7116       end Make_Temporary;
7117
7118    --  Start of processing for Expand_N_Slice
7119
7120    begin
7121       --  Special handling for access types
7122
7123       if Is_Access_Type (Ptp) then
7124
7125          Ptp := Designated_Type (Ptp);
7126
7127          Rewrite (Pfx,
7128            Make_Explicit_Dereference (Sloc (N),
7129             Prefix => Relocate_Node (Pfx)));
7130
7131          Analyze_And_Resolve (Pfx, Ptp);
7132       end if;
7133
7134       --  Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
7135       --  function, then additional actuals must be passed.
7136
7137       if Ada_Version >= Ada_05
7138         and then Is_Build_In_Place_Function_Call (Pfx)
7139       then
7140          Make_Build_In_Place_Call_In_Anonymous_Context (Pfx);
7141       end if;
7142
7143       --  Range checks are potentially also needed for cases involving a slice
7144       --  indexed by a subtype indication, but Do_Range_Check can currently
7145       --  only be set for expressions ???
7146
7147       if not Index_Checks_Suppressed (Ptp)
7148         and then (not Is_Entity_Name (Pfx)
7149                    or else not Index_Checks_Suppressed (Entity (Pfx)))
7150         and then Nkind (Discrete_Range (N)) /= N_Subtype_Indication
7151
7152          --  Do not enable range check to nodes associated with the frontend
7153          --  expansion of the dispatch table. We first check if Ada.Tags is
7154          --  already loaded to avoid the addition of an undesired dependence
7155          --  on such run-time unit.
7156
7157         and then
7158           (VM_Target /= No_VM
7159             or else not
7160              (RTU_Loaded (Ada_Tags)
7161                and then Nkind (Prefix (N)) = N_Selected_Component
7162                and then Present (Entity (Selector_Name (Prefix (N))))
7163                and then Entity (Selector_Name (Prefix (N))) =
7164                                   RTE_Record_Component (RE_Prims_Ptr)))
7165       then
7166          Enable_Range_Check (Discrete_Range (N));
7167       end if;
7168
7169       --  The remaining case to be handled is packed slices. We can leave
7170       --  packed slices as they are in the following situations:
7171
7172       --    1. Right or left side of an assignment (we can handle this
7173       --       situation correctly in the assignment statement expansion).
7174
7175       --    2. Prefix of indexed component (the slide is optimized away in this
7176       --       case, see the start of Expand_N_Slice.)
7177
7178       --    3. Object renaming declaration, since we want the name of the
7179       --       slice, not the value.
7180
7181       --    4. Argument to procedure call, since copy-in/copy-out handling may
7182       --       be required, and this is handled in the expansion of call
7183       --       itself.
7184
7185       --    5. Prefix of an address attribute (this is an error which is caught
7186       --       elsewhere, and the expansion would interfere with generating the
7187       --       error message).
7188
7189       if not Is_Packed (Typ) then
7190
7191          --  Apply transformation for actuals of a function call, where
7192          --  Expand_Actuals is not used.
7193
7194          if Nkind (Parent (N)) = N_Function_Call
7195            and then Is_Possibly_Unaligned_Slice (N)
7196          then
7197             Make_Temporary;
7198          end if;
7199
7200       elsif Nkind (Parent (N)) = N_Assignment_Statement
7201         or else (Nkind (Parent (Parent (N))) = N_Assignment_Statement
7202                    and then Parent (N) = Name (Parent (Parent (N))))
7203       then
7204          return;
7205
7206       elsif Nkind (Parent (N)) = N_Indexed_Component
7207         or else Is_Renamed_Object (N)
7208         or else Is_Procedure_Actual (N)
7209       then
7210          return;
7211
7212       elsif Nkind (Parent (N)) = N_Attribute_Reference
7213         and then Attribute_Name (Parent (N)) = Name_Address
7214       then
7215          return;
7216
7217       else
7218          Make_Temporary;
7219       end if;
7220    end Expand_N_Slice;
7221
7222    ------------------------------
7223    -- Expand_N_Type_Conversion --
7224    ------------------------------
7225
7226    procedure Expand_N_Type_Conversion (N : Node_Id) is
7227       Loc          : constant Source_Ptr := Sloc (N);
7228       Operand      : constant Node_Id    := Expression (N);
7229       Target_Type  : constant Entity_Id  := Etype (N);
7230       Operand_Type : Entity_Id           := Etype (Operand);
7231
7232       procedure Handle_Changed_Representation;
7233       --  This is called in the case of record and array type conversions to
7234       --  see if there is a change of representation to be handled. Change of
7235       --  representation is actually handled at the assignment statement level,
7236       --  and what this procedure does is rewrite node N conversion as an
7237       --  assignment to temporary. If there is no change of representation,
7238       --  then the conversion node is unchanged.
7239
7240       procedure Real_Range_Check;
7241       --  Handles generation of range check for real target value
7242
7243       -----------------------------------
7244       -- Handle_Changed_Representation --
7245       -----------------------------------
7246
7247       procedure Handle_Changed_Representation is
7248          Temp : Entity_Id;
7249          Decl : Node_Id;
7250          Odef : Node_Id;
7251          Disc : Node_Id;
7252          N_Ix : Node_Id;
7253          Cons : List_Id;
7254
7255       begin
7256          --  Nothing else to do if no change of representation
7257
7258          if Same_Representation (Operand_Type, Target_Type) then
7259             return;
7260
7261          --  The real change of representation work is done by the assignment
7262          --  statement processing. So if this type conversion is appearing as
7263          --  the expression of an assignment statement, nothing needs to be
7264          --  done to the conversion.
7265
7266          elsif Nkind (Parent (N)) = N_Assignment_Statement then
7267             return;
7268
7269          --  Otherwise we need to generate a temporary variable, and do the
7270          --  change of representation assignment into that temporary variable.
7271          --  The conversion is then replaced by a reference to this variable.
7272
7273          else
7274             Cons := No_List;
7275
7276             --  If type is unconstrained we have to add a constraint, copied
7277             --  from the actual value of the left hand side.
7278
7279             if not Is_Constrained (Target_Type) then
7280                if Has_Discriminants (Operand_Type) then
7281                   Disc := First_Discriminant (Operand_Type);
7282
7283                   if Disc /= First_Stored_Discriminant (Operand_Type) then
7284                      Disc := First_Stored_Discriminant (Operand_Type);
7285                   end if;
7286
7287                   Cons := New_List;
7288                   while Present (Disc) loop
7289                      Append_To (Cons,
7290                        Make_Selected_Component (Loc,
7291                          Prefix => Duplicate_Subexpr_Move_Checks (Operand),
7292                          Selector_Name =>
7293                            Make_Identifier (Loc, Chars (Disc))));
7294                      Next_Discriminant (Disc);
7295                   end loop;
7296
7297                elsif Is_Array_Type (Operand_Type) then
7298                   N_Ix := First_Index (Target_Type);
7299                   Cons := New_List;
7300
7301                   for J in 1 .. Number_Dimensions (Operand_Type) loop
7302
7303                      --  We convert the bounds explicitly. We use an unchecked
7304                      --  conversion because bounds checks are done elsewhere.
7305
7306                      Append_To (Cons,
7307                        Make_Range (Loc,
7308                          Low_Bound =>
7309                            Unchecked_Convert_To (Etype (N_Ix),
7310                              Make_Attribute_Reference (Loc,
7311                                Prefix =>
7312                                  Duplicate_Subexpr_No_Checks
7313                                    (Operand, Name_Req => True),
7314                                Attribute_Name => Name_First,
7315                                Expressions    => New_List (
7316                                  Make_Integer_Literal (Loc, J)))),
7317
7318                          High_Bound =>
7319                            Unchecked_Convert_To (Etype (N_Ix),
7320                              Make_Attribute_Reference (Loc,
7321                                Prefix =>
7322                                  Duplicate_Subexpr_No_Checks
7323                                    (Operand, Name_Req => True),
7324                                Attribute_Name => Name_Last,
7325                                Expressions    => New_List (
7326                                  Make_Integer_Literal (Loc, J))))));
7327
7328                      Next_Index (N_Ix);
7329                   end loop;
7330                end if;
7331             end if;
7332
7333             Odef := New_Occurrence_Of (Target_Type, Loc);
7334
7335             if Present (Cons) then
7336                Odef :=
7337                  Make_Subtype_Indication (Loc,
7338                    Subtype_Mark => Odef,
7339                    Constraint =>
7340                      Make_Index_Or_Discriminant_Constraint (Loc,
7341                        Constraints => Cons));
7342             end if;
7343
7344             Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('C'));
7345             Decl :=
7346               Make_Object_Declaration (Loc,
7347                 Defining_Identifier => Temp,
7348                 Object_Definition   => Odef);
7349
7350             Set_No_Initialization (Decl, True);
7351
7352             --  Insert required actions. It is essential to suppress checks
7353             --  since we have suppressed default initialization, which means
7354             --  that the variable we create may have no discriminants.
7355
7356             Insert_Actions (N,
7357               New_List (
7358                 Decl,
7359                 Make_Assignment_Statement (Loc,
7360                   Name => New_Occurrence_Of (Temp, Loc),
7361                   Expression => Relocate_Node (N))),
7362                 Suppress => All_Checks);
7363
7364             Rewrite (N, New_Occurrence_Of (Temp, Loc));
7365             return;
7366          end if;
7367       end Handle_Changed_Representation;
7368
7369       ----------------------
7370       -- Real_Range_Check --
7371       ----------------------
7372
7373       --  Case of conversions to floating-point or fixed-point. If range checks
7374       --  are enabled and the target type has a range constraint, we convert:
7375
7376       --     typ (x)
7377
7378       --       to
7379
7380       --     Tnn : typ'Base := typ'Base (x);
7381       --     [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
7382       --     Tnn
7383
7384       --  This is necessary when there is a conversion of integer to float or
7385       --  to fixed-point to ensure that the correct checks are made. It is not
7386       --  necessary for float to float where it is enough to simply set the
7387       --  Do_Range_Check flag.
7388
7389       procedure Real_Range_Check is
7390          Btyp : constant Entity_Id := Base_Type (Target_Type);
7391          Lo   : constant Node_Id   := Type_Low_Bound  (Target_Type);
7392          Hi   : constant Node_Id   := Type_High_Bound (Target_Type);
7393          Xtyp : constant Entity_Id := Etype (Operand);
7394          Conv : Node_Id;
7395          Tnn  : Entity_Id;
7396
7397       begin
7398          --  Nothing to do if conversion was rewritten
7399
7400          if Nkind (N) /= N_Type_Conversion then
7401             return;
7402          end if;
7403
7404          --  Nothing to do if range checks suppressed, or target has the same
7405          --  range as the base type (or is the base type).
7406
7407          if Range_Checks_Suppressed (Target_Type)
7408            or else (Lo = Type_Low_Bound (Btyp)
7409                       and then
7410                     Hi = Type_High_Bound (Btyp))
7411          then
7412             return;
7413          end if;
7414
7415          --  Nothing to do if expression is an entity on which checks have been
7416          --  suppressed.
7417
7418          if Is_Entity_Name (Operand)
7419            and then Range_Checks_Suppressed (Entity (Operand))
7420          then
7421             return;
7422          end if;
7423
7424          --  Nothing to do if bounds are all static and we can tell that the
7425          --  expression is within the bounds of the target. Note that if the
7426          --  operand is of an unconstrained floating-point type, then we do
7427          --  not trust it to be in range (might be infinite)
7428
7429          declare
7430             S_Lo : constant Node_Id := Type_Low_Bound (Xtyp);
7431             S_Hi : constant Node_Id := Type_High_Bound (Xtyp);
7432
7433          begin
7434             if (not Is_Floating_Point_Type (Xtyp)
7435                  or else Is_Constrained (Xtyp))
7436               and then Compile_Time_Known_Value (S_Lo)
7437               and then Compile_Time_Known_Value (S_Hi)
7438               and then Compile_Time_Known_Value (Hi)
7439               and then Compile_Time_Known_Value (Lo)
7440             then
7441                declare
7442                   D_Lov : constant Ureal := Expr_Value_R (Lo);
7443                   D_Hiv : constant Ureal := Expr_Value_R (Hi);
7444                   S_Lov : Ureal;
7445                   S_Hiv : Ureal;
7446
7447                begin
7448                   if Is_Real_Type (Xtyp) then
7449                      S_Lov := Expr_Value_R (S_Lo);
7450                      S_Hiv := Expr_Value_R (S_Hi);
7451                   else
7452                      S_Lov := UR_From_Uint (Expr_Value (S_Lo));
7453                      S_Hiv := UR_From_Uint (Expr_Value (S_Hi));
7454                   end if;
7455
7456                   if D_Hiv > D_Lov
7457                     and then S_Lov >= D_Lov
7458                     and then S_Hiv <= D_Hiv
7459                   then
7460                      Set_Do_Range_Check (Operand, False);
7461                      return;
7462                   end if;
7463                end;
7464             end if;
7465          end;
7466
7467          --  For float to float conversions, we are done
7468
7469          if Is_Floating_Point_Type (Xtyp)
7470               and then
7471             Is_Floating_Point_Type (Btyp)
7472          then
7473             return;
7474          end if;
7475
7476          --  Otherwise rewrite the conversion as described above
7477
7478          Conv := Relocate_Node (N);
7479          Rewrite
7480            (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc));
7481          Set_Etype (Conv, Btyp);
7482
7483          --  Enable overflow except for case of integer to float conversions,
7484          --  where it is never required, since we can never have overflow in
7485          --  this case.
7486
7487          if not Is_Integer_Type (Etype (Operand)) then
7488             Enable_Overflow_Check (Conv);
7489          end if;
7490
7491          Tnn :=
7492            Make_Defining_Identifier (Loc,
7493              Chars => New_Internal_Name ('T'));
7494
7495          Insert_Actions (N, New_List (
7496            Make_Object_Declaration (Loc,
7497              Defining_Identifier => Tnn,
7498              Object_Definition   => New_Occurrence_Of (Btyp, Loc),
7499              Expression => Conv),
7500
7501            Make_Raise_Constraint_Error (Loc,
7502              Condition =>
7503               Make_Or_Else (Loc,
7504                 Left_Opnd =>
7505                   Make_Op_Lt (Loc,
7506                     Left_Opnd  => New_Occurrence_Of (Tnn, Loc),
7507                     Right_Opnd =>
7508                       Make_Attribute_Reference (Loc,
7509                         Attribute_Name => Name_First,
7510                         Prefix =>
7511                           New_Occurrence_Of (Target_Type, Loc))),
7512
7513                 Right_Opnd =>
7514                   Make_Op_Gt (Loc,
7515                     Left_Opnd  => New_Occurrence_Of (Tnn, Loc),
7516                     Right_Opnd =>
7517                       Make_Attribute_Reference (Loc,
7518                         Attribute_Name => Name_Last,
7519                         Prefix =>
7520                           New_Occurrence_Of (Target_Type, Loc)))),
7521              Reason => CE_Range_Check_Failed)));
7522
7523          Rewrite (N, New_Occurrence_Of (Tnn, Loc));
7524          Analyze_And_Resolve (N, Btyp);
7525       end Real_Range_Check;
7526
7527    --  Start of processing for Expand_N_Type_Conversion
7528
7529    begin
7530       --  Nothing at all to do if conversion is to the identical type so remove
7531       --  the conversion completely, it is useless.
7532
7533       if Operand_Type = Target_Type then
7534          Rewrite (N, Relocate_Node (Operand));
7535          return;
7536       end if;
7537
7538       --  Nothing to do if this is the second argument of read. This is a
7539       --  "backwards" conversion that will be handled by the specialized code
7540       --  in attribute processing.
7541
7542       if Nkind (Parent (N)) = N_Attribute_Reference
7543         and then Attribute_Name (Parent (N)) = Name_Read
7544         and then Next (First (Expressions (Parent (N)))) = N
7545       then
7546          return;
7547       end if;
7548
7549       --  Here if we may need to expand conversion
7550
7551       --  Do validity check if validity checking operands
7552
7553       if Validity_Checks_On
7554         and then Validity_Check_Operands
7555       then
7556          Ensure_Valid (Operand);
7557       end if;
7558
7559       --  Special case of converting from non-standard boolean type
7560
7561       if Is_Boolean_Type (Operand_Type)
7562         and then (Nonzero_Is_True (Operand_Type))
7563       then
7564          Adjust_Condition (Operand);
7565          Set_Etype (Operand, Standard_Boolean);
7566          Operand_Type := Standard_Boolean;
7567       end if;
7568
7569       --  Case of converting to an access type
7570
7571       if Is_Access_Type (Target_Type) then
7572
7573          --  Apply an accessibility check when the conversion operand is an
7574          --  access parameter (or a renaming thereof), unless conversion was
7575          --  expanded from an Unchecked_ or Unrestricted_Access attribute.
7576          --  Note that other checks may still need to be applied below (such
7577          --  as tagged type checks).
7578
7579          if Is_Entity_Name (Operand)
7580            and then
7581              (Is_Formal (Entity (Operand))
7582                or else
7583                  (Present (Renamed_Object (Entity (Operand)))
7584                    and then Is_Entity_Name (Renamed_Object (Entity (Operand)))
7585                    and then Is_Formal
7586                               (Entity (Renamed_Object (Entity (Operand))))))
7587            and then Ekind (Etype (Operand)) = E_Anonymous_Access_Type
7588            and then (Nkind (Original_Node (N)) /= N_Attribute_Reference
7589                       or else Attribute_Name (Original_Node (N)) = Name_Access)
7590          then
7591             Apply_Accessibility_Check
7592               (Operand, Target_Type, Insert_Node => Operand);
7593
7594          --  If the level of the operand type is statically deeper than the
7595          --  level of the target type, then force Program_Error. Note that this
7596          --  can only occur for cases where the attribute is within the body of
7597          --  an instantiation (otherwise the conversion will already have been
7598          --  rejected as illegal). Note: warnings are issued by the analyzer
7599          --  for the instance cases.
7600
7601          elsif In_Instance_Body
7602            and then Type_Access_Level (Operand_Type) >
7603                     Type_Access_Level (Target_Type)
7604          then
7605             Rewrite (N,
7606               Make_Raise_Program_Error (Sloc (N),
7607                 Reason => PE_Accessibility_Check_Failed));
7608             Set_Etype (N, Target_Type);
7609
7610          --  When the operand is a selected access discriminant the check needs
7611          --  to be made against the level of the object denoted by the prefix
7612          --  of the selected name. Force Program_Error for this case as well
7613          --  (this accessibility violation can only happen if within the body
7614          --  of an instantiation).
7615
7616          elsif In_Instance_Body
7617            and then Ekind (Operand_Type) = E_Anonymous_Access_Type
7618            and then Nkind (Operand) = N_Selected_Component
7619            and then Object_Access_Level (Operand) >
7620                       Type_Access_Level (Target_Type)
7621          then
7622             Rewrite (N,
7623               Make_Raise_Program_Error (Sloc (N),
7624                 Reason => PE_Accessibility_Check_Failed));
7625             Set_Etype (N, Target_Type);
7626          end if;
7627       end if;
7628
7629       --  Case of conversions of tagged types and access to tagged types
7630
7631       --  When needed, that is to say when the expression is class-wide, Add
7632       --  runtime a tag check for (strict) downward conversion by using the
7633       --  membership test, generating:
7634
7635       --      [constraint_error when Operand not in Target_Type'Class]
7636
7637       --  or in the access type case
7638
7639       --      [constraint_error
7640       --        when Operand /= null
7641       --          and then Operand.all not in
7642       --            Designated_Type (Target_Type)'Class]
7643
7644       if (Is_Access_Type (Target_Type)
7645            and then Is_Tagged_Type (Designated_Type (Target_Type)))
7646         or else Is_Tagged_Type (Target_Type)
7647       then
7648          --  Do not do any expansion in the access type case if the parent is a
7649          --  renaming, since this is an error situation which will be caught by
7650          --  Sem_Ch8, and the expansion can interfere with this error check.
7651
7652          if Is_Access_Type (Target_Type)
7653            and then Is_Renamed_Object (N)
7654          then
7655             return;
7656          end if;
7657
7658          --  Otherwise, proceed with processing tagged conversion
7659
7660          declare
7661             Actual_Op_Typ   : Entity_Id;
7662             Actual_Targ_Typ : Entity_Id;
7663             Make_Conversion : Boolean := False;
7664             Root_Op_Typ     : Entity_Id;
7665
7666             procedure Make_Tag_Check (Targ_Typ : Entity_Id);
7667             --  Create a membership check to test whether Operand is a member
7668             --  of Targ_Typ. If the original Target_Type is an access, include
7669             --  a test for null value. The check is inserted at N.
7670
7671             --------------------
7672             -- Make_Tag_Check --
7673             --------------------
7674
7675             procedure Make_Tag_Check (Targ_Typ : Entity_Id) is
7676                Cond : Node_Id;
7677
7678             begin
7679                --  Generate:
7680                --    [Constraint_Error
7681                --       when Operand /= null
7682                --         and then Operand.all not in Targ_Typ]
7683
7684                if Is_Access_Type (Target_Type) then
7685                   Cond :=
7686                     Make_And_Then (Loc,
7687                       Left_Opnd =>
7688                         Make_Op_Ne (Loc,
7689                           Left_Opnd  => Duplicate_Subexpr_No_Checks (Operand),
7690                           Right_Opnd => Make_Null (Loc)),
7691
7692                       Right_Opnd =>
7693                         Make_Not_In (Loc,
7694                           Left_Opnd  =>
7695                             Make_Explicit_Dereference (Loc,
7696                               Prefix => Duplicate_Subexpr_No_Checks (Operand)),
7697                           Right_Opnd => New_Reference_To (Targ_Typ, Loc)));
7698
7699                --  Generate:
7700                --    [Constraint_Error when Operand not in Targ_Typ]
7701
7702                else
7703                   Cond :=
7704                     Make_Not_In (Loc,
7705                       Left_Opnd  => Duplicate_Subexpr_No_Checks (Operand),
7706                       Right_Opnd => New_Reference_To (Targ_Typ, Loc));
7707                end if;
7708
7709                Insert_Action (N,
7710                  Make_Raise_Constraint_Error (Loc,
7711                    Condition => Cond,
7712                    Reason    => CE_Tag_Check_Failed));
7713             end Make_Tag_Check;
7714
7715          --  Start of processing
7716
7717          begin
7718             if Is_Access_Type (Target_Type) then
7719                Actual_Op_Typ   := Designated_Type (Operand_Type);
7720                Actual_Targ_Typ := Designated_Type (Target_Type);
7721
7722             else
7723                Actual_Op_Typ   := Operand_Type;
7724                Actual_Targ_Typ := Target_Type;
7725             end if;
7726
7727             Root_Op_Typ := Root_Type (Actual_Op_Typ);
7728
7729             --  Ada 2005 (AI-251): Handle interface type conversion
7730
7731             if Is_Interface (Actual_Op_Typ) then
7732                Expand_Interface_Conversion (N, Is_Static => False);
7733                return;
7734             end if;
7735
7736             if not Tag_Checks_Suppressed (Actual_Targ_Typ) then
7737
7738                --  Create a runtime tag check for a downward class-wide type
7739                --  conversion.
7740
7741                if Is_Class_Wide_Type (Actual_Op_Typ)
7742                  and then Root_Op_Typ /= Actual_Targ_Typ
7743                  and then Is_Ancestor (Root_Op_Typ, Actual_Targ_Typ)
7744                then
7745                   Make_Tag_Check (Class_Wide_Type (Actual_Targ_Typ));
7746                   Make_Conversion := True;
7747                end if;
7748
7749                --  AI05-0073: If the result subtype of the function is defined
7750                --  by an access_definition designating a specific tagged type
7751                --  T, a check is made that the result value is null or the tag
7752                --  of the object designated by the result value identifies T.
7753                --  Constraint_Error is raised if this check fails.
7754
7755                if Nkind (Parent (N)) = Sinfo.N_Return_Statement then
7756                   declare
7757                      Func     : Entity_Id;
7758                      Func_Typ : Entity_Id;
7759
7760                   begin
7761                      --  Climb scope stack looking for the enclosing function
7762
7763                      Func := Current_Scope;
7764                      while Present (Func)
7765                        and then Ekind (Func) /= E_Function
7766                      loop
7767                         Func := Scope (Func);
7768                      end loop;
7769
7770                      --  The function's return subtype must be defined using
7771                      --  an access definition.
7772
7773                      if Nkind (Result_Definition (Parent (Func))) =
7774                           N_Access_Definition
7775                      then
7776                         Func_Typ := Directly_Designated_Type (Etype (Func));
7777
7778                         --  The return subtype denotes a specific tagged type,
7779                         --  in other words, a non class-wide type.
7780
7781                         if Is_Tagged_Type (Func_Typ)
7782                           and then not Is_Class_Wide_Type (Func_Typ)
7783                         then
7784                            Make_Tag_Check (Actual_Targ_Typ);
7785                            Make_Conversion := True;
7786                         end if;
7787                      end if;
7788                   end;
7789                end if;
7790
7791                --  We have generated a tag check for either a class-wide type
7792                --  conversion or for AI05-0073.
7793
7794                if Make_Conversion then
7795                   declare
7796                      Conv : Node_Id;
7797                   begin
7798                      Conv :=
7799                        Make_Unchecked_Type_Conversion (Loc,
7800                          Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
7801                          Expression   => Relocate_Node (Expression (N)));
7802                      Rewrite (N, Conv);
7803                      Analyze_And_Resolve (N, Target_Type);
7804                   end;
7805                end if;
7806             end if;
7807          end;
7808
7809       --  Case of other access type conversions
7810
7811       elsif Is_Access_Type (Target_Type) then
7812          Apply_Constraint_Check (Operand, Target_Type);
7813
7814       --  Case of conversions from a fixed-point type
7815
7816       --  These conversions require special expansion and processing, found in
7817       --  the Exp_Fixd package. We ignore cases where Conversion_OK is set,
7818       --  since from a semantic point of view, these are simple integer
7819       --  conversions, which do not need further processing.
7820
7821       elsif Is_Fixed_Point_Type (Operand_Type)
7822         and then not Conversion_OK (N)
7823       then
7824          --  We should never see universal fixed at this case, since the
7825          --  expansion of the constituent divide or multiply should have
7826          --  eliminated the explicit mention of universal fixed.
7827
7828          pragma Assert (Operand_Type /= Universal_Fixed);
7829
7830          --  Check for special case of the conversion to universal real that
7831          --  occurs as a result of the use of a round attribute. In this case,
7832          --  the real type for the conversion is taken from the target type of
7833          --  the Round attribute and the result must be marked as rounded.
7834
7835          if Target_Type = Universal_Real
7836            and then Nkind (Parent (N)) = N_Attribute_Reference
7837            and then Attribute_Name (Parent (N)) = Name_Round
7838          then
7839             Set_Rounded_Result (N);
7840             Set_Etype (N, Etype (Parent (N)));
7841          end if;
7842
7843          --  Otherwise do correct fixed-conversion, but skip these if the
7844          --  Conversion_OK flag is set, because from a semantic point of
7845          --  view these are simple integer conversions needing no further
7846          --  processing (the backend will simply treat them as integers)
7847
7848          if not Conversion_OK (N) then
7849             if Is_Fixed_Point_Type (Etype (N)) then
7850                Expand_Convert_Fixed_To_Fixed (N);
7851                Real_Range_Check;
7852
7853             elsif Is_Integer_Type (Etype (N)) then
7854                Expand_Convert_Fixed_To_Integer (N);
7855
7856             else
7857                pragma Assert (Is_Floating_Point_Type (Etype (N)));
7858                Expand_Convert_Fixed_To_Float (N);
7859                Real_Range_Check;
7860             end if;
7861          end if;
7862
7863       --  Case of conversions to a fixed-point type
7864
7865       --  These conversions require special expansion and processing, found in
7866       --  the Exp_Fixd package. Again, ignore cases where Conversion_OK is set,
7867       --  since from a semantic point of view, these are simple integer
7868       --  conversions, which do not need further processing.
7869
7870       elsif Is_Fixed_Point_Type (Target_Type)
7871         and then not Conversion_OK (N)
7872       then
7873          if Is_Integer_Type (Operand_Type) then
7874             Expand_Convert_Integer_To_Fixed (N);
7875             Real_Range_Check;
7876          else
7877             pragma Assert (Is_Floating_Point_Type (Operand_Type));
7878             Expand_Convert_Float_To_Fixed (N);
7879             Real_Range_Check;
7880          end if;
7881
7882       --  Case of float-to-integer conversions
7883
7884       --  We also handle float-to-fixed conversions with Conversion_OK set
7885       --  since semantically the fixed-point target is treated as though it
7886       --  were an integer in such cases.
7887
7888       elsif Is_Floating_Point_Type (Operand_Type)
7889         and then
7890           (Is_Integer_Type (Target_Type)
7891             or else
7892           (Is_Fixed_Point_Type (Target_Type) and then Conversion_OK (N)))
7893       then
7894          --  One more check here, gcc is still not able to do conversions of
7895          --  this type with proper overflow checking, and so gigi is doing an
7896          --  approximation of what is required by doing floating-point compares
7897          --  with the end-point. But that can lose precision in some cases, and
7898          --  give a wrong result. Converting the operand to Universal_Real is
7899          --  helpful, but still does not catch all cases with 64-bit integers
7900          --  on targets with only 64-bit floats
7901
7902          --  The above comment seems obsoleted by Apply_Float_Conversion_Check
7903          --  Can this code be removed ???
7904
7905          if Do_Range_Check (Operand) then
7906             Rewrite (Operand,
7907               Make_Type_Conversion (Loc,
7908                 Subtype_Mark =>
7909                   New_Occurrence_Of (Universal_Real, Loc),
7910                 Expression =>
7911                   Relocate_Node (Operand)));
7912
7913             Set_Etype (Operand, Universal_Real);
7914             Enable_Range_Check (Operand);
7915             Set_Do_Range_Check (Expression (Operand), False);
7916          end if;
7917
7918       --  Case of array conversions
7919
7920       --  Expansion of array conversions, add required length/range checks but
7921       --  only do this if there is no change of representation. For handling of
7922       --  this case, see Handle_Changed_Representation.
7923
7924       elsif Is_Array_Type (Target_Type) then
7925
7926          if Is_Constrained (Target_Type) then
7927             Apply_Length_Check (Operand, Target_Type);
7928          else
7929             Apply_Range_Check (Operand, Target_Type);
7930          end if;
7931
7932          Handle_Changed_Representation;
7933
7934       --  Case of conversions of discriminated types
7935
7936       --  Add required discriminant checks if target is constrained. Again this
7937       --  change is skipped if we have a change of representation.
7938
7939       elsif Has_Discriminants (Target_Type)
7940         and then Is_Constrained (Target_Type)
7941       then
7942          Apply_Discriminant_Check (Operand, Target_Type);
7943          Handle_Changed_Representation;
7944
7945       --  Case of all other record conversions. The only processing required
7946       --  is to check for a change of representation requiring the special
7947       --  assignment processing.
7948
7949       elsif Is_Record_Type (Target_Type) then
7950
7951          --  Ada 2005 (AI-216): Program_Error is raised when converting from
7952          --  a derived Unchecked_Union type to an unconstrained type that is
7953          --  not Unchecked_Union if the operand lacks inferable discriminants.
7954
7955          if Is_Derived_Type (Operand_Type)
7956            and then Is_Unchecked_Union (Base_Type (Operand_Type))
7957            and then not Is_Constrained (Target_Type)
7958            and then not Is_Unchecked_Union (Base_Type (Target_Type))
7959            and then not Has_Inferable_Discriminants (Operand)
7960          then
7961             --  To prevent Gigi from generating illegal code, we generate a
7962             --  Program_Error node, but we give it the target type of the
7963             --  conversion.
7964
7965             declare
7966                PE : constant Node_Id := Make_Raise_Program_Error (Loc,
7967                       Reason => PE_Unchecked_Union_Restriction);
7968
7969             begin
7970                Set_Etype (PE, Target_Type);
7971                Rewrite (N, PE);
7972
7973             end;
7974          else
7975             Handle_Changed_Representation;
7976          end if;
7977
7978       --  Case of conversions of enumeration types
7979
7980       elsif Is_Enumeration_Type (Target_Type) then
7981
7982          --  Special processing is required if there is a change of
7983          --  representation (from enumeration representation clauses)
7984
7985          if not Same_Representation (Target_Type, Operand_Type) then
7986
7987             --  Convert: x(y) to x'val (ytyp'val (y))
7988
7989             Rewrite (N,
7990                Make_Attribute_Reference (Loc,
7991                  Prefix => New_Occurrence_Of (Target_Type, Loc),
7992                  Attribute_Name => Name_Val,
7993                  Expressions => New_List (
7994                    Make_Attribute_Reference (Loc,
7995                      Prefix => New_Occurrence_Of (Operand_Type, Loc),
7996                      Attribute_Name => Name_Pos,
7997                      Expressions => New_List (Operand)))));
7998
7999             Analyze_And_Resolve (N, Target_Type);
8000          end if;
8001
8002       --  Case of conversions to floating-point
8003
8004       elsif Is_Floating_Point_Type (Target_Type) then
8005          Real_Range_Check;
8006       end if;
8007
8008       --  At this stage, either the conversion node has been transformed into
8009       --  some other equivalent expression, or left as a conversion that can
8010       --  be handled by Gigi. The conversions that Gigi can handle are the
8011       --  following:
8012
8013       --    Conversions with no change of representation or type
8014
8015       --    Numeric conversions involving integer, floating- and fixed-point
8016       --    values. Fixed-point values are allowed only if Conversion_OK is
8017       --    set, i.e. if the fixed-point values are to be treated as integers.
8018
8019       --  No other conversions should be passed to Gigi
8020
8021       --  Check: are these rules stated in sinfo??? if so, why restate here???
8022
8023       --  The only remaining step is to generate a range check if we still have
8024       --  a type conversion at this stage and Do_Range_Check is set. For now we
8025       --  do this only for conversions of discrete types.
8026
8027       if Nkind (N) = N_Type_Conversion
8028         and then Is_Discrete_Type (Etype (N))
8029       then
8030          declare
8031             Expr : constant Node_Id := Expression (N);
8032             Ftyp : Entity_Id;
8033             Ityp : Entity_Id;
8034
8035          begin
8036             if Do_Range_Check (Expr)
8037               and then Is_Discrete_Type (Etype (Expr))
8038             then
8039                Set_Do_Range_Check (Expr, False);
8040
8041                --  Before we do a range check, we have to deal with treating a
8042                --  fixed-point operand as an integer. The way we do this is
8043                --  simply to do an unchecked conversion to an appropriate
8044                --  integer type large enough to hold the result.
8045
8046                --  This code is not active yet, because we are only dealing
8047                --  with discrete types so far ???
8048
8049                if Nkind (Expr) in N_Has_Treat_Fixed_As_Integer
8050                  and then Treat_Fixed_As_Integer (Expr)
8051                then
8052                   Ftyp := Base_Type (Etype (Expr));
8053
8054                   if Esize (Ftyp) >= Esize (Standard_Integer) then
8055                      Ityp := Standard_Long_Long_Integer;
8056                   else
8057                      Ityp := Standard_Integer;
8058                   end if;
8059
8060                   Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
8061                end if;
8062
8063                --  Reset overflow flag, since the range check will include
8064                --  dealing with possible overflow, and generate the check If
8065                --  Address is either a source type or target type, suppress
8066                --  range check to avoid typing anomalies when it is a visible
8067                --  integer type.
8068
8069                Set_Do_Overflow_Check (N, False);
8070                if not Is_Descendent_Of_Address (Etype (Expr))
8071                  and then not Is_Descendent_Of_Address (Target_Type)
8072                then
8073                   Generate_Range_Check
8074                     (Expr, Target_Type, CE_Range_Check_Failed);
8075                end if;
8076             end if;
8077          end;
8078       end if;
8079
8080       --  Final step, if the result is a type conversion involving Vax_Float
8081       --  types, then it is subject for further special processing.
8082
8083       if Nkind (N) = N_Type_Conversion
8084         and then (Vax_Float (Operand_Type) or else Vax_Float (Target_Type))
8085       then
8086          Expand_Vax_Conversion (N);
8087          return;
8088       end if;
8089    end Expand_N_Type_Conversion;
8090
8091    -----------------------------------
8092    -- Expand_N_Unchecked_Expression --
8093    -----------------------------------
8094
8095    --  Remove the unchecked expression node from the tree. It's job was simply
8096    --  to make sure that its constituent expression was handled with checks
8097    --  off, and now that that is done, we can remove it from the tree, and
8098    --  indeed must, since gigi does not expect to see these nodes.
8099
8100    procedure Expand_N_Unchecked_Expression (N : Node_Id) is
8101       Exp : constant Node_Id := Expression (N);
8102
8103    begin
8104       Set_Assignment_OK (Exp, Assignment_OK (N) or Assignment_OK (Exp));
8105       Rewrite (N, Exp);
8106    end Expand_N_Unchecked_Expression;
8107
8108    ----------------------------------------
8109    -- Expand_N_Unchecked_Type_Conversion --
8110    ----------------------------------------
8111
8112    --  If this cannot be handled by Gigi and we haven't already made a
8113    --  temporary for it, do it now.
8114
8115    procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id) is
8116       Target_Type  : constant Entity_Id := Etype (N);
8117       Operand      : constant Node_Id   := Expression (N);
8118       Operand_Type : constant Entity_Id := Etype (Operand);
8119
8120    begin
8121       --  If we have a conversion of a compile time known value to a target
8122       --  type and the value is in range of the target type, then we can simply
8123       --  replace the construct by an integer literal of the correct type. We
8124       --  only apply this to integer types being converted. Possibly it may
8125       --  apply in other cases, but it is too much trouble to worry about.
8126
8127       --  Note that we do not do this transformation if the Kill_Range_Check
8128       --  flag is set, since then the value may be outside the expected range.
8129       --  This happens in the Normalize_Scalars case.
8130
8131       --  We also skip this if either the target or operand type is biased
8132       --  because in this case, the unchecked conversion is supposed to
8133       --  preserve the bit pattern, not the integer value.
8134
8135       if Is_Integer_Type (Target_Type)
8136         and then not Has_Biased_Representation (Target_Type)
8137         and then Is_Integer_Type (Operand_Type)
8138         and then not Has_Biased_Representation (Operand_Type)
8139         and then Compile_Time_Known_Value (Operand)
8140         and then not Kill_Range_Check (N)
8141       then
8142          declare
8143             Val : constant Uint := Expr_Value (Operand);
8144
8145          begin
8146             if Compile_Time_Known_Value (Type_Low_Bound (Target_Type))
8147                  and then
8148                Compile_Time_Known_Value (Type_High_Bound (Target_Type))
8149                  and then
8150                Val >= Expr_Value (Type_Low_Bound (Target_Type))
8151                  and then
8152                Val <= Expr_Value (Type_High_Bound (Target_Type))
8153             then
8154                Rewrite (N, Make_Integer_Literal (Sloc (N), Val));
8155
8156                --  If Address is the target type, just set the type to avoid a
8157                --  spurious type error on the literal when Address is a visible
8158                --  integer type.
8159
8160                if Is_Descendent_Of_Address (Target_Type) then
8161                   Set_Etype (N, Target_Type);
8162                else
8163                   Analyze_And_Resolve (N, Target_Type);
8164                end if;
8165
8166                return;
8167             end if;
8168          end;
8169       end if;
8170
8171       --  Nothing to do if conversion is safe
8172
8173       if Safe_Unchecked_Type_Conversion (N) then
8174          return;
8175       end if;
8176
8177       --  Otherwise force evaluation unless Assignment_OK flag is set (this
8178       --  flag indicates ??? -- more comments needed here)
8179
8180       if Assignment_OK (N) then
8181          null;
8182       else
8183          Force_Evaluation (N);
8184       end if;
8185    end Expand_N_Unchecked_Type_Conversion;
8186
8187    ----------------------------
8188    -- Expand_Record_Equality --
8189    ----------------------------
8190
8191    --  For non-variant records, Equality is expanded when needed into:
8192
8193    --      and then Lhs.Discr1 = Rhs.Discr1
8194    --      and then ...
8195    --      and then Lhs.Discrn = Rhs.Discrn
8196    --      and then Lhs.Cmp1 = Rhs.Cmp1
8197    --      and then ...
8198    --      and then Lhs.Cmpn = Rhs.Cmpn
8199
8200    --  The expression is folded by the back-end for adjacent fields. This
8201    --  function is called for tagged record in only one occasion: for imple-
8202    --  menting predefined primitive equality (see Predefined_Primitives_Bodies)
8203    --  otherwise the primitive "=" is used directly.
8204
8205    function Expand_Record_Equality
8206      (Nod    : Node_Id;
8207       Typ    : Entity_Id;
8208       Lhs    : Node_Id;
8209       Rhs    : Node_Id;
8210       Bodies : List_Id) return Node_Id
8211    is
8212       Loc : constant Source_Ptr := Sloc (Nod);
8213
8214       Result : Node_Id;
8215       C      : Entity_Id;
8216
8217       First_Time : Boolean := True;
8218
8219       function Suitable_Element (C : Entity_Id) return Entity_Id;
8220       --  Return the first field to compare beginning with C, skipping the
8221       --  inherited components.
8222
8223       ----------------------
8224       -- Suitable_Element --
8225       ----------------------
8226
8227       function Suitable_Element (C : Entity_Id) return Entity_Id is
8228       begin
8229          if No (C) then
8230             return Empty;
8231
8232          elsif Ekind (C) /= E_Discriminant
8233            and then Ekind (C) /= E_Component
8234          then
8235             return Suitable_Element (Next_Entity (C));
8236
8237          elsif Is_Tagged_Type (Typ)
8238            and then C /= Original_Record_Component (C)
8239          then
8240             return Suitable_Element (Next_Entity (C));
8241
8242          elsif Chars (C) = Name_uController
8243            or else Chars (C) = Name_uTag
8244          then
8245             return Suitable_Element (Next_Entity (C));
8246
8247          elsif Is_Interface (Etype (C)) then
8248             return Suitable_Element (Next_Entity (C));
8249
8250          else
8251             return C;
8252          end if;
8253       end Suitable_Element;
8254
8255    --  Start of processing for Expand_Record_Equality
8256
8257    begin
8258       --  Generates the following code: (assuming that Typ has one Discr and
8259       --  component C2 is also a record)
8260
8261       --   True
8262       --     and then Lhs.Discr1 = Rhs.Discr1
8263       --     and then Lhs.C1 = Rhs.C1
8264       --     and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
8265       --     and then ...
8266       --     and then Lhs.Cmpn = Rhs.Cmpn
8267
8268       Result := New_Reference_To (Standard_True, Loc);
8269       C := Suitable_Element (First_Entity (Typ));
8270
8271       while Present (C) loop
8272          declare
8273             New_Lhs : Node_Id;
8274             New_Rhs : Node_Id;
8275             Check   : Node_Id;
8276
8277          begin
8278             if First_Time then
8279                First_Time := False;
8280                New_Lhs := Lhs;
8281                New_Rhs := Rhs;
8282             else
8283                New_Lhs := New_Copy_Tree (Lhs);
8284                New_Rhs := New_Copy_Tree (Rhs);
8285             end if;
8286
8287             Check :=
8288               Expand_Composite_Equality (Nod, Etype (C),
8289                Lhs =>
8290                  Make_Selected_Component (Loc,
8291                    Prefix => New_Lhs,
8292                    Selector_Name => New_Reference_To (C, Loc)),
8293                Rhs =>
8294                  Make_Selected_Component (Loc,
8295                    Prefix => New_Rhs,
8296                    Selector_Name => New_Reference_To (C, Loc)),
8297                Bodies => Bodies);
8298
8299             --  If some (sub)component is an unchecked_union, the whole
8300             --  operation will raise program error.
8301
8302             if Nkind (Check) = N_Raise_Program_Error then
8303                Result := Check;
8304                Set_Etype (Result, Standard_Boolean);
8305                exit;
8306             else
8307                Result :=
8308                  Make_And_Then (Loc,
8309                    Left_Opnd  => Result,
8310                    Right_Opnd => Check);
8311             end if;
8312          end;
8313
8314          C := Suitable_Element (Next_Entity (C));
8315       end loop;
8316
8317       return Result;
8318    end Expand_Record_Equality;
8319
8320    -------------------------------------
8321    -- Fixup_Universal_Fixed_Operation --
8322    -------------------------------------
8323
8324    procedure Fixup_Universal_Fixed_Operation (N : Node_Id) is
8325       Conv : constant Node_Id := Parent (N);
8326
8327    begin
8328       --  We must have a type conversion immediately above us
8329
8330       pragma Assert (Nkind (Conv) = N_Type_Conversion);
8331
8332       --  Normally the type conversion gives our target type. The exception
8333       --  occurs in the case of the Round attribute, where the conversion
8334       --  will be to universal real, and our real type comes from the Round
8335       --  attribute (as well as an indication that we must round the result)
8336
8337       if Nkind (Parent (Conv)) = N_Attribute_Reference
8338         and then Attribute_Name (Parent (Conv)) = Name_Round
8339       then
8340          Set_Etype (N, Etype (Parent (Conv)));
8341          Set_Rounded_Result (N);
8342
8343       --  Normal case where type comes from conversion above us
8344
8345       else
8346          Set_Etype (N, Etype (Conv));
8347       end if;
8348    end Fixup_Universal_Fixed_Operation;
8349
8350    ------------------------------
8351    -- Get_Allocator_Final_List --
8352    ------------------------------
8353
8354    function Get_Allocator_Final_List
8355      (N    : Node_Id;
8356       T    : Entity_Id;
8357       PtrT : Entity_Id) return Entity_Id
8358    is
8359       Loc : constant Source_Ptr := Sloc (N);
8360
8361       Owner : Entity_Id := PtrT;
8362       --  The entity whose finalization list must be used to attach the
8363       --  allocated object.
8364
8365    begin
8366       if Ekind (PtrT) = E_Anonymous_Access_Type then
8367
8368          --  If the context is an access parameter, we need to create a
8369          --  non-anonymous access type in order to have a usable final list,
8370          --  because there is otherwise no pool to which the allocated object
8371          --  can belong. We create both the type and the finalization chain
8372          --  here, because freezing an internal type does not create such a
8373          --  chain. The Final_Chain that is thus created is shared by the
8374          --  access parameter. The access type is tested against the result
8375          --  type of the function to exclude allocators whose type is an
8376          --  anonymous access result type. We freeze the type at once to
8377          --  ensure that it is properly decorated for the back-end, even
8378          --  if the context and current scope is a loop.
8379
8380          if Nkind (Associated_Node_For_Itype (PtrT))
8381               in N_Subprogram_Specification
8382            and then
8383              PtrT /=
8384                Etype (Defining_Unit_Name (Associated_Node_For_Itype (PtrT)))
8385          then
8386             Owner := Make_Defining_Identifier (Loc, New_Internal_Name ('J'));
8387             Insert_Action (N,
8388               Make_Full_Type_Declaration (Loc,
8389                 Defining_Identifier => Owner,
8390                 Type_Definition =>
8391                    Make_Access_To_Object_Definition (Loc,
8392                      Subtype_Indication =>
8393                        New_Occurrence_Of (T, Loc))));
8394
8395             Freeze_Before (N, Owner);
8396             Build_Final_List (N, Owner);
8397             Set_Associated_Final_Chain (PtrT, Associated_Final_Chain (Owner));
8398
8399          --  Ada 2005 (AI-318-02): If the context is a return object
8400          --  declaration, then the anonymous return subtype is defined to have
8401          --  the same accessibility level as that of the function's result
8402          --  subtype, which means that we want the scope where the function is
8403          --  declared.
8404
8405          elsif Nkind (Associated_Node_For_Itype (PtrT)) = N_Object_Declaration
8406            and then Ekind (Scope (PtrT)) = E_Return_Statement
8407          then
8408             Owner := Scope (Return_Applies_To (Scope (PtrT)));
8409
8410          --  Case of an access discriminant, or (Ada 2005), of an anonymous
8411          --  access component or anonymous access function result: find the
8412          --  final list associated with the scope of the type. (In the
8413          --  anonymous access component kind, a list controller will have
8414          --  been allocated when freezing the record type, and PtrT has an
8415          --  Associated_Final_Chain attribute designating it.)
8416
8417          elsif No (Associated_Final_Chain (PtrT)) then
8418             Owner := Scope (PtrT);
8419          end if;
8420       end if;
8421
8422       return Find_Final_List (Owner);
8423    end Get_Allocator_Final_List;
8424
8425    ---------------------------------
8426    -- Has_Inferable_Discriminants --
8427    ---------------------------------
8428
8429    function Has_Inferable_Discriminants (N : Node_Id) return Boolean is
8430
8431       function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean;
8432       --  Determines whether the left-most prefix of a selected component is a
8433       --  formal parameter in a subprogram. Assumes N is a selected component.
8434
8435       --------------------------------
8436       -- Prefix_Is_Formal_Parameter --
8437       --------------------------------
8438
8439       function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean is
8440          Sel_Comp : Node_Id := N;
8441
8442       begin
8443          --  Move to the left-most prefix by climbing up the tree
8444
8445          while Present (Parent (Sel_Comp))
8446            and then Nkind (Parent (Sel_Comp)) = N_Selected_Component
8447          loop
8448             Sel_Comp := Parent (Sel_Comp);
8449          end loop;
8450
8451          return Ekind (Entity (Prefix (Sel_Comp))) in Formal_Kind;
8452       end Prefix_Is_Formal_Parameter;
8453
8454    --  Start of processing for Has_Inferable_Discriminants
8455
8456    begin
8457       --  For identifiers and indexed components, it is sufficient to have a
8458       --  constrained Unchecked_Union nominal subtype.
8459
8460       if Nkind_In (N, N_Identifier, N_Indexed_Component) then
8461          return Is_Unchecked_Union (Base_Type (Etype (N)))
8462                   and then
8463                 Is_Constrained (Etype (N));
8464
8465       --  For selected components, the subtype of the selector must be a
8466       --  constrained Unchecked_Union. If the component is subject to a
8467       --  per-object constraint, then the enclosing object must have inferable
8468       --  discriminants.
8469
8470       elsif Nkind (N) = N_Selected_Component then
8471          if Has_Per_Object_Constraint (Entity (Selector_Name (N))) then
8472
8473             --  A small hack. If we have a per-object constrained selected
8474             --  component of a formal parameter, return True since we do not
8475             --  know the actual parameter association yet.
8476
8477             if Prefix_Is_Formal_Parameter (N) then
8478                return True;
8479             end if;
8480
8481             --  Otherwise, check the enclosing object and the selector
8482
8483             return Has_Inferable_Discriminants (Prefix (N))
8484                      and then
8485                    Has_Inferable_Discriminants (Selector_Name (N));
8486          end if;
8487
8488          --  The call to Has_Inferable_Discriminants will determine whether
8489          --  the selector has a constrained Unchecked_Union nominal type.
8490
8491          return Has_Inferable_Discriminants (Selector_Name (N));
8492
8493       --  A qualified expression has inferable discriminants if its subtype
8494       --  mark is a constrained Unchecked_Union subtype.
8495
8496       elsif Nkind (N) = N_Qualified_Expression then
8497          return Is_Unchecked_Union (Subtype_Mark (N))
8498                   and then
8499                 Is_Constrained (Subtype_Mark (N));
8500
8501       end if;
8502
8503       return False;
8504    end Has_Inferable_Discriminants;
8505
8506    -------------------------------
8507    -- Insert_Dereference_Action --
8508    -------------------------------
8509
8510    procedure Insert_Dereference_Action (N : Node_Id) is
8511       Loc  : constant Source_Ptr := Sloc (N);
8512       Typ  : constant Entity_Id  := Etype (N);
8513       Pool : constant Entity_Id  := Associated_Storage_Pool (Typ);
8514       Pnod : constant Node_Id    := Parent (N);
8515
8516       function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
8517       --  Return true if type of P is derived from Checked_Pool;
8518
8519       -----------------------------
8520       -- Is_Checked_Storage_Pool --
8521       -----------------------------
8522
8523       function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean is
8524          T : Entity_Id;
8525
8526       begin
8527          if No (P) then
8528             return False;
8529          end if;
8530
8531          T := Etype (P);
8532          while T /= Etype (T) loop
8533             if Is_RTE (T, RE_Checked_Pool) then
8534                return True;
8535             else
8536                T := Etype (T);
8537             end if;
8538          end loop;
8539
8540          return False;
8541       end Is_Checked_Storage_Pool;
8542
8543    --  Start of processing for Insert_Dereference_Action
8544
8545    begin
8546       pragma Assert (Nkind (Pnod) = N_Explicit_Dereference);
8547
8548       if not (Is_Checked_Storage_Pool (Pool)
8549               and then Comes_From_Source (Original_Node (Pnod)))
8550       then
8551          return;
8552       end if;
8553
8554       Insert_Action (N,
8555         Make_Procedure_Call_Statement (Loc,
8556           Name => New_Reference_To (
8557             Find_Prim_Op (Etype (Pool), Name_Dereference), Loc),
8558
8559           Parameter_Associations => New_List (
8560
8561             --  Pool
8562
8563              New_Reference_To (Pool, Loc),
8564
8565             --  Storage_Address. We use the attribute Pool_Address, which uses
8566             --  the pointer itself to find the address of the object, and which
8567             --  handles unconstrained arrays properly by computing the address
8568             --  of the template. i.e. the correct address of the corresponding
8569             --  allocation.
8570
8571              Make_Attribute_Reference (Loc,
8572                Prefix         => Duplicate_Subexpr_Move_Checks (N),
8573                Attribute_Name => Name_Pool_Address),
8574
8575             --  Size_In_Storage_Elements
8576
8577              Make_Op_Divide (Loc,
8578                Left_Opnd  =>
8579                 Make_Attribute_Reference (Loc,
8580                   Prefix         =>
8581                     Make_Explicit_Dereference (Loc,
8582                       Duplicate_Subexpr_Move_Checks (N)),
8583                   Attribute_Name => Name_Size),
8584                Right_Opnd =>
8585                  Make_Integer_Literal (Loc, System_Storage_Unit)),
8586
8587             --  Alignment
8588
8589              Make_Attribute_Reference (Loc,
8590                Prefix         =>
8591                  Make_Explicit_Dereference (Loc,
8592                    Duplicate_Subexpr_Move_Checks (N)),
8593                Attribute_Name => Name_Alignment))));
8594
8595    exception
8596       when RE_Not_Available =>
8597          return;
8598    end Insert_Dereference_Action;
8599
8600    ------------------------------
8601    -- Make_Array_Comparison_Op --
8602    ------------------------------
8603
8604    --  This is a hand-coded expansion of the following generic function:
8605
8606    --  generic
8607    --    type elem is  (<>);
8608    --    type index is (<>);
8609    --    type a is array (index range <>) of elem;
8610
8611    --  function Gnnn (X : a; Y: a) return boolean is
8612    --    J : index := Y'first;
8613
8614    --  begin
8615    --    if X'length = 0 then
8616    --       return false;
8617
8618    --    elsif Y'length = 0 then
8619    --       return true;
8620
8621    --    else
8622    --      for I in X'range loop
8623    --        if X (I) = Y (J) then
8624    --          if J = Y'last then
8625    --            exit;
8626    --          else
8627    --            J := index'succ (J);
8628    --          end if;
8629
8630    --        else
8631    --           return X (I) > Y (J);
8632    --        end if;
8633    --      end loop;
8634
8635    --      return X'length > Y'length;
8636    --    end if;
8637    --  end Gnnn;
8638
8639    --  Note that since we are essentially doing this expansion by hand, we
8640    --  do not need to generate an actual or formal generic part, just the
8641    --  instantiated function itself.
8642
8643    function Make_Array_Comparison_Op
8644      (Typ : Entity_Id;
8645       Nod : Node_Id) return Node_Id
8646    is
8647       Loc : constant Source_Ptr := Sloc (Nod);
8648
8649       X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uX);
8650       Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uY);
8651       I : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uI);
8652       J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
8653
8654       Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ)));
8655
8656       Loop_Statement : Node_Id;
8657       Loop_Body      : Node_Id;
8658       If_Stat        : Node_Id;
8659       Inner_If       : Node_Id;
8660       Final_Expr     : Node_Id;
8661       Func_Body      : Node_Id;
8662       Func_Name      : Entity_Id;
8663       Formals        : List_Id;
8664       Length1        : Node_Id;
8665       Length2        : Node_Id;
8666
8667    begin
8668       --  if J = Y'last then
8669       --     exit;
8670       --  else
8671       --     J := index'succ (J);
8672       --  end if;
8673
8674       Inner_If :=
8675         Make_Implicit_If_Statement (Nod,
8676           Condition =>
8677             Make_Op_Eq (Loc,
8678               Left_Opnd => New_Reference_To (J, Loc),
8679               Right_Opnd =>
8680                 Make_Attribute_Reference (Loc,
8681                   Prefix => New_Reference_To (Y, Loc),
8682                   Attribute_Name => Name_Last)),
8683
8684           Then_Statements => New_List (
8685                 Make_Exit_Statement (Loc)),
8686
8687           Else_Statements =>
8688             New_List (
8689               Make_Assignment_Statement (Loc,
8690                 Name => New_Reference_To (J, Loc),
8691                 Expression =>
8692                   Make_Attribute_Reference (Loc,
8693                     Prefix => New_Reference_To (Index, Loc),
8694                     Attribute_Name => Name_Succ,
8695                     Expressions => New_List (New_Reference_To (J, Loc))))));
8696
8697       --  if X (I) = Y (J) then
8698       --     if ... end if;
8699       --  else
8700       --     return X (I) > Y (J);
8701       --  end if;
8702
8703       Loop_Body :=
8704         Make_Implicit_If_Statement (Nod,
8705           Condition =>
8706             Make_Op_Eq (Loc,
8707               Left_Opnd =>
8708                 Make_Indexed_Component (Loc,
8709                   Prefix      => New_Reference_To (X, Loc),
8710                   Expressions => New_List (New_Reference_To (I, Loc))),
8711
8712               Right_Opnd =>
8713                 Make_Indexed_Component (Loc,
8714                   Prefix      => New_Reference_To (Y, Loc),
8715                   Expressions => New_List (New_Reference_To (J, Loc)))),
8716
8717           Then_Statements => New_List (Inner_If),
8718
8719           Else_Statements => New_List (
8720             Make_Simple_Return_Statement (Loc,
8721               Expression =>
8722                 Make_Op_Gt (Loc,
8723                   Left_Opnd =>
8724                     Make_Indexed_Component (Loc,
8725                       Prefix      => New_Reference_To (X, Loc),
8726                       Expressions => New_List (New_Reference_To (I, Loc))),
8727
8728                   Right_Opnd =>
8729                     Make_Indexed_Component (Loc,
8730                       Prefix      => New_Reference_To (Y, Loc),
8731                       Expressions => New_List (
8732                         New_Reference_To (J, Loc)))))));
8733
8734       --  for I in X'range loop
8735       --     if ... end if;
8736       --  end loop;
8737
8738       Loop_Statement :=
8739         Make_Implicit_Loop_Statement (Nod,
8740           Identifier => Empty,
8741
8742           Iteration_Scheme =>
8743             Make_Iteration_Scheme (Loc,
8744               Loop_Parameter_Specification =>
8745                 Make_Loop_Parameter_Specification (Loc,
8746                   Defining_Identifier => I,
8747                   Discrete_Subtype_Definition =>
8748                     Make_Attribute_Reference (Loc,
8749                       Prefix => New_Reference_To (X, Loc),
8750                       Attribute_Name => Name_Range))),
8751
8752           Statements => New_List (Loop_Body));
8753
8754       --    if X'length = 0 then
8755       --       return false;
8756       --    elsif Y'length = 0 then
8757       --       return true;
8758       --    else
8759       --      for ... loop ... end loop;
8760       --      return X'length > Y'length;
8761       --    end if;
8762
8763       Length1 :=
8764         Make_Attribute_Reference (Loc,
8765           Prefix => New_Reference_To (X, Loc),
8766           Attribute_Name => Name_Length);
8767
8768       Length2 :=
8769         Make_Attribute_Reference (Loc,
8770           Prefix => New_Reference_To (Y, Loc),
8771           Attribute_Name => Name_Length);
8772
8773       Final_Expr :=
8774         Make_Op_Gt (Loc,
8775           Left_Opnd  => Length1,
8776           Right_Opnd => Length2);
8777
8778       If_Stat :=
8779         Make_Implicit_If_Statement (Nod,
8780           Condition =>
8781             Make_Op_Eq (Loc,
8782               Left_Opnd =>
8783                 Make_Attribute_Reference (Loc,
8784                   Prefix => New_Reference_To (X, Loc),
8785                   Attribute_Name => Name_Length),
8786               Right_Opnd =>
8787                 Make_Integer_Literal (Loc, 0)),
8788
8789           Then_Statements =>
8790             New_List (
8791               Make_Simple_Return_Statement (Loc,
8792                 Expression => New_Reference_To (Standard_False, Loc))),
8793
8794           Elsif_Parts => New_List (
8795             Make_Elsif_Part (Loc,
8796               Condition =>
8797                 Make_Op_Eq (Loc,
8798                   Left_Opnd =>
8799                     Make_Attribute_Reference (Loc,
8800                       Prefix => New_Reference_To (Y, Loc),
8801                       Attribute_Name => Name_Length),
8802                   Right_Opnd =>
8803                     Make_Integer_Literal (Loc, 0)),
8804
8805               Then_Statements =>
8806                 New_List (
8807                   Make_Simple_Return_Statement (Loc,
8808                      Expression => New_Reference_To (Standard_True, Loc))))),
8809
8810           Else_Statements => New_List (
8811             Loop_Statement,
8812             Make_Simple_Return_Statement (Loc,
8813               Expression => Final_Expr)));
8814
8815       --  (X : a; Y: a)
8816
8817       Formals := New_List (
8818         Make_Parameter_Specification (Loc,
8819           Defining_Identifier => X,
8820           Parameter_Type      => New_Reference_To (Typ, Loc)),
8821
8822         Make_Parameter_Specification (Loc,
8823           Defining_Identifier => Y,
8824           Parameter_Type      => New_Reference_To (Typ, Loc)));
8825
8826       --  function Gnnn (...) return boolean is
8827       --    J : index := Y'first;
8828       --  begin
8829       --    if ... end if;
8830       --  end Gnnn;
8831
8832       Func_Name := Make_Defining_Identifier (Loc, New_Internal_Name ('G'));
8833
8834       Func_Body :=
8835         Make_Subprogram_Body (Loc,
8836           Specification =>
8837             Make_Function_Specification (Loc,
8838               Defining_Unit_Name       => Func_Name,
8839               Parameter_Specifications => Formals,
8840               Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
8841
8842           Declarations => New_List (
8843             Make_Object_Declaration (Loc,
8844               Defining_Identifier => J,
8845               Object_Definition   => New_Reference_To (Index, Loc),
8846               Expression =>
8847                 Make_Attribute_Reference (Loc,
8848                   Prefix => New_Reference_To (Y, Loc),
8849                   Attribute_Name => Name_First))),
8850
8851           Handled_Statement_Sequence =>
8852             Make_Handled_Sequence_Of_Statements (Loc,
8853               Statements => New_List (If_Stat)));
8854
8855       return Func_Body;
8856    end Make_Array_Comparison_Op;
8857
8858    ---------------------------
8859    -- Make_Boolean_Array_Op --
8860    ---------------------------
8861
8862    --  For logical operations on boolean arrays, expand in line the following,
8863    --  replacing 'and' with 'or' or 'xor' where needed:
8864
8865    --    function Annn (A : typ; B: typ) return typ is
8866    --       C : typ;
8867    --    begin
8868    --       for J in A'range loop
8869    --          C (J) := A (J) op B (J);
8870    --       end loop;
8871    --       return C;
8872    --    end Annn;
8873
8874    --  Here typ is the boolean array type
8875
8876    function Make_Boolean_Array_Op
8877      (Typ : Entity_Id;
8878       N   : Node_Id) return Node_Id
8879    is
8880       Loc : constant Source_Ptr := Sloc (N);
8881
8882       A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
8883       B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
8884       C : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uC);
8885       J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
8886
8887       A_J : Node_Id;
8888       B_J : Node_Id;
8889       C_J : Node_Id;
8890       Op  : Node_Id;
8891
8892       Formals        : List_Id;
8893       Func_Name      : Entity_Id;
8894       Func_Body      : Node_Id;
8895       Loop_Statement : Node_Id;
8896
8897    begin
8898       A_J :=
8899         Make_Indexed_Component (Loc,
8900           Prefix      => New_Reference_To (A, Loc),
8901           Expressions => New_List (New_Reference_To (J, Loc)));
8902
8903       B_J :=
8904         Make_Indexed_Component (Loc,
8905           Prefix      => New_Reference_To (B, Loc),
8906           Expressions => New_List (New_Reference_To (J, Loc)));
8907
8908       C_J :=
8909         Make_Indexed_Component (Loc,
8910           Prefix      => New_Reference_To (C, Loc),
8911           Expressions => New_List (New_Reference_To (J, Loc)));
8912
8913       if Nkind (N) = N_Op_And then
8914          Op :=
8915            Make_Op_And (Loc,
8916              Left_Opnd  => A_J,
8917              Right_Opnd => B_J);
8918
8919       elsif Nkind (N) = N_Op_Or then
8920          Op :=
8921            Make_Op_Or (Loc,
8922              Left_Opnd  => A_J,
8923              Right_Opnd => B_J);
8924
8925       else
8926          Op :=
8927            Make_Op_Xor (Loc,
8928              Left_Opnd  => A_J,
8929              Right_Opnd => B_J);
8930       end if;
8931
8932       Loop_Statement :=
8933         Make_Implicit_Loop_Statement (N,
8934           Identifier => Empty,
8935
8936           Iteration_Scheme =>
8937             Make_Iteration_Scheme (Loc,
8938               Loop_Parameter_Specification =>
8939                 Make_Loop_Parameter_Specification (Loc,
8940                   Defining_Identifier => J,
8941                   Discrete_Subtype_Definition =>
8942                     Make_Attribute_Reference (Loc,
8943                       Prefix => New_Reference_To (A, Loc),
8944                       Attribute_Name => Name_Range))),
8945
8946           Statements => New_List (
8947             Make_Assignment_Statement (Loc,
8948               Name       => C_J,
8949               Expression => Op)));
8950
8951       Formals := New_List (
8952         Make_Parameter_Specification (Loc,
8953           Defining_Identifier => A,
8954           Parameter_Type      => New_Reference_To (Typ, Loc)),
8955
8956         Make_Parameter_Specification (Loc,
8957           Defining_Identifier => B,
8958           Parameter_Type      => New_Reference_To (Typ, Loc)));
8959
8960       Func_Name :=
8961         Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
8962       Set_Is_Inlined (Func_Name);
8963
8964       Func_Body :=
8965         Make_Subprogram_Body (Loc,
8966           Specification =>
8967             Make_Function_Specification (Loc,
8968               Defining_Unit_Name       => Func_Name,
8969               Parameter_Specifications => Formals,
8970               Result_Definition        => New_Reference_To (Typ, Loc)),
8971
8972           Declarations => New_List (
8973             Make_Object_Declaration (Loc,
8974               Defining_Identifier => C,
8975               Object_Definition   => New_Reference_To (Typ, Loc))),
8976
8977           Handled_Statement_Sequence =>
8978             Make_Handled_Sequence_Of_Statements (Loc,
8979               Statements => New_List (
8980                 Loop_Statement,
8981                 Make_Simple_Return_Statement (Loc,
8982                   Expression => New_Reference_To (C, Loc)))));
8983
8984       return Func_Body;
8985    end Make_Boolean_Array_Op;
8986
8987    ------------------------
8988    -- Rewrite_Comparison --
8989    ------------------------
8990
8991    procedure Rewrite_Comparison (N : Node_Id) is
8992       Warning_Generated : Boolean := False;
8993       --  Set to True if first pass with Assume_Valid generates a warning in
8994       --  which case we skip the second pass to avoid warning overloaded.
8995
8996       Result : Node_Id;
8997       --  Set to Standard_True or Standard_False
8998
8999    begin
9000       if Nkind (N) = N_Type_Conversion then
9001          Rewrite_Comparison (Expression (N));
9002          return;
9003
9004       elsif Nkind (N) not in N_Op_Compare then
9005          return;
9006       end if;
9007
9008       --  Now start looking at the comparison in detail. We potentially go
9009       --  through this loop twice. The first time, Assume_Valid is set False
9010       --  in the call to Compile_Time_Compare. If this call results in a
9011       --  clear result of always True or Always False, that's decisive and
9012       --  we are done. Otherwise we repeat the processing with Assume_Valid
9013       --  set to True to generate additional warnings. We can stil that step
9014       --  if Constant_Condition_Warnings is False.
9015
9016       for AV in False .. True loop
9017          declare
9018             Typ : constant Entity_Id := Etype (N);
9019             Op1 : constant Node_Id   := Left_Opnd (N);
9020             Op2 : constant Node_Id   := Right_Opnd (N);
9021
9022             Res : constant Compare_Result :=
9023                     Compile_Time_Compare (Op1, Op2, Assume_Valid => AV);
9024             --  Res indicates if compare outcome can be compile time determined
9025
9026             True_Result  : Boolean;
9027             False_Result : Boolean;
9028
9029          begin
9030             case N_Op_Compare (Nkind (N)) is
9031             when N_Op_Eq =>
9032                True_Result  := Res = EQ;
9033                False_Result := Res = LT or else Res = GT or else Res = NE;
9034
9035             when N_Op_Ge =>
9036                True_Result  := Res in Compare_GE;
9037                False_Result := Res = LT;
9038
9039                if Res = LE
9040                  and then Constant_Condition_Warnings
9041                  and then Comes_From_Source (Original_Node (N))
9042                  and then Nkind (Original_Node (N)) = N_Op_Ge
9043                  and then not In_Instance
9044                  and then Is_Integer_Type (Etype (Left_Opnd (N)))
9045                  and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
9046                then
9047                   Error_Msg_N
9048                     ("can never be greater than, could replace by ""'=""?", N);
9049                   Warning_Generated := True;
9050                end if;
9051
9052             when N_Op_Gt =>
9053                True_Result  := Res = GT;
9054                False_Result := Res in Compare_LE;
9055
9056             when N_Op_Lt =>
9057                True_Result  := Res = LT;
9058                False_Result := Res in Compare_GE;
9059
9060             when N_Op_Le =>
9061                True_Result  := Res in Compare_LE;
9062                False_Result := Res = GT;
9063
9064                if Res = GE
9065                  and then Constant_Condition_Warnings
9066                  and then Comes_From_Source (Original_Node (N))
9067                  and then Nkind (Original_Node (N)) = N_Op_Le
9068                  and then not In_Instance
9069                  and then Is_Integer_Type (Etype (Left_Opnd (N)))
9070                  and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
9071                then
9072                   Error_Msg_N
9073                     ("can never be less than, could replace by ""'=""?", N);
9074                   Warning_Generated := True;
9075                end if;
9076
9077             when N_Op_Ne =>
9078                True_Result  := Res = NE or else Res = GT or else Res = LT;
9079                False_Result := Res = EQ;
9080             end case;
9081
9082             --  If this is the first iteration, then we actually convert the
9083             --  comparison into True or False, if the result is certain.
9084
9085             if AV = False then
9086                if True_Result or False_Result then
9087                   if True_Result then
9088                      Result := Standard_True;
9089                   else
9090                      Result := Standard_False;
9091                   end if;
9092
9093                   Rewrite (N,
9094                     Convert_To (Typ,
9095                       New_Occurrence_Of (Result, Sloc (N))));
9096                   Analyze_And_Resolve (N, Typ);
9097                   Warn_On_Known_Condition (N);
9098                   return;
9099                end if;
9100
9101             --  If this is the second iteration (AV = True), and the original
9102             --  node comes from source and we are not in an instance, then
9103             --  give a warning if we know result would be True or False. Note
9104             --  we know Constant_Condition_Warnings is set if we get here.
9105
9106             elsif Comes_From_Source (Original_Node (N))
9107               and then not In_Instance
9108             then
9109                if True_Result then
9110                   Error_Msg_N
9111                     ("condition can only be False if invalid values present?",
9112                      N);
9113                elsif False_Result then
9114                   Error_Msg_N
9115                     ("condition can only be True if invalid values present?",
9116                      N);
9117                end if;
9118             end if;
9119          end;
9120
9121          --  Skip second iteration if not warning on constant conditions or
9122          --  if the first iteration already generated a warning of some kind
9123          --  or if we are in any case assuming all values are valid (so that
9124          --  the first iteration took care of the valid case).
9125
9126          exit when not Constant_Condition_Warnings;
9127          exit when Warning_Generated;
9128          exit when Assume_No_Invalid_Values;
9129       end loop;
9130    end Rewrite_Comparison;
9131
9132    ----------------------------
9133    -- Safe_In_Place_Array_Op --
9134    ----------------------------
9135
9136    function Safe_In_Place_Array_Op
9137      (Lhs : Node_Id;
9138       Op1 : Node_Id;
9139       Op2 : Node_Id) return Boolean
9140    is
9141       Target : Entity_Id;
9142
9143       function Is_Safe_Operand (Op : Node_Id) return Boolean;
9144       --  Operand is safe if it cannot overlap part of the target of the
9145       --  operation. If the operand and the target are identical, the operand
9146       --  is safe. The operand can be empty in the case of negation.
9147
9148       function Is_Unaliased (N : Node_Id) return Boolean;
9149       --  Check that N is a stand-alone entity
9150
9151       ------------------
9152       -- Is_Unaliased --
9153       ------------------
9154
9155       function Is_Unaliased (N : Node_Id) return Boolean is
9156       begin
9157          return
9158            Is_Entity_Name (N)
9159              and then No (Address_Clause (Entity (N)))
9160              and then No (Renamed_Object (Entity (N)));
9161       end Is_Unaliased;
9162
9163       ---------------------
9164       -- Is_Safe_Operand --
9165       ---------------------
9166
9167       function Is_Safe_Operand (Op : Node_Id) return Boolean is
9168       begin
9169          if No (Op) then
9170             return True;
9171
9172          elsif Is_Entity_Name (Op) then
9173             return Is_Unaliased (Op);
9174
9175          elsif Nkind_In (Op, N_Indexed_Component, N_Selected_Component) then
9176             return Is_Unaliased (Prefix (Op));
9177
9178          elsif Nkind (Op) = N_Slice then
9179             return
9180               Is_Unaliased (Prefix (Op))
9181                 and then Entity (Prefix (Op)) /= Target;
9182
9183          elsif Nkind (Op) = N_Op_Not then
9184             return Is_Safe_Operand (Right_Opnd (Op));
9185
9186          else
9187             return False;
9188          end if;
9189       end Is_Safe_Operand;
9190
9191       --  Start of processing for Is_Safe_In_Place_Array_Op
9192
9193    begin
9194       --  Skip this processing if the component size is different from system
9195       --  storage unit (since at least for NOT this would cause problems).
9196
9197       if Component_Size (Etype (Lhs)) /= System_Storage_Unit then
9198          return False;
9199
9200       --  Cannot do in place stuff on VM_Target since cannot pass addresses
9201
9202       elsif VM_Target /= No_VM then
9203          return False;
9204
9205       --  Cannot do in place stuff if non-standard Boolean representation
9206
9207       elsif Has_Non_Standard_Rep (Component_Type (Etype (Lhs))) then
9208          return False;
9209
9210       elsif not Is_Unaliased (Lhs) then
9211          return False;
9212       else
9213          Target := Entity (Lhs);
9214
9215          return
9216            Is_Safe_Operand (Op1)
9217              and then Is_Safe_Operand (Op2);
9218       end if;
9219    end Safe_In_Place_Array_Op;
9220
9221    -----------------------
9222    -- Tagged_Membership --
9223    -----------------------
9224
9225    --  There are two different cases to consider depending on whether the right
9226    --  operand is a class-wide type or not. If not we just compare the actual
9227    --  tag of the left expr to the target type tag:
9228    --
9229    --     Left_Expr.Tag = Right_Type'Tag;
9230    --
9231    --  If it is a class-wide type we use the RT function CW_Membership which is
9232    --  usually implemented by looking in the ancestor tables contained in the
9233    --  dispatch table pointed by Left_Expr.Tag for Typ'Tag
9234
9235    --  Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
9236    --  function IW_Membership which is usually implemented by looking in the
9237    --  table of abstract interface types plus the ancestor table contained in
9238    --  the dispatch table pointed by Left_Expr.Tag for Typ'Tag
9239
9240    function Tagged_Membership (N : Node_Id) return Node_Id is
9241       Left  : constant Node_Id    := Left_Opnd  (N);
9242       Right : constant Node_Id    := Right_Opnd (N);
9243       Loc   : constant Source_Ptr := Sloc (N);
9244
9245       Left_Type  : Entity_Id;
9246       Right_Type : Entity_Id;
9247       Obj_Tag    : Node_Id;
9248
9249    begin
9250       Left_Type  := Etype (Left);
9251       Right_Type := Etype (Right);
9252
9253       if Is_Class_Wide_Type (Left_Type) then
9254          Left_Type := Root_Type (Left_Type);
9255       end if;
9256
9257       Obj_Tag :=
9258         Make_Selected_Component (Loc,
9259           Prefix        => Relocate_Node (Left),
9260           Selector_Name =>
9261             New_Reference_To (First_Tag_Component (Left_Type), Loc));
9262
9263       if Is_Class_Wide_Type (Right_Type) then
9264
9265          --  No need to issue a run-time check if we statically know that the
9266          --  result of this membership test is always true. For example,
9267          --  considering the following declarations:
9268
9269          --    type Iface is interface;
9270          --    type T     is tagged null record;
9271          --    type DT    is new T and Iface with null record;
9272
9273          --    Obj1 : T;
9274          --    Obj2 : DT;
9275
9276          --  These membership tests are always true:
9277
9278          --    Obj1 in T'Class
9279          --    Obj2 in T'Class;
9280          --    Obj2 in Iface'Class;
9281
9282          --  We do not need to handle cases where the membership is illegal.
9283          --  For example:
9284
9285          --    Obj1 in DT'Class;     --  Compile time error
9286          --    Obj1 in Iface'Class;  --  Compile time error
9287
9288          if not Is_Class_Wide_Type (Left_Type)
9289            and then (Is_Ancestor (Etype (Right_Type), Left_Type)
9290                        or else (Is_Interface (Etype (Right_Type))
9291                                  and then Interface_Present_In_Ancestor
9292                                            (Typ   => Left_Type,
9293                                             Iface => Etype (Right_Type))))
9294          then
9295             return New_Reference_To (Standard_True, Loc);
9296          end if;
9297
9298          --  Ada 2005 (AI-251): Class-wide applied to interfaces
9299
9300          if Is_Interface (Etype (Class_Wide_Type (Right_Type)))
9301
9302             --   Support to: "Iface_CW_Typ in Typ'Class"
9303
9304            or else Is_Interface (Left_Type)
9305          then
9306             --  Issue error if IW_Membership operation not available in a
9307             --  configurable run time setting.
9308
9309             if not RTE_Available (RE_IW_Membership) then
9310                Error_Msg_CRT
9311                  ("dynamic membership test on interface types", N);
9312                return Empty;
9313             end if;
9314
9315             return
9316               Make_Function_Call (Loc,
9317                  Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
9318                  Parameter_Associations => New_List (
9319                    Make_Attribute_Reference (Loc,
9320                      Prefix => Obj_Tag,
9321                      Attribute_Name => Name_Address),
9322                    New_Reference_To (
9323                      Node (First_Elmt
9324                             (Access_Disp_Table (Root_Type (Right_Type)))),
9325                      Loc)));
9326
9327          --  Ada 95: Normal case
9328
9329          else
9330             return
9331               Build_CW_Membership (Loc,
9332                 Obj_Tag_Node => Obj_Tag,
9333                 Typ_Tag_Node =>
9334                    New_Reference_To (
9335                      Node (First_Elmt
9336                             (Access_Disp_Table (Root_Type (Right_Type)))),
9337                      Loc));
9338          end if;
9339
9340       --  Right_Type is not a class-wide type
9341
9342       else
9343          --  No need to check the tag of the object if Right_Typ is abstract
9344
9345          if Is_Abstract_Type (Right_Type) then
9346             return New_Reference_To (Standard_False, Loc);
9347
9348          else
9349             return
9350               Make_Op_Eq (Loc,
9351                 Left_Opnd  => Obj_Tag,
9352                 Right_Opnd =>
9353                   New_Reference_To
9354                     (Node (First_Elmt (Access_Disp_Table (Right_Type))), Loc));
9355          end if;
9356       end if;
9357    end Tagged_Membership;
9358
9359    ------------------------------
9360    -- Unary_Op_Validity_Checks --
9361    ------------------------------
9362
9363    procedure Unary_Op_Validity_Checks (N : Node_Id) is
9364    begin
9365       if Validity_Checks_On and Validity_Check_Operands then
9366          Ensure_Valid (Right_Opnd (N));
9367       end if;
9368    end Unary_Op_Validity_Checks;
9369
9370 end Exp_Ch4;