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