[multiple changes]
[gcc.git] / gcc / ada / exp_ch4.adb
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ C H 4 --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
25
26 with Atree; use Atree;
27 with Checks; use Checks;
28 with Debug; use Debug;
29 with Einfo; use Einfo;
30 with Elists; use Elists;
31 with Errout; use Errout;
32 with Exp_Aggr; use Exp_Aggr;
33 with Exp_Atag; use Exp_Atag;
34 with Exp_Ch2; use Exp_Ch2;
35 with Exp_Ch3; use Exp_Ch3;
36 with Exp_Ch6; use Exp_Ch6;
37 with Exp_Ch7; use Exp_Ch7;
38 with Exp_Ch9; use Exp_Ch9;
39 with Exp_Disp; use Exp_Disp;
40 with Exp_Fixd; use Exp_Fixd;
41 with Exp_Intr; use Exp_Intr;
42 with Exp_Pakd; use Exp_Pakd;
43 with Exp_Tss; use Exp_Tss;
44 with Exp_Util; use Exp_Util;
45 with Exp_VFpt; use Exp_VFpt;
46 with Freeze; use Freeze;
47 with Inline; use Inline;
48 with Lib; use Lib;
49 with Namet; use Namet;
50 with Nlists; use Nlists;
51 with Nmake; use Nmake;
52 with Opt; use Opt;
53 with Par_SCO; use Par_SCO;
54 with Restrict; use Restrict;
55 with Rident; use Rident;
56 with Rtsfind; use Rtsfind;
57 with Sem; use Sem;
58 with Sem_Aux; use Sem_Aux;
59 with Sem_Cat; use Sem_Cat;
60 with Sem_Ch3; use Sem_Ch3;
61 with Sem_Ch8; use Sem_Ch8;
62 with Sem_Ch13; use Sem_Ch13;
63 with Sem_Eval; use Sem_Eval;
64 with Sem_Res; use Sem_Res;
65 with Sem_Type; use Sem_Type;
66 with Sem_Util; use Sem_Util;
67 with Sem_Warn; use Sem_Warn;
68 with Sinfo; use Sinfo;
69 with Snames; use Snames;
70 with Stand; use Stand;
71 with SCIL_LL; use SCIL_LL;
72 with Targparm; use Targparm;
73 with Tbuild; use Tbuild;
74 with Ttypes; use Ttypes;
75 with Uintp; use Uintp;
76 with Urealp; use Urealp;
77 with Validsw; use Validsw;
78
79 package body Exp_Ch4 is
80
81 -----------------------
82 -- Local Subprograms --
83 -----------------------
84
85 procedure Binary_Op_Validity_Checks (N : Node_Id);
86 pragma Inline (Binary_Op_Validity_Checks);
87 -- Performs validity checks for a binary operator
88
89 procedure Build_Boolean_Array_Proc_Call
90 (N : Node_Id;
91 Op1 : Node_Id;
92 Op2 : Node_Id);
93 -- If a boolean array assignment can be done in place, build call to
94 -- corresponding library procedure.
95
96 function Current_Anonymous_Master return Entity_Id;
97 -- Return the entity of the heterogeneous finalization master belonging to
98 -- the current unit (either function, package or procedure). This master
99 -- services all anonymous access-to-controlled types. If the current unit
100 -- does not have such master, create one.
101
102 procedure Displace_Allocator_Pointer (N : Node_Id);
103 -- Ada 2005 (AI-251): Subsidiary procedure to Expand_N_Allocator and
104 -- Expand_Allocator_Expression. Allocating class-wide interface objects
105 -- this routine displaces the pointer to the allocated object to reference
106 -- the component referencing the corresponding secondary dispatch table.
107
108 procedure Expand_Allocator_Expression (N : Node_Id);
109 -- Subsidiary to Expand_N_Allocator, for the case when the expression
110 -- is a qualified expression or an aggregate.
111
112 procedure Expand_Array_Comparison (N : Node_Id);
113 -- This routine handles expansion of the comparison operators (N_Op_Lt,
114 -- N_Op_Le, N_Op_Gt, N_Op_Ge) when operating on an array type. The basic
115 -- code for these operators is similar, differing only in the details of
116 -- the actual comparison call that is made. Special processing (call a
117 -- run-time routine)
118
119 function Expand_Array_Equality
120 (Nod : Node_Id;
121 Lhs : Node_Id;
122 Rhs : Node_Id;
123 Bodies : List_Id;
124 Typ : Entity_Id) return Node_Id;
125 -- Expand an array equality into a call to a function implementing this
126 -- equality, and a call to it. Loc is the location for the generated nodes.
127 -- Lhs and Rhs are the array expressions to be compared. Bodies is a list
128 -- on which to attach bodies of local functions that are created in the
129 -- process. It is the responsibility of the caller to insert those bodies
130 -- at the right place. Nod provides the Sloc value for the generated code.
131 -- Normally the types used for the generated equality routine are taken
132 -- from Lhs and Rhs. However, in some situations of generated code, the
133 -- Etype fields of Lhs and Rhs are not set yet. In such cases, Typ supplies
134 -- the type to be used for the formal parameters.
135
136 procedure Expand_Boolean_Operator (N : Node_Id);
137 -- Common expansion processing for Boolean operators (And, Or, Xor) for the
138 -- case of array type arguments.
139
140 procedure Expand_Short_Circuit_Operator (N : Node_Id);
141 -- Common expansion processing for short-circuit boolean operators
142
143 procedure Expand_Compare_Minimize_Eliminate_Overflow (N : Node_Id);
144 -- Deal with comparison in Minimize/Eliminate overflow mode. This is where
145 -- we allow comparison of "out of range" values.
146
147 function Expand_Composite_Equality
148 (Nod : Node_Id;
149 Typ : Entity_Id;
150 Lhs : Node_Id;
151 Rhs : Node_Id;
152 Bodies : List_Id) return Node_Id;
153 -- Local recursive function used to expand equality for nested composite
154 -- types. Used by Expand_Record/Array_Equality, Bodies is a list on which
155 -- to attach bodies of local functions that are created in the process.
156 -- It is the responsibility of the caller to insert those bodies at the
157 -- right place. Nod provides the Sloc value for generated code. Lhs and Rhs
158 -- are the left and right sides for the comparison, and Typ is the type of
159 -- the objects to compare.
160
161 procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id);
162 -- Routine to expand concatenation of a sequence of two or more operands
163 -- (in the list Operands) and replace node Cnode with the result of the
164 -- concatenation. The operands can be of any appropriate type, and can
165 -- include both arrays and singleton elements.
166
167 procedure Expand_Membership_Minimize_Eliminate_Overflow (N : Node_Id);
168 -- N is an N_In membership test mode, with the overflow check mode
169 -- set to Minimized or Eliminated, and the type of the left operand
170 -- is a signed integer type. This is a case where top level processing
171 -- is required to handle overflow checks in subtrees.
172
173 procedure Fixup_Universal_Fixed_Operation (N : Node_Id);
174 -- N is a N_Op_Divide or N_Op_Multiply node whose result is universal
175 -- fixed. We do not have such a type at runtime, so the purpose of this
176 -- routine is to find the real type by looking up the tree. We also
177 -- determine if the operation must be rounded.
178
179 function Has_Inferable_Discriminants (N : Node_Id) return Boolean;
180 -- Ada 2005 (AI-216): A view of an Unchecked_Union object has inferable
181 -- discriminants if it has a constrained nominal type, unless the object
182 -- is a component of an enclosing Unchecked_Union object that is subject
183 -- to a per-object constraint and the enclosing object lacks inferable
184 -- discriminants.
185 --
186 -- An expression of an Unchecked_Union type has inferable discriminants
187 -- if it is either a name of an object with inferable discriminants or a
188 -- qualified expression whose subtype mark denotes a constrained subtype.
189
190 procedure Insert_Dereference_Action (N : Node_Id);
191 -- N is an expression whose type is an access. When the type of the
192 -- associated storage pool is derived from Checked_Pool, generate a
193 -- call to the 'Dereference' primitive operation.
194
195 function Make_Array_Comparison_Op
196 (Typ : Entity_Id;
197 Nod : Node_Id) return Node_Id;
198 -- Comparisons between arrays are expanded in line. This function produces
199 -- the body of the implementation of (a > b), where a and b are one-
200 -- dimensional arrays of some discrete type. The original node is then
201 -- expanded into the appropriate call to this function. Nod provides the
202 -- Sloc value for the generated code.
203
204 function Make_Boolean_Array_Op
205 (Typ : Entity_Id;
206 N : Node_Id) return Node_Id;
207 -- Boolean operations on boolean arrays are expanded in line. This function
208 -- produce the body for the node N, which is (a and b), (a or b), or (a xor
209 -- b). It is used only the normal case and not the packed case. The type
210 -- involved, Typ, is the Boolean array type, and the logical operations in
211 -- the body are simple boolean operations. Note that Typ is always a
212 -- constrained type (the caller has ensured this by using
213 -- Convert_To_Actual_Subtype if necessary).
214
215 function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean;
216 -- For signed arithmetic operations with Do_Overflow_Check set when the
217 -- current overflow mode is MINIMIZED or ELIMINATED, we need to make a
218 -- call to Apply_Arithmetic_Overflow_Checks as the first thing we do. We
219 -- then return. We count on the recursive apparatus for overflow checks
220 -- to call us back with an equivalent operation that does not have the
221 -- Do_Overflow_Check flag set, and that is when we will proceed with the
222 -- expansion of the operator (e.g. converting X+0 to X, or X**2 to X*X).
223 -- We cannot do these optimizations without first making this check, since
224 -- there may be operands further down the tree that are relying on the
225 -- recursive calls triggered by the top level nodes to properly process
226 -- overflow checking and remaining expansion on these nodes. Note that
227 -- this call back may be skipped if the operation is done in Bignum mode
228 -- but that's fine, since the Bignum call takes care of everything.
229
230 procedure Optimize_Length_Comparison (N : Node_Id);
231 -- Given an expression, if it is of the form X'Length op N (or the other
232 -- way round), where N is known at compile time to be 0 or 1, and X is a
233 -- simple entity, and op is a comparison operator, optimizes it into a
234 -- comparison of First and Last.
235
236 procedure Rewrite_Comparison (N : Node_Id);
237 -- If N is the node for a comparison whose outcome can be determined at
238 -- compile time, then the node N can be rewritten with True or False. If
239 -- the outcome cannot be determined at compile time, the call has no
240 -- effect. If N is a type conversion, then this processing is applied to
241 -- its expression. If N is neither comparison nor a type conversion, the
242 -- call has no effect.
243
244 procedure Tagged_Membership
245 (N : Node_Id;
246 SCIL_Node : out Node_Id;
247 Result : out Node_Id);
248 -- Construct the expression corresponding to the tagged membership test.
249 -- Deals with a second operand being (or not) a class-wide type.
250
251 function Safe_In_Place_Array_Op
252 (Lhs : Node_Id;
253 Op1 : Node_Id;
254 Op2 : Node_Id) return Boolean;
255 -- In the context of an assignment, where the right-hand side is a boolean
256 -- operation on arrays, check whether operation can be performed in place.
257
258 procedure Unary_Op_Validity_Checks (N : Node_Id);
259 pragma Inline (Unary_Op_Validity_Checks);
260 -- Performs validity checks for a unary operator
261
262 -------------------------------
263 -- Binary_Op_Validity_Checks --
264 -------------------------------
265
266 procedure Binary_Op_Validity_Checks (N : Node_Id) is
267 begin
268 if Validity_Checks_On and Validity_Check_Operands then
269 Ensure_Valid (Left_Opnd (N));
270 Ensure_Valid (Right_Opnd (N));
271 end if;
272 end Binary_Op_Validity_Checks;
273
274 ------------------------------------
275 -- Build_Boolean_Array_Proc_Call --
276 ------------------------------------
277
278 procedure Build_Boolean_Array_Proc_Call
279 (N : Node_Id;
280 Op1 : Node_Id;
281 Op2 : Node_Id)
282 is
283 Loc : constant Source_Ptr := Sloc (N);
284 Kind : constant Node_Kind := Nkind (Expression (N));
285 Target : constant Node_Id :=
286 Make_Attribute_Reference (Loc,
287 Prefix => Name (N),
288 Attribute_Name => Name_Address);
289
290 Arg1 : Node_Id := Op1;
291 Arg2 : Node_Id := Op2;
292 Call_Node : Node_Id;
293 Proc_Name : Entity_Id;
294
295 begin
296 if Kind = N_Op_Not then
297 if Nkind (Op1) in N_Binary_Op then
298
299 -- Use negated version of the binary operators
300
301 if Nkind (Op1) = N_Op_And then
302 Proc_Name := RTE (RE_Vector_Nand);
303
304 elsif Nkind (Op1) = N_Op_Or then
305 Proc_Name := RTE (RE_Vector_Nor);
306
307 else pragma Assert (Nkind (Op1) = N_Op_Xor);
308 Proc_Name := RTE (RE_Vector_Xor);
309 end if;
310
311 Call_Node :=
312 Make_Procedure_Call_Statement (Loc,
313 Name => New_Occurrence_Of (Proc_Name, Loc),
314
315 Parameter_Associations => New_List (
316 Target,
317 Make_Attribute_Reference (Loc,
318 Prefix => Left_Opnd (Op1),
319 Attribute_Name => Name_Address),
320
321 Make_Attribute_Reference (Loc,
322 Prefix => Right_Opnd (Op1),
323 Attribute_Name => Name_Address),
324
325 Make_Attribute_Reference (Loc,
326 Prefix => Left_Opnd (Op1),
327 Attribute_Name => Name_Length)));
328
329 else
330 Proc_Name := RTE (RE_Vector_Not);
331
332 Call_Node :=
333 Make_Procedure_Call_Statement (Loc,
334 Name => New_Occurrence_Of (Proc_Name, Loc),
335 Parameter_Associations => New_List (
336 Target,
337
338 Make_Attribute_Reference (Loc,
339 Prefix => Op1,
340 Attribute_Name => Name_Address),
341
342 Make_Attribute_Reference (Loc,
343 Prefix => Op1,
344 Attribute_Name => Name_Length)));
345 end if;
346
347 else
348 -- We use the following equivalences:
349
350 -- (not X) or (not Y) = not (X and Y) = Nand (X, Y)
351 -- (not X) and (not Y) = not (X or Y) = Nor (X, Y)
352 -- (not X) xor (not Y) = X xor Y
353 -- X xor (not Y) = not (X xor Y) = Nxor (X, Y)
354
355 if Nkind (Op1) = N_Op_Not then
356 Arg1 := Right_Opnd (Op1);
357 Arg2 := Right_Opnd (Op2);
358 if Kind = N_Op_And then
359 Proc_Name := RTE (RE_Vector_Nor);
360 elsif Kind = N_Op_Or then
361 Proc_Name := RTE (RE_Vector_Nand);
362 else
363 Proc_Name := RTE (RE_Vector_Xor);
364 end if;
365
366 else
367 if Kind = N_Op_And then
368 Proc_Name := RTE (RE_Vector_And);
369 elsif Kind = N_Op_Or then
370 Proc_Name := RTE (RE_Vector_Or);
371 elsif Nkind (Op2) = N_Op_Not then
372 Proc_Name := RTE (RE_Vector_Nxor);
373 Arg2 := Right_Opnd (Op2);
374 else
375 Proc_Name := RTE (RE_Vector_Xor);
376 end if;
377 end if;
378
379 Call_Node :=
380 Make_Procedure_Call_Statement (Loc,
381 Name => New_Occurrence_Of (Proc_Name, Loc),
382 Parameter_Associations => New_List (
383 Target,
384 Make_Attribute_Reference (Loc,
385 Prefix => Arg1,
386 Attribute_Name => Name_Address),
387 Make_Attribute_Reference (Loc,
388 Prefix => Arg2,
389 Attribute_Name => Name_Address),
390 Make_Attribute_Reference (Loc,
391 Prefix => Arg1,
392 Attribute_Name => Name_Length)));
393 end if;
394
395 Rewrite (N, Call_Node);
396 Analyze (N);
397
398 exception
399 when RE_Not_Available =>
400 return;
401 end Build_Boolean_Array_Proc_Call;
402
403 ------------------------------
404 -- Current_Anonymous_Master --
405 ------------------------------
406
407 function Current_Anonymous_Master return Entity_Id is
408 Decls : List_Id;
409 Loc : Source_Ptr;
410 Subp_Body : Node_Id;
411 Unit_Decl : Node_Id;
412 Unit_Id : Entity_Id;
413
414 begin
415 Unit_Id := Cunit_Entity (Current_Sem_Unit);
416
417 -- Find the entity of the current unit
418
419 if Ekind (Unit_Id) = E_Subprogram_Body then
420
421 -- When processing subprogram bodies, the proper scope is always that
422 -- of the spec.
423
424 Subp_Body := Unit_Id;
425 while Present (Subp_Body)
426 and then Nkind (Subp_Body) /= N_Subprogram_Body
427 loop
428 Subp_Body := Parent (Subp_Body);
429 end loop;
430
431 Unit_Id := Corresponding_Spec (Subp_Body);
432 end if;
433
434 Loc := Sloc (Unit_Id);
435 Unit_Decl := Unit (Cunit (Current_Sem_Unit));
436
437 -- Find the declarations list of the current unit
438
439 if Nkind (Unit_Decl) = N_Package_Declaration then
440 Unit_Decl := Specification (Unit_Decl);
441 Decls := Visible_Declarations (Unit_Decl);
442
443 if No (Decls) then
444 Decls := New_List (Make_Null_Statement (Loc));
445 Set_Visible_Declarations (Unit_Decl, Decls);
446
447 elsif Is_Empty_List (Decls) then
448 Append_To (Decls, Make_Null_Statement (Loc));
449 end if;
450
451 else
452 Decls := Declarations (Unit_Decl);
453
454 if No (Decls) then
455 Decls := New_List (Make_Null_Statement (Loc));
456 Set_Declarations (Unit_Decl, Decls);
457
458 elsif Is_Empty_List (Decls) then
459 Append_To (Decls, Make_Null_Statement (Loc));
460 end if;
461 end if;
462
463 -- The current unit has an existing anonymous master, traverse its
464 -- declarations and locate the entity.
465
466 if Has_Anonymous_Master (Unit_Id) then
467 declare
468 Decl : Node_Id;
469 Fin_Mas_Id : Entity_Id;
470
471 begin
472 Decl := First (Decls);
473 while Present (Decl) loop
474
475 -- Look for the first variable in the declarations whole type
476 -- is Finalization_Master.
477
478 if Nkind (Decl) = N_Object_Declaration then
479 Fin_Mas_Id := Defining_Identifier (Decl);
480
481 if Ekind (Fin_Mas_Id) = E_Variable
482 and then Etype (Fin_Mas_Id) = RTE (RE_Finalization_Master)
483 then
484 return Fin_Mas_Id;
485 end if;
486 end if;
487
488 Next (Decl);
489 end loop;
490
491 -- The master was not found even though the unit was labeled as
492 -- having one.
493
494 raise Program_Error;
495 end;
496
497 -- Create a new anonymous master
498
499 else
500 declare
501 First_Decl : constant Node_Id := First (Decls);
502 Action : Node_Id;
503 Fin_Mas_Id : Entity_Id;
504
505 begin
506 -- Since the master and its associated initialization is inserted
507 -- at top level, use the scope of the unit when analyzing.
508
509 Push_Scope (Unit_Id);
510
511 -- Create the finalization master
512
513 Fin_Mas_Id :=
514 Make_Defining_Identifier (Loc,
515 Chars => New_External_Name (Chars (Unit_Id), "AM"));
516
517 -- Generate:
518 -- <Fin_Mas_Id> : Finalization_Master;
519
520 Action :=
521 Make_Object_Declaration (Loc,
522 Defining_Identifier => Fin_Mas_Id,
523 Object_Definition =>
524 New_Reference_To (RTE (RE_Finalization_Master), Loc));
525
526 Insert_Before_And_Analyze (First_Decl, Action);
527
528 -- Mark the unit to prevent the generation of multiple masters
529
530 Set_Has_Anonymous_Master (Unit_Id);
531
532 -- Do not set the base pool and mode of operation on .NET/JVM
533 -- since those targets do not support pools and all VM masters
534 -- are heterogeneous by default.
535
536 if VM_Target = No_VM then
537
538 -- Generate:
539 -- Set_Base_Pool
540 -- (<Fin_Mas_Id>, Global_Pool_Object'Unrestricted_Access);
541
542 Action :=
543 Make_Procedure_Call_Statement (Loc,
544 Name =>
545 New_Reference_To (RTE (RE_Set_Base_Pool), Loc),
546
547 Parameter_Associations => New_List (
548 New_Reference_To (Fin_Mas_Id, Loc),
549 Make_Attribute_Reference (Loc,
550 Prefix =>
551 New_Reference_To (RTE (RE_Global_Pool_Object), Loc),
552 Attribute_Name => Name_Unrestricted_Access)));
553
554 Insert_Before_And_Analyze (First_Decl, Action);
555
556 -- Generate:
557 -- Set_Is_Heterogeneous (<Fin_Mas_Id>);
558
559 Action :=
560 Make_Procedure_Call_Statement (Loc,
561 Name =>
562 New_Reference_To (RTE (RE_Set_Is_Heterogeneous), Loc),
563 Parameter_Associations => New_List (
564 New_Reference_To (Fin_Mas_Id, Loc)));
565
566 Insert_Before_And_Analyze (First_Decl, Action);
567 end if;
568
569 -- Restore the original state of the scope stack
570
571 Pop_Scope;
572
573 return Fin_Mas_Id;
574 end;
575 end if;
576 end Current_Anonymous_Master;
577
578 --------------------------------
579 -- Displace_Allocator_Pointer --
580 --------------------------------
581
582 procedure Displace_Allocator_Pointer (N : Node_Id) is
583 Loc : constant Source_Ptr := Sloc (N);
584 Orig_Node : constant Node_Id := Original_Node (N);
585 Dtyp : Entity_Id;
586 Etyp : Entity_Id;
587 PtrT : Entity_Id;
588
589 begin
590 -- Do nothing in case of VM targets: the virtual machine will handle
591 -- interfaces directly.
592
593 if not Tagged_Type_Expansion then
594 return;
595 end if;
596
597 pragma Assert (Nkind (N) = N_Identifier
598 and then Nkind (Orig_Node) = N_Allocator);
599
600 PtrT := Etype (Orig_Node);
601 Dtyp := Available_View (Designated_Type (PtrT));
602 Etyp := Etype (Expression (Orig_Node));
603
604 if Is_Class_Wide_Type (Dtyp)
605 and then Is_Interface (Dtyp)
606 then
607 -- If the type of the allocator expression is not an interface type
608 -- we can generate code to reference the record component containing
609 -- the pointer to the secondary dispatch table.
610
611 if not Is_Interface (Etyp) then
612 declare
613 Saved_Typ : constant Entity_Id := Etype (Orig_Node);
614
615 begin
616 -- 1) Get access to the allocated object
617
618 Rewrite (N,
619 Make_Explicit_Dereference (Loc, Relocate_Node (N)));
620 Set_Etype (N, Etyp);
621 Set_Analyzed (N);
622
623 -- 2) Add the conversion to displace the pointer to reference
624 -- the secondary dispatch table.
625
626 Rewrite (N, Convert_To (Dtyp, Relocate_Node (N)));
627 Analyze_And_Resolve (N, Dtyp);
628
629 -- 3) The 'access to the secondary dispatch table will be used
630 -- as the value returned by the allocator.
631
632 Rewrite (N,
633 Make_Attribute_Reference (Loc,
634 Prefix => Relocate_Node (N),
635 Attribute_Name => Name_Access));
636 Set_Etype (N, Saved_Typ);
637 Set_Analyzed (N);
638 end;
639
640 -- If the type of the allocator expression is an interface type we
641 -- generate a run-time call to displace "this" to reference the
642 -- component containing the pointer to the secondary dispatch table
643 -- or else raise Constraint_Error if the actual object does not
644 -- implement the target interface. This case corresponds with the
645 -- following example:
646
647 -- function Op (Obj : Iface_1'Class) return access Iface_2'Class is
648 -- begin
649 -- return new Iface_2'Class'(Obj);
650 -- end Op;
651
652 else
653 Rewrite (N,
654 Unchecked_Convert_To (PtrT,
655 Make_Function_Call (Loc,
656 Name => New_Reference_To (RTE (RE_Displace), Loc),
657 Parameter_Associations => New_List (
658 Unchecked_Convert_To (RTE (RE_Address),
659 Relocate_Node (N)),
660
661 New_Occurrence_Of
662 (Elists.Node
663 (First_Elmt
664 (Access_Disp_Table (Etype (Base_Type (Dtyp))))),
665 Loc)))));
666 Analyze_And_Resolve (N, PtrT);
667 end if;
668 end if;
669 end Displace_Allocator_Pointer;
670
671 ---------------------------------
672 -- Expand_Allocator_Expression --
673 ---------------------------------
674
675 procedure Expand_Allocator_Expression (N : Node_Id) is
676 Loc : constant Source_Ptr := Sloc (N);
677 Exp : constant Node_Id := Expression (Expression (N));
678 PtrT : constant Entity_Id := Etype (N);
679 DesigT : constant Entity_Id := Designated_Type (PtrT);
680
681 procedure Apply_Accessibility_Check
682 (Ref : Node_Id;
683 Built_In_Place : Boolean := False);
684 -- Ada 2005 (AI-344): For an allocator with a class-wide designated
685 -- type, generate an accessibility check to verify that the level of the
686 -- type of the created object is not deeper than the level of the access
687 -- type. If the type of the qualified expression is class-wide, then
688 -- always generate the check (except in the case where it is known to be
689 -- unnecessary, see comment below). Otherwise, only generate the check
690 -- if the level of the qualified expression type is statically deeper
691 -- than the access type.
692 --
693 -- Although the static accessibility will generally have been performed
694 -- as a legality check, it won't have been done in cases where the
695 -- allocator appears in generic body, so a run-time check is needed in
696 -- general. One special case is when the access type is declared in the
697 -- same scope as the class-wide allocator, in which case the check can
698 -- never fail, so it need not be generated.
699 --
700 -- As an open issue, there seem to be cases where the static level
701 -- associated with the class-wide object's underlying type is not
702 -- sufficient to perform the proper accessibility check, such as for
703 -- allocators in nested subprograms or accept statements initialized by
704 -- class-wide formals when the actual originates outside at a deeper
705 -- static level. The nested subprogram case might require passing
706 -- accessibility levels along with class-wide parameters, and the task
707 -- case seems to be an actual gap in the language rules that needs to
708 -- be fixed by the ARG. ???
709
710 -------------------------------
711 -- Apply_Accessibility_Check --
712 -------------------------------
713
714 procedure Apply_Accessibility_Check
715 (Ref : Node_Id;
716 Built_In_Place : Boolean := False)
717 is
718 Pool_Id : constant Entity_Id := Associated_Storage_Pool (PtrT);
719 Cond : Node_Id;
720 Free_Stmt : Node_Id;
721 Obj_Ref : Node_Id;
722 Stmts : List_Id;
723
724 begin
725 if Ada_Version >= Ada_2005
726 and then Is_Class_Wide_Type (DesigT)
727 and then not Scope_Suppress.Suppress (Accessibility_Check)
728 and then
729 (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
730 or else
731 (Is_Class_Wide_Type (Etype (Exp))
732 and then Scope (PtrT) /= Current_Scope))
733 and then (Tagged_Type_Expansion or else VM_Target /= No_VM)
734 then
735 -- If the allocator was built in place, Ref is already a reference
736 -- to the access object initialized to the result of the allocator
737 -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). We call
738 -- Remove_Side_Effects for cases where the build-in-place call may
739 -- still be the prefix of the reference (to avoid generating
740 -- duplicate calls). Otherwise, it is the entity associated with
741 -- the object containing the address of the allocated object.
742
743 if Built_In_Place then
744 Remove_Side_Effects (Ref);
745 Obj_Ref := New_Copy (Ref);
746 else
747 Obj_Ref := New_Reference_To (Ref, Loc);
748 end if;
749
750 -- Step 1: Create the object clean up code
751
752 Stmts := New_List;
753
754 -- Create an explicit free statement to clean up the allocated
755 -- object in case the accessibility check fails. Generate:
756
757 -- Free (Obj_Ref);
758
759 Free_Stmt := Make_Free_Statement (Loc, New_Copy (Obj_Ref));
760 Set_Storage_Pool (Free_Stmt, Pool_Id);
761
762 Append_To (Stmts, Free_Stmt);
763
764 -- Finalize the object (if applicable), but wrap the call inside
765 -- a block to ensure that the object would still be deallocated in
766 -- case the finalization fails. Generate:
767
768 -- begin
769 -- [Deep_]Finalize (Obj_Ref.all);
770 -- exception
771 -- when others =>
772 -- Free (Obj_Ref);
773 -- raise;
774 -- end;
775
776 if Needs_Finalization (DesigT) then
777 Prepend_To (Stmts,
778 Make_Block_Statement (Loc,
779 Handled_Statement_Sequence =>
780 Make_Handled_Sequence_Of_Statements (Loc,
781 Statements => New_List (
782 Make_Final_Call (
783 Obj_Ref =>
784 Make_Explicit_Dereference (Loc,
785 Prefix => New_Copy (Obj_Ref)),
786 Typ => DesigT)),
787
788 Exception_Handlers => New_List (
789 Make_Exception_Handler (Loc,
790 Exception_Choices => New_List (
791 Make_Others_Choice (Loc)),
792 Statements => New_List (
793 New_Copy_Tree (Free_Stmt),
794 Make_Raise_Statement (Loc)))))));
795 end if;
796
797 -- Signal the accessibility failure through a Program_Error
798
799 Append_To (Stmts,
800 Make_Raise_Program_Error (Loc,
801 Condition => New_Reference_To (Standard_True, Loc),
802 Reason => PE_Accessibility_Check_Failed));
803
804 -- Step 2: Create the accessibility comparison
805
806 -- Generate:
807 -- Ref'Tag
808
809 Obj_Ref :=
810 Make_Attribute_Reference (Loc,
811 Prefix => Obj_Ref,
812 Attribute_Name => Name_Tag);
813
814 -- For tagged types, determine the accessibility level by looking
815 -- at the type specific data of the dispatch table. Generate:
816
817 -- Type_Specific_Data (Address (Ref'Tag)).Access_Level
818
819 if Tagged_Type_Expansion then
820 Cond := Build_Get_Access_Level (Loc, Obj_Ref);
821
822 -- Use a runtime call to determine the accessibility level when
823 -- compiling on virtual machine targets. Generate:
824
825 -- Get_Access_Level (Ref'Tag)
826
827 else
828 Cond :=
829 Make_Function_Call (Loc,
830 Name =>
831 New_Reference_To (RTE (RE_Get_Access_Level), Loc),
832 Parameter_Associations => New_List (Obj_Ref));
833 end if;
834
835 Cond :=
836 Make_Op_Gt (Loc,
837 Left_Opnd => Cond,
838 Right_Opnd =>
839 Make_Integer_Literal (Loc, Type_Access_Level (PtrT)));
840
841 -- Due to the complexity and side effects of the check, utilize an
842 -- if statement instead of the regular Program_Error circuitry.
843
844 Insert_Action (N,
845 Make_If_Statement (Loc,
846 Condition => Cond,
847 Then_Statements => Stmts));
848 end if;
849 end Apply_Accessibility_Check;
850
851 -- Local variables
852
853 Aggr_In_Place : constant Boolean := Is_Delayed_Aggregate (Exp);
854 Indic : constant Node_Id := Subtype_Mark (Expression (N));
855 T : constant Entity_Id := Entity (Indic);
856 Node : Node_Id;
857 Tag_Assign : Node_Id;
858 Temp : Entity_Id;
859 Temp_Decl : Node_Id;
860
861 TagT : Entity_Id := Empty;
862 -- Type used as source for tag assignment
863
864 TagR : Node_Id := Empty;
865 -- Target reference for tag assignment
866
867 -- Start of processing for Expand_Allocator_Expression
868
869 begin
870 -- In the case of an Ada 2012 allocator whose initial value comes from a
871 -- function call, pass "the accessibility level determined by the point
872 -- of call" (AI05-0234) to the function. Conceptually, this belongs in
873 -- Expand_Call but it couldn't be done there (because the Etype of the
874 -- allocator wasn't set then) so we generate the parameter here. See
875 -- the Boolean variable Defer in (a block within) Expand_Call.
876
877 if Ada_Version >= Ada_2012 and then Nkind (Exp) = N_Function_Call then
878 declare
879 Subp : Entity_Id;
880
881 begin
882 if Nkind (Name (Exp)) = N_Explicit_Dereference then
883 Subp := Designated_Type (Etype (Prefix (Name (Exp))));
884 else
885 Subp := Entity (Name (Exp));
886 end if;
887
888 Subp := Ultimate_Alias (Subp);
889
890 if Present (Extra_Accessibility_Of_Result (Subp)) then
891 Add_Extra_Actual_To_Call
892 (Subprogram_Call => Exp,
893 Extra_Formal => Extra_Accessibility_Of_Result (Subp),
894 Extra_Actual => Dynamic_Accessibility_Level (PtrT));
895 end if;
896 end;
897 end if;
898
899 -- Case of tagged type or type requiring finalization
900
901 if Is_Tagged_Type (T) or else Needs_Finalization (T) then
902 if Is_CPP_Constructor_Call (Exp) then
903
904 -- Generate:
905 -- Pnnn : constant ptr_T := new (T);
906 -- Init (Pnnn.all,...);
907
908 -- Allocate the object without an expression
909
910 Node := Relocate_Node (N);
911 Set_Expression (Node, New_Reference_To (Etype (Exp), Loc));
912
913 -- Avoid its expansion to avoid generating a call to the default
914 -- C++ constructor.
915
916 Set_Analyzed (Node);
917
918 Temp := Make_Temporary (Loc, 'P', N);
919
920 Temp_Decl :=
921 Make_Object_Declaration (Loc,
922 Defining_Identifier => Temp,
923 Constant_Present => True,
924 Object_Definition => New_Reference_To (PtrT, Loc),
925 Expression => Node);
926 Insert_Action (N, Temp_Decl);
927
928 Apply_Accessibility_Check (Temp);
929
930 -- Locate the enclosing list and insert the C++ constructor call
931
932 declare
933 P : Node_Id;
934
935 begin
936 P := Parent (Node);
937 while not Is_List_Member (P) loop
938 P := Parent (P);
939 end loop;
940
941 Insert_List_After_And_Analyze (P,
942 Build_Initialization_Call (Loc,
943 Id_Ref =>
944 Make_Explicit_Dereference (Loc,
945 Prefix => New_Reference_To (Temp, Loc)),
946 Typ => Etype (Exp),
947 Constructor_Ref => Exp));
948 end;
949
950 Rewrite (N, New_Reference_To (Temp, Loc));
951 Analyze_And_Resolve (N, PtrT);
952 return;
953 end if;
954
955 -- Ada 2005 (AI-318-02): If the initialization expression is a call
956 -- to a build-in-place function, then access to the allocated object
957 -- must be passed to the function. Currently we limit such functions
958 -- to those with constrained limited result subtypes, but eventually
959 -- we plan to expand the allowed forms of functions that are treated
960 -- as build-in-place.
961
962 if Ada_Version >= Ada_2005
963 and then Is_Build_In_Place_Function_Call (Exp)
964 then
965 Make_Build_In_Place_Call_In_Allocator (N, Exp);
966 Apply_Accessibility_Check (N, Built_In_Place => True);
967 return;
968 end if;
969
970 -- Actions inserted before:
971 -- Temp : constant ptr_T := new T'(Expression);
972 -- Temp._tag = T'tag; -- when not class-wide
973 -- [Deep_]Adjust (Temp.all);
974
975 -- We analyze by hand the new internal allocator to avoid any
976 -- recursion and inappropriate call to Initialize
977
978 -- We don't want to remove side effects when the expression must be
979 -- built in place. In the case of a build-in-place function call,
980 -- that could lead to a duplication of the call, which was already
981 -- substituted for the allocator.
982
983 if not Aggr_In_Place then
984 Remove_Side_Effects (Exp);
985 end if;
986
987 Temp := Make_Temporary (Loc, 'P', N);
988
989 -- For a class wide allocation generate the following code:
990
991 -- type Equiv_Record is record ... end record;
992 -- implicit subtype CW is <Class_Wide_Subytpe>;
993 -- temp : PtrT := new CW'(CW!(expr));
994
995 if Is_Class_Wide_Type (T) then
996 Expand_Subtype_From_Expr (Empty, T, Indic, Exp);
997
998 -- Ada 2005 (AI-251): If the expression is a class-wide interface
999 -- object we generate code to move up "this" to reference the
1000 -- base of the object before allocating the new object.
1001
1002 -- Note that Exp'Address is recursively expanded into a call
1003 -- to Base_Address (Exp.Tag)
1004
1005 if Is_Class_Wide_Type (Etype (Exp))
1006 and then Is_Interface (Etype (Exp))
1007 and then Tagged_Type_Expansion
1008 then
1009 Set_Expression
1010 (Expression (N),
1011 Unchecked_Convert_To (Entity (Indic),
1012 Make_Explicit_Dereference (Loc,
1013 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
1014 Make_Attribute_Reference (Loc,
1015 Prefix => Exp,
1016 Attribute_Name => Name_Address)))));
1017 else
1018 Set_Expression
1019 (Expression (N),
1020 Unchecked_Convert_To (Entity (Indic), Exp));
1021 end if;
1022
1023 Analyze_And_Resolve (Expression (N), Entity (Indic));
1024 end if;
1025
1026 -- Processing for allocators returning non-interface types
1027
1028 if not Is_Interface (Directly_Designated_Type (PtrT)) then
1029 if Aggr_In_Place then
1030 Temp_Decl :=
1031 Make_Object_Declaration (Loc,
1032 Defining_Identifier => Temp,
1033 Object_Definition => New_Reference_To (PtrT, Loc),
1034 Expression =>
1035 Make_Allocator (Loc,
1036 Expression =>
1037 New_Reference_To (Etype (Exp), Loc)));
1038
1039 -- Copy the Comes_From_Source flag for the allocator we just
1040 -- built, since logically this allocator is a replacement of
1041 -- the original allocator node. This is for proper handling of
1042 -- restriction No_Implicit_Heap_Allocations.
1043
1044 Set_Comes_From_Source
1045 (Expression (Temp_Decl), Comes_From_Source (N));
1046
1047 Set_No_Initialization (Expression (Temp_Decl));
1048 Insert_Action (N, Temp_Decl);
1049
1050 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
1051 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
1052
1053 -- Attach the object to the associated finalization master.
1054 -- This is done manually on .NET/JVM since those compilers do
1055 -- no support pools and can't benefit from internally generated
1056 -- Allocate / Deallocate procedures.
1057
1058 if VM_Target /= No_VM
1059 and then Is_Controlled (DesigT)
1060 and then Present (Finalization_Master (PtrT))
1061 then
1062 Insert_Action (N,
1063 Make_Attach_Call (
1064 Obj_Ref =>
1065 New_Reference_To (Temp, Loc),
1066 Ptr_Typ => PtrT));
1067 end if;
1068
1069 else
1070 Node := Relocate_Node (N);
1071 Set_Analyzed (Node);
1072
1073 Temp_Decl :=
1074 Make_Object_Declaration (Loc,
1075 Defining_Identifier => Temp,
1076 Constant_Present => True,
1077 Object_Definition => New_Reference_To (PtrT, Loc),
1078 Expression => Node);
1079
1080 Insert_Action (N, Temp_Decl);
1081 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
1082
1083 -- Attach the object to the associated finalization master.
1084 -- This is done manually on .NET/JVM since those compilers do
1085 -- no support pools and can't benefit from internally generated
1086 -- Allocate / Deallocate procedures.
1087
1088 if VM_Target /= No_VM
1089 and then Is_Controlled (DesigT)
1090 and then Present (Finalization_Master (PtrT))
1091 then
1092 Insert_Action (N,
1093 Make_Attach_Call (
1094 Obj_Ref =>
1095 New_Reference_To (Temp, Loc),
1096 Ptr_Typ => PtrT));
1097 end if;
1098 end if;
1099
1100 -- Ada 2005 (AI-251): Handle allocators whose designated type is an
1101 -- interface type. In this case we use the type of the qualified
1102 -- expression to allocate the object.
1103
1104 else
1105 declare
1106 Def_Id : constant Entity_Id := Make_Temporary (Loc, 'T');
1107 New_Decl : Node_Id;
1108
1109 begin
1110 New_Decl :=
1111 Make_Full_Type_Declaration (Loc,
1112 Defining_Identifier => Def_Id,
1113 Type_Definition =>
1114 Make_Access_To_Object_Definition (Loc,
1115 All_Present => True,
1116 Null_Exclusion_Present => False,
1117 Constant_Present =>
1118 Is_Access_Constant (Etype (N)),
1119 Subtype_Indication =>
1120 New_Reference_To (Etype (Exp), Loc)));
1121
1122 Insert_Action (N, New_Decl);
1123
1124 -- Inherit the allocation-related attributes from the original
1125 -- access type.
1126
1127 Set_Finalization_Master (Def_Id, Finalization_Master (PtrT));
1128
1129 Set_Associated_Storage_Pool (Def_Id,
1130 Associated_Storage_Pool (PtrT));
1131
1132 -- Declare the object using the previous type declaration
1133
1134 if Aggr_In_Place then
1135 Temp_Decl :=
1136 Make_Object_Declaration (Loc,
1137 Defining_Identifier => Temp,
1138 Object_Definition => New_Reference_To (Def_Id, Loc),
1139 Expression =>
1140 Make_Allocator (Loc,
1141 New_Reference_To (Etype (Exp), Loc)));
1142
1143 -- Copy the Comes_From_Source flag for the allocator we just
1144 -- built, since logically this allocator is a replacement of
1145 -- the original allocator node. This is for proper handling
1146 -- of restriction No_Implicit_Heap_Allocations.
1147
1148 Set_Comes_From_Source
1149 (Expression (Temp_Decl), Comes_From_Source (N));
1150
1151 Set_No_Initialization (Expression (Temp_Decl));
1152 Insert_Action (N, Temp_Decl);
1153
1154 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
1155 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
1156
1157 else
1158 Node := Relocate_Node (N);
1159 Set_Analyzed (Node);
1160
1161 Temp_Decl :=
1162 Make_Object_Declaration (Loc,
1163 Defining_Identifier => Temp,
1164 Constant_Present => True,
1165 Object_Definition => New_Reference_To (Def_Id, Loc),
1166 Expression => Node);
1167
1168 Insert_Action (N, Temp_Decl);
1169 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
1170 end if;
1171
1172 -- Generate an additional object containing the address of the
1173 -- returned object. The type of this second object declaration
1174 -- is the correct type required for the common processing that
1175 -- is still performed by this subprogram. The displacement of
1176 -- this pointer to reference the component associated with the
1177 -- interface type will be done at the end of common processing.
1178
1179 New_Decl :=
1180 Make_Object_Declaration (Loc,
1181 Defining_Identifier => Make_Temporary (Loc, 'P'),
1182 Object_Definition => New_Reference_To (PtrT, Loc),
1183 Expression =>
1184 Unchecked_Convert_To (PtrT,
1185 New_Reference_To (Temp, Loc)));
1186
1187 Insert_Action (N, New_Decl);
1188
1189 Temp_Decl := New_Decl;
1190 Temp := Defining_Identifier (New_Decl);
1191 end;
1192 end if;
1193
1194 Apply_Accessibility_Check (Temp);
1195
1196 -- Generate the tag assignment
1197
1198 -- Suppress the tag assignment when VM_Target because VM tags are
1199 -- represented implicitly in objects.
1200
1201 if not Tagged_Type_Expansion then
1202 null;
1203
1204 -- Ada 2005 (AI-251): Suppress the tag assignment with class-wide
1205 -- interface objects because in this case the tag does not change.
1206
1207 elsif Is_Interface (Directly_Designated_Type (Etype (N))) then
1208 pragma Assert (Is_Class_Wide_Type
1209 (Directly_Designated_Type (Etype (N))));
1210 null;
1211
1212 elsif Is_Tagged_Type (T) and then not Is_Class_Wide_Type (T) then
1213 TagT := T;
1214 TagR := New_Reference_To (Temp, Loc);
1215
1216 elsif Is_Private_Type (T)
1217 and then Is_Tagged_Type (Underlying_Type (T))
1218 then
1219 TagT := Underlying_Type (T);
1220 TagR :=
1221 Unchecked_Convert_To (Underlying_Type (T),
1222 Make_Explicit_Dereference (Loc,
1223 Prefix => New_Reference_To (Temp, Loc)));
1224 end if;
1225
1226 if Present (TagT) then
1227 declare
1228 Full_T : constant Entity_Id := Underlying_Type (TagT);
1229 begin
1230 Tag_Assign :=
1231 Make_Assignment_Statement (Loc,
1232 Name =>
1233 Make_Selected_Component (Loc,
1234 Prefix => TagR,
1235 Selector_Name =>
1236 New_Reference_To (First_Tag_Component (Full_T), Loc)),
1237 Expression =>
1238 Unchecked_Convert_To (RTE (RE_Tag),
1239 New_Reference_To
1240 (Elists.Node
1241 (First_Elmt (Access_Disp_Table (Full_T))), Loc)));
1242 end;
1243
1244 -- The previous assignment has to be done in any case
1245
1246 Set_Assignment_OK (Name (Tag_Assign));
1247 Insert_Action (N, Tag_Assign);
1248 end if;
1249
1250 if Needs_Finalization (DesigT)
1251 and then Needs_Finalization (T)
1252 then
1253 -- Generate an Adjust call if the object will be moved. In Ada
1254 -- 2005, the object may be inherently limited, in which case
1255 -- there is no Adjust procedure, and the object is built in
1256 -- place. In Ada 95, the object can be limited but not
1257 -- inherently limited if this allocator came from a return
1258 -- statement (we're allocating the result on the secondary
1259 -- stack). In that case, the object will be moved, so we _do_
1260 -- want to Adjust.
1261
1262 if not Aggr_In_Place
1263 and then not Is_Immutably_Limited_Type (T)
1264 then
1265 Insert_Action (N,
1266 Make_Adjust_Call (
1267 Obj_Ref =>
1268
1269 -- An unchecked conversion is needed in the classwide
1270 -- case because the designated type can be an ancestor
1271 -- of the subtype mark of the allocator.
1272
1273 Unchecked_Convert_To (T,
1274 Make_Explicit_Dereference (Loc,
1275 Prefix => New_Reference_To (Temp, Loc))),
1276 Typ => T));
1277 end if;
1278
1279 -- Generate:
1280 -- Set_Finalize_Address (<PtrT>FM, <T>FD'Unrestricted_Access);
1281
1282 -- Do not generate this call in the following cases:
1283
1284 -- * .NET/JVM - these targets do not support address arithmetic
1285 -- and unchecked conversion, key elements of Finalize_Address.
1286
1287 -- * Alfa mode - the call is useless and results in unwanted
1288 -- expansion.
1289
1290 -- * CodePeer mode - TSS primitive Finalize_Address is not
1291 -- created in this mode.
1292
1293 if VM_Target = No_VM
1294 and then not Alfa_Mode
1295 and then not CodePeer_Mode
1296 and then Present (Finalization_Master (PtrT))
1297 and then Present (Temp_Decl)
1298 and then Nkind (Expression (Temp_Decl)) = N_Allocator
1299 then
1300 Insert_Action (N,
1301 Make_Set_Finalize_Address_Call
1302 (Loc => Loc,
1303 Typ => T,
1304 Ptr_Typ => PtrT));
1305 end if;
1306 end if;
1307
1308 Rewrite (N, New_Reference_To (Temp, Loc));
1309 Analyze_And_Resolve (N, PtrT);
1310
1311 -- Ada 2005 (AI-251): Displace the pointer to reference the record
1312 -- component containing the secondary dispatch table of the interface
1313 -- type.
1314
1315 if Is_Interface (Directly_Designated_Type (PtrT)) then
1316 Displace_Allocator_Pointer (N);
1317 end if;
1318
1319 elsif Aggr_In_Place then
1320 Temp := Make_Temporary (Loc, 'P', N);
1321 Temp_Decl :=
1322 Make_Object_Declaration (Loc,
1323 Defining_Identifier => Temp,
1324 Object_Definition => New_Reference_To (PtrT, Loc),
1325 Expression =>
1326 Make_Allocator (Loc,
1327 Expression => New_Reference_To (Etype (Exp), Loc)));
1328
1329 -- Copy the Comes_From_Source flag for the allocator we just built,
1330 -- since logically this allocator is a replacement of the original
1331 -- allocator node. This is for proper handling of restriction
1332 -- No_Implicit_Heap_Allocations.
1333
1334 Set_Comes_From_Source
1335 (Expression (Temp_Decl), Comes_From_Source (N));
1336
1337 Set_No_Initialization (Expression (Temp_Decl));
1338 Insert_Action (N, Temp_Decl);
1339
1340 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
1341 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
1342
1343 -- Attach the object to the associated finalization master. Thisis
1344 -- done manually on .NET/JVM since those compilers do no support
1345 -- pools and cannot benefit from internally generated Allocate and
1346 -- Deallocate procedures.
1347
1348 if VM_Target /= No_VM
1349 and then Is_Controlled (DesigT)
1350 and then Present (Finalization_Master (PtrT))
1351 then
1352 Insert_Action (N,
1353 Make_Attach_Call
1354 (Obj_Ref => New_Reference_To (Temp, Loc),
1355 Ptr_Typ => PtrT));
1356 end if;
1357
1358 Rewrite (N, New_Reference_To (Temp, Loc));
1359 Analyze_And_Resolve (N, PtrT);
1360
1361 elsif Is_Access_Type (T)
1362 and then Can_Never_Be_Null (T)
1363 then
1364 Install_Null_Excluding_Check (Exp);
1365
1366 elsif Is_Access_Type (DesigT)
1367 and then Nkind (Exp) = N_Allocator
1368 and then Nkind (Expression (Exp)) /= N_Qualified_Expression
1369 then
1370 -- Apply constraint to designated subtype indication
1371
1372 Apply_Constraint_Check (Expression (Exp),
1373 Designated_Type (DesigT),
1374 No_Sliding => True);
1375
1376 if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then
1377
1378 -- Propagate constraint_error to enclosing allocator
1379
1380 Rewrite (Exp, New_Copy (Expression (Exp)));
1381 end if;
1382
1383 else
1384 Build_Allocate_Deallocate_Proc (N, True);
1385
1386 -- If we have:
1387 -- type A is access T1;
1388 -- X : A := new T2'(...);
1389 -- T1 and T2 can be different subtypes, and we might need to check
1390 -- both constraints. First check against the type of the qualified
1391 -- expression.
1392
1393 Apply_Constraint_Check (Exp, T, No_Sliding => True);
1394
1395 if Do_Range_Check (Exp) then
1396 Set_Do_Range_Check (Exp, False);
1397 Generate_Range_Check (Exp, DesigT, CE_Range_Check_Failed);
1398 end if;
1399
1400 -- A check is also needed in cases where the designated subtype is
1401 -- constrained and differs from the subtype given in the qualified
1402 -- expression. Note that the check on the qualified expression does
1403 -- not allow sliding, but this check does (a relaxation from Ada 83).
1404
1405 if Is_Constrained (DesigT)
1406 and then not Subtypes_Statically_Match (T, DesigT)
1407 then
1408 Apply_Constraint_Check
1409 (Exp, DesigT, No_Sliding => False);
1410
1411 if Do_Range_Check (Exp) then
1412 Set_Do_Range_Check (Exp, False);
1413 Generate_Range_Check (Exp, DesigT, CE_Range_Check_Failed);
1414 end if;
1415 end if;
1416
1417 -- For an access to unconstrained packed array, GIGI needs to see an
1418 -- expression with a constrained subtype in order to compute the
1419 -- proper size for the allocator.
1420
1421 if Is_Array_Type (T)
1422 and then not Is_Constrained (T)
1423 and then Is_Packed (T)
1424 then
1425 declare
1426 ConstrT : constant Entity_Id := Make_Temporary (Loc, 'A');
1427 Internal_Exp : constant Node_Id := Relocate_Node (Exp);
1428 begin
1429 Insert_Action (Exp,
1430 Make_Subtype_Declaration (Loc,
1431 Defining_Identifier => ConstrT,
1432 Subtype_Indication =>
1433 Make_Subtype_From_Expr (Internal_Exp, T)));
1434 Freeze_Itype (ConstrT, Exp);
1435 Rewrite (Exp, OK_Convert_To (ConstrT, Internal_Exp));
1436 end;
1437 end if;
1438
1439 -- Ada 2005 (AI-318-02): If the initialization expression is a call
1440 -- to a build-in-place function, then access to the allocated object
1441 -- must be passed to the function. Currently we limit such functions
1442 -- to those with constrained limited result subtypes, but eventually
1443 -- we plan to expand the allowed forms of functions that are treated
1444 -- as build-in-place.
1445
1446 if Ada_Version >= Ada_2005
1447 and then Is_Build_In_Place_Function_Call (Exp)
1448 then
1449 Make_Build_In_Place_Call_In_Allocator (N, Exp);
1450 end if;
1451 end if;
1452
1453 exception
1454 when RE_Not_Available =>
1455 return;
1456 end Expand_Allocator_Expression;
1457
1458 -----------------------------
1459 -- Expand_Array_Comparison --
1460 -----------------------------
1461
1462 -- Expansion is only required in the case of array types. For the unpacked
1463 -- case, an appropriate runtime routine is called. For packed cases, and
1464 -- also in some other cases where a runtime routine cannot be called, the
1465 -- form of the expansion is:
1466
1467 -- [body for greater_nn; boolean_expression]
1468
1469 -- The body is built by Make_Array_Comparison_Op, and the form of the
1470 -- Boolean expression depends on the operator involved.
1471
1472 procedure Expand_Array_Comparison (N : Node_Id) is
1473 Loc : constant Source_Ptr := Sloc (N);
1474 Op1 : Node_Id := Left_Opnd (N);
1475 Op2 : Node_Id := Right_Opnd (N);
1476 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
1477 Ctyp : constant Entity_Id := Component_Type (Typ1);
1478
1479 Expr : Node_Id;
1480 Func_Body : Node_Id;
1481 Func_Name : Entity_Id;
1482
1483 Comp : RE_Id;
1484
1485 Byte_Addressable : constant Boolean := System_Storage_Unit = Byte'Size;
1486 -- True for byte addressable target
1487
1488 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean;
1489 -- Returns True if the length of the given operand is known to be less
1490 -- than 4. Returns False if this length is known to be four or greater
1491 -- or is not known at compile time.
1492
1493 ------------------------
1494 -- Length_Less_Than_4 --
1495 ------------------------
1496
1497 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean is
1498 Otyp : constant Entity_Id := Etype (Opnd);
1499
1500 begin
1501 if Ekind (Otyp) = E_String_Literal_Subtype then
1502 return String_Literal_Length (Otyp) < 4;
1503
1504 else
1505 declare
1506 Ityp : constant Entity_Id := Etype (First_Index (Otyp));
1507 Lo : constant Node_Id := Type_Low_Bound (Ityp);
1508 Hi : constant Node_Id := Type_High_Bound (Ityp);
1509 Lov : Uint;
1510 Hiv : Uint;
1511
1512 begin
1513 if Compile_Time_Known_Value (Lo) then
1514 Lov := Expr_Value (Lo);
1515 else
1516 return False;
1517 end if;
1518
1519 if Compile_Time_Known_Value (Hi) then
1520 Hiv := Expr_Value (Hi);
1521 else
1522 return False;
1523 end if;
1524
1525 return Hiv < Lov + 3;
1526 end;
1527 end if;
1528 end Length_Less_Than_4;
1529
1530 -- Start of processing for Expand_Array_Comparison
1531
1532 begin
1533 -- Deal first with unpacked case, where we can call a runtime routine
1534 -- except that we avoid this for targets for which are not addressable
1535 -- by bytes, and for the JVM/CIL, since they do not support direct
1536 -- addressing of array components.
1537
1538 if not Is_Bit_Packed_Array (Typ1)
1539 and then Byte_Addressable
1540 and then VM_Target = No_VM
1541 then
1542 -- The call we generate is:
1543
1544 -- Compare_Array_xn[_Unaligned]
1545 -- (left'address, right'address, left'length, right'length) <op> 0
1546
1547 -- x = U for unsigned, S for signed
1548 -- n = 8,16,32,64 for component size
1549 -- Add _Unaligned if length < 4 and component size is 8.
1550 -- <op> is the standard comparison operator
1551
1552 if Component_Size (Typ1) = 8 then
1553 if Length_Less_Than_4 (Op1)
1554 or else
1555 Length_Less_Than_4 (Op2)
1556 then
1557 if Is_Unsigned_Type (Ctyp) then
1558 Comp := RE_Compare_Array_U8_Unaligned;
1559 else
1560 Comp := RE_Compare_Array_S8_Unaligned;
1561 end if;
1562
1563 else
1564 if Is_Unsigned_Type (Ctyp) then
1565 Comp := RE_Compare_Array_U8;
1566 else
1567 Comp := RE_Compare_Array_S8;
1568 end if;
1569 end if;
1570
1571 elsif Component_Size (Typ1) = 16 then
1572 if Is_Unsigned_Type (Ctyp) then
1573 Comp := RE_Compare_Array_U16;
1574 else
1575 Comp := RE_Compare_Array_S16;
1576 end if;
1577
1578 elsif Component_Size (Typ1) = 32 then
1579 if Is_Unsigned_Type (Ctyp) then
1580 Comp := RE_Compare_Array_U32;
1581 else
1582 Comp := RE_Compare_Array_S32;
1583 end if;
1584
1585 else pragma Assert (Component_Size (Typ1) = 64);
1586 if Is_Unsigned_Type (Ctyp) then
1587 Comp := RE_Compare_Array_U64;
1588 else
1589 Comp := RE_Compare_Array_S64;
1590 end if;
1591 end if;
1592
1593 Remove_Side_Effects (Op1, Name_Req => True);
1594 Remove_Side_Effects (Op2, Name_Req => True);
1595
1596 Rewrite (Op1,
1597 Make_Function_Call (Sloc (Op1),
1598 Name => New_Occurrence_Of (RTE (Comp), Loc),
1599
1600 Parameter_Associations => New_List (
1601 Make_Attribute_Reference (Loc,
1602 Prefix => Relocate_Node (Op1),
1603 Attribute_Name => Name_Address),
1604
1605 Make_Attribute_Reference (Loc,
1606 Prefix => Relocate_Node (Op2),
1607 Attribute_Name => Name_Address),
1608
1609 Make_Attribute_Reference (Loc,
1610 Prefix => Relocate_Node (Op1),
1611 Attribute_Name => Name_Length),
1612
1613 Make_Attribute_Reference (Loc,
1614 Prefix => Relocate_Node (Op2),
1615 Attribute_Name => Name_Length))));
1616
1617 Rewrite (Op2,
1618 Make_Integer_Literal (Sloc (Op2),
1619 Intval => Uint_0));
1620
1621 Analyze_And_Resolve (Op1, Standard_Integer);
1622 Analyze_And_Resolve (Op2, Standard_Integer);
1623 return;
1624 end if;
1625
1626 -- Cases where we cannot make runtime call
1627
1628 -- For (a <= b) we convert to not (a > b)
1629
1630 if Chars (N) = Name_Op_Le then
1631 Rewrite (N,
1632 Make_Op_Not (Loc,
1633 Right_Opnd =>
1634 Make_Op_Gt (Loc,
1635 Left_Opnd => Op1,
1636 Right_Opnd => Op2)));
1637 Analyze_And_Resolve (N, Standard_Boolean);
1638 return;
1639
1640 -- For < the Boolean expression is
1641 -- greater__nn (op2, op1)
1642
1643 elsif Chars (N) = Name_Op_Lt then
1644 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1645
1646 -- Switch operands
1647
1648 Op1 := Right_Opnd (N);
1649 Op2 := Left_Opnd (N);
1650
1651 -- For (a >= b) we convert to not (a < b)
1652
1653 elsif Chars (N) = Name_Op_Ge then
1654 Rewrite (N,
1655 Make_Op_Not (Loc,
1656 Right_Opnd =>
1657 Make_Op_Lt (Loc,
1658 Left_Opnd => Op1,
1659 Right_Opnd => Op2)));
1660 Analyze_And_Resolve (N, Standard_Boolean);
1661 return;
1662
1663 -- For > the Boolean expression is
1664 -- greater__nn (op1, op2)
1665
1666 else
1667 pragma Assert (Chars (N) = Name_Op_Gt);
1668 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1669 end if;
1670
1671 Func_Name := Defining_Unit_Name (Specification (Func_Body));
1672 Expr :=
1673 Make_Function_Call (Loc,
1674 Name => New_Reference_To (Func_Name, Loc),
1675 Parameter_Associations => New_List (Op1, Op2));
1676
1677 Insert_Action (N, Func_Body);
1678 Rewrite (N, Expr);
1679 Analyze_And_Resolve (N, Standard_Boolean);
1680
1681 exception
1682 when RE_Not_Available =>
1683 return;
1684 end Expand_Array_Comparison;
1685
1686 ---------------------------
1687 -- Expand_Array_Equality --
1688 ---------------------------
1689
1690 -- Expand an equality function for multi-dimensional arrays. Here is an
1691 -- example of such a function for Nb_Dimension = 2
1692
1693 -- function Enn (A : atyp; B : btyp) return boolean is
1694 -- begin
1695 -- if (A'length (1) = 0 or else A'length (2) = 0)
1696 -- and then
1697 -- (B'length (1) = 0 or else B'length (2) = 0)
1698 -- then
1699 -- return True; -- RM 4.5.2(22)
1700 -- end if;
1701
1702 -- if A'length (1) /= B'length (1)
1703 -- or else
1704 -- A'length (2) /= B'length (2)
1705 -- then
1706 -- return False; -- RM 4.5.2(23)
1707 -- end if;
1708
1709 -- declare
1710 -- A1 : Index_T1 := A'first (1);
1711 -- B1 : Index_T1 := B'first (1);
1712 -- begin
1713 -- loop
1714 -- declare
1715 -- A2 : Index_T2 := A'first (2);
1716 -- B2 : Index_T2 := B'first (2);
1717 -- begin
1718 -- loop
1719 -- if A (A1, A2) /= B (B1, B2) then
1720 -- return False;
1721 -- end if;
1722
1723 -- exit when A2 = A'last (2);
1724 -- A2 := Index_T2'succ (A2);
1725 -- B2 := Index_T2'succ (B2);
1726 -- end loop;
1727 -- end;
1728
1729 -- exit when A1 = A'last (1);
1730 -- A1 := Index_T1'succ (A1);
1731 -- B1 := Index_T1'succ (B1);
1732 -- end loop;
1733 -- end;
1734
1735 -- return true;
1736 -- end Enn;
1737
1738 -- Note on the formal types used (atyp and btyp). If either of the arrays
1739 -- is of a private type, we use the underlying type, and do an unchecked
1740 -- conversion of the actual. If either of the arrays has a bound depending
1741 -- on a discriminant, then we use the base type since otherwise we have an
1742 -- escaped discriminant in the function.
1743
1744 -- If both arrays are constrained and have the same bounds, we can generate
1745 -- a loop with an explicit iteration scheme using a 'Range attribute over
1746 -- the first array.
1747
1748 function Expand_Array_Equality
1749 (Nod : Node_Id;
1750 Lhs : Node_Id;
1751 Rhs : Node_Id;
1752 Bodies : List_Id;
1753 Typ : Entity_Id) return Node_Id
1754 is
1755 Loc : constant Source_Ptr := Sloc (Nod);
1756 Decls : constant List_Id := New_List;
1757 Index_List1 : constant List_Id := New_List;
1758 Index_List2 : constant List_Id := New_List;
1759
1760 Actuals : List_Id;
1761 Formals : List_Id;
1762 Func_Name : Entity_Id;
1763 Func_Body : Node_Id;
1764
1765 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
1766 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
1767
1768 Ltyp : Entity_Id;
1769 Rtyp : Entity_Id;
1770 -- The parameter types to be used for the formals
1771
1772 function Arr_Attr
1773 (Arr : Entity_Id;
1774 Nam : Name_Id;
1775 Num : Int) return Node_Id;
1776 -- This builds the attribute reference Arr'Nam (Expr)
1777
1778 function Component_Equality (Typ : Entity_Id) return Node_Id;
1779 -- Create one statement to compare corresponding components, designated
1780 -- by a full set of indexes.
1781
1782 function Get_Arg_Type (N : Node_Id) return Entity_Id;
1783 -- Given one of the arguments, computes the appropriate type to be used
1784 -- for that argument in the corresponding function formal
1785
1786 function Handle_One_Dimension
1787 (N : Int;
1788 Index : Node_Id) return Node_Id;
1789 -- This procedure returns the following code
1790 --
1791 -- declare
1792 -- Bn : Index_T := B'First (N);
1793 -- begin
1794 -- loop
1795 -- xxx
1796 -- exit when An = A'Last (N);
1797 -- An := Index_T'Succ (An)
1798 -- Bn := Index_T'Succ (Bn)
1799 -- end loop;
1800 -- end;
1801 --
1802 -- If both indexes are constrained and identical, the procedure
1803 -- returns a simpler loop:
1804 --
1805 -- for An in A'Range (N) loop
1806 -- xxx
1807 -- end loop
1808 --
1809 -- N is the dimension for which we are generating a loop. Index is the
1810 -- N'th index node, whose Etype is Index_Type_n in the above code. The
1811 -- xxx statement is either the loop or declare for the next dimension
1812 -- or if this is the last dimension the comparison of corresponding
1813 -- components of the arrays.
1814 --
1815 -- The actual way the code works is to return the comparison of
1816 -- corresponding components for the N+1 call. That's neater!
1817
1818 function Test_Empty_Arrays return Node_Id;
1819 -- This function constructs the test for both arrays being empty
1820 -- (A'length (1) = 0 or else A'length (2) = 0 or else ...)
1821 -- and then
1822 -- (B'length (1) = 0 or else B'length (2) = 0 or else ...)
1823
1824 function Test_Lengths_Correspond return Node_Id;
1825 -- This function constructs the test for arrays having different lengths
1826 -- in at least one index position, in which case the resulting code is:
1827
1828 -- A'length (1) /= B'length (1)
1829 -- or else
1830 -- A'length (2) /= B'length (2)
1831 -- or else
1832 -- ...
1833
1834 --------------
1835 -- Arr_Attr --
1836 --------------
1837
1838 function Arr_Attr
1839 (Arr : Entity_Id;
1840 Nam : Name_Id;
1841 Num : Int) return Node_Id
1842 is
1843 begin
1844 return
1845 Make_Attribute_Reference (Loc,
1846 Attribute_Name => Nam,
1847 Prefix => New_Reference_To (Arr, Loc),
1848 Expressions => New_List (Make_Integer_Literal (Loc, Num)));
1849 end Arr_Attr;
1850
1851 ------------------------
1852 -- Component_Equality --
1853 ------------------------
1854
1855 function Component_Equality (Typ : Entity_Id) return Node_Id is
1856 Test : Node_Id;
1857 L, R : Node_Id;
1858
1859 begin
1860 -- if a(i1...) /= b(j1...) then return false; end if;
1861
1862 L :=
1863 Make_Indexed_Component (Loc,
1864 Prefix => Make_Identifier (Loc, Chars (A)),
1865 Expressions => Index_List1);
1866
1867 R :=
1868 Make_Indexed_Component (Loc,
1869 Prefix => Make_Identifier (Loc, Chars (B)),
1870 Expressions => Index_List2);
1871
1872 Test := Expand_Composite_Equality
1873 (Nod, Component_Type (Typ), L, R, Decls);
1874
1875 -- If some (sub)component is an unchecked_union, the whole operation
1876 -- will raise program error.
1877
1878 if Nkind (Test) = N_Raise_Program_Error then
1879
1880 -- This node is going to be inserted at a location where a
1881 -- statement is expected: clear its Etype so analysis will set
1882 -- it to the expected Standard_Void_Type.
1883
1884 Set_Etype (Test, Empty);
1885 return Test;
1886
1887 else
1888 return
1889 Make_Implicit_If_Statement (Nod,
1890 Condition => Make_Op_Not (Loc, Right_Opnd => Test),
1891 Then_Statements => New_List (
1892 Make_Simple_Return_Statement (Loc,
1893 Expression => New_Occurrence_Of (Standard_False, Loc))));
1894 end if;
1895 end Component_Equality;
1896
1897 ------------------
1898 -- Get_Arg_Type --
1899 ------------------
1900
1901 function Get_Arg_Type (N : Node_Id) return Entity_Id is
1902 T : Entity_Id;
1903 X : Node_Id;
1904
1905 begin
1906 T := Etype (N);
1907
1908 if No (T) then
1909 return Typ;
1910
1911 else
1912 T := Underlying_Type (T);
1913
1914 X := First_Index (T);
1915 while Present (X) loop
1916 if Denotes_Discriminant (Type_Low_Bound (Etype (X)))
1917 or else
1918 Denotes_Discriminant (Type_High_Bound (Etype (X)))
1919 then
1920 T := Base_Type (T);
1921 exit;
1922 end if;
1923
1924 Next_Index (X);
1925 end loop;
1926
1927 return T;
1928 end if;
1929 end Get_Arg_Type;
1930
1931 --------------------------
1932 -- Handle_One_Dimension --
1933 ---------------------------
1934
1935 function Handle_One_Dimension
1936 (N : Int;
1937 Index : Node_Id) return Node_Id
1938 is
1939 Need_Separate_Indexes : constant Boolean :=
1940 Ltyp /= Rtyp
1941 or else not Is_Constrained (Ltyp);
1942 -- If the index types are identical, and we are working with
1943 -- constrained types, then we can use the same index for both
1944 -- of the arrays.
1945
1946 An : constant Entity_Id := Make_Temporary (Loc, 'A');
1947
1948 Bn : Entity_Id;
1949 Index_T : Entity_Id;
1950 Stm_List : List_Id;
1951 Loop_Stm : Node_Id;
1952
1953 begin
1954 if N > Number_Dimensions (Ltyp) then
1955 return Component_Equality (Ltyp);
1956 end if;
1957
1958 -- Case where we generate a loop
1959
1960 Index_T := Base_Type (Etype (Index));
1961
1962 if Need_Separate_Indexes then
1963 Bn := Make_Temporary (Loc, 'B');
1964 else
1965 Bn := An;
1966 end if;
1967
1968 Append (New_Reference_To (An, Loc), Index_List1);
1969 Append (New_Reference_To (Bn, Loc), Index_List2);
1970
1971 Stm_List := New_List (
1972 Handle_One_Dimension (N + 1, Next_Index (Index)));
1973
1974 if Need_Separate_Indexes then
1975
1976 -- Generate guard for loop, followed by increments of indexes
1977
1978 Append_To (Stm_List,
1979 Make_Exit_Statement (Loc,
1980 Condition =>
1981 Make_Op_Eq (Loc,
1982 Left_Opnd => New_Reference_To (An, Loc),
1983 Right_Opnd => Arr_Attr (A, Name_Last, N))));
1984
1985 Append_To (Stm_List,
1986 Make_Assignment_Statement (Loc,
1987 Name => New_Reference_To (An, Loc),
1988 Expression =>
1989 Make_Attribute_Reference (Loc,
1990 Prefix => New_Reference_To (Index_T, Loc),
1991 Attribute_Name => Name_Succ,
1992 Expressions => New_List (New_Reference_To (An, Loc)))));
1993
1994 Append_To (Stm_List,
1995 Make_Assignment_Statement (Loc,
1996 Name => New_Reference_To (Bn, Loc),
1997 Expression =>
1998 Make_Attribute_Reference (Loc,
1999 Prefix => New_Reference_To (Index_T, Loc),
2000 Attribute_Name => Name_Succ,
2001 Expressions => New_List (New_Reference_To (Bn, Loc)))));
2002 end if;
2003
2004 -- If separate indexes, we need a declare block for An and Bn, and a
2005 -- loop without an iteration scheme.
2006
2007 if Need_Separate_Indexes then
2008 Loop_Stm :=
2009 Make_Implicit_Loop_Statement (Nod, Statements => Stm_List);
2010
2011 return
2012 Make_Block_Statement (Loc,
2013 Declarations => New_List (
2014 Make_Object_Declaration (Loc,
2015 Defining_Identifier => An,
2016 Object_Definition => New_Reference_To (Index_T, Loc),
2017 Expression => Arr_Attr (A, Name_First, N)),
2018
2019 Make_Object_Declaration (Loc,
2020 Defining_Identifier => Bn,
2021 Object_Definition => New_Reference_To (Index_T, Loc),
2022 Expression => Arr_Attr (B, Name_First, N))),
2023
2024 Handled_Statement_Sequence =>
2025 Make_Handled_Sequence_Of_Statements (Loc,
2026 Statements => New_List (Loop_Stm)));
2027
2028 -- If no separate indexes, return loop statement with explicit
2029 -- iteration scheme on its own
2030
2031 else
2032 Loop_Stm :=
2033 Make_Implicit_Loop_Statement (Nod,
2034 Statements => Stm_List,
2035 Iteration_Scheme =>
2036 Make_Iteration_Scheme (Loc,
2037 Loop_Parameter_Specification =>
2038 Make_Loop_Parameter_Specification (Loc,
2039 Defining_Identifier => An,
2040 Discrete_Subtype_Definition =>
2041 Arr_Attr (A, Name_Range, N))));
2042 return Loop_Stm;
2043 end if;
2044 end Handle_One_Dimension;
2045
2046 -----------------------
2047 -- Test_Empty_Arrays --
2048 -----------------------
2049
2050 function Test_Empty_Arrays return Node_Id is
2051 Alist : Node_Id;
2052 Blist : Node_Id;
2053
2054 Atest : Node_Id;
2055 Btest : Node_Id;
2056
2057 begin
2058 Alist := Empty;
2059 Blist := Empty;
2060 for J in 1 .. Number_Dimensions (Ltyp) loop
2061 Atest :=
2062 Make_Op_Eq (Loc,
2063 Left_Opnd => Arr_Attr (A, Name_Length, J),
2064 Right_Opnd => Make_Integer_Literal (Loc, 0));
2065
2066 Btest :=
2067 Make_Op_Eq (Loc,
2068 Left_Opnd => Arr_Attr (B, Name_Length, J),
2069 Right_Opnd => Make_Integer_Literal (Loc, 0));
2070
2071 if No (Alist) then
2072 Alist := Atest;
2073 Blist := Btest;
2074
2075 else
2076 Alist :=
2077 Make_Or_Else (Loc,
2078 Left_Opnd => Relocate_Node (Alist),
2079 Right_Opnd => Atest);
2080
2081 Blist :=
2082 Make_Or_Else (Loc,
2083 Left_Opnd => Relocate_Node (Blist),
2084 Right_Opnd => Btest);
2085 end if;
2086 end loop;
2087
2088 return
2089 Make_And_Then (Loc,
2090 Left_Opnd => Alist,
2091 Right_Opnd => Blist);
2092 end Test_Empty_Arrays;
2093
2094 -----------------------------
2095 -- Test_Lengths_Correspond --
2096 -----------------------------
2097
2098 function Test_Lengths_Correspond return Node_Id is
2099 Result : Node_Id;
2100 Rtest : Node_Id;
2101
2102 begin
2103 Result := Empty;
2104 for J in 1 .. Number_Dimensions (Ltyp) loop
2105 Rtest :=
2106 Make_Op_Ne (Loc,
2107 Left_Opnd => Arr_Attr (A, Name_Length, J),
2108 Right_Opnd => Arr_Attr (B, Name_Length, J));
2109
2110 if No (Result) then
2111 Result := Rtest;
2112 else
2113 Result :=
2114 Make_Or_Else (Loc,
2115 Left_Opnd => Relocate_Node (Result),
2116 Right_Opnd => Rtest);
2117 end if;
2118 end loop;
2119
2120 return Result;
2121 end Test_Lengths_Correspond;
2122
2123 -- Start of processing for Expand_Array_Equality
2124
2125 begin
2126 Ltyp := Get_Arg_Type (Lhs);
2127 Rtyp := Get_Arg_Type (Rhs);
2128
2129 -- For now, if the argument types are not the same, go to the base type,
2130 -- since the code assumes that the formals have the same type. This is
2131 -- fixable in future ???
2132
2133 if Ltyp /= Rtyp then
2134 Ltyp := Base_Type (Ltyp);
2135 Rtyp := Base_Type (Rtyp);
2136 pragma Assert (Ltyp = Rtyp);
2137 end if;
2138
2139 -- Build list of formals for function
2140
2141 Formals := New_List (
2142 Make_Parameter_Specification (Loc,
2143 Defining_Identifier => A,
2144 Parameter_Type => New_Reference_To (Ltyp, Loc)),
2145
2146 Make_Parameter_Specification (Loc,
2147 Defining_Identifier => B,
2148 Parameter_Type => New_Reference_To (Rtyp, Loc)));
2149
2150 Func_Name := Make_Temporary (Loc, 'E');
2151
2152 -- Build statement sequence for function
2153
2154 Func_Body :=
2155 Make_Subprogram_Body (Loc,
2156 Specification =>
2157 Make_Function_Specification (Loc,
2158 Defining_Unit_Name => Func_Name,
2159 Parameter_Specifications => Formals,
2160 Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
2161
2162 Declarations => Decls,
2163
2164 Handled_Statement_Sequence =>
2165 Make_Handled_Sequence_Of_Statements (Loc,
2166 Statements => New_List (
2167
2168 Make_Implicit_If_Statement (Nod,
2169 Condition => Test_Empty_Arrays,
2170 Then_Statements => New_List (
2171 Make_Simple_Return_Statement (Loc,
2172 Expression =>
2173 New_Occurrence_Of (Standard_True, Loc)))),
2174
2175 Make_Implicit_If_Statement (Nod,
2176 Condition => Test_Lengths_Correspond,
2177 Then_Statements => New_List (
2178 Make_Simple_Return_Statement (Loc,
2179 Expression =>
2180 New_Occurrence_Of (Standard_False, Loc)))),
2181
2182 Handle_One_Dimension (1, First_Index (Ltyp)),
2183
2184 Make_Simple_Return_Statement (Loc,
2185 Expression => New_Occurrence_Of (Standard_True, Loc)))));
2186
2187 Set_Has_Completion (Func_Name, True);
2188 Set_Is_Inlined (Func_Name);
2189
2190 -- If the array type is distinct from the type of the arguments, it
2191 -- is the full view of a private type. Apply an unchecked conversion
2192 -- to insure that analysis of the call succeeds.
2193
2194 declare
2195 L, R : Node_Id;
2196
2197 begin
2198 L := Lhs;
2199 R := Rhs;
2200
2201 if No (Etype (Lhs))
2202 or else Base_Type (Etype (Lhs)) /= Base_Type (Ltyp)
2203 then
2204 L := OK_Convert_To (Ltyp, Lhs);
2205 end if;
2206
2207 if No (Etype (Rhs))
2208 or else Base_Type (Etype (Rhs)) /= Base_Type (Rtyp)
2209 then
2210 R := OK_Convert_To (Rtyp, Rhs);
2211 end if;
2212
2213 Actuals := New_List (L, R);
2214 end;
2215
2216 Append_To (Bodies, Func_Body);
2217
2218 return
2219 Make_Function_Call (Loc,
2220 Name => New_Reference_To (Func_Name, Loc),
2221 Parameter_Associations => Actuals);
2222 end Expand_Array_Equality;
2223
2224 -----------------------------
2225 -- Expand_Boolean_Operator --
2226 -----------------------------
2227
2228 -- Note that we first get the actual subtypes of the operands, since we
2229 -- always want to deal with types that have bounds.
2230
2231 procedure Expand_Boolean_Operator (N : Node_Id) is
2232 Typ : constant Entity_Id := Etype (N);
2233
2234 begin
2235 -- Special case of bit packed array where both operands are known to be
2236 -- properly aligned. In this case we use an efficient run time routine
2237 -- to carry out the operation (see System.Bit_Ops).
2238
2239 if Is_Bit_Packed_Array (Typ)
2240 and then not Is_Possibly_Unaligned_Object (Left_Opnd (N))
2241 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
2242 then
2243 Expand_Packed_Boolean_Operator (N);
2244 return;
2245 end if;
2246
2247 -- For the normal non-packed case, the general expansion is to build
2248 -- function for carrying out the comparison (use Make_Boolean_Array_Op)
2249 -- and then inserting it into the tree. The original operator node is
2250 -- then rewritten as a call to this function. We also use this in the
2251 -- packed case if either operand is a possibly unaligned object.
2252
2253 declare
2254 Loc : constant Source_Ptr := Sloc (N);
2255 L : constant Node_Id := Relocate_Node (Left_Opnd (N));
2256 R : constant Node_Id := Relocate_Node (Right_Opnd (N));
2257 Func_Body : Node_Id;
2258 Func_Name : Entity_Id;
2259
2260 begin
2261 Convert_To_Actual_Subtype (L);
2262 Convert_To_Actual_Subtype (R);
2263 Ensure_Defined (Etype (L), N);
2264 Ensure_Defined (Etype (R), N);
2265 Apply_Length_Check (R, Etype (L));
2266
2267 if Nkind (N) = N_Op_Xor then
2268 Silly_Boolean_Array_Xor_Test (N, Etype (L));
2269 end if;
2270
2271 if Nkind (Parent (N)) = N_Assignment_Statement
2272 and then Safe_In_Place_Array_Op (Name (Parent (N)), L, R)
2273 then
2274 Build_Boolean_Array_Proc_Call (Parent (N), L, R);
2275
2276 elsif Nkind (Parent (N)) = N_Op_Not
2277 and then Nkind (N) = N_Op_And
2278 and then
2279 Safe_In_Place_Array_Op (Name (Parent (Parent (N))), L, R)
2280 then
2281 return;
2282 else
2283
2284 Func_Body := Make_Boolean_Array_Op (Etype (L), N);
2285 Func_Name := Defining_Unit_Name (Specification (Func_Body));
2286 Insert_Action (N, Func_Body);
2287
2288 -- Now rewrite the expression with a call
2289
2290 Rewrite (N,
2291 Make_Function_Call (Loc,
2292 Name => New_Reference_To (Func_Name, Loc),
2293 Parameter_Associations =>
2294 New_List (
2295 L,
2296 Make_Type_Conversion
2297 (Loc, New_Reference_To (Etype (L), Loc), R))));
2298
2299 Analyze_And_Resolve (N, Typ);
2300 end if;
2301 end;
2302 end Expand_Boolean_Operator;
2303
2304 ------------------------------------------------
2305 -- Expand_Compare_Minimize_Eliminate_Overflow --
2306 ------------------------------------------------
2307
2308 procedure Expand_Compare_Minimize_Eliminate_Overflow (N : Node_Id) is
2309 Loc : constant Source_Ptr := Sloc (N);
2310
2311 Result_Type : constant Entity_Id := Etype (N);
2312 -- Capture result type (could be a derived boolean type)
2313
2314 Llo, Lhi : Uint;
2315 Rlo, Rhi : Uint;
2316
2317 LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
2318 -- Entity for Long_Long_Integer'Base
2319
2320 Check : constant Overflow_Check_Type := Overflow_Check_Mode (Empty);
2321 -- Current checking mode
2322
2323 procedure Set_True;
2324 procedure Set_False;
2325 -- These procedures rewrite N with an occurrence of Standard_True or
2326 -- Standard_False, and then makes a call to Warn_On_Known_Condition.
2327
2328 ---------------
2329 -- Set_False --
2330 ---------------
2331
2332 procedure Set_False is
2333 begin
2334 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
2335 Warn_On_Known_Condition (N);
2336 end Set_False;
2337
2338 --------------
2339 -- Set_True --
2340 --------------
2341
2342 procedure Set_True is
2343 begin
2344 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
2345 Warn_On_Known_Condition (N);
2346 end Set_True;
2347
2348 -- Start of processing for Expand_Compare_Minimize_Eliminate_Overflow
2349
2350 begin
2351 -- Nothing to do unless we have a comparison operator with operands
2352 -- that are signed integer types, and we are operating in either
2353 -- MINIMIZED or ELIMINATED overflow checking mode.
2354
2355 if Nkind (N) not in N_Op_Compare
2356 or else Check not in Minimized_Or_Eliminated
2357 or else not Is_Signed_Integer_Type (Etype (Left_Opnd (N)))
2358 then
2359 return;
2360 end if;
2361
2362 -- OK, this is the case we are interested in. First step is to process
2363 -- our operands using the Minimize_Eliminate circuitry which applies
2364 -- this processing to the two operand subtrees.
2365
2366 Minimize_Eliminate_Overflow_Checks
2367 (Left_Opnd (N), Llo, Lhi, Top_Level => False);
2368 Minimize_Eliminate_Overflow_Checks
2369 (Right_Opnd (N), Rlo, Rhi, Top_Level => False);
2370
2371 -- See if the range information decides the result of the comparison
2372
2373 case N_Op_Compare (Nkind (N)) is
2374 when N_Op_Eq =>
2375 if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
2376 Set_True;
2377 elsif Llo > Rhi or else Rlo > Lhi then
2378 Set_False;
2379 end if;
2380
2381 when N_Op_Ge =>
2382 if Llo >= Rhi then
2383 Set_True;
2384 elsif Lhi < Rlo then
2385 Set_False;
2386 end if;
2387
2388 when N_Op_Gt =>
2389 if Llo > Rhi then
2390 Set_True;
2391 elsif Lhi <= Rlo then
2392 Set_False;
2393 end if;
2394
2395 when N_Op_Le =>
2396 if Llo > Rhi then
2397 Set_False;
2398 elsif Lhi <= Rlo then
2399 Set_True;
2400 end if;
2401
2402 when N_Op_Lt =>
2403 if Llo >= Rhi then
2404 Set_False;
2405 elsif Lhi < Rlo then
2406 Set_True;
2407 end if;
2408
2409 when N_Op_Ne =>
2410 if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
2411 Set_True;
2412 elsif Llo > Rhi or else Rlo > Lhi then
2413 Set_False;
2414 end if;
2415 end case;
2416
2417 -- All done if we did the rewrite
2418
2419 if Nkind (N) not in N_Op_Compare then
2420 return;
2421 end if;
2422
2423 -- Otherwise, time to do the comparison
2424
2425 declare
2426 Ltype : constant Entity_Id := Etype (Left_Opnd (N));
2427 Rtype : constant Entity_Id := Etype (Right_Opnd (N));
2428
2429 begin
2430 -- If the two operands have the same signed integer type we are
2431 -- all set, nothing more to do. This is the case where either
2432 -- both operands were unchanged, or we rewrote both of them to
2433 -- be Long_Long_Integer.
2434
2435 -- Note: Entity for the comparison may be wrong, but it's not worth
2436 -- the effort to change it, since the back end does not use it.
2437
2438 if Is_Signed_Integer_Type (Ltype)
2439 and then Base_Type (Ltype) = Base_Type (Rtype)
2440 then
2441 return;
2442
2443 -- Here if bignums are involved (can only happen in ELIMINATED mode)
2444
2445 elsif Is_RTE (Ltype, RE_Bignum) or else Is_RTE (Rtype, RE_Bignum) then
2446 declare
2447 Left : Node_Id := Left_Opnd (N);
2448 Right : Node_Id := Right_Opnd (N);
2449 -- Bignum references for left and right operands
2450
2451 begin
2452 if not Is_RTE (Ltype, RE_Bignum) then
2453 Left := Convert_To_Bignum (Left);
2454 elsif not Is_RTE (Rtype, RE_Bignum) then
2455 Right := Convert_To_Bignum (Right);
2456 end if;
2457
2458 -- We rewrite our node with:
2459
2460 -- do
2461 -- Bnn : Result_Type;
2462 -- declare
2463 -- M : Mark_Id := SS_Mark;
2464 -- begin
2465 -- Bnn := Big_xx (Left, Right); (xx = EQ, NT etc)
2466 -- SS_Release (M);
2467 -- end;
2468 -- in
2469 -- Bnn
2470 -- end
2471
2472 declare
2473 Blk : constant Node_Id := Make_Bignum_Block (Loc);
2474 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
2475 Ent : RE_Id;
2476
2477 begin
2478 case N_Op_Compare (Nkind (N)) is
2479 when N_Op_Eq => Ent := RE_Big_EQ;
2480 when N_Op_Ge => Ent := RE_Big_GE;
2481 when N_Op_Gt => Ent := RE_Big_GT;
2482 when N_Op_Le => Ent := RE_Big_LE;
2483 when N_Op_Lt => Ent := RE_Big_LT;
2484 when N_Op_Ne => Ent := RE_Big_NE;
2485 end case;
2486
2487 -- Insert assignment to Bnn into the bignum block
2488
2489 Insert_Before
2490 (First (Statements (Handled_Statement_Sequence (Blk))),
2491 Make_Assignment_Statement (Loc,
2492 Name => New_Occurrence_Of (Bnn, Loc),
2493 Expression =>
2494 Make_Function_Call (Loc,
2495 Name =>
2496 New_Occurrence_Of (RTE (Ent), Loc),
2497 Parameter_Associations => New_List (Left, Right))));
2498
2499 -- Now do the rewrite with expression actions
2500
2501 Rewrite (N,
2502 Make_Expression_With_Actions (Loc,
2503 Actions => New_List (
2504 Make_Object_Declaration (Loc,
2505 Defining_Identifier => Bnn,
2506 Object_Definition =>
2507 New_Occurrence_Of (Result_Type, Loc)),
2508 Blk),
2509 Expression => New_Occurrence_Of (Bnn, Loc)));
2510 Analyze_And_Resolve (N, Result_Type);
2511 end;
2512 end;
2513
2514 -- No bignums involved, but types are different, so we must have
2515 -- rewritten one of the operands as a Long_Long_Integer but not
2516 -- the other one.
2517
2518 -- If left operand is Long_Long_Integer, convert right operand
2519 -- and we are done (with a comparison of two Long_Long_Integers).
2520
2521 elsif Ltype = LLIB then
2522 Convert_To_And_Rewrite (LLIB, Right_Opnd (N));
2523 Analyze_And_Resolve (Right_Opnd (N), LLIB, Suppress => All_Checks);
2524 return;
2525
2526 -- If right operand is Long_Long_Integer, convert left operand
2527 -- and we are done (with a comparison of two Long_Long_Integers).
2528
2529 -- This is the only remaining possibility
2530
2531 else pragma Assert (Rtype = LLIB);
2532 Convert_To_And_Rewrite (LLIB, Left_Opnd (N));
2533 Analyze_And_Resolve (Left_Opnd (N), LLIB, Suppress => All_Checks);
2534 return;
2535 end if;
2536 end;
2537 end Expand_Compare_Minimize_Eliminate_Overflow;
2538
2539 -------------------------------
2540 -- Expand_Composite_Equality --
2541 -------------------------------
2542
2543 -- This function is only called for comparing internal fields of composite
2544 -- types when these fields are themselves composites. This is a special
2545 -- case because it is not possible to respect normal Ada visibility rules.
2546
2547 function Expand_Composite_Equality
2548 (Nod : Node_Id;
2549 Typ : Entity_Id;
2550 Lhs : Node_Id;
2551 Rhs : Node_Id;
2552 Bodies : List_Id) return Node_Id
2553 is
2554 Loc : constant Source_Ptr := Sloc (Nod);
2555 Full_Type : Entity_Id;
2556 Prim : Elmt_Id;
2557 Eq_Op : Entity_Id;
2558
2559 function Find_Primitive_Eq return Node_Id;
2560 -- AI05-0123: Locate primitive equality for type if it exists, and
2561 -- build the corresponding call. If operation is abstract, replace
2562 -- call with an explicit raise. Return Empty if there is no primitive.
2563
2564 -----------------------
2565 -- Find_Primitive_Eq --
2566 -----------------------
2567
2568 function Find_Primitive_Eq return Node_Id is
2569 Prim_E : Elmt_Id;
2570 Prim : Node_Id;
2571
2572 begin
2573 Prim_E := First_Elmt (Collect_Primitive_Operations (Typ));
2574 while Present (Prim_E) loop
2575 Prim := Node (Prim_E);
2576
2577 -- Locate primitive equality with the right signature
2578
2579 if Chars (Prim) = Name_Op_Eq
2580 and then Etype (First_Formal (Prim)) =
2581 Etype (Next_Formal (First_Formal (Prim)))
2582 and then Etype (Prim) = Standard_Boolean
2583 then
2584 if Is_Abstract_Subprogram (Prim) then
2585 return
2586 Make_Raise_Program_Error (Loc,
2587 Reason => PE_Explicit_Raise);
2588
2589 else
2590 return
2591 Make_Function_Call (Loc,
2592 Name => New_Reference_To (Prim, Loc),
2593 Parameter_Associations => New_List (Lhs, Rhs));
2594 end if;
2595 end if;
2596
2597 Next_Elmt (Prim_E);
2598 end loop;
2599
2600 -- If not found, predefined operation will be used
2601
2602 return Empty;
2603 end Find_Primitive_Eq;
2604
2605 -- Start of processing for Expand_Composite_Equality
2606
2607 begin
2608 if Is_Private_Type (Typ) then
2609 Full_Type := Underlying_Type (Typ);
2610 else
2611 Full_Type := Typ;
2612 end if;
2613
2614 -- Defense against malformed private types with no completion the error
2615 -- will be diagnosed later by check_completion
2616
2617 if No (Full_Type) then
2618 return New_Reference_To (Standard_False, Loc);
2619 end if;
2620
2621 Full_Type := Base_Type (Full_Type);
2622
2623 if Is_Array_Type (Full_Type) then
2624
2625 -- If the operand is an elementary type other than a floating-point
2626 -- type, then we can simply use the built-in block bitwise equality,
2627 -- since the predefined equality operators always apply and bitwise
2628 -- equality is fine for all these cases.
2629
2630 if Is_Elementary_Type (Component_Type (Full_Type))
2631 and then not Is_Floating_Point_Type (Component_Type (Full_Type))
2632 then
2633 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
2634
2635 -- For composite component types, and floating-point types, use the
2636 -- expansion. This deals with tagged component types (where we use
2637 -- the applicable equality routine) and floating-point, (where we
2638 -- need to worry about negative zeroes), and also the case of any
2639 -- composite type recursively containing such fields.
2640
2641 else
2642 return Expand_Array_Equality (Nod, Lhs, Rhs, Bodies, Full_Type);
2643 end if;
2644
2645 elsif Is_Tagged_Type (Full_Type) then
2646
2647 -- Call the primitive operation "=" of this type
2648
2649 if Is_Class_Wide_Type (Full_Type) then
2650 Full_Type := Root_Type (Full_Type);
2651 end if;
2652
2653 -- If this is derived from an untagged private type completed with a
2654 -- tagged type, it does not have a full view, so we use the primitive
2655 -- operations of the private type. This check should no longer be
2656 -- necessary when these types receive their full views ???
2657
2658 if Is_Private_Type (Typ)
2659 and then not Is_Tagged_Type (Typ)
2660 and then not Is_Controlled (Typ)
2661 and then Is_Derived_Type (Typ)
2662 and then No (Full_View (Typ))
2663 then
2664 Prim := First_Elmt (Collect_Primitive_Operations (Typ));
2665 else
2666 Prim := First_Elmt (Primitive_Operations (Full_Type));
2667 end if;
2668
2669 loop
2670 Eq_Op := Node (Prim);
2671 exit when Chars (Eq_Op) = Name_Op_Eq
2672 and then Etype (First_Formal (Eq_Op)) =
2673 Etype (Next_Formal (First_Formal (Eq_Op)))
2674 and then Base_Type (Etype (Eq_Op)) = Standard_Boolean;
2675 Next_Elmt (Prim);
2676 pragma Assert (Present (Prim));
2677 end loop;
2678
2679 Eq_Op := Node (Prim);
2680
2681 return
2682 Make_Function_Call (Loc,
2683 Name => New_Reference_To (Eq_Op, Loc),
2684 Parameter_Associations =>
2685 New_List
2686 (Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Lhs),
2687 Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Rhs)));
2688
2689 elsif Is_Record_Type (Full_Type) then
2690 Eq_Op := TSS (Full_Type, TSS_Composite_Equality);
2691
2692 if Present (Eq_Op) then
2693 if Etype (First_Formal (Eq_Op)) /= Full_Type then
2694
2695 -- Inherited equality from parent type. Convert the actuals to
2696 -- match signature of operation.
2697
2698 declare
2699 T : constant Entity_Id := Etype (First_Formal (Eq_Op));
2700
2701 begin
2702 return
2703 Make_Function_Call (Loc,
2704 Name => New_Reference_To (Eq_Op, Loc),
2705 Parameter_Associations => New_List (
2706 OK_Convert_To (T, Lhs),
2707 OK_Convert_To (T, Rhs)));
2708 end;
2709
2710 else
2711 -- Comparison between Unchecked_Union components
2712
2713 if Is_Unchecked_Union (Full_Type) then
2714 declare
2715 Lhs_Type : Node_Id := Full_Type;
2716 Rhs_Type : Node_Id := Full_Type;
2717 Lhs_Discr_Val : Node_Id;
2718 Rhs_Discr_Val : Node_Id;
2719
2720 begin
2721 -- Lhs subtype
2722
2723 if Nkind (Lhs) = N_Selected_Component then
2724 Lhs_Type := Etype (Entity (Selector_Name (Lhs)));
2725 end if;
2726
2727 -- Rhs subtype
2728
2729 if Nkind (Rhs) = N_Selected_Component then
2730 Rhs_Type := Etype (Entity (Selector_Name (Rhs)));
2731 end if;
2732
2733 -- Lhs of the composite equality
2734
2735 if Is_Constrained (Lhs_Type) then
2736
2737 -- Since the enclosing record type can never be an
2738 -- Unchecked_Union (this code is executed for records
2739 -- that do not have variants), we may reference its
2740 -- discriminant(s).
2741
2742 if Nkind (Lhs) = N_Selected_Component
2743 and then Has_Per_Object_Constraint (
2744 Entity (Selector_Name (Lhs)))
2745 then
2746 Lhs_Discr_Val :=
2747 Make_Selected_Component (Loc,
2748 Prefix => Prefix (Lhs),
2749 Selector_Name =>
2750 New_Copy
2751 (Get_Discriminant_Value
2752 (First_Discriminant (Lhs_Type),
2753 Lhs_Type,
2754 Stored_Constraint (Lhs_Type))));
2755
2756 else
2757 Lhs_Discr_Val :=
2758 New_Copy
2759 (Get_Discriminant_Value
2760 (First_Discriminant (Lhs_Type),
2761 Lhs_Type,
2762 Stored_Constraint (Lhs_Type)));
2763
2764 end if;
2765 else
2766 -- It is not possible to infer the discriminant since
2767 -- the subtype is not constrained.
2768
2769 return
2770 Make_Raise_Program_Error (Loc,
2771 Reason => PE_Unchecked_Union_Restriction);
2772 end if;
2773
2774 -- Rhs of the composite equality
2775
2776 if Is_Constrained (Rhs_Type) then
2777 if Nkind (Rhs) = N_Selected_Component
2778 and then Has_Per_Object_Constraint
2779 (Entity (Selector_Name (Rhs)))
2780 then
2781 Rhs_Discr_Val :=
2782 Make_Selected_Component (Loc,
2783 Prefix => Prefix (Rhs),
2784 Selector_Name =>
2785 New_Copy
2786 (Get_Discriminant_Value
2787 (First_Discriminant (Rhs_Type),
2788 Rhs_Type,
2789 Stored_Constraint (Rhs_Type))));
2790
2791 else
2792 Rhs_Discr_Val :=
2793 New_Copy
2794 (Get_Discriminant_Value
2795 (First_Discriminant (Rhs_Type),
2796 Rhs_Type,
2797 Stored_Constraint (Rhs_Type)));
2798
2799 end if;
2800 else
2801 return
2802 Make_Raise_Program_Error (Loc,
2803 Reason => PE_Unchecked_Union_Restriction);
2804 end if;
2805
2806 -- Call the TSS equality function with the inferred
2807 -- discriminant values.
2808
2809 return
2810 Make_Function_Call (Loc,
2811 Name => New_Reference_To (Eq_Op, Loc),
2812 Parameter_Associations => New_List (
2813 Lhs,
2814 Rhs,
2815 Lhs_Discr_Val,
2816 Rhs_Discr_Val));
2817 end;
2818
2819 else
2820 return
2821 Make_Function_Call (Loc,
2822 Name => New_Reference_To (Eq_Op, Loc),
2823 Parameter_Associations => New_List (Lhs, Rhs));
2824 end if;
2825 end if;
2826
2827 -- Equality composes in Ada 2012 for untagged record types. It also
2828 -- composes for bounded strings, because they are part of the
2829 -- predefined environment. We could make it compose for bounded
2830 -- strings by making them tagged, or by making sure all subcomponents
2831 -- are set to the same value, even when not used. Instead, we have
2832 -- this special case in the compiler, because it's more efficient.
2833
2834 elsif Ada_Version >= Ada_2012 or else Is_Bounded_String (Typ) then
2835
2836 -- if no TSS has been created for the type, check whether there is
2837 -- a primitive equality declared for it.
2838
2839 declare
2840 Op : constant Node_Id := Find_Primitive_Eq;
2841
2842 begin
2843 -- Use user-defined primitive if it exists, otherwise use
2844 -- predefined equality.
2845
2846 if Present (Op) then
2847 return Op;
2848 else
2849 return Make_Op_Eq (Loc, Lhs, Rhs);
2850 end if;
2851 end;
2852
2853 else
2854 return Expand_Record_Equality (Nod, Full_Type, Lhs, Rhs, Bodies);
2855 end if;
2856
2857 else
2858 -- If not array or record type, it is predefined equality.
2859
2860 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
2861 end if;
2862 end Expand_Composite_Equality;
2863
2864 ------------------------
2865 -- Expand_Concatenate --
2866 ------------------------
2867
2868 procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id) is
2869 Loc : constant Source_Ptr := Sloc (Cnode);
2870
2871 Atyp : constant Entity_Id := Base_Type (Etype (Cnode));
2872 -- Result type of concatenation
2873
2874 Ctyp : constant Entity_Id := Base_Type (Component_Type (Etype (Cnode)));
2875 -- Component type. Elements of this component type can appear as one
2876 -- of the operands of concatenation as well as arrays.
2877
2878 Istyp : constant Entity_Id := Etype (First_Index (Atyp));
2879 -- Index subtype
2880
2881 Ityp : constant Entity_Id := Base_Type (Istyp);
2882 -- Index type. This is the base type of the index subtype, and is used
2883 -- for all computed bounds (which may be out of range of Istyp in the
2884 -- case of null ranges).
2885
2886 Artyp : Entity_Id;
2887 -- This is the type we use to do arithmetic to compute the bounds and
2888 -- lengths of operands. The choice of this type is a little subtle and
2889 -- is discussed in a separate section at the start of the body code.
2890
2891 Concatenation_Error : exception;
2892 -- Raised if concatenation is sure to raise a CE
2893
2894 Result_May_Be_Null : Boolean := True;
2895 -- Reset to False if at least one operand is encountered which is known
2896 -- at compile time to be non-null. Used for handling the special case
2897 -- of setting the high bound to the last operand high bound for a null
2898 -- result, thus ensuring a proper high bound in the super-flat case.
2899
2900 N : constant Nat := List_Length (Opnds);
2901 -- Number of concatenation operands including possibly null operands
2902
2903 NN : Nat := 0;
2904 -- Number of operands excluding any known to be null, except that the
2905 -- last operand is always retained, in case it provides the bounds for
2906 -- a null result.
2907
2908 Opnd : Node_Id;
2909 -- Current operand being processed in the loop through operands. After
2910 -- this loop is complete, always contains the last operand (which is not
2911 -- the same as Operands (NN), since null operands are skipped).
2912
2913 -- Arrays describing the operands, only the first NN entries of each
2914 -- array are set (NN < N when we exclude known null operands).
2915
2916 Is_Fixed_Length : array (1 .. N) of Boolean;
2917 -- True if length of corresponding operand known at compile time
2918
2919 Operands : array (1 .. N) of Node_Id;
2920 -- Set to the corresponding entry in the Opnds list (but note that null
2921 -- operands are excluded, so not all entries in the list are stored).
2922
2923 Fixed_Length : array (1 .. N) of Uint;
2924 -- Set to length of operand. Entries in this array are set only if the
2925 -- corresponding entry in Is_Fixed_Length is True.
2926
2927 Opnd_Low_Bound : array (1 .. N) of Node_Id;
2928 -- Set to lower bound of operand. Either an integer literal in the case
2929 -- where the bound is known at compile time, else actual lower bound.
2930 -- The operand low bound is of type Ityp.
2931
2932 Var_Length : array (1 .. N) of Entity_Id;
2933 -- Set to an entity of type Natural that contains the length of an
2934 -- operand whose length is not known at compile time. Entries in this
2935 -- array are set only if the corresponding entry in Is_Fixed_Length
2936 -- is False. The entity is of type Artyp.
2937
2938 Aggr_Length : array (0 .. N) of Node_Id;
2939 -- The J'th entry in an expression node that represents the total length
2940 -- of operands 1 through J. It is either an integer literal node, or a
2941 -- reference to a constant entity with the right value, so it is fine
2942 -- to just do a Copy_Node to get an appropriate copy. The extra zero'th
2943 -- entry always is set to zero. The length is of type Artyp.
2944
2945 Low_Bound : Node_Id;
2946 -- A tree node representing the low bound of the result (of type Ityp).
2947 -- This is either an integer literal node, or an identifier reference to
2948 -- a constant entity initialized to the appropriate value.
2949
2950 Last_Opnd_Low_Bound : Node_Id;
2951 -- A tree node representing the low bound of the last operand. This
2952 -- need only be set if the result could be null. It is used for the
2953 -- special case of setting the right low bound for a null result.
2954 -- This is of type Ityp.
2955
2956 Last_Opnd_High_Bound : Node_Id;
2957 -- A tree node representing the high bound of the last operand. This
2958 -- need only be set if the result could be null. It is used for the
2959 -- special case of setting the right high bound for a null result.
2960 -- This is of type Ityp.
2961
2962 High_Bound : Node_Id;
2963 -- A tree node representing the high bound of the result (of type Ityp)
2964
2965 Result : Node_Id;
2966 -- Result of the concatenation (of type Ityp)
2967
2968 Actions : constant List_Id := New_List;
2969 -- Collect actions to be inserted
2970
2971 Known_Non_Null_Operand_Seen : Boolean;
2972 -- Set True during generation of the assignments of operands into
2973 -- result once an operand known to be non-null has been seen.
2974
2975 function Make_Artyp_Literal (Val : Nat) return Node_Id;
2976 -- This function makes an N_Integer_Literal node that is returned in
2977 -- analyzed form with the type set to Artyp. Importantly this literal
2978 -- is not flagged as static, so that if we do computations with it that
2979 -- result in statically detected out of range conditions, we will not
2980 -- generate error messages but instead warning messages.
2981
2982 function To_Artyp (X : Node_Id) return Node_Id;
2983 -- Given a node of type Ityp, returns the corresponding value of type
2984 -- Artyp. For non-enumeration types, this is a plain integer conversion.
2985 -- For enum types, the Pos of the value is returned.
2986
2987 function To_Ityp (X : Node_Id) return Node_Id;
2988 -- The inverse function (uses Val in the case of enumeration types)
2989
2990 ------------------------
2991 -- Make_Artyp_Literal --
2992 ------------------------
2993
2994 function Make_Artyp_Literal (Val : Nat) return Node_Id is
2995 Result : constant Node_Id := Make_Integer_Literal (Loc, Val);
2996 begin
2997 Set_Etype (Result, Artyp);
2998 Set_Analyzed (Result, True);
2999 Set_Is_Static_Expression (Result, False);
3000 return Result;
3001 end Make_Artyp_Literal;
3002
3003 --------------
3004 -- To_Artyp --
3005 --------------
3006
3007 function To_Artyp (X : Node_Id) return Node_Id is
3008 begin
3009 if Ityp = Base_Type (Artyp) then
3010 return X;
3011
3012 elsif Is_Enumeration_Type (Ityp) then
3013 return
3014 Make_Attribute_Reference (Loc,
3015 Prefix => New_Occurrence_Of (Ityp, Loc),
3016 Attribute_Name => Name_Pos,
3017 Expressions => New_List (X));
3018
3019 else
3020 return Convert_To (Artyp, X);
3021 end if;
3022 end To_Artyp;
3023
3024 -------------
3025 -- To_Ityp --
3026 -------------
3027
3028 function To_Ityp (X : Node_Id) return Node_Id is
3029 begin
3030 if Is_Enumeration_Type (Ityp) then
3031 return
3032 Make_Attribute_Reference (Loc,
3033 Prefix => New_Occurrence_Of (Ityp, Loc),
3034 Attribute_Name => Name_Val,
3035 Expressions => New_List (X));
3036
3037 -- Case where we will do a type conversion
3038
3039 else
3040 if Ityp = Base_Type (Artyp) then
3041 return X;
3042 else
3043 return Convert_To (Ityp, X);
3044 end if;
3045 end if;
3046 end To_Ityp;
3047
3048 -- Local Declarations
3049
3050 Opnd_Typ : Entity_Id;
3051 Ent : Entity_Id;
3052 Len : Uint;
3053 J : Nat;
3054 Clen : Node_Id;
3055 Set : Boolean;
3056
3057 -- Start of processing for Expand_Concatenate
3058
3059 begin
3060 -- Choose an appropriate computational type
3061
3062 -- We will be doing calculations of lengths and bounds in this routine
3063 -- and computing one from the other in some cases, e.g. getting the high
3064 -- bound by adding the length-1 to the low bound.
3065
3066 -- We can't just use the index type, or even its base type for this
3067 -- purpose for two reasons. First it might be an enumeration type which
3068 -- is not suitable for computations of any kind, and second it may
3069 -- simply not have enough range. For example if the index type is
3070 -- -128..+127 then lengths can be up to 256, which is out of range of
3071 -- the type.
3072
3073 -- For enumeration types, we can simply use Standard_Integer, this is
3074 -- sufficient since the actual number of enumeration literals cannot
3075 -- possibly exceed the range of integer (remember we will be doing the
3076 -- arithmetic with POS values, not representation values).
3077
3078 if Is_Enumeration_Type (Ityp) then
3079 Artyp := Standard_Integer;
3080
3081 -- If index type is Positive, we use the standard unsigned type, to give
3082 -- more room on the top of the range, obviating the need for an overflow
3083 -- check when creating the upper bound. This is needed to avoid junk
3084 -- overflow checks in the common case of String types.
3085
3086 -- ??? Disabled for now
3087
3088 -- elsif Istyp = Standard_Positive then
3089 -- Artyp := Standard_Unsigned;
3090
3091 -- For modular types, we use a 32-bit modular type for types whose size
3092 -- is in the range 1-31 bits. For 32-bit unsigned types, we use the
3093 -- identity type, and for larger unsigned types we use 64-bits.
3094
3095 elsif Is_Modular_Integer_Type (Ityp) then
3096 if RM_Size (Ityp) < RM_Size (Standard_Unsigned) then
3097 Artyp := Standard_Unsigned;
3098 elsif RM_Size (Ityp) = RM_Size (Standard_Unsigned) then
3099 Artyp := Ityp;
3100 else
3101 Artyp := RTE (RE_Long_Long_Unsigned);
3102 end if;
3103
3104 -- Similar treatment for signed types
3105
3106 else
3107 if RM_Size (Ityp) < RM_Size (Standard_Integer) then
3108 Artyp := Standard_Integer;
3109 elsif RM_Size (Ityp) = RM_Size (Standard_Integer) then
3110 Artyp := Ityp;
3111 else
3112 Artyp := Standard_Long_Long_Integer;
3113 end if;
3114 end if;
3115
3116 -- Supply dummy entry at start of length array
3117
3118 Aggr_Length (0) := Make_Artyp_Literal (0);
3119
3120 -- Go through operands setting up the above arrays
3121
3122 J := 1;
3123 while J <= N loop
3124 Opnd := Remove_Head (Opnds);
3125 Opnd_Typ := Etype (Opnd);
3126
3127 -- The parent got messed up when we put the operands in a list,
3128 -- so now put back the proper parent for the saved operand, that
3129 -- is to say the concatenation node, to make sure that each operand
3130 -- is seen as a subexpression, e.g. if actions must be inserted.
3131
3132 Set_Parent (Opnd, Cnode);
3133
3134 -- Set will be True when we have setup one entry in the array
3135
3136 Set := False;
3137
3138 -- Singleton element (or character literal) case
3139
3140 if Base_Type (Opnd_Typ) = Ctyp then
3141 NN := NN + 1;
3142 Operands (NN) := Opnd;
3143 Is_Fixed_Length (NN) := True;
3144 Fixed_Length (NN) := Uint_1;
3145 Result_May_Be_Null := False;
3146
3147 -- Set low bound of operand (no need to set Last_Opnd_High_Bound
3148 -- since we know that the result cannot be null).
3149
3150 Opnd_Low_Bound (NN) :=
3151 Make_Attribute_Reference (Loc,
3152 Prefix => New_Reference_To (Istyp, Loc),
3153 Attribute_Name => Name_First);
3154
3155 Set := True;
3156
3157 -- String literal case (can only occur for strings of course)
3158
3159 elsif Nkind (Opnd) = N_String_Literal then
3160 Len := String_Literal_Length (Opnd_Typ);
3161
3162 if Len /= 0 then
3163 Result_May_Be_Null := False;
3164 end if;
3165
3166 -- Capture last operand low and high bound if result could be null
3167
3168 if J = N and then Result_May_Be_Null then
3169 Last_Opnd_Low_Bound :=
3170 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));
3171
3172 Last_Opnd_High_Bound :=
3173 Make_Op_Subtract (Loc,
3174 Left_Opnd =>
3175 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)),
3176 Right_Opnd => Make_Integer_Literal (Loc, 1));
3177 end if;
3178
3179 -- Skip null string literal
3180
3181 if J < N and then Len = 0 then
3182 goto Continue;
3183 end if;
3184
3185 NN := NN + 1;
3186 Operands (NN) := Opnd;
3187 Is_Fixed_Length (NN) := True;
3188
3189 -- Set length and bounds
3190
3191 Fixed_Length (NN) := Len;
3192
3193 Opnd_Low_Bound (NN) :=
3194 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));
3195
3196 Set := True;
3197
3198 -- All other cases
3199
3200 else
3201 -- Check constrained case with known bounds
3202
3203 if Is_Constrained (Opnd_Typ) then
3204 declare
3205 Index : constant Node_Id := First_Index (Opnd_Typ);
3206 Indx_Typ : constant Entity_Id := Etype (Index);
3207 Lo : constant Node_Id := Type_Low_Bound (Indx_Typ);
3208 Hi : constant Node_Id := Type_High_Bound (Indx_Typ);
3209
3210 begin
3211 -- Fixed length constrained array type with known at compile
3212 -- time bounds is last case of fixed length operand.
3213
3214 if Compile_Time_Known_Value (Lo)
3215 and then
3216 Compile_Time_Known_Value (Hi)
3217 then
3218 declare
3219 Loval : constant Uint := Expr_Value (Lo);
3220 Hival : constant Uint := Expr_Value (Hi);
3221 Len : constant Uint :=
3222 UI_Max (Hival - Loval + 1, Uint_0);
3223
3224 begin
3225 if Len > 0 then
3226 Result_May_Be_Null := False;
3227 end if;
3228
3229 -- Capture last operand bounds if result could be null
3230
3231 if J = N and then Result_May_Be_Null then
3232 Last_Opnd_Low_Bound :=
3233 Convert_To (Ityp,
3234 Make_Integer_Literal (Loc, Expr_Value (Lo)));
3235
3236 Last_Opnd_High_Bound :=
3237 Convert_To (Ityp,
3238 Make_Integer_Literal (Loc, Expr_Value (Hi)));
3239 end if;
3240
3241 -- Exclude null length case unless last operand
3242
3243 if J < N and then Len = 0 then
3244 goto Continue;
3245 end if;
3246
3247 NN := NN + 1;
3248 Operands (NN) := Opnd;
3249 Is_Fixed_Length (NN) := True;
3250 Fixed_Length (NN) := Len;
3251
3252 Opnd_Low_Bound (NN) :=
3253 To_Ityp
3254 (Make_Integer_Literal (Loc, Expr_Value (Lo)));
3255 Set := True;
3256 end;
3257 end if;
3258 end;
3259 end if;
3260
3261 -- All cases where the length is not known at compile time, or the
3262 -- special case of an operand which is known to be null but has a
3263 -- lower bound other than 1 or is other than a string type.
3264
3265 if not Set then
3266 NN := NN + 1;
3267
3268 -- Capture operand bounds
3269
3270 Opnd_Low_Bound (NN) :=
3271 Make_Attribute_Reference (Loc,
3272 Prefix =>
3273 Duplicate_Subexpr (Opnd, Name_Req => True),
3274 Attribute_Name => Name_First);
3275
3276 -- Capture last operand bounds if result could be null
3277
3278 if J = N and Result_May_Be_Null then
3279 Last_Opnd_Low_Bound :=
3280 Convert_To (Ityp,
3281 Make_Attribute_Reference (Loc,
3282 Prefix =>
3283 Duplicate_Subexpr (Opnd, Name_Req => True),
3284 Attribute_Name => Name_First));
3285
3286 Last_Opnd_High_Bound :=
3287 Convert_To (Ityp,
3288 Make_Attribute_Reference (Loc,
3289 Prefix =>
3290 Duplicate_Subexpr (Opnd, Name_Req => True),
3291 Attribute_Name => Name_Last));
3292 end if;
3293
3294 -- Capture length of operand in entity
3295
3296 Operands (NN) := Opnd;
3297 Is_Fixed_Length (NN) := False;
3298
3299 Var_Length (NN) := Make_Temporary (Loc, 'L');
3300
3301 Append_To (Actions,
3302 Make_Object_Declaration (Loc,
3303 Defining_Identifier => Var_Length (NN),
3304 Constant_Present => True,
3305 Object_Definition => New_Occurrence_Of (Artyp, Loc),
3306 Expression =>
3307 Make_Attribute_Reference (Loc,
3308 Prefix =>
3309 Duplicate_Subexpr (Opnd, Name_Req => True),
3310 Attribute_Name => Name_Length)));
3311 end if;
3312 end if;
3313
3314 -- Set next entry in aggregate length array
3315
3316 -- For first entry, make either integer literal for fixed length
3317 -- or a reference to the saved length for variable length.
3318
3319 if NN = 1 then
3320 if Is_Fixed_Length (1) then
3321 Aggr_Length (1) := Make_Integer_Literal (Loc, Fixed_Length (1));
3322 else
3323 Aggr_Length (1) := New_Reference_To (Var_Length (1), Loc);
3324 end if;
3325
3326 -- If entry is fixed length and only fixed lengths so far, make
3327 -- appropriate new integer literal adding new length.
3328
3329 elsif Is_Fixed_Length (NN)
3330 and then Nkind (Aggr_Length (NN - 1)) = N_Integer_Literal
3331 then
3332 Aggr_Length (NN) :=
3333 Make_Integer_Literal (Loc,
3334 Intval => Fixed_Length (NN) + Intval (Aggr_Length (NN - 1)));
3335
3336 -- All other cases, construct an addition node for the length and
3337 -- create an entity initialized to this length.
3338
3339 else
3340 Ent := Make_Temporary (Loc, 'L');
3341
3342 if Is_Fixed_Length (NN) then
3343 Clen := Make_Integer_Literal (Loc, Fixed_Length (NN));
3344 else
3345 Clen := New_Reference_To (Var_Length (NN), Loc);
3346 end if;
3347
3348 Append_To (Actions,
3349 Make_Object_Declaration (Loc,
3350 Defining_Identifier => Ent,
3351 Constant_Present => True,
3352 Object_Definition => New_Occurrence_Of (Artyp, Loc),
3353 Expression =>
3354 Make_Op_Add (Loc,
3355 Left_Opnd => New_Copy (Aggr_Length (NN - 1)),
3356 Right_Opnd => Clen)));
3357
3358 Aggr_Length (NN) := Make_Identifier (Loc, Chars => Chars (Ent));
3359 end if;
3360
3361 <<Continue>>
3362 J := J + 1;
3363 end loop;
3364
3365 -- If we have only skipped null operands, return the last operand
3366
3367 if NN = 0 then
3368 Result := Opnd;
3369 goto Done;
3370 end if;
3371
3372 -- If we have only one non-null operand, return it and we are done.
3373 -- There is one case in which this cannot be done, and that is when
3374 -- the sole operand is of the element type, in which case it must be
3375 -- converted to an array, and the easiest way of doing that is to go
3376 -- through the normal general circuit.
3377
3378 if NN = 1
3379 and then Base_Type (Etype (Operands (1))) /= Ctyp
3380 then
3381 Result := Operands (1);
3382 goto Done;
3383 end if;
3384
3385 -- Cases where we have a real concatenation
3386
3387 -- Next step is to find the low bound for the result array that we
3388 -- will allocate. The rules for this are in (RM 4.5.6(5-7)).
3389
3390 -- If the ultimate ancestor of the index subtype is a constrained array
3391 -- definition, then the lower bound is that of the index subtype as
3392 -- specified by (RM 4.5.3(6)).
3393
3394 -- The right test here is to go to the root type, and then the ultimate
3395 -- ancestor is the first subtype of this root type.
3396
3397 if Is_Constrained (First_Subtype (Root_Type (Atyp))) then
3398 Low_Bound :=
3399 Make_Attribute_Reference (Loc,
3400 Prefix =>
3401 New_Occurrence_Of (First_Subtype (Root_Type (Atyp)), Loc),
3402 Attribute_Name => Name_First);
3403
3404 -- If the first operand in the list has known length we know that
3405 -- the lower bound of the result is the lower bound of this operand.
3406
3407 elsif Is_Fixed_Length (1) then
3408 Low_Bound := Opnd_Low_Bound (1);
3409
3410 -- OK, we don't know the lower bound, we have to build a horrible
3411 -- if expression node of the form
3412
3413 -- if Cond1'Length /= 0 then
3414 -- Opnd1 low bound
3415 -- else
3416 -- if Opnd2'Length /= 0 then
3417 -- Opnd2 low bound
3418 -- else
3419 -- ...
3420
3421 -- The nesting ends either when we hit an operand whose length is known
3422 -- at compile time, or on reaching the last operand, whose low bound we
3423 -- take unconditionally whether or not it is null. It's easiest to do
3424 -- this with a recursive procedure:
3425
3426 else
3427 declare
3428 function Get_Known_Bound (J : Nat) return Node_Id;
3429 -- Returns the lower bound determined by operands J .. NN
3430
3431 ---------------------
3432 -- Get_Known_Bound --
3433 ---------------------
3434
3435 function Get_Known_Bound (J : Nat) return Node_Id is
3436 begin
3437 if Is_Fixed_Length (J) or else J = NN then
3438 return New_Copy (Opnd_Low_Bound (J));
3439
3440 else
3441 return
3442 Make_If_Expression (Loc,
3443 Expressions => New_List (
3444
3445 Make_Op_Ne (Loc,
3446 Left_Opnd => New_Reference_To (Var_Length (J), Loc),
3447 Right_Opnd => Make_Integer_Literal (Loc, 0)),
3448
3449 New_Copy (Opnd_Low_Bound (J)),
3450 Get_Known_Bound (J + 1)));
3451 end if;
3452 end Get_Known_Bound;
3453
3454 begin
3455 Ent := Make_Temporary (Loc, 'L');
3456
3457 Append_To (Actions,
3458 Make_Object_Declaration (Loc,
3459 Defining_Identifier => Ent,
3460 Constant_Present => True,
3461 Object_Definition => New_Occurrence_Of (Ityp, Loc),
3462 Expression => Get_Known_Bound (1)));
3463
3464 Low_Bound := New_Reference_To (Ent, Loc);
3465 end;
3466 end if;
3467
3468 -- Now we can safely compute the upper bound, normally
3469 -- Low_Bound + Length - 1.
3470
3471 High_Bound :=
3472 To_Ityp (
3473 Make_Op_Add (Loc,
3474 Left_Opnd => To_Artyp (New_Copy (Low_Bound)),
3475 Right_Opnd =>
3476 Make_Op_Subtract (Loc,
3477 Left_Opnd => New_Copy (Aggr_Length (NN)),
3478 Right_Opnd => Make_Artyp_Literal (1))));
3479
3480 -- Note that calculation of the high bound may cause overflow in some
3481 -- very weird cases, so in the general case we need an overflow check on
3482 -- the high bound. We can avoid this for the common case of string types
3483 -- and other types whose index is Positive, since we chose a wider range
3484 -- for the arithmetic type.
3485
3486 if Istyp /= Standard_Positive then
3487 Activate_Overflow_Check (High_Bound);
3488 end if;
3489
3490 -- Handle the exceptional case where the result is null, in which case
3491 -- case the bounds come from the last operand (so that we get the proper
3492 -- bounds if the last operand is super-flat).
3493
3494 if Result_May_Be_Null then
3495 Low_Bound :=
3496 Make_If_Expression (Loc,
3497 Expressions => New_List (
3498 Make_Op_Eq (Loc,
3499 Left_Opnd => New_Copy (Aggr_Length (NN)),
3500 Right_Opnd => Make_Artyp_Literal (0)),
3501 Last_Opnd_Low_Bound,
3502 Low_Bound));
3503
3504 High_Bound :=
3505 Make_If_Expression (Loc,
3506 Expressions => New_List (
3507 Make_Op_Eq (Loc,
3508 Left_Opnd => New_Copy (Aggr_Length (NN)),
3509 Right_Opnd => Make_Artyp_Literal (0)),
3510 Last_Opnd_High_Bound,
3511 High_Bound));
3512 end if;
3513
3514 -- Here is where we insert the saved up actions
3515
3516 Insert_Actions (Cnode, Actions, Suppress => All_Checks);
3517
3518 -- Now we construct an array object with appropriate bounds. We mark
3519 -- the target as internal to prevent useless initialization when
3520 -- Initialize_Scalars is enabled. Also since this is the actual result
3521 -- entity, we make sure we have debug information for the result.
3522
3523 Ent := Make_Temporary (Loc, 'S');
3524 Set_Is_Internal (Ent);
3525 Set_Needs_Debug_Info (Ent);
3526
3527 -- If the bound is statically known to be out of range, we do not want
3528 -- to abort, we want a warning and a runtime constraint error. Note that
3529 -- we have arranged that the result will not be treated as a static
3530 -- constant, so we won't get an illegality during this insertion.
3531
3532 Insert_Action (Cnode,
3533 Make_Object_Declaration (Loc,
3534 Defining_Identifier => Ent,
3535 Object_Definition =>
3536 Make_Subtype_Indication (Loc,
3537 Subtype_Mark => New_Occurrence_Of (Atyp, Loc),
3538 Constraint =>
3539 Make_Index_Or_Discriminant_Constraint (Loc,
3540 Constraints => New_List (
3541 Make_Range (Loc,
3542 Low_Bound => Low_Bound,
3543 High_Bound => High_Bound))))),
3544 Suppress => All_Checks);
3545
3546 -- If the result of the concatenation appears as the initializing
3547 -- expression of an object declaration, we can just rename the
3548 -- result, rather than copying it.
3549
3550 Set_OK_To_Rename (Ent);
3551
3552 -- Catch the static out of range case now
3553
3554 if Raises_Constraint_Error (High_Bound) then
3555 raise Concatenation_Error;
3556 end if;
3557
3558 -- Now we will generate the assignments to do the actual concatenation
3559
3560 -- There is one case in which we will not do this, namely when all the
3561 -- following conditions are met:
3562
3563 -- The result type is Standard.String
3564
3565 -- There are nine or fewer retained (non-null) operands
3566
3567 -- The optimization level is -O0
3568
3569 -- The corresponding System.Concat_n.Str_Concat_n routine is
3570 -- available in the run time.
3571
3572 -- The debug flag gnatd.c is not set
3573
3574 -- If all these conditions are met then we generate a call to the
3575 -- relevant concatenation routine. The purpose of this is to avoid
3576 -- undesirable code bloat at -O0.
3577
3578 if Atyp = Standard_String
3579 and then NN in 2 .. 9
3580 and then (Opt.Optimization_Level = 0 or else Debug_Flag_Dot_CC)
3581 and then not Debug_Flag_Dot_C
3582 then
3583 declare
3584 RR : constant array (Nat range 2 .. 9) of RE_Id :=
3585 (RE_Str_Concat_2,
3586 RE_Str_Concat_3,
3587 RE_Str_Concat_4,
3588 RE_Str_Concat_5,
3589 RE_Str_Concat_6,
3590 RE_Str_Concat_7,
3591 RE_Str_Concat_8,
3592 RE_Str_Concat_9);
3593
3594 begin
3595 if RTE_Available (RR (NN)) then
3596 declare
3597 Opnds : constant List_Id :=
3598 New_List (New_Occurrence_Of (Ent, Loc));
3599
3600 begin
3601 for J in 1 .. NN loop
3602 if Is_List_Member (Operands (J)) then
3603 Remove (Operands (J));
3604 end if;
3605
3606 if Base_Type (Etype (Operands (J))) = Ctyp then
3607 Append_To (Opnds,
3608 Make_Aggregate (Loc,
3609 Component_Associations => New_List (
3610 Make_Component_Association (Loc,
3611 Choices => New_List (
3612 Make_Integer_Literal (Loc, 1)),
3613 Expression => Operands (J)))));
3614
3615 else
3616 Append_To (Opnds, Operands (J));
3617 end if;
3618 end loop;
3619
3620 Insert_Action (Cnode,
3621 Make_Procedure_Call_Statement (Loc,
3622 Name => New_Reference_To (RTE (RR (NN)), Loc),
3623 Parameter_Associations => Opnds));
3624
3625 Result := New_Reference_To (Ent, Loc);
3626 goto Done;
3627 end;
3628 end if;
3629 end;
3630 end if;
3631
3632 -- Not special case so generate the assignments
3633
3634 Known_Non_Null_Operand_Seen := False;
3635
3636 for J in 1 .. NN loop
3637 declare
3638 Lo : constant Node_Id :=
3639 Make_Op_Add (Loc,
3640 Left_Opnd => To_Artyp (New_Copy (Low_Bound)),
3641 Right_Opnd => Aggr_Length (J - 1));
3642
3643 Hi : constant Node_Id :=
3644 Make_Op_Add (Loc,
3645 Left_Opnd => To_Artyp (New_Copy (Low_Bound)),
3646 Right_Opnd =>
3647 Make_Op_Subtract (Loc,
3648 Left_Opnd => Aggr_Length (J),
3649 Right_Opnd => Make_Artyp_Literal (1)));
3650
3651 begin
3652 -- Singleton case, simple assignment
3653
3654 if Base_Type (Etype (Operands (J))) = Ctyp then
3655 Known_Non_Null_Operand_Seen := True;
3656 Insert_Action (Cnode,
3657 Make_Assignment_Statement (Loc,
3658 Name =>
3659 Make_Indexed_Component (Loc,
3660 Prefix => New_Occurrence_Of (Ent, Loc),
3661 Expressions => New_List (To_Ityp (Lo))),
3662 Expression => Operands (J)),
3663 Suppress => All_Checks);
3664
3665 -- Array case, slice assignment, skipped when argument is fixed
3666 -- length and known to be null.
3667
3668 elsif (not Is_Fixed_Length (J)) or else (Fixed_Length (J) > 0) then
3669 declare
3670 Assign : Node_Id :=
3671 Make_Assignment_Statement (Loc,
3672 Name =>
3673 Make_Slice (Loc,
3674 Prefix =>
3675 New_Occurrence_Of (Ent, Loc),
3676 Discrete_Range =>
3677 Make_Range (Loc,
3678 Low_Bound => To_Ityp (Lo),
3679 High_Bound => To_Ityp (Hi))),
3680 Expression => Operands (J));
3681 begin
3682 if Is_Fixed_Length (J) then
3683 Known_Non_Null_Operand_Seen := True;
3684
3685 elsif not Known_Non_Null_Operand_Seen then
3686
3687 -- Here if operand length is not statically known and no
3688 -- operand known to be non-null has been processed yet.
3689 -- If operand length is 0, we do not need to perform the
3690 -- assignment, and we must avoid the evaluation of the
3691 -- high bound of the slice, since it may underflow if the
3692 -- low bound is Ityp'First.
3693
3694 Assign :=
3695 Make_Implicit_If_Statement (Cnode,
3696 Condition =>
3697 Make_Op_Ne (Loc,
3698 Left_Opnd =>
3699 New_Occurrence_Of (Var_Length (J), Loc),
3700 Right_Opnd => Make_Integer_Literal (Loc, 0)),
3701 Then_Statements => New_List (Assign));
3702 end if;
3703
3704 Insert_Action (Cnode, Assign, Suppress => All_Checks);
3705 end;
3706 end if;
3707 end;
3708 end loop;
3709
3710 -- Finally we build the result, which is a reference to the array object
3711
3712 Result := New_Reference_To (Ent, Loc);
3713
3714 <<Done>>
3715 Rewrite (Cnode, Result);
3716 Analyze_And_Resolve (Cnode, Atyp);
3717
3718 exception
3719 when Concatenation_Error =>
3720
3721 -- Kill warning generated for the declaration of the static out of
3722 -- range high bound, and instead generate a Constraint_Error with
3723 -- an appropriate specific message.
3724
3725 Kill_Dead_Code (Declaration_Node (Entity (High_Bound)));
3726 Apply_Compile_Time_Constraint_Error
3727 (N => Cnode,
3728 Msg => "concatenation result upper bound out of range?",
3729 Reason => CE_Range_Check_Failed);
3730 end Expand_Concatenate;
3731
3732 ---------------------------------------------------
3733 -- Expand_Membership_Minimize_Eliminate_Overflow --
3734 ---------------------------------------------------
3735
3736 procedure Expand_Membership_Minimize_Eliminate_Overflow (N : Node_Id) is
3737 pragma Assert (Nkind (N) = N_In);
3738 -- Despite the name, this routine applies only to N_In, not to
3739 -- N_Not_In. The latter is always rewritten as not (X in Y).
3740
3741 Result_Type : constant Entity_Id := Etype (N);
3742 -- Capture result type, may be a derived boolean type
3743
3744 Loc : constant Source_Ptr := Sloc (N);
3745 Lop : constant Node_Id := Left_Opnd (N);
3746 Rop : constant Node_Id := Right_Opnd (N);
3747
3748 -- Note: there are many referencs to Etype (Lop) and Etype (Rop). It
3749 -- is thus tempting to capture these values, but due to the rewrites
3750 -- that occur as a result of overflow checking, these values change
3751 -- as we go along, and it is safe just to always use Etype explicitly.
3752
3753 Restype : constant Entity_Id := Etype (N);
3754 -- Save result type
3755
3756 Lo, Hi : Uint;
3757 -- Bounds in Minimize calls, not used yet ???
3758
3759 LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
3760 -- Entity for Long_Long_Integer'Base (Standard should export this???)
3761
3762 begin
3763 Minimize_Eliminate_Overflow_Checks (Lop, Lo, Hi, Top_Level => False);
3764
3765 -- If right operand is a subtype name, and the subtype name has no
3766 -- predicate, then we can just replace the right operand with an
3767 -- explicit range T'First .. T'Last, and use the explicit range code.
3768
3769 if Nkind (Rop) /= N_Range
3770 and then No (Predicate_Function (Etype (Rop)))
3771 then
3772 declare
3773 Rtyp : constant Entity_Id := Etype (Rop);
3774 begin
3775 Rewrite (Rop,
3776 Make_Range (Loc,
3777 Low_Bound =>
3778 Make_Attribute_Reference (Loc,
3779 Attribute_Name => Name_First,
3780 Prefix => New_Reference_To (Rtyp, Loc)),
3781 High_Bound =>
3782 Make_Attribute_Reference (Loc,
3783 Attribute_Name => Name_Last,
3784 Prefix => New_Reference_To (Rtyp, Loc))));
3785 Analyze_And_Resolve (Rop, Rtyp, Suppress => All_Checks);
3786 end;
3787 end if;
3788
3789 -- Here for the explicit range case. Note that the bounds of the range
3790 -- have not been processed for minimized or eliminated checks.
3791
3792 if Nkind (Rop) = N_Range then
3793 Minimize_Eliminate_Overflow_Checks
3794 (Low_Bound (Rop), Lo, Hi, Top_Level => False);
3795 Minimize_Eliminate_Overflow_Checks
3796 (High_Bound (Rop), Lo, Hi, Top_Level => False);
3797
3798 -- We have A in B .. C, treated as A >= B and then A <= C
3799
3800 -- Bignum case
3801
3802 if Is_RTE (Etype (Lop), RE_Bignum)
3803 or else Is_RTE (Etype (Low_Bound (Rop)), RE_Bignum)
3804 or else Is_RTE (Etype (High_Bound (Rop)), RE_Bignum)
3805 then
3806 declare
3807 Blk : constant Node_Id := Make_Bignum_Block (Loc);
3808 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
3809 L : constant Entity_Id :=
3810 Make_Defining_Identifier (Loc, Name_uL);
3811 Lopnd : constant Node_Id := Convert_To_Bignum (Lop);
3812 Lbound : constant Node_Id :=
3813 Convert_To_Bignum (Low_Bound (Rop));
3814 Hbound : constant Node_Id :=
3815 Convert_To_Bignum (High_Bound (Rop));
3816
3817 -- Now we rewrite the membership test node to look like
3818
3819 -- do
3820 -- Bnn : Result_Type;
3821 -- declare
3822 -- M : Mark_Id := SS_Mark;
3823 -- L : Bignum := Lopnd;
3824 -- begin
3825 -- Bnn := Big_GE (L, Lbound) and then Big_LE (L, Hbound)
3826 -- SS_Release (M);
3827 -- end;
3828 -- in
3829 -- Bnn
3830 -- end
3831
3832 begin
3833 -- Insert declaration of L into declarations of bignum block
3834
3835 Insert_After
3836 (Last (Declarations (Blk)),
3837 Make_Object_Declaration (Loc,
3838 Defining_Identifier => L,
3839 Object_Definition =>
3840 New_Occurrence_Of (RTE (RE_Bignum), Loc),
3841 Expression => Lopnd));
3842
3843 -- Insert assignment to Bnn into expressions of bignum block
3844
3845 Insert_Before
3846 (First (Statements (Handled_Statement_Sequence (Blk))),
3847 Make_Assignment_Statement (Loc,
3848 Name => New_Occurrence_Of (Bnn, Loc),
3849 Expression =>
3850 Make_And_Then (Loc,
3851 Left_Opnd =>
3852 Make_Function_Call (Loc,
3853 Name =>
3854 New_Occurrence_Of (RTE (RE_Big_GE), Loc),
3855 Parameter_Associations => New_List (
3856 New_Occurrence_Of (L, Loc),
3857 Lbound)),
3858 Right_Opnd =>
3859 Make_Function_Call (Loc,
3860 Name =>
3861 New_Occurrence_Of (RTE (RE_Big_LE), Loc),
3862 Parameter_Associations => New_List (
3863 New_Occurrence_Of (L, Loc),
3864 Hbound)))));
3865
3866 -- Now rewrite the node
3867
3868 Rewrite (N,
3869 Make_Expression_With_Actions (Loc,
3870 Actions => New_List (
3871 Make_Object_Declaration (Loc,
3872 Defining_Identifier => Bnn,
3873 Object_Definition =>
3874 New_Occurrence_Of (Result_Type, Loc)),
3875 Blk),
3876 Expression => New_Occurrence_Of (Bnn, Loc)));
3877 Analyze_And_Resolve (N, Result_Type);
3878 return;
3879 end;
3880
3881 -- Here if no bignums around
3882
3883 else
3884 -- Case where types are all the same
3885
3886 if Base_Type (Etype (Lop)) = Base_Type (Etype (Low_Bound (Rop)))
3887 and then
3888 Base_Type (Etype (Lop)) = Base_Type (Etype (High_Bound (Rop)))
3889 then
3890 null;
3891
3892 -- If types are not all the same, it means that we have rewritten
3893 -- at least one of them to be of type Long_Long_Integer, and we
3894 -- will convert the other operands to Long_Long_Integer.
3895
3896 else
3897 Convert_To_And_Rewrite (LLIB, Lop);
3898 Set_Analyzed (Lop, False);
3899 Analyze_And_Resolve (Lop, LLIB);
3900
3901 -- For the right operand, avoid unnecessary recursion into
3902 -- this routine, we know that overflow is not possible.
3903
3904 Convert_To_And_Rewrite (LLIB, Low_Bound (Rop));
3905 Convert_To_And_Rewrite (LLIB, High_Bound (Rop));
3906 Set_Analyzed (Rop, False);
3907 Analyze_And_Resolve (Rop, LLIB, Suppress => Overflow_Check);
3908 end if;
3909
3910 -- Now the three operands are of the same signed integer type,
3911 -- so we can use the normal expansion routine for membership,
3912 -- setting the flag to prevent recursion into this procedure.
3913
3914 Set_No_Minimize_Eliminate (N);
3915 Expand_N_In (N);
3916 end if;
3917
3918 -- Right operand is a subtype name and the subtype has a predicate. We
3919 -- have to make sure predicate is checked, and for that we need to use
3920 -- the standard N_In circuitry with appropriate types.
3921
3922 else
3923 pragma Assert (Present (Predicate_Function (Etype (Rop))));
3924
3925 -- If types are "right", just call Expand_N_In preventing recursion
3926
3927 if Base_Type (Etype (Lop)) = Base_Type (Etype (Rop)) then
3928 Set_No_Minimize_Eliminate (N);
3929 Expand_N_In (N);
3930
3931 -- Bignum case
3932
3933 elsif Is_RTE (Etype (Lop), RE_Bignum) then
3934
3935 -- For X in T, we want to rewrite our node as
3936
3937 -- do
3938 -- Bnn : Result_Type;
3939
3940 -- declare
3941 -- M : Mark_Id := SS_Mark;
3942 -- Lnn : Long_Long_Integer'Base
3943 -- Nnn : Bignum;
3944
3945 -- begin
3946 -- Nnn := X;
3947
3948 -- if not Bignum_In_LLI_Range (Nnn) then
3949 -- Bnn := False;
3950 -- else
3951 -- Lnn := From_Bignum (Nnn);
3952 -- Bnn :=
3953 -- Lnn in LLIB (T'Base'First) .. LLIB (T'Base'Last)
3954 -- and then T'Base (Lnn) in T;
3955 -- end if;
3956 --
3957 -- SS_Release (M);
3958 -- end
3959 -- in
3960 -- Bnn
3961 -- end
3962
3963 -- A bit gruesome, but here goes.
3964
3965 declare
3966 Blk : constant Node_Id := Make_Bignum_Block (Loc);
3967 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
3968 Lnn : constant Entity_Id := Make_Temporary (Loc, 'L', N);
3969 Nnn : constant Entity_Id := Make_Temporary (Loc, 'N', N);
3970 T : constant Entity_Id := Etype (Rop);
3971 TB : constant Entity_Id := Base_Type (T);
3972 Nin : Node_Id;
3973
3974 begin
3975 -- Mark the last membership operation to prevent recursion
3976
3977 Nin :=
3978 Make_In (Loc,
3979 Left_Opnd =>
3980 Convert_To (Base_Type (Etype (Rop)),
3981 New_Occurrence_Of (Lnn, Loc)),
3982 Right_Opnd => New_Occurrence_Of (Etype (Rop), Loc));
3983 Set_No_Minimize_Eliminate (Nin);
3984
3985 -- Now decorate the block
3986
3987 Insert_After
3988 (Last (Declarations (Blk)),
3989 Make_Object_Declaration (Loc,
3990 Defining_Identifier => Lnn,
3991 Object_Definition => New_Occurrence_Of (LLIB, Loc)));
3992
3993 Insert_After
3994 (Last (Declarations (Blk)),
3995 Make_Object_Declaration (Loc,
3996 Defining_Identifier => Nnn,
3997 Object_Definition =>
3998 New_Occurrence_Of (RTE (RE_Bignum), Loc)));
3999
4000 Insert_List_Before
4001 (First (Statements (Handled_Statement_Sequence (Blk))),
4002 New_List (
4003 Make_Assignment_Statement (Loc,
4004 Name => New_Occurrence_Of (Nnn, Loc),
4005 Expression => Relocate_Node (Lop)),
4006
4007 Make_If_Statement (Loc,
4008 Condition =>
4009 Make_Op_Not (Loc,
4010 Right_Opnd =>
4011 Make_Function_Call (Loc,
4012 Name =>
4013 New_Occurrence_Of
4014 (RTE (RE_Bignum_In_LLI_Range), Loc),
4015 Parameter_Associations => New_List (
4016 New_Occurrence_Of (Nnn, Loc)))),
4017
4018 Then_Statements => New_List (
4019 Make_Assignment_Statement (Loc,
4020 Name => New_Occurrence_Of (Bnn, Loc),
4021 Expression =>
4022 New_Occurrence_Of (Standard_False, Loc))),
4023
4024 Else_Statements => New_List (
4025 Make_Assignment_Statement (Loc,
4026 Name => New_Occurrence_Of (Lnn, Loc),
4027 Expression =>
4028 Make_Function_Call (Loc,
4029 Name =>
4030 New_Occurrence_Of (RTE (RE_From_Bignum), Loc),
4031 Parameter_Associations => New_List (
4032 New_Occurrence_Of (Nnn, Loc)))),
4033
4034 Make_Assignment_Statement (Loc,
4035 Name => New_Occurrence_Of (Bnn, Loc),
4036 Expression =>
4037 Make_And_Then (Loc,
4038 Left_Opnd =>
4039 Make_In (Loc,
4040 Left_Opnd => New_Occurrence_Of (Lnn, Loc),
4041 Right_Opnd =>
4042 Make_Range (Loc,
4043 Low_Bound =>
4044 Convert_To (LLIB,
4045 Make_Attribute_Reference (Loc,
4046 Attribute_Name => Name_First,
4047 Prefix =>
4048 New_Occurrence_Of (TB, Loc))),
4049
4050 High_Bound =>
4051 Convert_To (LLIB,
4052 Make_Attribute_Reference (Loc,
4053 Attribute_Name => Name_Last,
4054 Prefix =>
4055 New_Occurrence_Of (TB, Loc))))),
4056
4057 Right_Opnd => Nin))))));
4058
4059 -- Now we can do the rewrite
4060
4061 Rewrite (N,
4062 Make_Expression_With_Actions (Loc,
4063 Actions => New_List (
4064 Make_Object_Declaration (Loc,
4065 Defining_Identifier => Bnn,
4066 Object_Definition =>
4067 New_Occurrence_Of (Result_Type, Loc)),
4068 Blk),
4069 Expression => New_Occurrence_Of (Bnn, Loc)));
4070 Analyze_And_Resolve (N, Result_Type);
4071 return;
4072 end;
4073
4074 -- Not bignum case, but types don't match (this means we rewrote the
4075 -- left operand to be Long_Long_Integer).
4076
4077 else
4078 pragma Assert (Base_Type (Etype (Lop)) = LLIB);
4079
4080 -- We rewrite the membership test as (where T is the type with
4081 -- the predicate, i.e. the type of the right operand)
4082
4083 -- Lop in LLIB (T'Base'First) .. LLIB (T'Base'Last)
4084 -- and then T'Base (Lop) in T
4085
4086 declare
4087 T : constant Entity_Id := Etype (Rop);
4088 TB : constant Entity_Id := Base_Type (T);
4089 Nin : Node_Id;
4090
4091 begin
4092 -- The last membership test is marked to prevent recursion
4093
4094 Nin :=
4095 Make_In (Loc,
4096 Left_Opnd => Convert_To (TB, Duplicate_Subexpr (Lop)),
4097 Right_Opnd => New_Occurrence_Of (T, Loc));
4098 Set_No_Minimize_Eliminate (Nin);
4099
4100 -- Now do the rewrite
4101
4102 Rewrite (N,
4103 Make_And_Then (Loc,
4104 Left_Opnd =>
4105 Make_In (Loc,
4106 Left_Opnd => Lop,
4107 Right_Opnd =>
4108 Make_Range (Loc,
4109 Low_Bound =>
4110 Convert_To (LLIB,
4111 Make_Attribute_Reference (Loc,
4112 Attribute_Name => Name_First,
4113 Prefix => New_Occurrence_Of (TB, Loc))),
4114 High_Bound =>
4115 Convert_To (LLIB,
4116 Make_Attribute_Reference (Loc,
4117 Attribute_Name => Name_Last,
4118 Prefix => New_Occurrence_Of (TB, Loc))))),
4119 Right_Opnd => Nin));
4120 Set_Analyzed (N, False);
4121 Analyze_And_Resolve (N, Restype);
4122 end;
4123 end if;
4124 end if;
4125 end Expand_Membership_Minimize_Eliminate_Overflow;
4126
4127 ------------------------
4128 -- Expand_N_Allocator --
4129 ------------------------
4130
4131 procedure Expand_N_Allocator (N : Node_Id) is
4132 PtrT : constant Entity_Id := Etype (N);
4133 Dtyp : constant Entity_Id := Available_View (Designated_Type (PtrT));
4134 Etyp : constant Entity_Id := Etype (Expression (N));
4135 Loc : constant Source_Ptr := Sloc (N);
4136 Desig : Entity_Id;
4137 Nod : Node_Id;
4138 Pool : Entity_Id;
4139 Temp : Entity_Id;
4140
4141 procedure Rewrite_Coextension (N : Node_Id);
4142 -- Static coextensions have the same lifetime as the entity they
4143 -- constrain. Such occurrences can be rewritten as aliased objects
4144 -- and their unrestricted access used instead of the coextension.
4145
4146 function Size_In_Storage_Elements (E : Entity_Id) return Node_Id;
4147 -- Given a constrained array type E, returns a node representing the
4148 -- code to compute the size in storage elements for the given type.
4149 -- This is done without using the attribute (which malfunctions for
4150 -- large sizes ???)
4151
4152 -------------------------
4153 -- Rewrite_Coextension --
4154 -------------------------
4155
4156 procedure Rewrite_Coextension (N : Node_Id) is
4157 Temp_Id : constant Node_Id := Make_Temporary (Loc, 'C');
4158 Temp_Decl : Node_Id;
4159
4160 begin
4161 -- Generate:
4162 -- Cnn : aliased Etyp;
4163
4164 Temp_Decl :=
4165 Make_Object_Declaration (Loc,
4166 Defining_Identifier => Temp_Id,
4167 Aliased_Present => True,
4168 Object_Definition => New_Occurrence_Of (Etyp, Loc));
4169
4170 if Nkind (Expression (N)) = N_Qualified_Expression then
4171 Set_Expression (Temp_Decl, Expression (Expression (N)));
4172 end if;
4173
4174 Insert_Action (N, Temp_Decl);
4175 Rewrite (N,
4176 Make_Attribute_Reference (Loc,
4177 Prefix => New_Occurrence_Of (Temp_Id, Loc),
4178 Attribute_Name => Name_Unrestricted_Access));
4179
4180 Analyze_And_Resolve (N, PtrT);
4181 end Rewrite_Coextension;
4182
4183 ------------------------------
4184 -- Size_In_Storage_Elements --
4185 ------------------------------
4186
4187 function Size_In_Storage_Elements (E : Entity_Id) return Node_Id is
4188 begin
4189 -- Logically this just returns E'Max_Size_In_Storage_Elements.
4190 -- However, the reason for the existence of this function is
4191 -- to construct a test for sizes too large, which means near the
4192 -- 32-bit limit on a 32-bit machine, and precisely the trouble
4193 -- is that we get overflows when sizes are greater than 2**31.
4194
4195 -- So what we end up doing for array types is to use the expression:
4196
4197 -- number-of-elements * component_type'Max_Size_In_Storage_Elements
4198
4199 -- which avoids this problem. All this is a bit bogus, but it does
4200 -- mean we catch common cases of trying to allocate arrays that
4201 -- are too large, and which in the absence of a check results in
4202 -- undetected chaos ???
4203
4204 declare
4205 Len : Node_Id;
4206 Res : Node_Id;
4207
4208 begin
4209 for J in 1 .. Number_Dimensions (E) loop
4210 Len :=
4211 Make_Attribute_Reference (Loc,
4212 Prefix => New_Occurrence_Of (E, Loc),
4213 Attribute_Name => Name_Length,
4214 Expressions => New_List (Make_Integer_Literal (Loc, J)));
4215
4216 if J = 1 then
4217 Res := Len;
4218
4219 else
4220 Res :=
4221 Make_Op_Multiply (Loc,
4222 Left_Opnd => Res,
4223 Right_Opnd => Len);
4224 end if;
4225 end loop;
4226
4227 return
4228 Make_Op_Multiply (Loc,
4229 Left_Opnd => Len,
4230 Right_Opnd =>
4231 Make_Attribute_Reference (Loc,
4232 Prefix => New_Occurrence_Of (Component_Type (E), Loc),
4233 Attribute_Name => Name_Max_Size_In_Storage_Elements));
4234 end;
4235 end Size_In_Storage_Elements;
4236
4237 -- Start of processing for Expand_N_Allocator
4238
4239 begin
4240 -- RM E.2.3(22). We enforce that the expected type of an allocator
4241 -- shall not be a remote access-to-class-wide-limited-private type
4242
4243 -- Why is this being done at expansion time, seems clearly wrong ???
4244
4245 Validate_Remote_Access_To_Class_Wide_Type (N);
4246
4247 -- Processing for anonymous access-to-controlled types. These access
4248 -- types receive a special finalization master which appears in the
4249 -- declarations of the enclosing semantic unit. This expansion is done
4250 -- now to ensure that any additional types generated by this routine or
4251 -- Expand_Allocator_Expression inherit the proper type attributes.
4252
4253 if (Ekind (PtrT) = E_Anonymous_Access_Type
4254 or else
4255 (Is_Itype (PtrT) and then No (Finalization_Master (PtrT))))
4256 and then Needs_Finalization (Dtyp)
4257 then
4258 -- Anonymous access-to-controlled types allocate on the global pool.
4259 -- Do not set this attribute on .NET/JVM since those targets do not
4260 -- support pools.
4261
4262 if No (Associated_Storage_Pool (PtrT)) and then VM_Target = No_VM then
4263 Set_Associated_Storage_Pool
4264 (PtrT, Get_Global_Pool_For_Access_Type (PtrT));
4265 end if;
4266
4267 -- The finalization master must be inserted and analyzed as part of
4268 -- the current semantic unit. This form of expansion is not carried
4269 -- out in Alfa mode because it is useless. Note that the master is
4270 -- updated when analysis changes current units.
4271
4272 if not Alfa_Mode then
4273 Set_Finalization_Master (PtrT, Current_Anonymous_Master);
4274 end if;
4275 end if;
4276
4277 -- Set the storage pool and find the appropriate version of Allocate to
4278 -- call. Do not overwrite the storage pool if it is already set, which
4279 -- can happen for build-in-place function returns (see
4280 -- Exp_Ch4.Expand_N_Extended_Return_Statement).
4281
4282 if No (Storage_Pool (N)) then
4283 Pool := Associated_Storage_Pool (Root_Type (PtrT));
4284
4285 if Present (Pool) then
4286 Set_Storage_Pool (N, Pool);
4287
4288 if Is_RTE (Pool, RE_SS_Pool) then
4289 if VM_Target = No_VM then
4290 Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));
4291 end if;
4292
4293 -- In the case of an allocator for a simple storage pool, locate
4294 -- and save a reference to the pool type's Allocate routine.
4295
4296 elsif Present (Get_Rep_Pragma
4297 (Etype (Pool), Name_Simple_Storage_Pool_Type))
4298 then
4299 declare
4300 Pool_Type : constant Entity_Id := Base_Type (Etype (Pool));
4301 Alloc_Op : Entity_Id;
4302 begin
4303 Alloc_Op := Get_Name_Entity_Id (Name_Allocate);
4304 while Present (Alloc_Op) loop
4305 if Scope (Alloc_Op) = Scope (Pool_Type)
4306 and then Present (First_Formal (Alloc_Op))
4307 and then Etype (First_Formal (Alloc_Op)) = Pool_Type
4308 then
4309 Set_Procedure_To_Call (N, Alloc_Op);
4310 exit;
4311 else
4312 Alloc_Op := Homonym (Alloc_Op);
4313 end if;
4314 end loop;
4315 end;
4316
4317 elsif Is_Class_Wide_Type (Etype (Pool)) then
4318 Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));
4319
4320 else
4321 Set_Procedure_To_Call (N,
4322 Find_Prim_Op (Etype (Pool), Name_Allocate));
4323 end if;
4324 end if;
4325 end if;
4326
4327 -- Under certain circumstances we can replace an allocator by an access
4328 -- to statically allocated storage. The conditions, as noted in AARM
4329 -- 3.10 (10c) are as follows:
4330
4331 -- Size and initial value is known at compile time
4332 -- Access type is access-to-constant
4333
4334 -- The allocator is not part of a constraint on a record component,
4335 -- because in that case the inserted actions are delayed until the
4336 -- record declaration is fully analyzed, which is too late for the
4337 -- analysis of the rewritten allocator.
4338
4339 if Is_Access_Constant (PtrT)
4340 and then Nkind (Expression (N)) = N_Qualified_Expression
4341 and then Compile_Time_Known_Value (Expression (Expression (N)))
4342 and then Size_Known_At_Compile_Time
4343 (Etype (Expression (Expression (N))))
4344 and then not Is_Record_Type (Current_Scope)
4345 then
4346 -- Here we can do the optimization. For the allocator
4347
4348 -- new x'(y)
4349
4350 -- We insert an object declaration
4351
4352 -- Tnn : aliased x := y;
4353
4354 -- and replace the allocator by Tnn'Unrestricted_Access. Tnn is
4355 -- marked as requiring static allocation.
4356
4357 Temp := Make_Temporary (Loc, 'T', Expression (Expression (N)));
4358 Desig := Subtype_Mark (Expression (N));
4359
4360 -- If context is constrained, use constrained subtype directly,
4361 -- so that the constant is not labelled as having a nominally
4362 -- unconstrained subtype.
4363
4364 if Entity (Desig) = Base_Type (Dtyp) then
4365 Desig := New_Occurrence_Of (Dtyp, Loc);
4366 end if;
4367
4368 Insert_Action (N,
4369 Make_Object_Declaration (Loc,
4370 Defining_Identifier => Temp,
4371 Aliased_Present => True,
4372 Constant_Present => Is_Access_Constant (PtrT),
4373 Object_Definition => Desig,
4374 Expression => Expression (Expression (N))));
4375
4376 Rewrite (N,
4377 Make_Attribute_Reference (Loc,
4378 Prefix => New_Occurrence_Of (Temp, Loc),
4379 Attribute_Name => Name_Unrestricted_Access));
4380
4381 Analyze_And_Resolve (N, PtrT);
4382
4383 -- We set the variable as statically allocated, since we don't want
4384 -- it going on the stack of the current procedure!
4385
4386 Set_Is_Statically_Allocated (Temp);
4387 return;
4388 end if;
4389
4390 -- Same if the allocator is an access discriminant for a local object:
4391 -- instead of an allocator we create a local value and constrain the
4392 -- enclosing object with the corresponding access attribute.
4393
4394 if Is_Static_Coextension (N) then
4395 Rewrite_Coextension (N);
4396 return;
4397 end if;
4398
4399 -- Check for size too large, we do this because the back end misses
4400 -- proper checks here and can generate rubbish allocation calls when
4401 -- we are near the limit. We only do this for the 32-bit address case
4402 -- since that is from a practical point of view where we see a problem.
4403
4404 if System_Address_Size = 32
4405 and then not Storage_Checks_Suppressed (PtrT)
4406 and then not Storage_Checks_Suppressed (Dtyp)
4407 and then not Storage_Checks_Suppressed (Etyp)
4408 then
4409 -- The check we want to generate should look like
4410
4411 -- if Etyp'Max_Size_In_Storage_Elements > 3.5 gigabytes then
4412 -- raise Storage_Error;
4413 -- end if;
4414
4415 -- where 3.5 gigabytes is a constant large enough to accommodate any
4416 -- reasonable request for. But we can't do it this way because at
4417 -- least at the moment we don't compute this attribute right, and
4418 -- can silently give wrong results when the result gets large. Since
4419 -- this is all about large results, that's bad, so instead we only
4420 -- apply the check for constrained arrays, and manually compute the
4421 -- value of the attribute ???
4422
4423 if Is_Array_Type (Etyp) and then Is_Constrained (Etyp) then
4424 Insert_Action (N,
4425 Make_Raise_Storage_Error (Loc,
4426 Condition =>
4427 Make_Op_Gt (Loc,
4428 Left_Opnd => Size_In_Storage_Elements (Etyp),
4429 Right_Opnd =>
4430 Make_Integer_Literal (Loc, Uint_7 * (Uint_2 ** 29))),
4431 Reason => SE_Object_Too_Large));
4432 end if;
4433 end if;
4434
4435 -- Handle case of qualified expression (other than optimization above)
4436 -- First apply constraint checks, because the bounds or discriminants
4437 -- in the aggregate might not match the subtype mark in the allocator.
4438
4439 if Nkind (Expression (N)) = N_Qualified_Expression then
4440 Apply_Constraint_Check
4441 (Expression (Expression (N)), Etype (Expression (N)));
4442
4443 Expand_Allocator_Expression (N);
4444 return;
4445 end if;
4446
4447 -- If the allocator is for a type which requires initialization, and
4448 -- there is no initial value (i.e. operand is a subtype indication
4449 -- rather than a qualified expression), then we must generate a call to
4450 -- the initialization routine using an expressions action node:
4451
4452 -- [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
4453
4454 -- Here ptr_T is the pointer type for the allocator, and T is the
4455 -- subtype of the allocator. A special case arises if the designated
4456 -- type of the access type is a task or contains tasks. In this case
4457 -- the call to Init (Temp.all ...) is replaced by code that ensures
4458 -- that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
4459 -- for details). In addition, if the type T is a task T, then the
4460 -- first argument to Init must be converted to the task record type.
4461
4462 declare
4463 T : constant Entity_Id := Entity (Expression (N));
4464 Args : List_Id;
4465 Decls : List_Id;
4466 Decl : Node_Id;
4467 Discr : Elmt_Id;
4468 Init : Entity_Id;
4469 Init_Arg1 : Node_Id;
4470 Temp_Decl : Node_Id;
4471 Temp_Type : Entity_Id;
4472
4473 begin
4474 if No_Initialization (N) then
4475
4476 -- Even though this might be a simple allocation, create a custom
4477 -- Allocate if the context requires it. Since .NET/JVM compilers
4478 -- do not support pools, this step is skipped.
4479
4480 if VM_Target = No_VM
4481 and then Present (Finalization_Master (PtrT))
4482 then
4483 Build_Allocate_Deallocate_Proc
4484 (N => N,
4485 Is_Allocate => True);
4486 end if;
4487
4488 -- Case of no initialization procedure present
4489
4490 elsif not Has_Non_Null_Base_Init_Proc (T) then
4491
4492 -- Case of simple initialization required
4493
4494 if Needs_Simple_Initialization (T) then
4495 Check_Restriction (No_Default_Initialization, N);
4496 Rewrite (Expression (N),
4497 Make_Qualified_Expression (Loc,
4498 Subtype_Mark => New_Occurrence_Of (T, Loc),
4499 Expression => Get_Simple_Init_Val (T, N)));
4500
4501 Analyze_And_Resolve (Expression (Expression (N)), T);
4502 Analyze_And_Resolve (Expression (N), T);
4503 Set_Paren_Count (Expression (Expression (N)), 1);
4504 Expand_N_Allocator (N);
4505
4506 -- No initialization required
4507
4508 else
4509 null;
4510 end if;
4511
4512 -- Case of initialization procedure present, must be called
4513
4514 else
4515 Check_Restriction (No_Default_Initialization, N);
4516
4517 if not Restriction_Active (No_Default_Initialization) then
4518 Init := Base_Init_Proc (T);
4519 Nod := N;
4520 Temp := Make_Temporary (Loc, 'P');
4521
4522 -- Construct argument list for the initialization routine call
4523
4524 Init_Arg1 :=
4525 Make_Explicit_Dereference (Loc,
4526 Prefix =>
4527 New_Reference_To (Temp, Loc));
4528
4529 Set_Assignment_OK (Init_Arg1);
4530 Temp_Type := PtrT;
4531
4532 -- The initialization procedure expects a specific type. if the
4533 -- context is access to class wide, indicate that the object
4534 -- being allocated has the right specific type.
4535
4536 if Is_Class_Wide_Type (Dtyp) then
4537 Init_Arg1 := Unchecked_Convert_To (T, Init_Arg1);
4538 end if;
4539
4540 -- If designated type is a concurrent type or if it is private
4541 -- type whose definition is a concurrent type, the first
4542 -- argument in the Init routine has to be unchecked conversion
4543 -- to the corresponding record type. If the designated type is
4544 -- a derived type, also convert the argument to its root type.
4545
4546 if Is_Concurrent_Type (T) then
4547 Init_Arg1 :=
4548 Unchecked_Convert_To (
4549 Corresponding_Record_Type (T), Init_Arg1);
4550
4551 elsif Is_Private_Type (T)
4552 and then Present (Full_View (T))
4553 and then Is_Concurrent_Type (Full_View (T))
4554 then
4555 Init_Arg1 :=
4556 Unchecked_Convert_To
4557 (Corresponding_Record_Type (Full_View (T)), Init_Arg1);
4558
4559 elsif Etype (First_Formal (Init)) /= Base_Type (T) then
4560 declare
4561 Ftyp : constant Entity_Id := Etype (First_Formal (Init));
4562
4563 begin
4564 Init_Arg1 := OK_Convert_To (Etype (Ftyp), Init_Arg1);
4565 Set_Etype (Init_Arg1, Ftyp);
4566 end;
4567 end if;
4568
4569 Args := New_List (Init_Arg1);
4570
4571 -- For the task case, pass the Master_Id of the access type as
4572 -- the value of the _Master parameter, and _Chain as the value
4573 -- of the _Chain parameter (_Chain will be defined as part of
4574 -- the generated code for the allocator).
4575
4576 -- In Ada 2005, the context may be a function that returns an
4577 -- anonymous access type. In that case the Master_Id has been
4578 -- created when expanding the function declaration.
4579
4580 if Has_Task (T) then
4581 if No (Master_Id (Base_Type (PtrT))) then
4582
4583 -- The designated type was an incomplete type, and the
4584 -- access type did not get expanded. Salvage it now.
4585
4586 if not Restriction_Active (No_Task_Hierarchy) then
4587 pragma Assert (Present (Parent (Base_Type (PtrT))));
4588 Expand_N_Full_Type_Declaration
4589 (Parent (Base_Type (PtrT)));
4590 end if;
4591 end if;
4592
4593 -- If the context of the allocator is a declaration or an
4594 -- assignment, we can generate a meaningful image for it,
4595 -- even though subsequent assignments might remove the
4596 -- connection between task and entity. We build this image
4597 -- when the left-hand side is a simple variable, a simple
4598 -- indexed assignment or a simple selected component.
4599
4600 if Nkind (Parent (N)) = N_Assignment_Statement then
4601 declare
4602 Nam : constant Node_Id := Name (Parent (N));
4603
4604 begin
4605 if Is_Entity_Name (Nam) then
4606 Decls :=
4607 Build_Task_Image_Decls
4608 (Loc,
4609 New_Occurrence_Of
4610 (Entity (Nam), Sloc (Nam)), T);
4611
4612 elsif Nkind_In (Nam, N_Indexed_Component,
4613 N_Selected_Component)
4614 and then Is_Entity_Name (Prefix (Nam))
4615 then
4616 Decls :=
4617 Build_Task_Image_Decls
4618 (Loc, Nam, Etype (Prefix (Nam)));
4619 else
4620 Decls := Build_Task_Image_Decls (Loc, T, T);
4621 end if;
4622 end;
4623
4624 elsif Nkind (Parent (N)) = N_Object_Declaration then
4625 Decls :=
4626 Build_Task_Image_Decls
4627 (Loc, Defining_Identifier (Parent (N)), T);
4628
4629 else
4630 Decls := Build_Task_Image_Decls (Loc, T, T);
4631 end if;
4632
4633 if Restriction_Active (No_Task_Hierarchy) then
4634 Append_To (Args,
4635 New_Occurrence_Of (RTE (RE_Library_Task_Level), Loc));
4636 else
4637 Append_To (Args,
4638 New_Reference_To
4639 (Master_Id (Base_Type (Root_Type (PtrT))), Loc));
4640 end if;
4641
4642 Append_To (Args, Make_Identifier (Loc, Name_uChain));
4643
4644 Decl := Last (Decls);
4645 Append_To (Args,
4646 New_Occurrence_Of (Defining_Identifier (Decl), Loc));
4647
4648 -- Has_Task is false, Decls not used
4649
4650 else
4651 Decls := No_List;
4652 end if;
4653
4654 -- Add discriminants if discriminated type
4655
4656 declare
4657 Dis : Boolean := False;
4658 Typ : Entity_Id;
4659
4660 begin
4661 if Has_Discriminants (T) then
4662 Dis := True;
4663 Typ := T;
4664
4665 elsif Is_Private_Type (T)
4666 and then Present (Full_View (T))
4667 and then Has_Discriminants (Full_View (T))
4668 then
4669 Dis := True;
4670 Typ := Full_View (T);
4671 end if;
4672
4673 if Dis then
4674
4675 -- If the allocated object will be constrained by the
4676 -- default values for discriminants, then build a subtype
4677 -- with those defaults, and change the allocated subtype
4678 -- to that. Note that this happens in fewer cases in Ada
4679 -- 2005 (AI-363).
4680
4681 if not Is_Constrained (Typ)
4682 and then Present (Discriminant_Default_Value
4683 (First_Discriminant (Typ)))
4684 and then (Ada_Version < Ada_2005
4685 or else not
4686 Effectively_Has_Constrained_Partial_View
4687 (Typ => Typ,
4688 Scop => Current_Scope))
4689 then
4690 Typ := Build_Default_Subtype (Typ, N);
4691 Set_Expression (N, New_Reference_To (Typ, Loc));
4692 end if;
4693
4694 Discr := First_Elmt (Discriminant_Constraint (Typ));
4695 while Present (Discr) loop
4696 Nod := Node (Discr);
4697 Append (New_Copy_Tree (Node (Discr)), Args);
4698
4699 -- AI-416: when the discriminant constraint is an
4700 -- anonymous access type make sure an accessibility
4701 -- check is inserted if necessary (3.10.2(22.q/2))
4702
4703 if Ada_Version >= Ada_2005
4704 and then
4705 Ekind (Etype (Nod)) = E_Anonymous_Access_Type
4706 then
4707 Apply_Accessibility_Check
4708 (Nod, Typ, Insert_Node => Nod);
4709 end if;
4710
4711 Next_Elmt (Discr);
4712 end loop;
4713 end if;
4714 end;
4715
4716 -- We set the allocator as analyzed so that when we analyze
4717 -- the if expression node, we do not get an unwanted recursive
4718 -- expansion of the allocator expression.
4719
4720 Set_Analyzed (N, True);
4721 Nod := Relocate_Node (N);
4722
4723 -- Here is the transformation:
4724 -- input: new Ctrl_Typ
4725 -- output: Temp : constant Ctrl_Typ_Ptr := new Ctrl_Typ;
4726 -- Ctrl_TypIP (Temp.all, ...);
4727 -- [Deep_]Initialize (Temp.all);
4728
4729 -- Here Ctrl_Typ_Ptr is the pointer type for the allocator, and
4730 -- is the subtype of the allocator.
4731
4732 Temp_Decl :=
4733 Make_Object_Declaration (Loc,
4734 Defining_Identifier => Temp,
4735 Constant_Present => True,
4736 Object_Definition => New_Reference_To (Temp_Type, Loc),
4737 Expression => Nod);
4738
4739 Set_Assignment_OK (Temp_Decl);
4740 Insert_Action (N, Temp_Decl, Suppress => All_Checks);
4741
4742 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
4743
4744 -- If the designated type is a task type or contains tasks,
4745 -- create block to activate created tasks, and insert
4746 -- declaration for Task_Image variable ahead of call.
4747
4748 if Has_Task (T) then
4749 declare
4750 L : constant List_Id := New_List;
4751 Blk : Node_Id;
4752 begin
4753 Build_Task_Allocate_Block (L, Nod, Args);
4754 Blk := Last (L);
4755 Insert_List_Before (First (Declarations (Blk)), Decls);
4756 Insert_Actions (N, L);
4757 end;
4758
4759 else
4760 Insert_Action (N,
4761 Make_Procedure_Call_Statement (Loc,
4762 Name => New_Reference_To (Init, Loc),
4763 Parameter_Associations => Args));
4764 end if;
4765
4766 if Needs_Finalization (T) then
4767
4768 -- Generate:
4769 -- [Deep_]Initialize (Init_Arg1);
4770
4771 Insert_Action (N,
4772 Make_Init_Call
4773 (Obj_Ref => New_Copy_Tree (Init_Arg1),
4774 Typ => T));
4775
4776 if Present (Finalization_Master (PtrT)) then
4777
4778 -- Special processing for .NET/JVM, the allocated object
4779 -- is attached to the finalization master. Generate:
4780
4781 -- Attach (<PtrT>FM, Root_Controlled_Ptr (Init_Arg1));
4782
4783 -- Types derived from [Limited_]Controlled are the only
4784 -- ones considered since they have fields Prev and Next.
4785
4786 if VM_Target /= No_VM then
4787 if Is_Controlled (T) then
4788 Insert_Action (N,
4789 Make_Attach_Call
4790 (Obj_Ref => New_Copy_Tree (Init_Arg1),
4791 Ptr_Typ => PtrT));
4792 end if;
4793
4794 -- Default case, generate:
4795
4796 -- Set_Finalize_Address
4797 -- (<PtrT>FM, <T>FD'Unrestricted_Access);
4798
4799 -- Do not generate this call in the following cases:
4800 --
4801 -- * Alfa mode - the call is useless and results in
4802 -- unwanted expansion.
4803 --
4804 -- * CodePeer mode - TSS primitive Finalize_Address is
4805 -- not created in this mode.
4806
4807 elsif not Alfa_Mode
4808 and then not CodePeer_Mode
4809 then
4810 Insert_Action (N,
4811 Make_Set_Finalize_Address_Call
4812 (Loc => Loc,
4813 Typ => T,
4814 Ptr_Typ => PtrT));
4815 end if;
4816 end if;
4817 end if;
4818
4819 Rewrite (N, New_Reference_To (Temp, Loc));
4820 Analyze_And_Resolve (N, PtrT);
4821 end if;
4822 end if;
4823 end;
4824
4825 -- Ada 2005 (AI-251): If the allocator is for a class-wide interface
4826 -- object that has been rewritten as a reference, we displace "this"
4827 -- to reference properly its secondary dispatch table.
4828
4829 if Nkind (N) = N_Identifier
4830 and then Is_Interface (Dtyp)
4831 then
4832 Displace_Allocator_Pointer (N);
4833 end if;
4834
4835 exception
4836 when RE_Not_Available =>
4837 return;
4838 end Expand_N_Allocator;
4839
4840 -----------------------
4841 -- Expand_N_And_Then --
4842 -----------------------
4843
4844 procedure Expand_N_And_Then (N : Node_Id)
4845 renames Expand_Short_Circuit_Operator;
4846
4847 ------------------------------
4848 -- Expand_N_Case_Expression --
4849 ------------------------------
4850
4851 procedure Expand_N_Case_Expression (N : Node_Id) is
4852 Loc : constant Source_Ptr := Sloc (N);
4853 Typ : constant Entity_Id := Etype (N);
4854 Cstmt : Node_Id;
4855 Tnn : Entity_Id;
4856 Pnn : Entity_Id;
4857 Actions : List_Id;
4858 Ttyp : Entity_Id;
4859 Alt : Node_Id;
4860 Fexp : Node_Id;
4861
4862 begin
4863 -- Check for MINIMIZED/ELIMINATED overflow mode
4864
4865 if Minimized_Eliminated_Overflow_Check (N) then
4866 Apply_Arithmetic_Overflow_Check (N);
4867 return;
4868 end if;
4869
4870 -- We expand
4871
4872 -- case X is when A => AX, when B => BX ...
4873
4874 -- to
4875
4876 -- do
4877 -- Tnn : typ;
4878 -- case X is
4879 -- when A =>
4880 -- Tnn := AX;
4881 -- when B =>
4882 -- Tnn := BX;
4883 -- ...
4884 -- end case;
4885 -- in Tnn end;
4886
4887 -- However, this expansion is wrong for limited types, and also
4888 -- wrong for unconstrained types (since the bounds may not be the
4889 -- same in all branches). Furthermore it involves an extra copy
4890 -- for large objects. So we take care of this by using the following
4891 -- modified expansion for non-elementary types:
4892
4893 -- do
4894 -- type Pnn is access all typ;
4895 -- Tnn : Pnn;
4896 -- case X is
4897 -- when A =>
4898 -- T := AX'Unrestricted_Access;
4899 -- when B =>
4900 -- T := BX'Unrestricted_Access;
4901 -- ...
4902 -- end case;
4903 -- in Tnn.all end;
4904
4905 Cstmt :=
4906 Make_Case_Statement (Loc,
4907 Expression => Expression (N),
4908 Alternatives => New_List);
4909
4910 Actions := New_List;
4911
4912 -- Scalar case
4913
4914 if Is_Elementary_Type (Typ) then
4915 Ttyp := Typ;
4916
4917 else
4918 Pnn := Make_Temporary (Loc, 'P');
4919 Append_To (Actions,
4920 Make_Full_Type_Declaration (Loc,
4921 Defining_Identifier => Pnn,
4922 Type_Definition =>
4923 Make_Access_To_Object_Definition (Loc,
4924 All_Present => True,
4925 Subtype_Indication =>
4926 New_Reference_To (Typ, Loc))));
4927 Ttyp := Pnn;
4928 end if;
4929
4930 Tnn := Make_Temporary (Loc, 'T');
4931 Append_To (Actions,
4932 Make_Object_Declaration (Loc,
4933 Defining_Identifier => Tnn,
4934 Object_Definition => New_Occurrence_Of (Ttyp, Loc)));
4935
4936 -- Now process the alternatives
4937
4938 Alt := First (Alternatives (N));
4939 while Present (Alt) loop
4940 declare
4941 Aexp : Node_Id := Expression (Alt);
4942 Aloc : constant Source_Ptr := Sloc (Aexp);
4943 Stats : List_Id;
4944
4945 begin
4946 -- As described above, take Unrestricted_Access for case of non-
4947 -- scalar types, to avoid big copies, and special cases.
4948
4949 if not Is_Elementary_Type (Typ) then
4950 Aexp :=
4951 Make_Attribute_Reference (Aloc,
4952 Prefix => Relocate_Node (Aexp),
4953 Attribute_Name => Name_Unrestricted_Access);
4954 end if;
4955
4956 Stats := New_List (
4957 Make_Assignment_Statement (Aloc,
4958 Name => New_Occurrence_Of (Tnn, Loc),
4959 Expression => Aexp));
4960
4961 -- Propagate declarations inserted in the node by Insert_Actions
4962 -- (for example, temporaries generated to remove side effects).
4963 -- These actions must remain attached to the alternative, given
4964 -- that they are generated by the corresponding expression.
4965
4966 if Present (Sinfo.Actions (Alt)) then
4967 Prepend_List (Sinfo.Actions (Alt), Stats);
4968 end if;
4969
4970 Append_To
4971 (Alternatives (Cstmt),
4972 Make_Case_Statement_Alternative (Sloc (Alt),
4973 Discrete_Choices => Discrete_Choices (Alt),
4974 Statements => Stats));
4975 end;
4976
4977 Next (Alt);
4978 end loop;
4979
4980 Append_To (Actions, Cstmt);
4981
4982 -- Construct and return final expression with actions
4983
4984 if Is_Elementary_Type (Typ) then
4985 Fexp := New_Occurrence_Of (Tnn, Loc);
4986 else
4987 Fexp :=
4988 Make_Explicit_Dereference (Loc,
4989 Prefix => New_Occurrence_Of (Tnn, Loc));
4990 end if;
4991
4992 Rewrite (N,
4993 Make_Expression_With_Actions (Loc,
4994 Expression => Fexp,
4995 Actions => Actions));
4996
4997 Analyze_And_Resolve (N, Typ);
4998 end Expand_N_Case_Expression;
4999
5000 -----------------------------------
5001 -- Expand_N_Explicit_Dereference --
5002 -----------------------------------
5003
5004 procedure Expand_N_Explicit_Dereference (N : Node_Id) is
5005 begin
5006 -- Insert explicit dereference call for the checked storage pool case
5007
5008 Insert_Dereference_Action (Prefix (N));
5009
5010 -- If the type is an Atomic type for which Atomic_Sync is enabled, then
5011 -- we set the atomic sync flag.
5012
5013 if Is_Atomic (Etype (N))
5014 and then not Atomic_Synchronization_Disabled (Etype (N))
5015 then
5016 Activate_Atomic_Synchronization (N);
5017 end if;
5018 end Expand_N_Explicit_Dereference;
5019
5020 --------------------------------------
5021 -- Expand_N_Expression_With_Actions --
5022 --------------------------------------
5023
5024 procedure Expand_N_Expression_With_Actions (N : Node_Id) is
5025
5026 procedure Process_Transient_Object (Decl : Node_Id);
5027 -- Given the declaration of a controlled transient declared inside the
5028 -- Actions list of an Expression_With_Actions, generate all necessary
5029 -- types and hooks in order to properly finalize the transient. This
5030 -- mechanism works in conjunction with Build_Finalizer.
5031
5032 ------------------------------
5033 -- Process_Transient_Object --
5034 ------------------------------
5035
5036 procedure Process_Transient_Object (Decl : Node_Id) is
5037
5038 function Find_Insertion_Node return Node_Id;
5039 -- Complex conditions in if statements may be converted into nested
5040 -- EWAs. In this case, any generated code must be inserted before the
5041 -- if statement to ensure proper visibility of the hook objects. This
5042 -- routine returns the top most short circuit operator or the parent
5043 -- of the EWA if no nesting was detected.
5044
5045 -------------------------
5046 -- Find_Insertion_Node --
5047 -------------------------
5048
5049 function Find_Insertion_Node return Node_Id is
5050 Par : Node_Id;
5051
5052 begin
5053 -- Climb up the branches of a complex condition
5054
5055 Par := N;
5056 while Nkind_In (Parent (Par), N_And_Then, N_Op_Not, N_Or_Else) loop
5057 Par := Parent (Par);
5058 end loop;
5059
5060 return Par;
5061 end Find_Insertion_Node;
5062
5063 -- Local variables
5064
5065 Ins_Node : constant Node_Id := Find_Insertion_Node;
5066 Loc : constant Source_Ptr := Sloc (Decl);
5067 Obj_Id : constant Entity_Id := Defining_Identifier (Decl);
5068 Obj_Typ : constant Entity_Id := Etype (Obj_Id);
5069 Desig_Typ : Entity_Id;
5070 Expr : Node_Id;
5071 Ptr_Decl : Node_Id;
5072 Ptr_Id : Entity_Id;
5073 Temp_Decl : Node_Id;
5074 Temp_Id : Node_Id;
5075
5076 -- Start of processing for Process_Transient_Object
5077
5078 begin
5079 -- Step 1: Create the access type which provides a reference to the
5080 -- transient object.
5081
5082 if Is_Access_Type (Obj_Typ) then
5083 Desig_Typ := Directly_Designated_Type (Obj_Typ);
5084 else
5085 Desig_Typ := Obj_Typ;
5086 end if;
5087
5088 -- Generate:
5089 -- Ann : access [all] <Desig_Typ>;
5090
5091 Ptr_Id := Make_Temporary (Loc, 'A');
5092
5093 Ptr_Decl :=
5094 Make_Full_Type_Declaration (Loc,
5095 Defining_Identifier => Ptr_Id,
5096 Type_Definition =>
5097 Make_Access_To_Object_Definition (Loc,
5098 All_Present =>
5099 Ekind (Obj_Typ) = E_General_Access_Type,
5100 Subtype_Indication => New_Reference_To (Desig_Typ, Loc)));
5101
5102 Insert_Action (Ins_Node, Ptr_Decl);
5103 Analyze (Ptr_Decl);
5104
5105 -- Step 2: Create a temporary which acts as a hook to the transient
5106 -- object. Generate:
5107
5108 -- Temp : Ptr_Id := null;
5109
5110 Temp_Id := Make_Temporary (Loc, 'T');
5111
5112 Temp_Decl :=
5113 Make_Object_Declaration (Loc,
5114 Defining_Identifier => Temp_Id,
5115 Object_Definition => New_Reference_To (Ptr_Id, Loc));
5116
5117 Insert_Action (Ins_Node, Temp_Decl);
5118 Analyze (Temp_Decl);
5119
5120 -- Mark this temporary as created for the purposes of exporting the
5121 -- transient declaration out of the Actions list. This signals the
5122 -- machinery in Build_Finalizer to recognize this special case.
5123
5124 Set_Status_Flag_Or_Transient_Decl (Temp_Id, Decl);
5125
5126 -- Step 3: Hook the transient object to the temporary
5127
5128 if Is_Access_Type (Obj_Typ) then
5129 Expr := Convert_To (Ptr_Id, New_Reference_To (Obj_Id, Loc));
5130 else
5131 Expr :=
5132 Make_Attribute_Reference (Loc,
5133 Prefix => New_Reference_To (Obj_Id, Loc),
5134 Attribute_Name => Name_Unrestricted_Access);
5135 end if;
5136
5137 -- Generate:
5138 -- Temp := Ptr_Id (Obj_Id);
5139 -- <or>
5140 -- Temp := Obj_Id'Unrestricted_Access;
5141
5142 Insert_After_And_Analyze (Decl,
5143 Make_Assignment_Statement (Loc,
5144 Name => New_Reference_To (Temp_Id, Loc),
5145 Expression => Expr));
5146 end Process_Transient_Object;
5147
5148 -- Local variables
5149
5150 Decl : Node_Id;
5151
5152 -- Start of processing for Expand_N_Expression_With_Actions
5153
5154 begin
5155 Decl := First (Actions (N));
5156 while Present (Decl) loop
5157 if Nkind (Decl) = N_Object_Declaration
5158 and then Is_Finalizable_Transient (Decl, N)
5159 then
5160 Process_Transient_Object (Decl);
5161 end if;
5162
5163 Next (Decl);
5164 end loop;
5165 end Expand_N_Expression_With_Actions;
5166
5167 ----------------------------
5168 -- Expand_N_If_Expression --
5169 ----------------------------
5170
5171 -- Deal with limited types and condition actions
5172
5173 procedure Expand_N_If_Expression (N : Node_Id) is
5174 function Create_Alternative
5175 (Loc : Source_Ptr;
5176 Temp_Id : Entity_Id;
5177 Flag_Id : Entity_Id;
5178 Expr : Node_Id) return List_Id;
5179 -- Build the statements of a "then" or "else" dependent expression
5180 -- alternative. Temp_Id is the if expression result, Flag_Id is a
5181 -- finalization flag created to service expression Expr.
5182
5183 function Is_Controlled_Function_Call (Expr : Node_Id) return Boolean;
5184 -- Determine if expression Expr is a rewritten controlled function call
5185
5186 ------------------------
5187 -- Create_Alternative --
5188 ------------------------
5189
5190 function Create_Alternative
5191 (Loc : Source_Ptr;
5192 Temp_Id : Entity_Id;
5193 Flag_Id : Entity_Id;
5194 Expr : Node_Id) return List_Id
5195 is
5196 Result : constant List_Id := New_List;
5197
5198 begin
5199 -- Generate:
5200 -- Fnn := True;
5201
5202 if Present (Flag_Id)
5203 and then not Is_Controlled_Function_Call (Expr)
5204 then
5205 Append_To (Result,
5206 Make_Assignment_Statement (Loc,
5207 Name => New_Reference_To (Flag_Id, Loc),
5208 Expression => New_Reference_To (Standard_True, Loc)));
5209 end if;
5210
5211 -- Generate:
5212 -- Cnn := <expr>'Unrestricted_Access;
5213
5214 Append_To (Result,
5215 Make_Assignment_Statement (Loc,
5216 Name => New_Reference_To (Temp_Id, Loc),
5217 Expression =>
5218 Make_Attribute_Reference (Loc,
5219 Prefix => Relocate_Node (Expr),
5220 Attribute_Name => Name_Unrestricted_Access)));
5221
5222 return Result;
5223 end Create_Alternative;
5224
5225 ---------------------------------
5226 -- Is_Controlled_Function_Call --
5227 ---------------------------------
5228
5229 function Is_Controlled_Function_Call (Expr : Node_Id) return Boolean is
5230 begin
5231 return
5232 Nkind (Original_Node (Expr)) = N_Function_Call
5233 and then Needs_Finalization (Etype (Expr));
5234 end Is_Controlled_Function_Call;
5235
5236 -- Local variables
5237
5238 Loc : constant Source_Ptr := Sloc (N);
5239 Cond : constant Node_Id := First (Expressions (N));
5240 Thenx : constant Node_Id := Next (Cond);
5241 Elsex : constant Node_Id := Next (Thenx);
5242 Typ : constant Entity_Id := Etype (N);
5243
5244 Actions : List_Id;
5245 Cnn : Entity_Id;
5246 Decl : Node_Id;
5247 Expr : Node_Id;
5248 New_If : Node_Id;
5249 New_N : Node_Id;
5250
5251 begin
5252 -- Check for MINIMIZED/ELIMINATED overflow mode
5253
5254 if Minimized_Eliminated_Overflow_Check (N) then
5255 Apply_Arithmetic_Overflow_Check (N);
5256 return;
5257 end if;
5258
5259 -- Fold at compile time if condition known. We have already folded
5260 -- static if expressions, but it is possible to fold any case in which
5261 -- the condition is known at compile time, even though the result is
5262 -- non-static.
5263
5264 -- Note that we don't do the fold of such cases in Sem_Elab because
5265 -- it can cause infinite loops with the expander adding a conditional
5266 -- expression, and Sem_Elab circuitry removing it repeatedly.
5267
5268 if Compile_Time_Known_Value (Cond) then
5269 if Is_True (Expr_Value (Cond)) then
5270 Expr := Thenx;
5271 Actions := Then_Actions (N);
5272 else
5273 Expr := Elsex;
5274 Actions := Else_Actions (N);
5275 end if;
5276
5277 Remove (Expr);
5278
5279 if Present (Actions) then
5280
5281 -- If we are not allowed to use Expression_With_Actions, just skip
5282 -- the optimization, it is not critical for correctness.
5283
5284 if not Use_Expression_With_Actions then
5285 goto Skip_Optimization;
5286 end if;
5287
5288 Rewrite (N,
5289 Make_Expression_With_Actions (Loc,
5290 Expression => Relocate_Node (Expr),
5291 Actions => Actions));
5292 Analyze_And_Resolve (N, Typ);
5293
5294 else
5295 Rewrite (N, Relocate_Node (Expr));
5296 end if;
5297
5298 -- Note that the result is never static (legitimate cases of static
5299 -- if expressions were folded in Sem_Eval).
5300
5301 Set_Is_Static_Expression (N, False);
5302 return;
5303 end if;
5304
5305 <<Skip_Optimization>>
5306
5307 -- If the type is limited or unconstrained, we expand as follows to
5308 -- avoid any possibility of improper copies.
5309
5310 -- Note: it may be possible to avoid this special processing if the
5311 -- back end uses its own mechanisms for handling by-reference types ???
5312
5313 -- type Ptr is access all Typ;
5314 -- Cnn : Ptr;
5315 -- if cond then
5316 -- <<then actions>>
5317 -- Cnn := then-expr'Unrestricted_Access;
5318 -- else
5319 -- <<else actions>>
5320 -- Cnn := else-expr'Unrestricted_Access;
5321 -- end if;
5322
5323 -- and replace the if expression by a reference to Cnn.all.
5324
5325 -- This special case can be skipped if the back end handles limited
5326 -- types properly and ensures that no incorrect copies are made.
5327
5328 if Is_By_Reference_Type (Typ)
5329 and then not Back_End_Handles_Limited_Types
5330 then
5331 declare
5332 Flag_Id : Entity_Id;
5333 Ptr_Typ : Entity_Id;
5334
5335 begin
5336 Flag_Id := Empty;
5337
5338 -- At least one of the if expression dependent expressions uses a
5339 -- controlled function to provide the result. Create a status flag
5340 -- to signal the finalization machinery that Cnn needs special
5341 -- handling.
5342
5343 if Is_Controlled_Function_Call (Thenx)
5344 or else
5345 Is_Controlled_Function_Call (Elsex)
5346 then
5347 Flag_Id := Make_Temporary (Loc, 'F');
5348
5349 Insert_Action (N,
5350 Make_Object_Declaration (Loc,
5351 Defining_Identifier => Flag_Id,
5352 Object_Definition =>
5353 New_Reference_To (Standard_Boolean, Loc),
5354 Expression =>
5355 New_Reference_To (Standard_False, Loc)));
5356 end if;
5357
5358 -- Generate:
5359 -- type Ann is access all Typ;
5360
5361 Ptr_Typ := Make_Temporary (Loc, 'A');
5362
5363 Insert_Action (N,
5364 Make_Full_Type_Declaration (Loc,
5365 Defining_Identifier => Ptr_Typ,
5366 Type_Definition =>
5367 Make_Access_To_Object_Definition (Loc,
5368 All_Present => True,
5369 Subtype_Indication => New_Reference_To (Typ, Loc))));
5370
5371 -- Generate:
5372 -- Cnn : Ann;
5373
5374 Cnn := Make_Temporary (Loc, 'C', N);
5375 Set_Ekind (Cnn, E_Variable);
5376 Set_Status_Flag_Or_Transient_Decl (Cnn, Flag_Id);
5377
5378 Decl :=
5379 Make_Object_Declaration (Loc,
5380 Defining_Identifier => Cnn,
5381 Object_Definition => New_Occurrence_Of (Ptr_Typ, Loc));
5382
5383 New_If :=
5384 Make_Implicit_If_Statement (N,
5385 Condition => Relocate_Node (Cond),
5386 Then_Statements =>
5387 Create_Alternative (Sloc (Thenx), Cnn, Flag_Id, Thenx),
5388 Else_Statements =>
5389 Create_Alternative (Sloc (Elsex), Cnn, Flag_Id, Elsex));
5390
5391 New_N :=
5392 Make_Explicit_Dereference (Loc,
5393 Prefix => New_Occurrence_Of (Cnn, Loc));
5394 end;
5395
5396 -- For other types, we only need to expand if there are other actions
5397 -- associated with either branch.
5398
5399 elsif Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
5400
5401 -- We have two approaches to handling this. If we are allowed to use
5402 -- N_Expression_With_Actions, then we can just wrap the actions into
5403 -- the appropriate expression.
5404
5405 if Use_Expression_With_Actions then
5406 if Present (Then_Actions (N)) then
5407 Rewrite (Thenx,
5408 Make_Expression_With_Actions (Sloc (Thenx),
5409 Actions => Then_Actions (N),
5410 Expression => Relocate_Node (Thenx)));
5411 Set_Then_Actions (N, No_List);
5412 Analyze_And_Resolve (Thenx, Typ);
5413 end if;
5414
5415 if Present (Else_Actions (N)) then
5416 Rewrite (Elsex,
5417 Make_Expression_With_Actions (Sloc (Elsex),
5418 Actions => Else_Actions (N),
5419 Expression => Relocate_Node (Elsex)));
5420 Set_Else_Actions (N, No_List);
5421 Analyze_And_Resolve (Elsex, Typ);
5422 end if;
5423
5424 return;
5425
5426 -- if we can't use N_Expression_With_Actions nodes, then we insert
5427 -- the following sequence of actions (using Insert_Actions):
5428
5429 -- Cnn : typ;
5430 -- if cond then
5431 -- <<then actions>>
5432 -- Cnn := then-expr;
5433 -- else
5434 -- <<else actions>>
5435 -- Cnn := else-expr
5436 -- end if;
5437
5438 -- and replace the if expression by a reference to Cnn
5439
5440 else
5441 Cnn := Make_Temporary (Loc, 'C', N);
5442
5443 Decl :=
5444 Make_Object_Declaration (Loc,
5445 Defining_Identifier => Cnn,
5446 Object_Definition => New_Occurrence_Of (Typ, Loc));
5447
5448 New_If :=
5449 Make_Implicit_If_Statement (N,
5450 Condition => Relocate_Node (Cond),
5451
5452 Then_Statements => New_List (
5453 Make_Assignment_Statement (Sloc (Thenx),
5454 Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
5455 Expression => Relocate_Node (Thenx))),
5456
5457 Else_Statements => New_List (
5458 Make_Assignment_Statement (Sloc (Elsex),
5459 Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
5460 Expression => Relocate_Node (Elsex))));
5461
5462 Set_Assignment_OK (Name (First (Then_Statements (New_If))));
5463 Set_Assignment_OK (Name (First (Else_Statements (New_If))));
5464
5465 New_N := New_Occurrence_Of (Cnn, Loc);
5466 end if;
5467
5468 -- If no actions then no expansion needed, gigi will handle it using
5469 -- the same approach as a C conditional expression.
5470
5471 else
5472 return;
5473 end if;
5474
5475 -- Fall through here for either the limited expansion, or the case of
5476 -- inserting actions for non-limited types. In both these cases, we must
5477 -- move the SLOC of the parent If statement to the newly created one and
5478 -- change it to the SLOC of the expression which, after expansion, will
5479 -- correspond to what is being evaluated.
5480
5481 if Present (Parent (N))
5482 and then Nkind (Parent (N)) = N_If_Statement
5483 then
5484 Set_Sloc (New_If, Sloc (Parent (N)));
5485 Set_Sloc (Parent (N), Loc);
5486 end if;
5487
5488 -- Make sure Then_Actions and Else_Actions are appropriately moved
5489 -- to the new if statement.
5490
5491 if Present (Then_Actions (N)) then
5492 Insert_List_Before
5493 (First (Then_Statements (New_If)), Then_Actions (N));
5494 end if;
5495
5496 if Present (Else_Actions (N)) then
5497 Insert_List_Before
5498 (First (Else_Statements (New_If)), Else_Actions (N));
5499 end if;
5500
5501 Insert_Action (N, Decl);
5502 Insert_Action (N, New_If);
5503 Rewrite (N, New_N);
5504 Analyze_And_Resolve (N, Typ);
5505 end Expand_N_If_Expression;
5506
5507 -----------------
5508 -- Expand_N_In --
5509 -----------------
5510
5511 procedure Expand_N_In (N : Node_Id) is
5512 Loc : constant Source_Ptr := Sloc (N);
5513 Restyp : constant Entity_Id := Etype (N);
5514 Lop : constant Node_Id := Left_Opnd (N);
5515 Rop : constant Node_Id := Right_Opnd (N);
5516 Static : constant Boolean := Is_OK_Static_Expression (N);
5517
5518 Ltyp : Entity_Id;
5519 Rtyp : Entity_Id;
5520
5521 procedure Substitute_Valid_Check;
5522 -- Replaces node N by Lop'Valid. This is done when we have an explicit
5523 -- test for the left operand being in range of its subtype.
5524
5525 ----------------------------
5526 -- Substitute_Valid_Check --
5527 ----------------------------
5528
5529 procedure Substitute_Valid_Check is
5530 begin
5531 Rewrite (N,
5532 Make_Attribute_Reference (Loc,
5533 Prefix => Relocate_Node (Lop),
5534 Attribute_Name => Name_Valid));
5535
5536 Analyze_And_Resolve (N, Restyp);
5537
5538 -- Give warning unless overflow checking is MINIMIZED or ELIMINATED,
5539 -- in which case, this usage makes sense, and in any case, we have
5540 -- actually eliminated the danger of optimization above.
5541
5542 if Overflow_Check_Mode (Restyp) not in Minimized_Or_Eliminated then
5543 Error_Msg_N ("?explicit membership test may be optimized away", N);
5544 Error_Msg_N -- CODEFIX
5545 ("\?use ''Valid attribute instead", N);
5546 end if;
5547
5548 return;
5549 end Substitute_Valid_Check;
5550
5551 -- Start of processing for Expand_N_In
5552
5553 begin
5554 -- If set membership case, expand with separate procedure
5555
5556 if Present (Alternatives (N)) then
5557 Expand_Set_Membership (N);
5558 return;
5559 end if;
5560
5561 -- Not set membership, proceed with expansion
5562
5563 Ltyp := Etype (Left_Opnd (N));
5564 Rtyp := Etype (Right_Opnd (N));
5565
5566 -- If Minimize/Eliminate overflow mode and type is a signed integer
5567 -- type, then expand with a separate procedure. Note the use of the
5568 -- flag No_Minimize_Eliminate to prevent infinite recursion.
5569
5570 if Overflow_Check_Mode (Empty) in Minimized_Or_Eliminated
5571 and then Is_Signed_Integer_Type (Ltyp)
5572 and then not No_Minimize_Eliminate (N)
5573 then
5574 Expand_Membership_Minimize_Eliminate_Overflow (N);
5575 return;
5576 end if;
5577
5578 -- Check case of explicit test for an expression in range of its
5579 -- subtype. This is suspicious usage and we replace it with a 'Valid
5580 -- test and give a warning for scalar types.
5581
5582 if Is_Scalar_Type (Ltyp)
5583
5584 -- Only relevant for source comparisons
5585
5586 and then Comes_From_Source (N)
5587
5588 -- In floating-point this is a standard way to check for finite values
5589 -- and using 'Valid would typically be a pessimization.
5590
5591 and then not Is_Floating_Point_Type (Ltyp)
5592
5593 -- Don't give the message unless right operand is a type entity and
5594 -- the type of the left operand matches this type. Note that this
5595 -- eliminates the cases where MINIMIZED/ELIMINATED mode overflow
5596 -- checks have changed the type of the left operand.
5597
5598 and then Nkind (Rop) in N_Has_Entity
5599 and then Ltyp = Entity (Rop)
5600
5601 -- Skip in VM mode, where we have no sense of invalid values. The
5602 -- warning still seems relevant, but not important enough to worry.
5603
5604 and then VM_Target = No_VM
5605
5606 -- Skip this for predicated types, where such expressions are a
5607 -- reasonable way of testing if something meets the predicate.
5608
5609 and then not (Is_Discrete_Type (Ltyp)
5610 and then Present (Predicate_Function (Ltyp)))
5611 then
5612 Substitute_Valid_Check;
5613 return;
5614 end if;
5615
5616 -- Do validity check on operands
5617
5618 if Validity_Checks_On and Validity_Check_Operands then
5619 Ensure_Valid (Left_Opnd (N));
5620 Validity_Check_Range (Right_Opnd (N));
5621 end if;
5622
5623 -- Case of explicit range
5624
5625 if Nkind (Rop) = N_Range then
5626 declare
5627 Lo : constant Node_Id := Low_Bound (Rop);
5628 Hi : constant Node_Id := High_Bound (Rop);
5629
5630 Lo_Orig : constant Node_Id := Original_Node (Lo);
5631 Hi_Orig : constant Node_Id := Original_Node (Hi);
5632
5633 Lcheck : Compare_Result;
5634 Ucheck : Compare_Result;
5635
5636 Warn1 : constant Boolean :=
5637 Constant_Condition_Warnings
5638 and then Comes_From_Source (N)
5639 and then not In_Instance;
5640 -- This must be true for any of the optimization warnings, we
5641 -- clearly want to give them only for source with the flag on. We
5642 -- also skip these warnings in an instance since it may be the
5643 -- case that different instantiations have different ranges.
5644
5645 Warn2 : constant Boolean :=
5646 Warn1
5647 and then Nkind (Original_Node (Rop)) = N_Range
5648 and then Is_Integer_Type (Etype (Lo));
5649 -- For the case where only one bound warning is elided, we also
5650 -- insist on an explicit range and an integer type. The reason is
5651 -- that the use of enumeration ranges including an end point is
5652 -- common, as is the use of a subtype name, one of whose bounds is
5653 -- the same as the type of the expression.
5654
5655 begin
5656 -- If test is explicit x'First .. x'Last, replace by valid check
5657
5658 -- Could use some individual comments for this complex test ???
5659
5660 if Is_Scalar_Type (Ltyp)
5661
5662 -- And left operand is X'First where X matches left operand
5663 -- type (this eliminates cases of type mismatch, including
5664 -- the cases where ELIMINATED/MINIMIZED mode has changed the
5665 -- type of the left operand.
5666
5667 and then Nkind (Lo_Orig) = N_Attribute_Reference
5668 and then Attribute_Name (Lo_Orig) = Name_First
5669 and then Nkind (Prefix (Lo_Orig)) in N_Has_Entity
5670 and then Entity (Prefix (Lo_Orig)) = Ltyp
5671
5672 -- Same tests for right operand
5673
5674 and then Nkind (Hi_Orig) = N_Attribute_Reference
5675 and then Attribute_Name (Hi_Orig) = Name_Last
5676 and then Nkind (Prefix (Hi_Orig)) in N_Has_Entity
5677 and then Entity (Prefix (Hi_Orig)) = Ltyp
5678
5679 -- Relevant only for source cases
5680
5681 and then Comes_From_Source (N)
5682
5683 -- Omit for VM cases, where we don't have invalid values
5684
5685 and then VM_Target = No_VM
5686 then
5687 Substitute_Valid_Check;
5688 goto Leave;
5689 end if;
5690
5691 -- If bounds of type are known at compile time, and the end points
5692 -- are known at compile time and identical, this is another case
5693 -- for substituting a valid test. We only do this for discrete
5694 -- types, since it won't arise in practice for float types.
5695
5696 if Comes_From_Source (N)
5697 and then Is_Discrete_Type (Ltyp)
5698 and then Compile_Time_Known_Value (Type_High_Bound (Ltyp))
5699 and then Compile_Time_Known_Value (Type_Low_Bound (Ltyp))
5700 and then Compile_Time_Known_Value (Lo)
5701 and then Compile_Time_Known_Value (Hi)
5702 and then Expr_Value (Type_High_Bound (Ltyp)) = Expr_Value (Hi)
5703 and then Expr_Value (Type_Low_Bound (Ltyp)) = Expr_Value (Lo)
5704
5705 -- Kill warnings in instances, since they may be cases where we
5706 -- have a test in the generic that makes sense with some types
5707 -- and not with other types.
5708
5709 and then not In_Instance
5710 then
5711 Substitute_Valid_Check;
5712 goto Leave;
5713 end if;
5714
5715 -- If we have an explicit range, do a bit of optimization based on
5716 -- range analysis (we may be able to kill one or both checks).
5717
5718 Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => False);
5719 Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => False);
5720
5721 -- If either check is known to fail, replace result by False since
5722 -- the other check does not matter. Preserve the static flag for
5723 -- legality checks, because we are constant-folding beyond RM 4.9.
5724
5725 if Lcheck = LT or else Ucheck = GT then
5726 if Warn1 then
5727 Error_Msg_N ("?range test optimized away", N);
5728 Error_Msg_N ("\?value is known to be out of range", N);
5729 end if;
5730
5731 Rewrite (N, New_Reference_To (Standard_False, Loc));
5732 Analyze_And_Resolve (N, Restyp);
5733 Set_Is_Static_Expression (N, Static);
5734 goto Leave;
5735
5736 -- If both checks are known to succeed, replace result by True,
5737 -- since we know we are in range.
5738
5739 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
5740 if Warn1 then
5741 Error_Msg_N ("?range test optimized away", N);
5742 Error_Msg_N ("\?value is known to be in range", N);
5743 end if;
5744
5745 Rewrite (N, New_Reference_To (Standard_True, Loc));
5746 Analyze_And_Resolve (N, Restyp);
5747 Set_Is_Static_Expression (N, Static);
5748 goto Leave;
5749
5750 -- If lower bound check succeeds and upper bound check is not
5751 -- known to succeed or fail, then replace the range check with
5752 -- a comparison against the upper bound.
5753
5754 elsif Lcheck in Compare_GE then
5755 if Warn2 and then not In_Instance then
5756 Error_Msg_N ("?lower bound test optimized away", Lo);
5757 Error_Msg_N ("\?value is known to be in range", Lo);
5758 end if;
5759
5760 Rewrite (N,
5761 Make_Op_Le (Loc,
5762 Left_Opnd => Lop,
5763 Right_Opnd => High_Bound (Rop)));
5764 Analyze_And_Resolve (N, Restyp);
5765 goto Leave;
5766
5767 -- If upper bound check succeeds and lower bound check is not
5768 -- known to succeed or fail, then replace the range check with
5769 -- a comparison against the lower bound.
5770
5771 elsif Ucheck in Compare_LE then
5772 if Warn2 and then not In_Instance then
5773 Error_Msg_N ("?upper bound test optimized away", Hi);
5774 Error_Msg_N ("\?value is known to be in range", Hi);
5775 end if;
5776
5777 Rewrite (N,
5778 Make_Op_Ge (Loc,
5779 Left_Opnd => Lop,
5780 Right_Opnd => Low_Bound (Rop)));
5781 Analyze_And_Resolve (N, Restyp);
5782 goto Leave;
5783 end if;
5784
5785 -- We couldn't optimize away the range check, but there is one
5786 -- more issue. If we are checking constant conditionals, then we
5787 -- see if we can determine the outcome assuming everything is
5788 -- valid, and if so give an appropriate warning.
5789
5790 if Warn1 and then not Assume_No_Invalid_Values then
5791 Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => True);
5792 Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => True);
5793
5794 -- Result is out of range for valid value
5795
5796 if Lcheck = LT or else Ucheck = GT then
5797 Error_Msg_N
5798 ("?value can only be in range if it is invalid", N);
5799
5800 -- Result is in range for valid value
5801
5802 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
5803 Error_Msg_N
5804 ("?value can only be out of range if it is invalid", N);
5805
5806 -- Lower bound check succeeds if value is valid
5807
5808 elsif Warn2 and then Lcheck in Compare_GE then
5809 Error_Msg_N
5810 ("?lower bound check only fails if it is invalid", Lo);
5811
5812 -- Upper bound check succeeds if value is valid
5813
5814 elsif Warn2 and then Ucheck in Compare_LE then
5815 Error_Msg_N
5816 ("?upper bound check only fails for invalid values", Hi);
5817 end if;
5818 end if;
5819 end;
5820
5821 -- For all other cases of an explicit range, nothing to be done
5822
5823 goto Leave;
5824
5825 -- Here right operand is a subtype mark
5826
5827 else
5828 declare
5829 Typ : Entity_Id := Etype (Rop);
5830 Is_Acc : constant Boolean := Is_Access_Type (Typ);
5831 Cond : Node_Id := Empty;
5832 New_N : Node_Id;
5833 Obj : Node_Id := Lop;
5834 SCIL_Node : Node_Id;
5835
5836 begin
5837 Remove_Side_Effects (Obj);
5838
5839 -- For tagged type, do tagged membership operation
5840
5841 if Is_Tagged_Type (Typ) then
5842
5843 -- No expansion will be performed when VM_Target, as the VM
5844 -- back-ends will handle the membership tests directly (tags
5845 -- are not explicitly represented in Java objects, so the
5846 -- normal tagged membership expansion is not what we want).
5847
5848 if Tagged_Type_Expansion then
5849 Tagged_Membership (N, SCIL_Node, New_N);
5850 Rewrite (N, New_N);
5851 Analyze_And_Resolve (N, Restyp);
5852
5853 -- Update decoration of relocated node referenced by the
5854 -- SCIL node.
5855
5856 if Generate_SCIL and then Present (SCIL_Node) then
5857 Set_SCIL_Node (N, SCIL_Node);
5858 end if;
5859 end if;
5860
5861 goto Leave;
5862
5863 -- If type is scalar type, rewrite as x in t'First .. t'Last.
5864 -- This reason we do this is that the bounds may have the wrong
5865 -- type if they come from the original type definition. Also this
5866 -- way we get all the processing above for an explicit range.
5867
5868 -- Don't do this for predicated types, since in this case we
5869 -- want to check the predicate!
5870
5871 elsif Is_Scalar_Type (Typ) then
5872 if No (Predicate_Function (Typ)) then
5873 Rewrite (Rop,
5874 Make_Range (Loc,
5875 Low_Bound =>
5876 Make_Attribute_Reference (Loc,
5877 Attribute_Name => Name_First,
5878 Prefix => New_Reference_To (Typ, Loc)),
5879
5880 High_Bound =>
5881 Make_Attribute_Reference (Loc,
5882 Attribute_Name => Name_Last,
5883 Prefix => New_Reference_To (Typ, Loc))));
5884 Analyze_And_Resolve (N, Restyp);
5885 end if;
5886
5887 goto Leave;
5888
5889 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
5890 -- a membership test if the subtype mark denotes a constrained
5891 -- Unchecked_Union subtype and the expression lacks inferable
5892 -- discriminants.
5893
5894 elsif Is_Unchecked_Union (Base_Type (Typ))
5895 and then Is_Constrained (Typ)
5896 and then not Has_Inferable_Discriminants (Lop)
5897 then
5898 Insert_Action (N,
5899 Make_Raise_Program_Error (Loc,
5900 Reason => PE_Unchecked_Union_Restriction));
5901
5902 -- Prevent Gigi from generating incorrect code by rewriting the
5903 -- test as False. What is this undocumented thing about ???
5904
5905 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
5906 goto Leave;
5907 end if;
5908
5909 -- Here we have a non-scalar type
5910
5911 if Is_Acc then
5912 Typ := Designated_Type (Typ);
5913 end if;
5914
5915 if not Is_Constrained (Typ) then
5916 Rewrite (N, New_Reference_To (Standard_True, Loc));
5917 Analyze_And_Resolve (N, Restyp);
5918
5919 -- For the constrained array case, we have to check the subscripts
5920 -- for an exact match if the lengths are non-zero (the lengths
5921 -- must match in any case).
5922
5923 elsif Is_Array_Type (Typ) then
5924 Check_Subscripts : declare
5925 function Build_Attribute_Reference
5926 (E : Node_Id;
5927 Nam : Name_Id;
5928 Dim : Nat) return Node_Id;
5929 -- Build attribute reference E'Nam (Dim)
5930
5931 -------------------------------
5932 -- Build_Attribute_Reference --
5933 -------------------------------
5934
5935 function Build_Attribute_Reference
5936 (E : Node_Id;
5937 Nam : Name_Id;
5938 Dim : Nat) return Node_Id
5939 is
5940 begin
5941 return
5942 Make_Attribute_Reference (Loc,
5943 Prefix => E,
5944 Attribute_Name => Nam,
5945 Expressions => New_List (
5946 Make_Integer_Literal (Loc, Dim)));
5947 end Build_Attribute_Reference;
5948
5949 -- Start of processing for Check_Subscripts
5950
5951 begin
5952 for J in 1 .. Number_Dimensions (Typ) loop
5953 Evolve_And_Then (Cond,
5954 Make_Op_Eq (Loc,
5955 Left_Opnd =>
5956 Build_Attribute_Reference
5957 (Duplicate_Subexpr_No_Checks (Obj),
5958 Name_First, J),
5959 Right_Opnd =>
5960 Build_Attribute_Reference
5961 (New_Occurrence_Of (Typ, Loc), Name_First, J)));
5962
5963 Evolve_And_Then (Cond,
5964 Make_Op_Eq (Loc,
5965 Left_Opnd =>
5966 Build_Attribute_Reference
5967 (Duplicate_Subexpr_No_Checks (Obj),
5968 Name_Last, J),
5969 Right_Opnd =>
5970 Build_Attribute_Reference
5971 (New_Occurrence_Of (Typ, Loc), Name_Last, J)));
5972 end loop;
5973
5974 if Is_Acc then
5975 Cond :=
5976 Make_Or_Else (Loc,
5977 Left_Opnd =>
5978 Make_Op_Eq (Loc,
5979 Left_Opnd => Obj,
5980 Right_Opnd => Make_Null (Loc)),
5981 Right_Opnd => Cond);
5982 end if;
5983
5984 Rewrite (N, Cond);
5985 Analyze_And_Resolve (N, Restyp);
5986 end Check_Subscripts;
5987
5988 -- These are the cases where constraint checks may be required,
5989 -- e.g. records with possible discriminants
5990
5991 else
5992 -- Expand the test into a series of discriminant comparisons.
5993 -- The expression that is built is the negation of the one that
5994 -- is used for checking discriminant constraints.
5995
5996 Obj := Relocate_Node (Left_Opnd (N));
5997
5998 if Has_Discriminants (Typ) then
5999 Cond := Make_Op_Not (Loc,
6000 Right_Opnd => Build_Discriminant_Checks (Obj, Typ));
6001
6002 if Is_Acc then
6003 Cond := Make_Or_Else (Loc,
6004 Left_Opnd =>
6005 Make_Op_Eq (Loc,
6006 Left_Opnd => Obj,
6007 Right_Opnd => Make_Null (Loc)),
6008 Right_Opnd => Cond);
6009 end if;
6010
6011 else
6012 Cond := New_Occurrence_Of (Standard_True, Loc);
6013 end if;
6014
6015 Rewrite (N, Cond);
6016 Analyze_And_Resolve (N, Restyp);
6017 end if;
6018
6019 -- Ada 2012 (AI05-0149): Handle membership tests applied to an
6020 -- expression of an anonymous access type. This can involve an
6021 -- accessibility test and a tagged type membership test in the
6022 -- case of tagged designated types.
6023
6024 if Ada_Version >= Ada_2012
6025 and then Is_Acc
6026 and then Ekind (Ltyp) = E_Anonymous_Access_Type
6027 then
6028 declare
6029 Expr_Entity : Entity_Id := Empty;
6030 New_N : Node_Id;
6031 Param_Level : Node_Id;
6032 Type_Level : Node_Id;
6033
6034 begin
6035 if Is_Entity_Name (Lop) then
6036 Expr_Entity := Param_Entity (Lop);
6037
6038 if not Present (Expr_Entity) then
6039 Expr_Entity := Entity (Lop);
6040 end if;
6041 end if;
6042
6043 -- If a conversion of the anonymous access value to the
6044 -- tested type would be illegal, then the result is False.
6045
6046 if not Valid_Conversion
6047 (Lop, Rtyp, Lop, Report_Errs => False)
6048 then
6049 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
6050 Analyze_And_Resolve (N, Restyp);
6051
6052 -- Apply an accessibility check if the access object has an
6053 -- associated access level and when the level of the type is
6054 -- less deep than the level of the access parameter. This
6055 -- only occur for access parameters and stand-alone objects
6056 -- of an anonymous access type.
6057
6058 else
6059 if Present (Expr_Entity)
6060 and then
6061 Present
6062 (Effective_Extra_Accessibility (Expr_Entity))
6063 and then UI_Gt (Object_Access_Level (Lop),
6064 Type_Access_Level (Rtyp))
6065 then
6066 Param_Level :=
6067 New_Occurrence_Of
6068 (Effective_Extra_Accessibility (Expr_Entity), Loc);
6069
6070 Type_Level :=
6071 Make_Integer_Literal (Loc, Type_Access_Level (Rtyp));
6072
6073 -- Return True only if the accessibility level of the
6074 -- expression entity is not deeper than the level of
6075 -- the tested access type.
6076
6077 Rewrite (N,
6078 Make_And_Then (Loc,
6079 Left_Opnd => Relocate_Node (N),
6080 Right_Opnd => Make_Op_Le (Loc,
6081 Left_Opnd => Param_Level,
6082 Right_Opnd => Type_Level)));
6083
6084 Analyze_And_Resolve (N);
6085 end if;
6086
6087 -- If the designated type is tagged, do tagged membership
6088 -- operation.
6089
6090 -- *** NOTE: we have to check not null before doing the
6091 -- tagged membership test (but maybe that can be done
6092 -- inside Tagged_Membership?).
6093
6094 if Is_Tagged_Type (Typ) then
6095 Rewrite (N,
6096 Make_And_Then (Loc,
6097 Left_Opnd => Relocate_Node (N),
6098 Right_Opnd =>
6099 Make_Op_Ne (Loc,
6100 Left_Opnd => Obj,
6101 Right_Opnd => Make_Null (Loc))));
6102
6103 -- No expansion will be performed when VM_Target, as
6104 -- the VM back-ends will handle the membership tests
6105 -- directly (tags are not explicitly represented in
6106 -- Java objects, so the normal tagged membership
6107 -- expansion is not what we want).
6108
6109 if Tagged_Type_Expansion then
6110
6111 -- Note that we have to pass Original_Node, because
6112 -- the membership test might already have been
6113 -- rewritten by earlier parts of membership test.
6114
6115 Tagged_Membership
6116 (Original_Node (N), SCIL_Node, New_N);
6117
6118 -- Update decoration of relocated node referenced
6119 -- by the SCIL node.
6120
6121 if Generate_SCIL and then Present (SCIL_Node) then
6122 Set_SCIL_Node (New_N, SCIL_Node);
6123 end if;
6124
6125 Rewrite (N,
6126 Make_And_Then (Loc,
6127 Left_Opnd => Relocate_Node (N),
6128 Right_Opnd => New_N));
6129
6130 Analyze_And_Resolve (N, Restyp);
6131 end if;
6132 end if;
6133 end if;
6134 end;
6135 end if;
6136 end;
6137 end if;
6138
6139 -- At this point, we have done the processing required for the basic
6140 -- membership test, but not yet dealt with the predicate.
6141
6142 <<Leave>>
6143
6144 -- If a predicate is present, then we do the predicate test, but we
6145 -- most certainly want to omit this if we are within the predicate
6146 -- function itself, since otherwise we have an infinite recursion!
6147
6148 declare
6149 PFunc : constant Entity_Id := Predicate_Function (Rtyp);
6150
6151 begin
6152 if Present (PFunc)
6153 and then Current_Scope /= PFunc
6154 then
6155 Rewrite (N,
6156 Make_And_Then (Loc,
6157 Left_Opnd => Relocate_Node (N),
6158 Right_Opnd => Make_Predicate_Call (Rtyp, Lop)));
6159
6160 -- Analyze new expression, mark left operand as analyzed to
6161 -- avoid infinite recursion adding predicate calls. Similarly,
6162 -- suppress further range checks on the call.
6163
6164 Set_Analyzed (Left_Opnd (N));
6165 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
6166
6167 -- All done, skip attempt at compile time determination of result
6168
6169 return;
6170 end if;
6171 end;
6172 end Expand_N_In;
6173
6174 --------------------------------
6175 -- Expand_N_Indexed_Component --
6176 --------------------------------
6177
6178 procedure Expand_N_Indexed_Component (N : Node_Id) is
6179 Loc : constant Source_Ptr := Sloc (N);
6180 Typ : constant Entity_Id := Etype (N);
6181 P : constant Node_Id := Prefix (N);
6182 T : constant Entity_Id := Etype (P);
6183 Atp : Entity_Id;
6184
6185 begin
6186 -- A special optimization, if we have an indexed component that is
6187 -- selecting from a slice, then we can eliminate the slice, since, for
6188 -- example, x (i .. j)(k) is identical to x(k). The only difference is
6189 -- the range check required by the slice. The range check for the slice
6190 -- itself has already been generated. The range check for the
6191 -- subscripting operation is ensured by converting the subject to
6192 -- the subtype of the slice.
6193
6194 -- This optimization not only generates better code, avoiding slice
6195 -- messing especially in the packed case, but more importantly bypasses
6196 -- some problems in handling this peculiar case, for example, the issue
6197 -- of dealing specially with object renamings.
6198
6199 if Nkind (P) = N_Slice then
6200 Rewrite (N,
6201 Make_Indexed_Component (Loc,
6202 Prefix => Prefix (P),
6203 Expressions => New_List (
6204 Convert_To
6205 (Etype (First_Index (Etype (P))),
6206 First (Expressions (N))))));
6207 Analyze_And_Resolve (N, Typ);
6208 return;
6209 end if;
6210
6211 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
6212 -- function, then additional actuals must be passed.
6213
6214 if Ada_Version >= Ada_2005
6215 and then Is_Build_In_Place_Function_Call (P)
6216 then
6217 Make_Build_In_Place_Call_In_Anonymous_Context (P);
6218 end if;
6219
6220 -- If the prefix is an access type, then we unconditionally rewrite if
6221 -- as an explicit dereference. This simplifies processing for several
6222 -- cases, including packed array cases and certain cases in which checks
6223 -- must be generated. We used to try to do this only when it was
6224 -- necessary, but it cleans up the code to do it all the time.
6225
6226 if Is_Access_Type (T) then
6227 Insert_Explicit_Dereference (P);
6228 Analyze_And_Resolve (P, Designated_Type (T));
6229 Atp := Designated_Type (T);
6230 else
6231 Atp := T;
6232 end if;
6233
6234 -- Generate index and validity checks
6235
6236 Generate_Index_Checks (N);
6237
6238 if Validity_Checks_On and then Validity_Check_Subscripts then
6239 Apply_Subscript_Validity_Checks (N);
6240 end if;
6241
6242 -- If selecting from an array with atomic components, and atomic sync
6243 -- is not suppressed for this array type, set atomic sync flag.
6244
6245 if (Has_Atomic_Components (Atp)
6246 and then not Atomic_Synchronization_Disabled (Atp))
6247 or else (Is_Atomic (Typ)
6248 and then not Atomic_Synchronization_Disabled (Typ))
6249 then
6250 Activate_Atomic_Synchronization (N);
6251 end if;
6252
6253 -- All done for the non-packed case
6254
6255 if not Is_Packed (Etype (Prefix (N))) then
6256 return;
6257 end if;
6258
6259 -- For packed arrays that are not bit-packed (i.e. the case of an array
6260 -- with one or more index types with a non-contiguous enumeration type),
6261 -- we can always use the normal packed element get circuit.
6262
6263 if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
6264 Expand_Packed_Element_Reference (N);
6265 return;
6266 end if;
6267
6268 -- For a reference to a component of a bit packed array, we have to
6269 -- convert it to a reference to the corresponding Packed_Array_Type.
6270 -- We only want to do this for simple references, and not for:
6271
6272 -- Left side of assignment, or prefix of left side of assignment, or
6273 -- prefix of the prefix, to handle packed arrays of packed arrays,
6274 -- This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
6275
6276 -- Renaming objects in renaming associations
6277 -- This case is handled when a use of the renamed variable occurs
6278
6279 -- Actual parameters for a procedure call
6280 -- This case is handled in Exp_Ch6.Expand_Actuals
6281
6282 -- The second expression in a 'Read attribute reference
6283
6284 -- The prefix of an address or bit or size attribute reference
6285
6286 -- The following circuit detects these exceptions
6287
6288 declare
6289 Child : Node_Id := N;
6290 Parnt : Node_Id := Parent (N);
6291
6292 begin
6293 loop
6294 if Nkind (Parnt) = N_Unchecked_Expression then
6295 null;
6296
6297 elsif Nkind_In (Parnt, N_Object_Renaming_Declaration,
6298 N_Procedure_Call_Statement)
6299 or else (Nkind (Parnt) = N_Parameter_Association
6300 and then
6301 Nkind (Parent (Parnt)) = N_Procedure_Call_Statement)
6302 then
6303 return;
6304
6305 elsif Nkind (Parnt) = N_Attribute_Reference
6306 and then (Attribute_Name (Parnt) = Name_Address
6307 or else
6308 Attribute_Name (Parnt) = Name_Bit
6309 or else
6310 Attribute_Name (Parnt) = Name_Size)
6311 and then Prefix (Parnt) = Child
6312 then
6313 return;
6314
6315 elsif Nkind (Parnt) = N_Assignment_Statement
6316 and then Name (Parnt) = Child
6317 then
6318 return;
6319
6320 -- If the expression is an index of an indexed component, it must
6321 -- be expanded regardless of context.
6322
6323 elsif Nkind (Parnt) = N_Indexed_Component
6324 and then Child /= Prefix (Parnt)
6325 then
6326 Expand_Packed_Element_Reference (N);
6327 return;
6328
6329 elsif Nkind (Parent (Parnt)) = N_Assignment_Statement
6330 and then Name (Parent (Parnt)) = Parnt
6331 then
6332 return;
6333
6334 elsif Nkind (Parnt) = N_Attribute_Reference
6335 and then Attribute_Name (Parnt) = Name_Read
6336 and then Next (First (Expressions (Parnt))) = Child
6337 then
6338 return;
6339
6340 elsif Nkind_In (Parnt, N_Indexed_Component, N_Selected_Component)
6341 and then Prefix (Parnt) = Child
6342 then
6343 null;
6344
6345 else
6346 Expand_Packed_Element_Reference (N);
6347 return;
6348 end if;
6349
6350 -- Keep looking up tree for unchecked expression, or if we are the
6351 -- prefix of a possible assignment left side.
6352
6353 Child := Parnt;
6354 Parnt := Parent (Child);
6355 end loop;
6356 end;
6357 end Expand_N_Indexed_Component;
6358
6359 ---------------------
6360 -- Expand_N_Not_In --
6361 ---------------------
6362
6363 -- Replace a not in b by not (a in b) so that the expansions for (a in b)
6364 -- can be done. This avoids needing to duplicate this expansion code.
6365
6366 procedure Expand_N_Not_In (N : Node_Id) is
6367 Loc : constant Source_Ptr := Sloc (N);
6368 Typ : constant Entity_Id := Etype (N);
6369 Cfs : constant Boolean := Comes_From_Source (N);
6370
6371 begin
6372 Rewrite (N,
6373 Make_Op_Not (Loc,
6374 Right_Opnd =>
6375 Make_In (Loc,
6376 Left_Opnd => Left_Opnd (N),
6377 Right_Opnd => Right_Opnd (N))));
6378
6379 -- If this is a set membership, preserve list of alternatives
6380
6381 Set_Alternatives (Right_Opnd (N), Alternatives (Original_Node (N)));
6382
6383 -- We want this to appear as coming from source if original does (see
6384 -- transformations in Expand_N_In).
6385
6386 Set_Comes_From_Source (N, Cfs);
6387 Set_Comes_From_Source (Right_Opnd (N), Cfs);
6388
6389 -- Now analyze transformed node
6390
6391 Analyze_And_Resolve (N, Typ);
6392 end Expand_N_Not_In;
6393
6394 -------------------
6395 -- Expand_N_Null --
6396 -------------------
6397
6398 -- The only replacement required is for the case of a null of a type that
6399 -- is an access to protected subprogram, or a subtype thereof. We represent
6400 -- such access values as a record, and so we must replace the occurrence of
6401 -- null by the equivalent record (with a null address and a null pointer in
6402 -- it), so that the backend creates the proper value.
6403
6404 procedure Expand_N_Null (N : Node_Id) is
6405 Loc : constant Source_Ptr := Sloc (N);
6406 Typ : constant Entity_Id := Base_Type (Etype (N));
6407 Agg : Node_Id;
6408
6409 begin
6410 if Is_Access_Protected_Subprogram_Type (Typ) then
6411 Agg :=
6412 Make_Aggregate (Loc,
6413 Expressions => New_List (
6414 New_Occurrence_Of (RTE (RE_Null_Address), Loc),
6415 Make_Null (Loc)));
6416
6417 Rewrite (N, Agg);
6418 Analyze_And_Resolve (N, Equivalent_Type (Typ));
6419
6420 -- For subsequent semantic analysis, the node must retain its type.
6421 -- Gigi in any case replaces this type by the corresponding record
6422 -- type before processing the node.
6423
6424 Set_Etype (N, Typ);
6425 end if;
6426
6427 exception
6428 when RE_Not_Available =>
6429 return;
6430 end Expand_N_Null;
6431
6432 ---------------------
6433 -- Expand_N_Op_Abs --
6434 ---------------------
6435
6436 procedure Expand_N_Op_Abs (N : Node_Id) is
6437 Loc : constant Source_Ptr := Sloc (N);
6438 Expr : constant Node_Id := Right_Opnd (N);
6439
6440 begin
6441 Unary_Op_Validity_Checks (N);
6442
6443 -- Check for MINIMIZED/ELIMINATED overflow mode
6444
6445 if Minimized_Eliminated_Overflow_Check (N) then
6446 Apply_Arithmetic_Overflow_Check (N);
6447 return;
6448 end if;
6449
6450 -- Deal with software overflow checking
6451
6452 if not Backend_Overflow_Checks_On_Target
6453 and then Is_Signed_Integer_Type (Etype (N))
6454 and then Do_Overflow_Check (N)
6455 then
6456 -- The only case to worry about is when the argument is equal to the
6457 -- largest negative number, so what we do is to insert the check:
6458
6459 -- [constraint_error when Expr = typ'Base'First]
6460
6461 -- with the usual Duplicate_Subexpr use coding for expr
6462
6463 Insert_Action (N,
6464 Make_Raise_Constraint_Error (Loc,
6465 Condition =>
6466 Make_Op_Eq (Loc,
6467 Left_Opnd => Duplicate_Subexpr (Expr),
6468 Right_Opnd =>
6469 Make_Attribute_Reference (Loc,
6470 Prefix =>
6471 New_Occurrence_Of (Base_Type (Etype (Expr)), Loc),
6472 Attribute_Name => Name_First)),
6473 Reason => CE_Overflow_Check_Failed));
6474 end if;
6475
6476 -- Vax floating-point types case
6477
6478 if Vax_Float (Etype (N)) then
6479 Expand_Vax_Arith (N);
6480 end if;
6481 end Expand_N_Op_Abs;
6482
6483 ---------------------
6484 -- Expand_N_Op_Add --
6485 ---------------------
6486
6487 procedure Expand_N_Op_Add (N : Node_Id) is
6488 Typ : constant Entity_Id := Etype (N);
6489
6490 begin
6491 Binary_Op_Validity_Checks (N);
6492
6493 -- Check for MINIMIZED/ELIMINATED overflow mode
6494
6495 if Minimized_Eliminated_Overflow_Check (N) then
6496 Apply_Arithmetic_Overflow_Check (N);
6497 return;
6498 end if;
6499
6500 -- N + 0 = 0 + N = N for integer types
6501
6502 if Is_Integer_Type (Typ) then
6503 if Compile_Time_Known_Value (Right_Opnd (N))
6504 and then Expr_Value (Right_Opnd (N)) = Uint_0
6505 then
6506 Rewrite (N, Left_Opnd (N));
6507 return;
6508
6509 elsif Compile_Time_Known_Value (Left_Opnd (N))
6510 and then Expr_Value (Left_Opnd (N)) = Uint_0
6511 then
6512 Rewrite (N, Right_Opnd (N));
6513 return;
6514 end if;
6515 end if;
6516
6517 -- Arithmetic overflow checks for signed integer/fixed point types
6518
6519 if Is_Signed_Integer_Type (Typ)
6520 or else Is_Fixed_Point_Type (Typ)
6521 then
6522 Apply_Arithmetic_Overflow_Check (N);
6523 return;
6524
6525 -- Vax floating-point types case
6526
6527 elsif Vax_Float (Typ) then
6528 Expand_Vax_Arith (N);
6529 end if;
6530 end Expand_N_Op_Add;
6531
6532 ---------------------
6533 -- Expand_N_Op_And --
6534 ---------------------
6535
6536 procedure Expand_N_Op_And (N : Node_Id) is
6537 Typ : constant Entity_Id := Etype (N);
6538
6539 begin
6540 Binary_Op_Validity_Checks (N);
6541
6542 if Is_Array_Type (Etype (N)) then
6543 Expand_Boolean_Operator (N);
6544
6545 elsif Is_Boolean_Type (Etype (N)) then
6546 Adjust_Condition (Left_Opnd (N));
6547 Adjust_Condition (Right_Opnd (N));
6548 Set_Etype (N, Standard_Boolean);
6549 Adjust_Result_Type (N, Typ);
6550
6551 elsif Is_Intrinsic_Subprogram (Entity (N)) then
6552 Expand_Intrinsic_Call (N, Entity (N));
6553
6554 end if;
6555 end Expand_N_Op_And;
6556
6557 ------------------------
6558 -- Expand_N_Op_Concat --
6559 ------------------------
6560
6561 procedure Expand_N_Op_Concat (N : Node_Id) is
6562 Opnds : List_Id;
6563 -- List of operands to be concatenated
6564
6565 Cnode : Node_Id;
6566 -- Node which is to be replaced by the result of concatenating the nodes
6567 -- in the list Opnds.
6568
6569 begin
6570 -- Ensure validity of both operands
6571
6572 Binary_Op_Validity_Checks (N);
6573
6574 -- If we are the left operand of a concatenation higher up the tree,
6575 -- then do nothing for now, since we want to deal with a series of
6576 -- concatenations as a unit.
6577
6578 if Nkind (Parent (N)) = N_Op_Concat
6579 and then N = Left_Opnd (Parent (N))
6580 then
6581 return;
6582 end if;
6583
6584 -- We get here with a concatenation whose left operand may be a
6585 -- concatenation itself with a consistent type. We need to process
6586 -- these concatenation operands from left to right, which means
6587 -- from the deepest node in the tree to the highest node.
6588
6589 Cnode := N;
6590 while Nkind (Left_Opnd (Cnode)) = N_Op_Concat loop
6591 Cnode := Left_Opnd (Cnode);
6592 end loop;
6593
6594 -- Now Cnode is the deepest concatenation, and its parents are the
6595 -- concatenation nodes above, so now we process bottom up, doing the
6596 -- operations. We gather a string that is as long as possible up to five
6597 -- operands.
6598
6599 -- The outer loop runs more than once if more than one concatenation
6600 -- type is involved.
6601
6602 Outer : loop
6603 Opnds := New_List (Left_Opnd (Cnode), Right_Opnd (Cnode));
6604 Set_Parent (Opnds, N);
6605
6606 -- The inner loop gathers concatenation operands
6607
6608 Inner : while Cnode /= N
6609 and then Base_Type (Etype (Cnode)) =
6610 Base_Type (Etype (Parent (Cnode)))
6611 loop
6612 Cnode := Parent (Cnode);
6613 Append (Right_Opnd (Cnode), Opnds);
6614 end loop Inner;
6615
6616 Expand_Concatenate (Cnode, Opnds);
6617
6618 exit Outer when Cnode = N;
6619 Cnode := Parent (Cnode);
6620 end loop Outer;
6621 end Expand_N_Op_Concat;
6622
6623 ------------------------
6624 -- Expand_N_Op_Divide --
6625 ------------------------
6626
6627 procedure Expand_N_Op_Divide (N : Node_Id) is
6628 Loc : constant Source_Ptr := Sloc (N);
6629 Lopnd : constant Node_Id := Left_Opnd (N);
6630 Ropnd : constant Node_Id := Right_Opnd (N);
6631 Ltyp : constant Entity_Id := Etype (Lopnd);
6632 Rtyp : constant Entity_Id := Etype (Ropnd);
6633 Typ : Entity_Id := Etype (N);
6634 Rknow : constant Boolean := Is_Integer_Type (Typ)
6635 and then
6636 Compile_Time_Known_Value (Ropnd);
6637 Rval : Uint;
6638
6639 begin
6640 Binary_Op_Validity_Checks (N);
6641
6642 -- Check for MINIMIZED/ELIMINATED overflow mode
6643
6644 if Minimized_Eliminated_Overflow_Check (N) then
6645 Apply_Arithmetic_Overflow_Check (N);
6646 return;
6647 end if;
6648
6649 -- Otherwise proceed with expansion of division
6650
6651 if Rknow then
6652 Rval := Expr_Value (Ropnd);
6653 end if;
6654
6655 -- N / 1 = N for integer types
6656
6657 if Rknow and then Rval = Uint_1 then
6658 Rewrite (N, Lopnd);
6659 return;
6660 end if;
6661
6662 -- Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
6663 -- Is_Power_Of_2_For_Shift is set means that we know that our left
6664 -- operand is an unsigned integer, as required for this to work.
6665
6666 if Nkind (Ropnd) = N_Op_Expon
6667 and then Is_Power_Of_2_For_Shift (Ropnd)
6668
6669 -- We cannot do this transformation in configurable run time mode if we
6670 -- have 64-bit integers and long shifts are not available.
6671
6672 and then
6673 (Esize (Ltyp) <= 32
6674 or else Support_Long_Shifts_On_Target)
6675 then
6676 Rewrite (N,
6677 Make_Op_Shift_Right (Loc,
6678 Left_Opnd => Lopnd,
6679 Right_Opnd =>
6680 Convert_To (Standard_Natural, Right_Opnd (Ropnd))));
6681 Analyze_And_Resolve (N, Typ);
6682 return;
6683 end if;
6684
6685 -- Do required fixup of universal fixed operation
6686
6687 if Typ = Universal_Fixed then
6688 Fixup_Universal_Fixed_Operation (N);
6689 Typ := Etype (N);
6690 end if;
6691
6692 -- Divisions with fixed-point results
6693
6694 if Is_Fixed_Point_Type (Typ) then
6695
6696 -- No special processing if Treat_Fixed_As_Integer is set, since
6697 -- from a semantic point of view such operations are simply integer
6698 -- operations and will be treated that way.
6699
6700 if not Treat_Fixed_As_Integer (N) then
6701 if Is_Integer_Type (Rtyp) then
6702 Expand_Divide_Fixed_By_Integer_Giving_Fixed (N);
6703 else
6704 Expand_Divide_Fixed_By_Fixed_Giving_Fixed (N);
6705 end if;
6706 end if;
6707
6708 -- Other cases of division of fixed-point operands. Again we exclude the
6709 -- case where Treat_Fixed_As_Integer is set.
6710
6711 elsif (Is_Fixed_Point_Type (Ltyp) or else
6712 Is_Fixed_Point_Type (Rtyp))
6713 and then not Treat_Fixed_As_Integer (N)
6714 then
6715 if Is_Integer_Type (Typ) then
6716 Expand_Divide_Fixed_By_Fixed_Giving_Integer (N);
6717 else
6718 pragma Assert (Is_Floating_Point_Type (Typ));
6719 Expand_Divide_Fixed_By_Fixed_Giving_Float (N);
6720 end if;
6721
6722 -- Mixed-mode operations can appear in a non-static universal context,
6723 -- in which case the integer argument must be converted explicitly.
6724
6725 elsif Typ = Universal_Real
6726 and then Is_Integer_Type (Rtyp)
6727 then
6728 Rewrite (Ropnd,
6729 Convert_To (Universal_Real, Relocate_Node (Ropnd)));
6730
6731 Analyze_And_Resolve (Ropnd, Universal_Real);
6732
6733 elsif Typ = Universal_Real
6734 and then Is_Integer_Type (Ltyp)
6735 then
6736 Rewrite (Lopnd,
6737 Convert_To (Universal_Real, Relocate_Node (Lopnd)));
6738
6739 Analyze_And_Resolve (Lopnd, Universal_Real);
6740
6741 -- Non-fixed point cases, do integer zero divide and overflow checks
6742
6743 elsif Is_Integer_Type (Typ) then
6744 Apply_Divide_Checks (N);
6745
6746 -- Deal with Vax_Float
6747
6748 elsif Vax_Float (Typ) then
6749 Expand_Vax_Arith (N);
6750 return;
6751 end if;
6752 end Expand_N_Op_Divide;
6753
6754 --------------------
6755 -- Expand_N_Op_Eq --
6756 --------------------
6757
6758 procedure Expand_N_Op_Eq (N : Node_Id) is
6759 Loc : constant Source_Ptr := Sloc (N);
6760 Typ : constant Entity_Id := Etype (N);
6761 Lhs : constant Node_Id := Left_Opnd (N);
6762 Rhs : constant Node_Id := Right_Opnd (N);
6763 Bodies : constant List_Id := New_List;
6764 A_Typ : constant Entity_Id := Etype (Lhs);
6765
6766 Typl : Entity_Id := A_Typ;
6767 Op_Name : Entity_Id;
6768 Prim : Elmt_Id;
6769
6770 procedure Build_Equality_Call (Eq : Entity_Id);
6771 -- If a constructed equality exists for the type or for its parent,
6772 -- build and analyze call, adding conversions if the operation is
6773 -- inherited.
6774
6775 function Has_Unconstrained_UU_Component (Typ : Node_Id) return Boolean;
6776 -- Determines whether a type has a subcomponent of an unconstrained
6777 -- Unchecked_Union subtype. Typ is a record type.
6778
6779 -------------------------
6780 -- Build_Equality_Call --
6781 -------------------------
6782
6783 procedure Build_Equality_Call (Eq : Entity_Id) is
6784 Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
6785 L_Exp : Node_Id := Relocate_Node (Lhs);
6786 R_Exp : Node_Id := Relocate_Node (Rhs);
6787
6788 begin
6789 if Base_Type (Op_Type) /= Base_Type (A_Typ)
6790 and then not Is_Class_Wide_Type (A_Typ)
6791 then
6792 L_Exp := OK_Convert_To (Op_Type, L_Exp);
6793 R_Exp := OK_Convert_To (Op_Type, R_Exp);
6794 end if;
6795
6796 -- If we have an Unchecked_Union, we need to add the inferred
6797 -- discriminant values as actuals in the function call. At this
6798 -- point, the expansion has determined that both operands have
6799 -- inferable discriminants.
6800
6801 if Is_Unchecked_Union (Op_Type) then
6802 declare
6803 Lhs_Type : constant Node_Id := Etype (L_Exp);
6804 Rhs_Type : constant Node_Id := Etype (R_Exp);
6805 Lhs_Discr_Val : Node_Id;
6806 Rhs_Discr_Val : Node_Id;
6807
6808 begin
6809 -- Per-object constrained selected components require special
6810 -- attention. If the enclosing scope of the component is an
6811 -- Unchecked_Union, we cannot reference its discriminants
6812 -- directly. This is why we use the two extra parameters of
6813 -- the equality function of the enclosing Unchecked_Union.
6814
6815 -- type UU_Type (Discr : Integer := 0) is
6816 -- . . .
6817 -- end record;
6818 -- pragma Unchecked_Union (UU_Type);
6819
6820 -- 1. Unchecked_Union enclosing record:
6821
6822 -- type Enclosing_UU_Type (Discr : Integer := 0) is record
6823 -- . . .
6824 -- Comp : UU_Type (Discr);
6825 -- . . .
6826 -- end Enclosing_UU_Type;
6827 -- pragma Unchecked_Union (Enclosing_UU_Type);
6828
6829 -- Obj1 : Enclosing_UU_Type;
6830 -- Obj2 : Enclosing_UU_Type (1);
6831
6832 -- [. . .] Obj1 = Obj2 [. . .]
6833
6834 -- Generated code:
6835
6836 -- if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
6837
6838 -- A and B are the formal parameters of the equality function
6839 -- of Enclosing_UU_Type. The function always has two extra
6840 -- formals to capture the inferred discriminant values.
6841
6842 -- 2. Non-Unchecked_Union enclosing record:
6843
6844 -- type
6845 -- Enclosing_Non_UU_Type (Discr : Integer := 0)
6846 -- is record
6847 -- . . .
6848 -- Comp : UU_Type (Discr);
6849 -- . . .
6850 -- end Enclosing_Non_UU_Type;
6851
6852 -- Obj1 : Enclosing_Non_UU_Type;
6853 -- Obj2 : Enclosing_Non_UU_Type (1);
6854
6855 -- ... Obj1 = Obj2 ...
6856
6857 -- Generated code:
6858
6859 -- if not (uu_typeEQ (obj1.comp, obj2.comp,
6860 -- obj1.discr, obj2.discr)) then
6861
6862 -- In this case we can directly reference the discriminants of
6863 -- the enclosing record.
6864
6865 -- Lhs of equality
6866
6867 if Nkind (Lhs) = N_Selected_Component
6868 and then Has_Per_Object_Constraint
6869 (Entity (Selector_Name (Lhs)))
6870 then
6871 -- Enclosing record is an Unchecked_Union, use formal A
6872
6873 if Is_Unchecked_Union
6874 (Scope (Entity (Selector_Name (Lhs))))
6875 then
6876 Lhs_Discr_Val := Make_Identifier (Loc, Name_A);
6877
6878 -- Enclosing record is of a non-Unchecked_Union type, it is
6879 -- possible to reference the discriminant.
6880
6881 else
6882 Lhs_Discr_Val :=
6883 Make_Selected_Component (Loc,
6884 Prefix => Prefix (Lhs),
6885 Selector_Name =>
6886 New_Copy
6887 (Get_Discriminant_Value
6888 (First_Discriminant (Lhs_Type),
6889 Lhs_Type,
6890 Stored_Constraint (Lhs_Type))));
6891 end if;
6892
6893 -- Comment needed here ???
6894
6895 else
6896 -- Infer the discriminant value
6897
6898 Lhs_Discr_Val :=
6899 New_Copy
6900 (Get_Discriminant_Value
6901 (First_Discriminant (Lhs_Type),
6902 Lhs_Type,
6903 Stored_Constraint (Lhs_Type)));
6904 end if;
6905
6906 -- Rhs of equality
6907
6908 if Nkind (Rhs) = N_Selected_Component
6909 and then Has_Per_Object_Constraint
6910 (Entity (Selector_Name (Rhs)))
6911 then
6912 if Is_Unchecked_Union
6913 (Scope (Entity (Selector_Name (Rhs))))
6914 then
6915 Rhs_Discr_Val := Make_Identifier (Loc, Name_B);
6916
6917 else
6918 Rhs_Discr_Val :=
6919 Make_Selected_Component (Loc,
6920 Prefix => Prefix (Rhs),
6921 Selector_Name =>
6922 New_Copy (Get_Discriminant_Value (
6923 First_Discriminant (Rhs_Type),
6924 Rhs_Type,
6925 Stored_Constraint (Rhs_Type))));
6926
6927 end if;
6928 else
6929 Rhs_Discr_Val :=
6930 New_Copy (Get_Discriminant_Value (
6931 First_Discriminant (Rhs_Type),
6932 Rhs_Type,
6933 Stored_Constraint (Rhs_Type)));
6934
6935 end if;
6936
6937 Rewrite (N,
6938 Make_Function_Call (Loc,
6939 Name => New_Reference_To (Eq, Loc),
6940 Parameter_Associations => New_List (
6941 L_Exp,
6942 R_Exp,
6943 Lhs_Discr_Val,
6944 Rhs_Discr_Val)));
6945 end;
6946
6947 -- Normal case, not an unchecked union
6948
6949 else
6950 Rewrite (N,
6951 Make_Function_Call (Loc,
6952 Name => New_Reference_To (Eq, Loc),
6953 Parameter_Associations => New_List (L_Exp, R_Exp)));
6954 end if;
6955
6956 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
6957 end Build_Equality_Call;
6958
6959 ------------------------------------
6960 -- Has_Unconstrained_UU_Component --
6961 ------------------------------------
6962
6963 function Has_Unconstrained_UU_Component
6964 (Typ : Node_Id) return Boolean
6965 is
6966 Tdef : constant Node_Id :=
6967 Type_Definition (Declaration_Node (Base_Type (Typ)));
6968 Clist : Node_Id;
6969 Vpart : Node_Id;
6970
6971 function Component_Is_Unconstrained_UU
6972 (Comp : Node_Id) return Boolean;
6973 -- Determines whether the subtype of the component is an
6974 -- unconstrained Unchecked_Union.
6975
6976 function Variant_Is_Unconstrained_UU
6977 (Variant : Node_Id) return Boolean;
6978 -- Determines whether a component of the variant has an unconstrained
6979 -- Unchecked_Union subtype.
6980
6981 -----------------------------------
6982 -- Component_Is_Unconstrained_UU --
6983 -----------------------------------
6984
6985 function Component_Is_Unconstrained_UU
6986 (Comp : Node_Id) return Boolean
6987 is
6988 begin
6989 if Nkind (Comp) /= N_Component_Declaration then
6990 return False;
6991 end if;
6992
6993 declare
6994 Sindic : constant Node_Id :=
6995 Subtype_Indication (Component_Definition (Comp));
6996
6997 begin
6998 -- Unconstrained nominal type. In the case of a constraint
6999 -- present, the node kind would have been N_Subtype_Indication.
7000
7001 if Nkind (Sindic) = N_Identifier then
7002 return Is_Unchecked_Union (Base_Type (Etype (Sindic)));
7003 end if;
7004
7005 return False;
7006 end;
7007 end Component_Is_Unconstrained_UU;
7008
7009 ---------------------------------
7010 -- Variant_Is_Unconstrained_UU --
7011 ---------------------------------
7012
7013 function Variant_Is_Unconstrained_UU
7014 (Variant : Node_Id) return Boolean
7015 is
7016 Clist : constant Node_Id := Component_List (Variant);
7017
7018 begin
7019 if Is_Empty_List (Component_Items (Clist)) then
7020 return False;
7021 end if;
7022
7023 -- We only need to test one component
7024
7025 declare
7026 Comp : Node_Id := First (Component_Items (Clist));
7027
7028 begin
7029 while Present (Comp) loop
7030 if Component_Is_Unconstrained_UU (Comp) then
7031 return True;
7032 end if;
7033
7034 Next (Comp);
7035 end loop;
7036 end;
7037
7038 -- None of the components withing the variant were of
7039 -- unconstrained Unchecked_Union type.
7040
7041 return False;
7042 end Variant_Is_Unconstrained_UU;
7043
7044 -- Start of processing for Has_Unconstrained_UU_Component
7045
7046 begin
7047 if Null_Present (Tdef) then
7048 return False;
7049 end if;
7050
7051 Clist := Component_List (Tdef);
7052 Vpart := Variant_Part (Clist);
7053
7054 -- Inspect available components
7055
7056 if Present (Component_Items (Clist)) then
7057 declare
7058 Comp : Node_Id := First (Component_Items (Clist));
7059
7060 begin
7061 while Present (Comp) loop
7062
7063 -- One component is sufficient
7064
7065 if Component_Is_Unconstrained_UU (Comp) then
7066 return True;
7067 end if;
7068
7069 Next (Comp);
7070 end loop;
7071 end;
7072 end if;
7073
7074 -- Inspect available components withing variants
7075
7076 if Present (Vpart) then
7077 declare
7078 Variant : Node_Id := First (Variants (Vpart));
7079
7080 begin
7081 while Present (Variant) loop
7082
7083 -- One component within a variant is sufficient
7084
7085 if Variant_Is_Unconstrained_UU (Variant) then
7086 return True;
7087 end if;
7088
7089 Next (Variant);
7090 end loop;
7091 end;
7092 end if;
7093
7094 -- Neither the available components, nor the components inside the
7095 -- variant parts were of an unconstrained Unchecked_Union subtype.
7096
7097 return False;
7098 end Has_Unconstrained_UU_Component;
7099
7100 -- Start of processing for Expand_N_Op_Eq
7101
7102 begin
7103 Binary_Op_Validity_Checks (N);
7104
7105 -- Deal with private types
7106
7107 if Ekind (Typl) = E_Private_Type then
7108 Typl := Underlying_Type (Typl);
7109 elsif Ekind (Typl) = E_Private_Subtype then
7110 Typl := Underlying_Type (Base_Type (Typl));
7111 else
7112 null;
7113 end if;
7114
7115 -- It may happen in error situations that the underlying type is not
7116 -- set. The error will be detected later, here we just defend the
7117 -- expander code.
7118
7119 if No (Typl) then
7120 return;
7121 end if;
7122
7123 Typl := Base_Type (Typl);
7124
7125 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
7126 -- results in not having a comparison operation any more, we are done.
7127
7128 Expand_Compare_Minimize_Eliminate_Overflow (N);
7129
7130 if Nkind (N) /= N_Op_Eq then
7131 return;
7132 end if;
7133
7134 -- Boolean types (requiring handling of non-standard case)
7135
7136 if Is_Boolean_Type (Typl) then
7137 Adjust_Condition (Left_Opnd (N));
7138 Adjust_Condition (Right_Opnd (N));
7139 Set_Etype (N, Standard_Boolean);
7140 Adjust_Result_Type (N, Typ);
7141
7142 -- Array types
7143
7144 elsif Is_Array_Type (Typl) then
7145
7146 -- If we are doing full validity checking, and it is possible for the
7147 -- array elements to be invalid then expand out array comparisons to
7148 -- make sure that we check the array elements.
7149
7150 if Validity_Check_Operands
7151 and then not Is_Known_Valid (Component_Type (Typl))
7152 then
7153 declare
7154 Save_Force_Validity_Checks : constant Boolean :=
7155 Force_Validity_Checks;
7156 begin
7157 Force_Validity_Checks := True;
7158 Rewrite (N,
7159 Expand_Array_Equality
7160 (N,
7161 Relocate_Node (Lhs),
7162 Relocate_Node (Rhs),
7163 Bodies,
7164 Typl));
7165 Insert_Actions (N, Bodies);
7166 Analyze_And_Resolve (N, Standard_Boolean);
7167 Force_Validity_Checks := Save_Force_Validity_Checks;
7168 end;
7169
7170 -- Packed case where both operands are known aligned
7171
7172 elsif Is_Bit_Packed_Array (Typl)
7173 and then not Is_Possibly_Unaligned_Object (Lhs)
7174 and then not Is_Possibly_Unaligned_Object (Rhs)
7175 then
7176 Expand_Packed_Eq (N);
7177
7178 -- Where the component type is elementary we can use a block bit
7179 -- comparison (if supported on the target) exception in the case
7180 -- of floating-point (negative zero issues require element by
7181 -- element comparison), and atomic types (where we must be sure
7182 -- to load elements independently) and possibly unaligned arrays.
7183
7184 elsif Is_Elementary_Type (Component_Type (Typl))
7185 and then not Is_Floating_Point_Type (Component_Type (Typl))
7186 and then not Is_Atomic (Component_Type (Typl))
7187 and then not Is_Possibly_Unaligned_Object (Lhs)
7188 and then not Is_Possibly_Unaligned_Object (Rhs)
7189 and then Support_Composite_Compare_On_Target
7190 then
7191 null;
7192
7193 -- For composite and floating-point cases, expand equality loop to
7194 -- make sure of using proper comparisons for tagged types, and
7195 -- correctly handling the floating-point case.
7196
7197 else
7198 Rewrite (N,
7199 Expand_Array_Equality
7200 (N,
7201 Relocate_Node (Lhs),
7202 Relocate_Node (Rhs),
7203 Bodies,
7204 Typl));
7205 Insert_Actions (N, Bodies, Suppress => All_Checks);
7206 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
7207 end if;
7208
7209 -- Record Types
7210
7211 elsif Is_Record_Type (Typl) then
7212
7213 -- For tagged types, use the primitive "="
7214
7215 if Is_Tagged_Type (Typl) then
7216
7217 -- No need to do anything else compiling under restriction
7218 -- No_Dispatching_Calls. During the semantic analysis we
7219 -- already notified such violation.
7220
7221 if Restriction_Active (No_Dispatching_Calls) then
7222 return;
7223 end if;
7224
7225 -- If this is derived from an untagged private type completed with
7226 -- a tagged type, it does not have a full view, so we use the
7227 -- primitive operations of the private type. This check should no
7228 -- longer be necessary when these types get their full views???
7229
7230 if Is_Private_Type (A_Typ)
7231 and then not Is_Tagged_Type (A_Typ)
7232 and then Is_Derived_Type (A_Typ)
7233 and then No (Full_View (A_Typ))
7234 then
7235 -- Search for equality operation, checking that the operands
7236 -- have the same type. Note that we must find a matching entry,
7237 -- or something is very wrong!
7238
7239 Prim := First_Elmt (Collect_Primitive_Operations (A_Typ));
7240
7241 while Present (Prim) loop
7242 exit when Chars (Node (Prim)) = Name_Op_Eq
7243 and then Etype (First_Formal (Node (Prim))) =
7244 Etype (Next_Formal (First_Formal (Node (Prim))))
7245 and then
7246 Base_Type (Etype (Node (Prim))) = Standard_Boolean;
7247
7248 Next_Elmt (Prim);
7249 end loop;
7250
7251 pragma Assert (Present (Prim));
7252 Op_Name := Node (Prim);
7253
7254 -- Find the type's predefined equality or an overriding
7255 -- user- defined equality. The reason for not simply calling
7256 -- Find_Prim_Op here is that there may be a user-defined
7257 -- overloaded equality op that precedes the equality that we want,
7258 -- so we have to explicitly search (e.g., there could be an
7259 -- equality with two different parameter types).
7260
7261 else
7262 if Is_Class_Wide_Type (Typl) then
7263 Typl := Root_Type (Typl);
7264 end if;
7265
7266 Prim := First_Elmt (Primitive_Operations (Typl));
7267 while Present (Prim) loop
7268 exit when Chars (Node (Prim)) = Name_Op_Eq
7269 and then Etype (First_Formal (Node (Prim))) =
7270 Etype (Next_Formal (First_Formal (Node (Prim))))
7271 and then
7272 Base_Type (Etype (Node (Prim))) = Standard_Boolean;
7273
7274 Next_Elmt (Prim);
7275 end loop;
7276
7277 pragma Assert (Present (Prim));
7278 Op_Name := Node (Prim);
7279 end if;
7280
7281 Build_Equality_Call (Op_Name);
7282
7283 -- Ada 2005 (AI-216): Program_Error is raised when evaluating the
7284 -- predefined equality operator for a type which has a subcomponent
7285 -- of an Unchecked_Union type whose nominal subtype is unconstrained.
7286
7287 elsif Has_Unconstrained_UU_Component (Typl) then
7288 Insert_Action (N,
7289 Make_Raise_Program_Error (Loc,
7290 Reason => PE_Unchecked_Union_Restriction));
7291
7292 -- Prevent Gigi from generating incorrect code by rewriting the
7293 -- equality as a standard False. (is this documented somewhere???)
7294
7295 Rewrite (N,
7296 New_Occurrence_Of (Standard_False, Loc));
7297
7298 elsif Is_Unchecked_Union (Typl) then
7299
7300 -- If we can infer the discriminants of the operands, we make a
7301 -- call to the TSS equality function.
7302
7303 if Has_Inferable_Discriminants (Lhs)
7304 and then
7305 Has_Inferable_Discriminants (Rhs)
7306 then
7307 Build_Equality_Call
7308 (TSS (Root_Type (Typl), TSS_Composite_Equality));
7309
7310 else
7311 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
7312 -- the predefined equality operator for an Unchecked_Union type
7313 -- if either of the operands lack inferable discriminants.
7314
7315 Insert_Action (N,
7316 Make_Raise_Program_Error (Loc,
7317 Reason => PE_Unchecked_Union_Restriction));
7318
7319 -- Prevent Gigi from generating incorrect code by rewriting
7320 -- the equality as a standard False (documented where???).
7321
7322 Rewrite (N,
7323 New_Occurrence_Of (Standard_False, Loc));
7324
7325 end if;
7326
7327 -- If a type support function is present (for complex cases), use it
7328
7329 elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
7330 Build_Equality_Call
7331 (TSS (Root_Type (Typl), TSS_Composite_Equality));
7332
7333 -- Otherwise expand the component by component equality. Note that
7334 -- we never use block-bit comparisons for records, because of the
7335 -- problems with gaps. The backend will often be able to recombine
7336 -- the separate comparisons that we generate here.
7337
7338 else
7339 Remove_Side_Effects (Lhs);
7340 Remove_Side_Effects (Rhs);
7341 Rewrite (N,
7342 Expand_Record_Equality (N, Typl, Lhs, Rhs, Bodies));
7343
7344 Insert_Actions (N, Bodies, Suppress => All_Checks);
7345 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
7346 end if;
7347 end if;
7348
7349 -- Test if result is known at compile time
7350
7351 Rewrite_Comparison (N);
7352
7353 -- If we still have comparison for Vax_Float, process it
7354
7355 if Vax_Float (Typl) and then Nkind (N) in N_Op_Compare then
7356 Expand_Vax_Comparison (N);
7357 return;
7358 end if;
7359
7360 Optimize_Length_Comparison (N);
7361 end Expand_N_Op_Eq;
7362
7363 -----------------------
7364 -- Expand_N_Op_Expon --
7365 -----------------------
7366
7367 procedure Expand_N_Op_Expon (N : Node_Id) is
7368 Loc : constant Source_Ptr := Sloc (N);
7369 Typ : constant Entity_Id := Etype (N);
7370 Rtyp : constant Entity_Id := Root_Type (Typ);
7371 Base : constant Node_Id := Relocate_Node (Left_Opnd (N));
7372 Bastyp : constant Node_Id := Etype (Base);
7373 Exp : constant Node_Id := Relocate_Node (Right_Opnd (N));
7374 Exptyp : constant Entity_Id := Etype (Exp);
7375 Ovflo : constant Boolean := Do_Overflow_Check (N);
7376 Expv : Uint;
7377 Temp : Node_Id;
7378 Rent : RE_Id;
7379 Ent : Entity_Id;
7380 Etyp : Entity_Id;
7381 Xnode : Node_Id;
7382
7383 begin
7384 Binary_Op_Validity_Checks (N);
7385
7386 -- CodePeer and GNATprove want to see the unexpanded N_Op_Expon node
7387
7388 if CodePeer_Mode or Alfa_Mode then
7389 return;
7390 end if;
7391
7392 -- If either operand is of a private type, then we have the use of an
7393 -- intrinsic operator, and we get rid of the privateness, by using root
7394 -- types of underlying types for the actual operation. Otherwise the
7395 -- private types will cause trouble if we expand multiplications or
7396 -- shifts etc. We also do this transformation if the result type is
7397 -- different from the base type.
7398
7399 if Is_Private_Type (Etype (Base))
7400 or else Is_Private_Type (Typ)
7401 or else Is_Private_Type (Exptyp)
7402 or else Rtyp /= Root_Type (Bastyp)
7403 then
7404 declare
7405 Bt : constant Entity_Id := Root_Type (Underlying_Type (Bastyp));
7406 Et : constant Entity_Id := Root_Type (Underlying_Type (Exptyp));
7407
7408 begin
7409 Rewrite (N,
7410 Unchecked_Convert_To (Typ,
7411 Make_Op_Expon (Loc,
7412 Left_Opnd => Unchecked_Convert_To (Bt, Base),
7413 Right_Opnd => Unchecked_Convert_To (Et, Exp))));
7414 Analyze_And_Resolve (N, Typ);
7415 return;
7416 end;
7417 end if;
7418
7419 -- Check for MINIMIZED/ELIMINATED overflow mode
7420
7421 if Minimized_Eliminated_Overflow_Check (N) then
7422 Apply_Arithmetic_Overflow_Check (N);
7423 return;
7424 end if;
7425
7426 -- Test for case of known right argument where we can replace the
7427 -- exponentiation by an equivalent expression using multiplication.
7428
7429 if Compile_Time_Known_Value (Exp) then
7430 Expv := Expr_Value (Exp);
7431
7432 -- We only fold small non-negative exponents. You might think we
7433 -- could fold small negative exponents for the real case, but we
7434 -- can't because we are required to raise Constraint_Error for
7435 -- the case of 0.0 ** (negative) even if Machine_Overflows = False.
7436 -- See ACVC test C4A012B.
7437
7438 if Expv >= 0 and then Expv <= 4 then
7439
7440 -- X ** 0 = 1 (or 1.0)
7441
7442 if Expv = 0 then
7443
7444 -- Call Remove_Side_Effects to ensure that any side effects
7445 -- in the ignored left operand (in particular function calls
7446 -- to user defined functions) are properly executed.
7447
7448 Remove_Side_Effects (Base);
7449
7450 if Ekind (Typ) in Integer_Kind then
7451 Xnode := Make_Integer_Literal (Loc, Intval => 1);
7452 else
7453 Xnode := Make_Real_Literal (Loc, Ureal_1);
7454 end if;
7455
7456 -- X ** 1 = X
7457
7458 elsif Expv = 1 then
7459 Xnode := Base;
7460
7461 -- X ** 2 = X * X
7462
7463 elsif Expv = 2 then
7464 Xnode :=
7465 Make_Op_Multiply (Loc,
7466 Left_Opnd => Duplicate_Subexpr (Base),
7467 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
7468
7469 -- X ** 3 = X * X * X
7470
7471 elsif Expv = 3 then
7472 Xnode :=
7473 Make_Op_Multiply (Loc,
7474 Left_Opnd =>
7475 Make_Op_Multiply (Loc,
7476 Left_Opnd => Duplicate_Subexpr (Base),
7477 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)),
7478 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
7479
7480 -- X ** 4 ->
7481
7482 -- do
7483 -- En : constant base'type := base * base;
7484 -- in
7485 -- En * En
7486
7487 else
7488 pragma Assert (Expv = 4);
7489 Temp := Make_Temporary (Loc, 'E', Base);
7490
7491 Xnode :=
7492 Make_Expression_With_Actions (Loc,
7493 Actions => New_List (
7494 Make_Object_Declaration (Loc,
7495 Defining_Identifier => Temp,
7496 Constant_Present => True,
7497 Object_Definition => New_Reference_To (Typ, Loc),
7498 Expression =>
7499 Make_Op_Multiply (Loc,
7500 Left_Opnd =>
7501 Duplicate_Subexpr (Base),
7502 Right_Opnd =>
7503 Duplicate_Subexpr_No_Checks (Base)))),
7504
7505 Expression =>
7506 Make_Op_Multiply (Loc,
7507 Left_Opnd => New_Reference_To (Temp, Loc),
7508 Right_Opnd => New_Reference_To (Temp, Loc)));
7509 end if;
7510
7511 Rewrite (N, Xnode);
7512 Analyze_And_Resolve (N, Typ);
7513 return;
7514 end if;
7515 end if;
7516
7517 -- Case of (2 ** expression) appearing as an argument of an integer
7518 -- multiplication, or as the right argument of a division of a non-
7519 -- negative integer. In such cases we leave the node untouched, setting
7520 -- the flag Is_Natural_Power_Of_2_for_Shift set, then the expansion
7521 -- of the higher level node converts it into a shift.
7522
7523 -- Another case is 2 ** N in any other context. We simply convert
7524 -- this to 1 * 2 ** N, and then the above transformation applies.
7525
7526 -- Note: this transformation is not applicable for a modular type with
7527 -- a non-binary modulus in the multiplication case, since we get a wrong
7528 -- result if the shift causes an overflow before the modular reduction.
7529
7530 if Nkind (Base) = N_Integer_Literal
7531 and then Intval (Base) = 2
7532 and then Is_Integer_Type (Root_Type (Exptyp))
7533 and then Esize (Root_Type (Exptyp)) <= Esize (Standard_Integer)
7534 and then Is_Unsigned_Type (Exptyp)
7535 and then not Ovflo
7536 then
7537 -- First the multiply and divide cases
7538
7539 if Nkind_In (Parent (N), N_Op_Divide, N_Op_Multiply) then
7540 declare
7541 P : constant Node_Id := Parent (N);
7542 L : constant Node_Id := Left_Opnd (P);
7543 R : constant Node_Id := Right_Opnd (P);
7544
7545 begin
7546 if (Nkind (P) = N_Op_Multiply
7547 and then not Non_Binary_Modulus (Typ)
7548 and then
7549 ((Is_Integer_Type (Etype (L)) and then R = N)
7550 or else
7551 (Is_Integer_Type (Etype (R)) and then L = N))
7552 and then not Do_Overflow_Check (P))
7553 or else
7554 (Nkind (P) = N_Op_Divide
7555 and then Is_Integer_Type (Etype (L))
7556 and then Is_Unsigned_Type (Etype (L))
7557 and then R = N
7558 and then not Do_Overflow_Check (P))
7559 then
7560 Set_Is_Power_Of_2_For_Shift (N);
7561 return;
7562 end if;
7563 end;
7564
7565 -- Now the other cases
7566
7567 elsif not Non_Binary_Modulus (Typ) then
7568 Rewrite (N,
7569 Make_Op_Multiply (Loc,
7570 Left_Opnd => Make_Integer_Literal (Loc, 1),
7571 Right_Opnd => Relocate_Node (N)));
7572 Analyze_And_Resolve (N, Typ);
7573 return;
7574 end if;
7575 end if;
7576
7577 -- Fall through if exponentiation must be done using a runtime routine
7578
7579 -- First deal with modular case
7580
7581 if Is_Modular_Integer_Type (Rtyp) then
7582
7583 -- Non-binary case, we call the special exponentiation routine for
7584 -- the non-binary case, converting the argument to Long_Long_Integer
7585 -- and passing the modulus value. Then the result is converted back
7586 -- to the base type.
7587
7588 if Non_Binary_Modulus (Rtyp) then
7589 Rewrite (N,
7590 Convert_To (Typ,
7591 Make_Function_Call (Loc,
7592 Name => New_Reference_To (RTE (RE_Exp_Modular), Loc),
7593 Parameter_Associations => New_List (
7594 Convert_To (Standard_Integer, Base),
7595 Make_Integer_Literal (Loc, Modulus (Rtyp)),
7596 Exp))));
7597
7598 -- Binary case, in this case, we call one of two routines, either the
7599 -- unsigned integer case, or the unsigned long long integer case,
7600 -- with a final "and" operation to do the required mod.
7601
7602 else
7603 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
7604 Ent := RTE (RE_Exp_Unsigned);
7605 else
7606 Ent := RTE (RE_Exp_Long_Long_Unsigned);
7607 end if;
7608
7609 Rewrite (N,
7610 Convert_To (Typ,
7611 Make_Op_And (Loc,
7612 Left_Opnd =>
7613 Make_Function_Call (Loc,
7614 Name => New_Reference_To (Ent, Loc),
7615 Parameter_Associations => New_List (
7616 Convert_To (Etype (First_Formal (Ent)), Base),
7617 Exp)),
7618 Right_Opnd =>
7619 Make_Integer_Literal (Loc, Modulus (Rtyp) - 1))));
7620
7621 end if;
7622
7623 -- Common exit point for modular type case
7624
7625 Analyze_And_Resolve (N, Typ);
7626 return;
7627
7628 -- Signed integer cases, done using either Integer or Long_Long_Integer.
7629 -- It is not worth having routines for Short_[Short_]Integer, since for
7630 -- most machines it would not help, and it would generate more code that
7631 -- might need certification when a certified run time is required.
7632
7633 -- In the integer cases, we have two routines, one for when overflow
7634 -- checks are required, and one when they are not required, since there
7635 -- is a real gain in omitting checks on many machines.
7636
7637 elsif Rtyp = Base_Type (Standard_Long_Long_Integer)
7638 or else (Rtyp = Base_Type (Standard_Long_Integer)
7639 and then
7640 Esize (Standard_Long_Integer) > Esize (Standard_Integer))
7641 or else (Rtyp = Universal_Integer)
7642 then
7643 Etyp := Standard_Long_Long_Integer;
7644
7645 if Ovflo then
7646 Rent := RE_Exp_Long_Long_Integer;
7647 else
7648 Rent := RE_Exn_Long_Long_Integer;
7649 end if;
7650
7651 elsif Is_Signed_Integer_Type (Rtyp) then
7652 Etyp := Standard_Integer;
7653
7654 if Ovflo then
7655 Rent := RE_Exp_Integer;
7656 else
7657 Rent := RE_Exn_Integer;
7658 end if;
7659
7660 -- Floating-point cases, always done using Long_Long_Float. We do not
7661 -- need separate routines for the overflow case here, since in the case
7662 -- of floating-point, we generate infinities anyway as a rule (either
7663 -- that or we automatically trap overflow), and if there is an infinity
7664 -- generated and a range check is required, the check will fail anyway.
7665
7666 else
7667 pragma Assert (Is_Floating_Point_Type (Rtyp));
7668 Etyp := Standard_Long_Long_Float;
7669 Rent := RE_Exn_Long_Long_Float;
7670 end if;
7671
7672 -- Common processing for integer cases and floating-point cases.
7673 -- If we are in the right type, we can call runtime routine directly
7674
7675 if Typ = Etyp
7676 and then Rtyp /= Universal_Integer
7677 and then Rtyp /= Universal_Real
7678 then
7679 Rewrite (N,
7680 Make_Function_Call (Loc,
7681 Name => New_Reference_To (RTE (Rent), Loc),
7682 Parameter_Associations => New_List (Base, Exp)));
7683
7684 -- Otherwise we have to introduce conversions (conversions are also
7685 -- required in the universal cases, since the runtime routine is
7686 -- typed using one of the standard types).
7687
7688 else
7689 Rewrite (N,
7690 Convert_To (Typ,
7691 Make_Function_Call (Loc,
7692 Name => New_Reference_To (RTE (Rent), Loc),
7693 Parameter_Associations => New_List (
7694 Convert_To (Etyp, Base),
7695 Exp))));
7696 end if;
7697
7698 Analyze_And_Resolve (N, Typ);
7699 return;
7700
7701 exception
7702 when RE_Not_Available =>
7703 return;
7704 end Expand_N_Op_Expon;
7705
7706 --------------------
7707 -- Expand_N_Op_Ge --
7708 --------------------
7709
7710 procedure Expand_N_Op_Ge (N : Node_Id) is
7711 Typ : constant Entity_Id := Etype (N);
7712 Op1 : constant Node_Id := Left_Opnd (N);
7713 Op2 : constant Node_Id := Right_Opnd (N);
7714 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
7715
7716 begin
7717 Binary_Op_Validity_Checks (N);
7718
7719 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
7720 -- results in not having a comparison operation any more, we are done.
7721
7722 Expand_Compare_Minimize_Eliminate_Overflow (N);
7723
7724 if Nkind (N) /= N_Op_Ge then
7725 return;
7726 end if;
7727
7728 -- Array type case
7729
7730 if Is_Array_Type (Typ1) then
7731 Expand_Array_Comparison (N);
7732 return;
7733 end if;
7734
7735 -- Deal with boolean operands
7736
7737 if Is_Boolean_Type (Typ1) then
7738 Adjust_Condition (Op1);
7739 Adjust_Condition (Op2);
7740 Set_Etype (N, Standard_Boolean);
7741 Adjust_Result_Type (N, Typ);
7742 end if;
7743
7744 Rewrite_Comparison (N);
7745
7746 -- If we still have comparison, and Vax_Float type, process it
7747
7748 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
7749 Expand_Vax_Comparison (N);
7750 return;
7751 end if;
7752
7753 Optimize_Length_Comparison (N);
7754 end Expand_N_Op_Ge;
7755
7756 --------------------
7757 -- Expand_N_Op_Gt --
7758 --------------------
7759
7760 procedure Expand_N_Op_Gt (N : Node_Id) is
7761 Typ : constant Entity_Id := Etype (N);
7762 Op1 : constant Node_Id := Left_Opnd (N);
7763 Op2 : constant Node_Id := Right_Opnd (N);
7764 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
7765
7766 begin
7767 Binary_Op_Validity_Checks (N);
7768
7769 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
7770 -- results in not having a comparison operation any more, we are done.
7771
7772 Expand_Compare_Minimize_Eliminate_Overflow (N);
7773
7774 if Nkind (N) /= N_Op_Gt then
7775 return;
7776 end if;
7777
7778 -- Deal with array type operands
7779
7780 if Is_Array_Type (Typ1) then
7781 Expand_Array_Comparison (N);
7782 return;
7783 end if;
7784
7785 -- Deal with boolean type operands
7786
7787 if Is_Boolean_Type (Typ1) then
7788 Adjust_Condition (Op1);
7789 Adjust_Condition (Op2);
7790 Set_Etype (N, Standard_Boolean);
7791 Adjust_Result_Type (N, Typ);
7792 end if;
7793
7794 Rewrite_Comparison (N);
7795
7796 -- If we still have comparison, and Vax_Float type, process it
7797
7798 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
7799 Expand_Vax_Comparison (N);
7800 return;
7801 end if;
7802
7803 Optimize_Length_Comparison (N);
7804 end Expand_N_Op_Gt;
7805
7806 --------------------
7807 -- Expand_N_Op_Le --
7808 --------------------
7809
7810 procedure Expand_N_Op_Le (N : Node_Id) is
7811 Typ : constant Entity_Id := Etype (N);
7812 Op1 : constant Node_Id := Left_Opnd (N);
7813 Op2 : constant Node_Id := Right_Opnd (N);
7814 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
7815
7816 begin
7817 Binary_Op_Validity_Checks (N);
7818
7819 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
7820 -- results in not having a comparison operation any more, we are done.
7821
7822 Expand_Compare_Minimize_Eliminate_Overflow (N);
7823
7824 if Nkind (N) /= N_Op_Le then
7825 return;
7826 end if;
7827
7828 -- Deal with array type operands
7829
7830 if Is_Array_Type (Typ1) then
7831 Expand_Array_Comparison (N);
7832 return;
7833 end if;
7834
7835 -- Deal with Boolean type operands
7836
7837 if Is_Boolean_Type (Typ1) then
7838 Adjust_Condition (Op1);
7839 Adjust_Condition (Op2);
7840 Set_Etype (N, Standard_Boolean);
7841 Adjust_Result_Type (N, Typ);
7842 end if;
7843
7844 Rewrite_Comparison (N);
7845
7846 -- If we still have comparison, and Vax_Float type, process it
7847
7848 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
7849 Expand_Vax_Comparison (N);
7850 return;
7851 end if;
7852
7853 Optimize_Length_Comparison (N);
7854 end Expand_N_Op_Le;
7855
7856 --------------------
7857 -- Expand_N_Op_Lt --
7858 --------------------
7859
7860 procedure Expand_N_Op_Lt (N : Node_Id) is
7861 Typ : constant Entity_Id := Etype (N);
7862 Op1 : constant Node_Id := Left_Opnd (N);
7863 Op2 : constant Node_Id := Right_Opnd (N);
7864 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
7865
7866 begin
7867 Binary_Op_Validity_Checks (N);
7868
7869 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
7870 -- results in not having a comparison operation any more, we are done.
7871
7872 Expand_Compare_Minimize_Eliminate_Overflow (N);
7873
7874 if Nkind (N) /= N_Op_Lt then
7875 return;
7876 end if;
7877
7878 -- Deal with array type operands
7879
7880 if Is_Array_Type (Typ1) then
7881 Expand_Array_Comparison (N);
7882 return;
7883 end if;
7884
7885 -- Deal with Boolean type operands
7886
7887 if Is_Boolean_Type (Typ1) then
7888 Adjust_Condition (Op1);
7889 Adjust_Condition (Op2);
7890 Set_Etype (N, Standard_Boolean);
7891 Adjust_Result_Type (N, Typ);
7892 end if;
7893
7894 Rewrite_Comparison (N);
7895
7896 -- If we still have comparison, and Vax_Float type, process it
7897
7898 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
7899 Expand_Vax_Comparison (N);
7900 return;
7901 end if;
7902
7903 Optimize_Length_Comparison (N);
7904 end Expand_N_Op_Lt;
7905
7906 -----------------------
7907 -- Expand_N_Op_Minus --
7908 -----------------------
7909
7910 procedure Expand_N_Op_Minus (N : Node_Id) is
7911 Loc : constant Source_Ptr := Sloc (N);
7912 Typ : constant Entity_Id := Etype (N);
7913
7914 begin
7915 Unary_Op_Validity_Checks (N);
7916
7917 -- Check for MINIMIZED/ELIMINATED overflow mode
7918
7919 if Minimized_Eliminated_Overflow_Check (N) then
7920 Apply_Arithmetic_Overflow_Check (N);
7921 return;
7922 end if;
7923
7924 if not Backend_Overflow_Checks_On_Target
7925 and then Is_Signed_Integer_Type (Etype (N))
7926 and then Do_Overflow_Check (N)
7927 then
7928 -- Software overflow checking expands -expr into (0 - expr)
7929
7930 Rewrite (N,
7931 Make_Op_Subtract (Loc,
7932 Left_Opnd => Make_Integer_Literal (Loc, 0),
7933 Right_Opnd => Right_Opnd (N)));
7934
7935 Analyze_And_Resolve (N, Typ);
7936
7937 -- Vax floating-point types case
7938
7939 elsif Vax_Float (Etype (N)) then
7940 Expand_Vax_Arith (N);
7941 end if;
7942 end Expand_N_Op_Minus;
7943
7944 ---------------------
7945 -- Expand_N_Op_Mod --
7946 ---------------------
7947
7948 procedure Expand_N_Op_Mod (N : Node_Id) is
7949 Loc : constant Source_Ptr := Sloc (N);
7950 Typ : constant Entity_Id := Etype (N);
7951 DOC : constant Boolean := Do_Overflow_Check (N);
7952 DDC : constant Boolean := Do_Division_Check (N);
7953
7954 Left : Node_Id;
7955 Right : Node_Id;
7956
7957 LLB : Uint;
7958 Llo : Uint;
7959 Lhi : Uint;
7960 LOK : Boolean;
7961 Rlo : Uint;
7962 Rhi : Uint;
7963 ROK : Boolean;
7964
7965 pragma Warnings (Off, Lhi);
7966
7967 begin
7968 Binary_Op_Validity_Checks (N);
7969
7970 -- Check for MINIMIZED/ELIMINATED overflow mode
7971
7972 if Minimized_Eliminated_Overflow_Check (N) then
7973 Apply_Arithmetic_Overflow_Check (N);
7974 return;
7975 end if;
7976
7977 if Is_Integer_Type (Etype (N)) then
7978 Apply_Divide_Checks (N);
7979
7980 -- All done if we don't have a MOD any more, which can happen as a
7981 -- result of overflow expansion in MINIMIZED or ELIMINATED modes.
7982
7983 if Nkind (N) /= N_Op_Mod then
7984 return;
7985 end if;
7986 end if;
7987
7988 -- Proceed with expansion of mod operator
7989
7990 Left := Left_Opnd (N);
7991 Right := Right_Opnd (N);
7992
7993 Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);
7994 Determine_Range (Left, LOK, Llo, Lhi, Assume_Valid => True);
7995
7996 -- Convert mod to rem if operands are known non-negative. We do this
7997 -- since it is quite likely that this will improve the quality of code,
7998 -- (the operation now corresponds to the hardware remainder), and it
7999 -- does not seem likely that it could be harmful.
8000
8001 if LOK and then Llo >= 0
8002 and then
8003 ROK and then Rlo >= 0
8004 then
8005 Rewrite (N,
8006 Make_Op_Rem (Sloc (N),
8007 Left_Opnd => Left_Opnd (N),
8008 Right_Opnd => Right_Opnd (N)));
8009
8010 -- Instead of reanalyzing the node we do the analysis manually. This
8011 -- avoids anomalies when the replacement is done in an instance and
8012 -- is epsilon more efficient.
8013
8014 Set_Entity (N, Standard_Entity (S_Op_Rem));
8015 Set_Etype (N, Typ);
8016 Set_Do_Overflow_Check (N, DOC);
8017 Set_Do_Division_Check (N, DDC);
8018 Expand_N_Op_Rem (N);
8019 Set_Analyzed (N);
8020
8021 -- Otherwise, normal mod processing
8022
8023 else
8024 -- Apply optimization x mod 1 = 0. We don't really need that with
8025 -- gcc, but it is useful with other back ends (e.g. AAMP), and is
8026 -- certainly harmless.
8027
8028 if Is_Integer_Type (Etype (N))
8029 and then Compile_Time_Known_Value (Right)
8030 and then Expr_Value (Right) = Uint_1
8031 then
8032 -- Call Remove_Side_Effects to ensure that any side effects in
8033 -- the ignored left operand (in particular function calls to
8034 -- user defined functions) are properly executed.
8035
8036 Remove_Side_Effects (Left);
8037
8038 Rewrite (N, Make_Integer_Literal (Loc, 0));
8039 Analyze_And_Resolve (N, Typ);
8040 return;
8041 end if;
8042
8043 -- Deal with annoying case of largest negative number remainder
8044 -- minus one. Gigi does not handle this case correctly, because
8045 -- it generates a divide instruction which may trap in this case.
8046
8047 -- In fact the check is quite easy, if the right operand is -1, then
8048 -- the mod value is always 0, and we can just ignore the left operand
8049 -- completely in this case.
8050
8051 -- This only applies if we still have a mod operator. Skip if we
8052 -- have already rewritten this (e.g. in the case of eliminated
8053 -- overflow checks which have driven us into bignum mode).
8054
8055 if Nkind (N) = N_Op_Mod then
8056
8057 -- The operand type may be private (e.g. in the expansion of an
8058 -- intrinsic operation) so we must use the underlying type to get
8059 -- the bounds, and convert the literals explicitly.
8060
8061 LLB :=
8062 Expr_Value
8063 (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
8064
8065 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
8066 and then
8067 ((not LOK) or else (Llo = LLB))
8068 then
8069 Rewrite (N,
8070 Make_If_Expression (Loc,
8071 Expressions => New_List (
8072 Make_Op_Eq (Loc,
8073 Left_Opnd => Duplicate_Subexpr (Right),
8074 Right_Opnd =>
8075 Unchecked_Convert_To (Typ,
8076 Make_Integer_Literal (Loc, -1))),
8077 Unchecked_Convert_To (Typ,
8078 Make_Integer_Literal (Loc, Uint_0)),
8079 Relocate_Node (N))));
8080
8081 Set_Analyzed (Next (Next (First (Expressions (N)))));
8082 Analyze_And_Resolve (N, Typ);
8083 end if;
8084 end if;
8085 end if;
8086 end Expand_N_Op_Mod;
8087
8088 --------------------------
8089 -- Expand_N_Op_Multiply --
8090 --------------------------
8091
8092 procedure Expand_N_Op_Multiply (N : Node_Id) is
8093 Loc : constant Source_Ptr := Sloc (N);
8094 Lop : constant Node_Id := Left_Opnd (N);
8095 Rop : constant Node_Id := Right_Opnd (N);
8096
8097 Lp2 : constant Boolean :=
8098 Nkind (Lop) = N_Op_Expon
8099 and then Is_Power_Of_2_For_Shift (Lop);
8100
8101 Rp2 : constant Boolean :=
8102 Nkind (Rop) = N_Op_Expon
8103 and then Is_Power_Of_2_For_Shift (Rop);
8104
8105 Ltyp : constant Entity_Id := Etype (Lop);
8106 Rtyp : constant Entity_Id := Etype (Rop);
8107 Typ : Entity_Id := Etype (N);
8108
8109 begin
8110 Binary_Op_Validity_Checks (N);
8111
8112 -- Check for MINIMIZED/ELIMINATED overflow mode
8113
8114 if Minimized_Eliminated_Overflow_Check (N) then
8115 Apply_Arithmetic_Overflow_Check (N);
8116 return;
8117 end if;
8118
8119 -- Special optimizations for integer types
8120
8121 if Is_Integer_Type (Typ) then
8122
8123 -- N * 0 = 0 for integer types
8124
8125 if Compile_Time_Known_Value (Rop)
8126 and then Expr_Value (Rop) = Uint_0
8127 then
8128 -- Call Remove_Side_Effects to ensure that any side effects in
8129 -- the ignored left operand (in particular function calls to
8130 -- user defined functions) are properly executed.
8131
8132 Remove_Side_Effects (Lop);
8133
8134 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
8135 Analyze_And_Resolve (N, Typ);
8136 return;
8137 end if;
8138
8139 -- Similar handling for 0 * N = 0
8140
8141 if Compile_Time_Known_Value (Lop)
8142 and then Expr_Value (Lop) = Uint_0
8143 then
8144 Remove_Side_Effects (Rop);
8145 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
8146 Analyze_And_Resolve (N, Typ);
8147 return;
8148 end if;
8149
8150 -- N * 1 = 1 * N = N for integer types
8151
8152 -- This optimisation is not done if we are going to
8153 -- rewrite the product 1 * 2 ** N to a shift.
8154
8155 if Compile_Time_Known_Value (Rop)
8156 and then Expr_Value (Rop) = Uint_1
8157 and then not Lp2
8158 then
8159 Rewrite (N, Lop);
8160 return;
8161
8162 elsif Compile_Time_Known_Value (Lop)
8163 and then Expr_Value (Lop) = Uint_1
8164 and then not Rp2
8165 then
8166 Rewrite (N, Rop);
8167 return;
8168 end if;
8169 end if;
8170
8171 -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
8172 -- Is_Power_Of_2_For_Shift is set means that we know that our left
8173 -- operand is an integer, as required for this to work.
8174
8175 if Rp2 then
8176 if Lp2 then
8177
8178 -- Convert 2 ** A * 2 ** B into 2 ** (A + B)
8179
8180 Rewrite (N,
8181 Make_Op_Expon (Loc,
8182 Left_Opnd => Make_Integer_Literal (Loc, 2),
8183 Right_Opnd =>
8184 Make_Op_Add (Loc,
8185 Left_Opnd => Right_Opnd (Lop),
8186 Right_Opnd => Right_Opnd (Rop))));
8187 Analyze_And_Resolve (N, Typ);
8188 return;
8189
8190 else
8191 Rewrite (N,
8192 Make_Op_Shift_Left (Loc,
8193 Left_Opnd => Lop,
8194 Right_Opnd =>
8195 Convert_To (Standard_Natural, Right_Opnd (Rop))));
8196 Analyze_And_Resolve (N, Typ);
8197 return;
8198 end if;
8199
8200 -- Same processing for the operands the other way round
8201
8202 elsif Lp2 then
8203 Rewrite (N,
8204 Make_Op_Shift_Left (Loc,
8205 Left_Opnd => Rop,
8206 Right_Opnd =>
8207 Convert_To (Standard_Natural, Right_Opnd (Lop))));
8208 Analyze_And_Resolve (N, Typ);
8209 return;
8210 end if;
8211
8212 -- Do required fixup of universal fixed operation
8213
8214 if Typ = Universal_Fixed then
8215 Fixup_Universal_Fixed_Operation (N);
8216 Typ := Etype (N);
8217 end if;
8218
8219 -- Multiplications with fixed-point results
8220
8221 if Is_Fixed_Point_Type (Typ) then
8222
8223 -- No special processing if Treat_Fixed_As_Integer is set, since from
8224 -- a semantic point of view such operations are simply integer
8225 -- operations and will be treated that way.
8226
8227 if not Treat_Fixed_As_Integer (N) then
8228
8229 -- Case of fixed * integer => fixed
8230
8231 if Is_Integer_Type (Rtyp) then
8232 Expand_Multiply_Fixed_By_Integer_Giving_Fixed (N);
8233
8234 -- Case of integer * fixed => fixed
8235
8236 elsif Is_Integer_Type (Ltyp) then
8237 Expand_Multiply_Integer_By_Fixed_Giving_Fixed (N);
8238
8239 -- Case of fixed * fixed => fixed
8240
8241 else
8242 Expand_Multiply_Fixed_By_Fixed_Giving_Fixed (N);
8243 end if;
8244 end if;
8245
8246 -- Other cases of multiplication of fixed-point operands. Again we
8247 -- exclude the cases where Treat_Fixed_As_Integer flag is set.
8248
8249 elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
8250 and then not Treat_Fixed_As_Integer (N)
8251 then
8252 if Is_Integer_Type (Typ) then
8253 Expand_Multiply_Fixed_By_Fixed_Giving_Integer (N);
8254 else
8255 pragma Assert (Is_Floating_Point_Type (Typ));
8256 Expand_Multiply_Fixed_By_Fixed_Giving_Float (N);
8257 end if;
8258
8259 -- Mixed-mode operations can appear in a non-static universal context,
8260 -- in which case the integer argument must be converted explicitly.
8261
8262 elsif Typ = Universal_Real
8263 and then Is_Integer_Type (Rtyp)
8264 then
8265 Rewrite (Rop, Convert_To (Universal_Real, Relocate_Node (Rop)));
8266
8267 Analyze_And_Resolve (Rop, Universal_Real);
8268
8269 elsif Typ = Universal_Real
8270 and then Is_Integer_Type (Ltyp)
8271 then
8272 Rewrite (Lop, Convert_To (Universal_Real, Relocate_Node (Lop)));
8273
8274 Analyze_And_Resolve (Lop, Universal_Real);
8275
8276 -- Non-fixed point cases, check software overflow checking required
8277
8278 elsif Is_Signed_Integer_Type (Etype (N)) then
8279 Apply_Arithmetic_Overflow_Check (N);
8280
8281 -- Deal with VAX float case
8282
8283 elsif Vax_Float (Typ) then
8284 Expand_Vax_Arith (N);
8285 return;
8286 end if;
8287 end Expand_N_Op_Multiply;
8288
8289 --------------------
8290 -- Expand_N_Op_Ne --
8291 --------------------
8292
8293 procedure Expand_N_Op_Ne (N : Node_Id) is
8294 Typ : constant Entity_Id := Etype (Left_Opnd (N));
8295
8296 begin
8297 -- Case of elementary type with standard operator
8298
8299 if Is_Elementary_Type (Typ)
8300 and then Sloc (Entity (N)) = Standard_Location
8301 then
8302 Binary_Op_Validity_Checks (N);
8303
8304 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if
8305 -- that results in not having a /= opertion any more, we are done.
8306
8307 Expand_Compare_Minimize_Eliminate_Overflow (N);
8308
8309 if Nkind (N) /= N_Op_Ne then
8310 return;
8311 end if;
8312
8313 -- Boolean types (requiring handling of non-standard case)
8314
8315 if Is_Boolean_Type (Typ) then
8316 Adjust_Condition (Left_Opnd (N));
8317 Adjust_Condition (Right_Opnd (N));
8318 Set_Etype (N, Standard_Boolean);
8319 Adjust_Result_Type (N, Typ);
8320 end if;
8321
8322 Rewrite_Comparison (N);
8323
8324 -- If we still have comparison for Vax_Float, process it
8325
8326 if Vax_Float (Typ) and then Nkind (N) in N_Op_Compare then
8327 Expand_Vax_Comparison (N);
8328 return;
8329 end if;
8330
8331 -- For all cases other than elementary types, we rewrite node as the
8332 -- negation of an equality operation, and reanalyze. The equality to be
8333 -- used is defined in the same scope and has the same signature. This
8334 -- signature must be set explicitly since in an instance it may not have
8335 -- the same visibility as in the generic unit. This avoids duplicating
8336 -- or factoring the complex code for record/array equality tests etc.
8337
8338 else
8339 declare
8340 Loc : constant Source_Ptr := Sloc (N);
8341 Neg : Node_Id;
8342 Ne : constant Entity_Id := Entity (N);
8343
8344 begin
8345 Binary_Op_Validity_Checks (N);
8346
8347 Neg :=
8348 Make_Op_Not (Loc,
8349 Right_Opnd =>
8350 Make_Op_Eq (Loc,
8351 Left_Opnd => Left_Opnd (N),
8352 Right_Opnd => Right_Opnd (N)));
8353 Set_Paren_Count (Right_Opnd (Neg), 1);
8354
8355 if Scope (Ne) /= Standard_Standard then
8356 Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
8357 end if;
8358
8359 -- For navigation purposes, we want to treat the inequality as an
8360 -- implicit reference to the corresponding equality. Preserve the
8361 -- Comes_From_ source flag to generate proper Xref entries.
8362
8363 Preserve_Comes_From_Source (Neg, N);
8364 Preserve_Comes_From_Source (Right_Opnd (Neg), N);
8365 Rewrite (N, Neg);
8366 Analyze_And_Resolve (N, Standard_Boolean);
8367 end;
8368 end if;
8369
8370 Optimize_Length_Comparison (N);
8371 end Expand_N_Op_Ne;
8372
8373 ---------------------
8374 -- Expand_N_Op_Not --
8375 ---------------------
8376
8377 -- If the argument is other than a Boolean array type, there is no special
8378 -- expansion required, except for VMS operations on signed integers.
8379
8380 -- For the packed case, we call the special routine in Exp_Pakd, except
8381 -- that if the component size is greater than one, we use the standard
8382 -- routine generating a gruesome loop (it is so peculiar to have packed
8383 -- arrays with non-standard Boolean representations anyway, so it does not
8384 -- matter that we do not handle this case efficiently).
8385
8386 -- For the unpacked case (and for the special packed case where we have non
8387 -- standard Booleans, as discussed above), we generate and insert into the
8388 -- tree the following function definition:
8389
8390 -- function Nnnn (A : arr) is
8391 -- B : arr;
8392 -- begin
8393 -- for J in a'range loop
8394 -- B (J) := not A (J);
8395 -- end loop;
8396 -- return B;
8397 -- end Nnnn;
8398
8399 -- Here arr is the actual subtype of the parameter (and hence always
8400 -- constrained). Then we replace the not with a call to this function.
8401
8402 procedure Expand_N_Op_Not (N : Node_Id) is
8403 Loc : constant Source_Ptr := Sloc (N);
8404 Typ : constant Entity_Id := Etype (N);
8405 Opnd : Node_Id;
8406 Arr : Entity_Id;
8407 A : Entity_Id;
8408 B : Entity_Id;
8409 J : Entity_Id;
8410 A_J : Node_Id;
8411 B_J : Node_Id;
8412
8413 Func_Name : Entity_Id;
8414 Loop_Statement : Node_Id;
8415
8416 begin
8417 Unary_Op_Validity_Checks (N);
8418
8419 -- For boolean operand, deal with non-standard booleans
8420
8421 if Is_Boolean_Type (Typ) then
8422 Adjust_Condition (Right_Opnd (N));
8423 Set_Etype (N, Standard_Boolean);
8424 Adjust_Result_Type (N, Typ);
8425 return;
8426 end if;
8427
8428 -- For the VMS "not" on signed integer types, use conversion to and from
8429 -- a predefined modular type.
8430
8431 if Is_VMS_Operator (Entity (N)) then
8432 declare
8433 Rtyp : Entity_Id;
8434 Utyp : Entity_Id;
8435
8436 begin
8437 -- If this is a derived type, retrieve original VMS type so that
8438 -- the proper sized type is used for intermediate values.
8439
8440 if Is_Derived_Type (Typ) then
8441 Rtyp := First_Subtype (Etype (Typ));
8442 else
8443 Rtyp := Typ;
8444 end if;
8445
8446 -- The proper unsigned type must have a size compatible with the
8447 -- operand, to prevent misalignment.
8448
8449 if RM_Size (Rtyp) <= 8 then
8450 Utyp := RTE (RE_Unsigned_8);
8451
8452 elsif RM_Size (Rtyp) <= 16 then
8453 Utyp := RTE (RE_Unsigned_16);
8454
8455 elsif RM_Size (Rtyp) = RM_Size (Standard_Unsigned) then
8456 Utyp := RTE (RE_Unsigned_32);
8457
8458 else
8459 Utyp := RTE (RE_Long_Long_Unsigned);
8460 end if;
8461
8462 Rewrite (N,
8463 Unchecked_Convert_To (Typ,
8464 Make_Op_Not (Loc,
8465 Unchecked_Convert_To (Utyp, Right_Opnd (N)))));
8466 Analyze_And_Resolve (N, Typ);
8467 return;
8468 end;
8469 end if;
8470
8471 -- Only array types need any other processing
8472
8473 if not Is_Array_Type (Typ) then
8474 return;
8475 end if;
8476
8477 -- Case of array operand. If bit packed with a component size of 1,
8478 -- handle it in Exp_Pakd if the operand is known to be aligned.
8479
8480 if Is_Bit_Packed_Array (Typ)
8481 and then Component_Size (Typ) = 1
8482 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
8483 then
8484 Expand_Packed_Not (N);
8485 return;
8486 end if;
8487
8488 -- Case of array operand which is not bit-packed. If the context is
8489 -- a safe assignment, call in-place operation, If context is a larger
8490 -- boolean expression in the context of a safe assignment, expansion is
8491 -- done by enclosing operation.
8492
8493 Opnd := Relocate_Node (Right_Opnd (N));
8494 Convert_To_Actual_Subtype (Opnd);
8495 Arr := Etype (Opnd);
8496 Ensure_Defined (Arr, N);
8497 Silly_Boolean_Array_Not_Test (N, Arr);
8498
8499 if Nkind (Parent (N)) = N_Assignment_Statement then
8500 if Safe_In_Place_Array_Op (Name (Parent (N)), N, Empty) then
8501 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
8502 return;
8503
8504 -- Special case the negation of a binary operation
8505
8506 elsif Nkind_In (Opnd, N_Op_And, N_Op_Or, N_Op_Xor)
8507 and then Safe_In_Place_Array_Op
8508 (Name (Parent (N)), Left_Opnd (Opnd), Right_Opnd (Opnd))
8509 then
8510 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
8511 return;
8512 end if;
8513
8514 elsif Nkind (Parent (N)) in N_Binary_Op
8515 and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
8516 then
8517 declare
8518 Op1 : constant Node_Id := Left_Opnd (Parent (N));
8519 Op2 : constant Node_Id := Right_Opnd (Parent (N));
8520 Lhs : constant Node_Id := Name (Parent (Parent (N)));
8521
8522 begin
8523 if Safe_In_Place_Array_Op (Lhs, Op1, Op2) then
8524
8525 -- (not A) op (not B) can be reduced to a single call
8526
8527 if N = Op1 and then Nkind (Op2) = N_Op_Not then
8528 return;
8529
8530 elsif N = Op2 and then Nkind (Op1) = N_Op_Not then
8531 return;
8532
8533 -- A xor (not B) can also be special-cased
8534
8535 elsif N = Op2 and then Nkind (Parent (N)) = N_Op_Xor then
8536 return;
8537 end if;
8538 end if;
8539 end;
8540 end if;
8541
8542 A := Make_Defining_Identifier (Loc, Name_uA);
8543 B := Make_Defining_Identifier (Loc, Name_uB);
8544 J := Make_Defining_Identifier (Loc, Name_uJ);
8545
8546 A_J :=
8547 Make_Indexed_Component (Loc,
8548 Prefix => New_Reference_To (A, Loc),
8549 Expressions => New_List (New_Reference_To (J, Loc)));
8550
8551 B_J :=
8552 Make_Indexed_Component (Loc,
8553 Prefix => New_Reference_To (B, Loc),
8554 Expressions => New_List (New_Reference_To (J, Loc)));
8555
8556 Loop_Statement :=
8557 Make_Implicit_Loop_Statement (N,
8558 Identifier => Empty,
8559
8560 Iteration_Scheme =>
8561 Make_Iteration_Scheme (Loc,
8562 Loop_Parameter_Specification =>
8563 Make_Loop_Parameter_Specification (Loc,
8564 Defining_Identifier => J,
8565 Discrete_Subtype_Definition =>
8566 Make_Attribute_Reference (Loc,
8567 Prefix => Make_Identifier (Loc, Chars (A)),
8568 Attribute_Name => Name_Range))),
8569
8570 Statements => New_List (
8571 Make_Assignment_Statement (Loc,
8572 Name => B_J,
8573 Expression => Make_Op_Not (Loc, A_J))));
8574
8575 Func_Name := Make_Temporary (Loc, 'N');
8576 Set_Is_Inlined (Func_Name);
8577
8578 Insert_Action (N,
8579 Make_Subprogram_Body (Loc,
8580 Specification =>
8581 Make_Function_Specification (Loc,
8582 Defining_Unit_Name => Func_Name,
8583 Parameter_Specifications => New_List (
8584 Make_Parameter_Specification (Loc,
8585 Defining_Identifier => A,
8586 Parameter_Type => New_Reference_To (Typ, Loc))),
8587 Result_Definition => New_Reference_To (Typ, Loc)),
8588
8589 Declarations => New_List (
8590 Make_Object_Declaration (Loc,
8591 Defining_Identifier => B,
8592 Object_Definition => New_Reference_To (Arr, Loc))),
8593
8594 Handled_Statement_Sequence =>
8595 Make_Handled_Sequence_Of_Statements (Loc,
8596 Statements => New_List (
8597 Loop_Statement,
8598 Make_Simple_Return_Statement (Loc,
8599 Expression => Make_Identifier (Loc, Chars (B)))))));
8600
8601 Rewrite (N,
8602 Make_Function_Call (Loc,
8603 Name => New_Reference_To (Func_Name, Loc),
8604 Parameter_Associations => New_List (Opnd)));
8605
8606 Analyze_And_Resolve (N, Typ);
8607 end Expand_N_Op_Not;
8608
8609 --------------------
8610 -- Expand_N_Op_Or --
8611 --------------------
8612
8613 procedure Expand_N_Op_Or (N : Node_Id) is
8614 Typ : constant Entity_Id := Etype (N);
8615
8616 begin
8617 Binary_Op_Validity_Checks (N);
8618
8619 if Is_Array_Type (Etype (N)) then
8620 Expand_Boolean_Operator (N);
8621
8622 elsif Is_Boolean_Type (Etype (N)) then
8623 Adjust_Condition (Left_Opnd (N));
8624 Adjust_Condition (Right_Opnd (N));
8625 Set_Etype (N, Standard_Boolean);
8626 Adjust_Result_Type (N, Typ);
8627
8628 elsif Is_Intrinsic_Subprogram (Entity (N)) then
8629 Expand_Intrinsic_Call (N, Entity (N));
8630
8631 end if;
8632 end Expand_N_Op_Or;
8633
8634 ----------------------
8635 -- Expand_N_Op_Plus --
8636 ----------------------
8637
8638 procedure Expand_N_Op_Plus (N : Node_Id) is
8639 begin
8640 Unary_Op_Validity_Checks (N);
8641
8642 -- Check for MINIMIZED/ELIMINATED overflow mode
8643
8644 if Minimized_Eliminated_Overflow_Check (N) then
8645 Apply_Arithmetic_Overflow_Check (N);
8646 return;
8647 end if;
8648 end Expand_N_Op_Plus;
8649
8650 ---------------------
8651 -- Expand_N_Op_Rem --
8652 ---------------------
8653
8654 procedure Expand_N_Op_Rem (N : Node_Id) is
8655 Loc : constant Source_Ptr := Sloc (N);
8656 Typ : constant Entity_Id := Etype (N);
8657
8658 Left : Node_Id;
8659 Right : Node_Id;
8660
8661 Lo : Uint;
8662 Hi : Uint;
8663 OK : Boolean;
8664
8665 Lneg : Boolean;
8666 Rneg : Boolean;
8667 -- Set if corresponding operand can be negative
8668
8669 pragma Unreferenced (Hi);
8670
8671 begin
8672 Binary_Op_Validity_Checks (N);
8673
8674 -- Check for MINIMIZED/ELIMINATED overflow mode
8675
8676 if Minimized_Eliminated_Overflow_Check (N) then
8677 Apply_Arithmetic_Overflow_Check (N);
8678 return;
8679 end if;
8680
8681 if Is_Integer_Type (Etype (N)) then
8682 Apply_Divide_Checks (N);
8683
8684 -- All done if we don't have a REM any more, which can happen as a
8685 -- result of overflow expansion in MINIMIZED or ELIMINATED modes.
8686
8687 if Nkind (N) /= N_Op_Rem then
8688 return;
8689 end if;
8690 end if;
8691
8692 -- Proceed with expansion of REM
8693
8694 Left := Left_Opnd (N);
8695 Right := Right_Opnd (N);
8696
8697 -- Apply optimization x rem 1 = 0. We don't really need that with gcc,
8698 -- but it is useful with other back ends (e.g. AAMP), and is certainly
8699 -- harmless.
8700
8701 if Is_Integer_Type (Etype (N))
8702 and then Compile_Time_Known_Value (Right)
8703 and then Expr_Value (Right) = Uint_1
8704 then
8705 -- Call Remove_Side_Effects to ensure that any side effects in the
8706 -- ignored left operand (in particular function calls to user defined
8707 -- functions) are properly executed.
8708
8709 Remove_Side_Effects (Left);
8710
8711 Rewrite (N, Make_Integer_Literal (Loc, 0));
8712 Analyze_And_Resolve (N, Typ);
8713 return;
8714 end if;
8715
8716 -- Deal with annoying case of largest negative number remainder minus
8717 -- one. Gigi does not handle this case correctly, because it generates
8718 -- a divide instruction which may trap in this case.
8719
8720 -- In fact the check is quite easy, if the right operand is -1, then
8721 -- the remainder is always 0, and we can just ignore the left operand
8722 -- completely in this case.
8723
8724 Determine_Range (Right, OK, Lo, Hi, Assume_Valid => True);
8725 Lneg := (not OK) or else Lo < 0;
8726
8727 Determine_Range (Left, OK, Lo, Hi, Assume_Valid => True);
8728 Rneg := (not OK) or else Lo < 0;
8729
8730 -- We won't mess with trying to find out if the left operand can really
8731 -- be the largest negative number (that's a pain in the case of private
8732 -- types and this is really marginal). We will just assume that we need
8733 -- the test if the left operand can be negative at all.
8734
8735 if Lneg and Rneg then
8736 Rewrite (N,
8737 Make_If_Expression (Loc,
8738 Expressions => New_List (
8739 Make_Op_Eq (Loc,
8740 Left_Opnd => Duplicate_Subexpr (Right),
8741 Right_Opnd =>
8742 Unchecked_Convert_To (Typ, Make_Integer_Literal (Loc, -1))),
8743
8744 Unchecked_Convert_To (Typ,
8745 Make_Integer_Literal (Loc, Uint_0)),
8746
8747 Relocate_Node (N))));
8748
8749 Set_Analyzed (Next (Next (First (Expressions (N)))));
8750 Analyze_And_Resolve (N, Typ);
8751 end if;
8752 end Expand_N_Op_Rem;
8753
8754 -----------------------------
8755 -- Expand_N_Op_Rotate_Left --
8756 -----------------------------
8757
8758 procedure Expand_N_Op_Rotate_Left (N : Node_Id) is
8759 begin
8760 Binary_Op_Validity_Checks (N);
8761 end Expand_N_Op_Rotate_Left;
8762
8763 ------------------------------
8764 -- Expand_N_Op_Rotate_Right --
8765 ------------------------------
8766
8767 procedure Expand_N_Op_Rotate_Right (N : Node_Id) is
8768 begin
8769 Binary_Op_Validity_Checks (N);
8770 end Expand_N_Op_Rotate_Right;
8771
8772 ----------------------------
8773 -- Expand_N_Op_Shift_Left --
8774 ----------------------------
8775
8776 procedure Expand_N_Op_Shift_Left (N : Node_Id) is
8777 begin
8778 Binary_Op_Validity_Checks (N);
8779 end Expand_N_Op_Shift_Left;
8780
8781 -----------------------------
8782 -- Expand_N_Op_Shift_Right --
8783 -----------------------------
8784
8785 procedure Expand_N_Op_Shift_Right (N : Node_Id) is
8786 begin
8787 Binary_Op_Validity_Checks (N);
8788 end Expand_N_Op_Shift_Right;
8789
8790 ----------------------------------------
8791 -- Expand_N_Op_Shift_Right_Arithmetic --
8792 ----------------------------------------
8793
8794 procedure Expand_N_Op_Shift_Right_Arithmetic (N : Node_Id) is
8795 begin
8796 Binary_Op_Validity_Checks (N);
8797 end Expand_N_Op_Shift_Right_Arithmetic;
8798
8799 --------------------------
8800 -- Expand_N_Op_Subtract --
8801 --------------------------
8802
8803 procedure Expand_N_Op_Subtract (N : Node_Id) is
8804 Typ : constant Entity_Id := Etype (N);
8805
8806 begin
8807 Binary_Op_Validity_Checks (N);
8808
8809 -- Check for MINIMIZED/ELIMINATED overflow mode
8810
8811 if Minimized_Eliminated_Overflow_Check (N) then
8812 Apply_Arithmetic_Overflow_Check (N);
8813 return;
8814 end if;
8815
8816 -- N - 0 = N for integer types
8817
8818 if Is_Integer_Type (Typ)
8819 and then Compile_Time_Known_Value (Right_Opnd (N))
8820 and then Expr_Value (Right_Opnd (N)) = 0
8821 then
8822 Rewrite (N, Left_Opnd (N));
8823 return;
8824 end if;
8825
8826 -- Arithmetic overflow checks for signed integer/fixed point types
8827
8828 if Is_Signed_Integer_Type (Typ)
8829 or else
8830 Is_Fixed_Point_Type (Typ)
8831 then
8832 Apply_Arithmetic_Overflow_Check (N);
8833
8834 -- VAX floating-point types case
8835
8836 elsif Vax_Float (Typ) then
8837 Expand_Vax_Arith (N);
8838 end if;
8839 end Expand_N_Op_Subtract;
8840
8841 ---------------------
8842 -- Expand_N_Op_Xor --
8843 ---------------------
8844
8845 procedure Expand_N_Op_Xor (N : Node_Id) is
8846 Typ : constant Entity_Id := Etype (N);
8847
8848 begin
8849 Binary_Op_Validity_Checks (N);
8850
8851 if Is_Array_Type (Etype (N)) then
8852 Expand_Boolean_Operator (N);
8853
8854 elsif Is_Boolean_Type (Etype (N)) then
8855 Adjust_Condition (Left_Opnd (N));
8856 Adjust_Condition (Right_Opnd (N));
8857 Set_Etype (N, Standard_Boolean);
8858 Adjust_Result_Type (N, Typ);
8859
8860 elsif Is_Intrinsic_Subprogram (Entity (N)) then
8861 Expand_Intrinsic_Call (N, Entity (N));
8862
8863 end if;
8864 end Expand_N_Op_Xor;
8865
8866 ----------------------
8867 -- Expand_N_Or_Else --
8868 ----------------------
8869
8870 procedure Expand_N_Or_Else (N : Node_Id)
8871 renames Expand_Short_Circuit_Operator;
8872
8873 -----------------------------------
8874 -- Expand_N_Qualified_Expression --
8875 -----------------------------------
8876
8877 procedure Expand_N_Qualified_Expression (N : Node_Id) is
8878 Operand : constant Node_Id := Expression (N);
8879 Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));
8880
8881 begin
8882 -- Do validity check if validity checking operands
8883
8884 if Validity_Checks_On and then Validity_Check_Operands then
8885 Ensure_Valid (Operand);
8886 end if;
8887
8888 -- Apply possible constraint check
8889
8890 Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);
8891
8892 if Do_Range_Check (Operand) then
8893 Set_Do_Range_Check (Operand, False);
8894 Generate_Range_Check (Operand, Target_Type, CE_Range_Check_Failed);
8895 end if;
8896 end Expand_N_Qualified_Expression;
8897
8898 ------------------------------------
8899 -- Expand_N_Quantified_Expression --
8900 ------------------------------------
8901
8902 -- We expand:
8903
8904 -- for all X in range => Cond
8905
8906 -- into:
8907
8908 -- T := True;
8909 -- for X in range loop
8910 -- if not Cond then
8911 -- T := False;
8912 -- exit;
8913 -- end if;
8914 -- end loop;
8915
8916 -- Similarly, an existentially quantified expression:
8917
8918 -- for some X in range => Cond
8919
8920 -- becomes:
8921
8922 -- T := False;
8923 -- for X in range loop
8924 -- if Cond then
8925 -- T := True;
8926 -- exit;
8927 -- end if;
8928 -- end loop;
8929
8930 -- In both cases, the iteration may be over a container in which case it is
8931 -- given by an iterator specification, not a loop parameter specification.
8932
8933 procedure Expand_N_Quantified_Expression (N : Node_Id) is
8934 Actions : constant List_Id := New_List;
8935 For_All : constant Boolean := All_Present (N);
8936 Iter_Spec : constant Node_Id := Iterator_Specification (N);
8937 Loc : constant Source_Ptr := Sloc (N);
8938 Loop_Spec : constant Node_Id := Loop_Parameter_Specification (N);
8939 Cond : Node_Id;
8940 Flag : Entity_Id;
8941 Scheme : Node_Id;
8942 Stmts : List_Id;
8943
8944 begin
8945 -- Create the declaration of the flag which tracks the status of the
8946 -- quantified expression. Generate:
8947
8948 -- Flag : Boolean := (True | False);
8949
8950 Flag := Make_Temporary (Loc, 'T', N);
8951
8952 Append_To (Actions,
8953 Make_Object_Declaration (Loc,
8954 Defining_Identifier => Flag,
8955 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
8956 Expression =>
8957 New_Occurrence_Of (Boolean_Literals (For_All), Loc)));
8958
8959 -- Construct the circuitry which tracks the status of the quantified
8960 -- expression. Generate:
8961
8962 -- if [not] Cond then
8963 -- Flag := (False | True);
8964 -- exit;
8965 -- end if;
8966
8967 Cond := Relocate_Node (Condition (N));
8968
8969 if For_All then
8970 Cond := Make_Op_Not (Loc, Cond);
8971 end if;
8972
8973 Stmts := New_List (
8974 Make_Implicit_If_Statement (N,
8975 Condition => Cond,
8976 Then_Statements => New_List (
8977 Make_Assignment_Statement (Loc,
8978 Name => New_Occurrence_Of (Flag, Loc),
8979 Expression =>
8980 New_Occurrence_Of (Boolean_Literals (not For_All), Loc)),
8981 Make_Exit_Statement (Loc))));
8982
8983 -- Build the loop equivalent of the quantified expression
8984
8985 if Present (Iter_Spec) then
8986 Scheme :=
8987 Make_Iteration_Scheme (Loc,
8988 Iterator_Specification => Iter_Spec);
8989 else
8990 Scheme :=
8991 Make_Iteration_Scheme (Loc,
8992 Loop_Parameter_Specification => Loop_Spec);
8993 end if;
8994
8995 Append_To (Actions,
8996 Make_Loop_Statement (Loc,
8997 Iteration_Scheme => Scheme,
8998 Statements => Stmts,
8999 End_Label => Empty));
9000
9001 -- Transform the quantified expression
9002
9003 Rewrite (N,
9004 Make_Expression_With_Actions (Loc,
9005 Expression => New_Occurrence_Of (Flag, Loc),
9006 Actions => Actions));
9007 Analyze_And_Resolve (N, Standard_Boolean);
9008 end Expand_N_Quantified_Expression;
9009
9010 ---------------------------------
9011 -- Expand_N_Selected_Component --
9012 ---------------------------------
9013
9014 procedure Expand_N_Selected_Component (N : Node_Id) is
9015 Loc : constant Source_Ptr := Sloc (N);
9016 Par : constant Node_Id := Parent (N);
9017 P : constant Node_Id := Prefix (N);
9018 Ptyp : Entity_Id := Underlying_Type (Etype (P));
9019 Disc : Entity_Id;
9020 New_N : Node_Id;
9021 Dcon : Elmt_Id;
9022 Dval : Node_Id;
9023
9024 function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
9025 -- Gigi needs a temporary for prefixes that depend on a discriminant,
9026 -- unless the context of an assignment can provide size information.
9027 -- Don't we have a general routine that does this???
9028
9029 function Is_Subtype_Declaration return Boolean;
9030 -- The replacement of a discriminant reference by its value is required
9031 -- if this is part of the initialization of an temporary generated by a
9032 -- change of representation. This shows up as the construction of a
9033 -- discriminant constraint for a subtype declared at the same point as
9034 -- the entity in the prefix of the selected component. We recognize this
9035 -- case when the context of the reference is:
9036 -- subtype ST is T(Obj.D);
9037 -- where the entity for Obj comes from source, and ST has the same sloc.
9038
9039 -----------------------
9040 -- In_Left_Hand_Side --
9041 -----------------------
9042
9043 function In_Left_Hand_Side (Comp : Node_Id) return Boolean is
9044 begin
9045 return (Nkind (Parent (Comp)) = N_Assignment_Statement
9046 and then Comp = Name (Parent (Comp)))
9047 or else (Present (Parent (Comp))
9048 and then Nkind (Parent (Comp)) in N_Subexpr
9049 and then In_Left_Hand_Side (Parent (Comp)));
9050 end In_Left_Hand_Side;
9051
9052 -----------------------------
9053 -- Is_Subtype_Declaration --
9054 -----------------------------
9055
9056 function Is_Subtype_Declaration return Boolean is
9057 Par : constant Node_Id := Parent (N);
9058 begin
9059 return
9060 Nkind (Par) = N_Index_Or_Discriminant_Constraint
9061 and then Nkind (Parent (Parent (Par))) = N_Subtype_Declaration
9062 and then Comes_From_Source (Entity (Prefix (N)))
9063 and then Sloc (Par) = Sloc (Entity (Prefix (N)));
9064 end Is_Subtype_Declaration;
9065
9066 -- Start of processing for Expand_N_Selected_Component
9067
9068 begin
9069 -- Insert explicit dereference if required
9070
9071 if Is_Access_Type (Ptyp) then
9072
9073 -- First set prefix type to proper access type, in case it currently
9074 -- has a private (non-access) view of this type.
9075
9076 Set_Etype (P, Ptyp);
9077
9078 Insert_Explicit_Dereference (P);
9079 Analyze_And_Resolve (P, Designated_Type (Ptyp));
9080
9081 if Ekind (Etype (P)) = E_Private_Subtype
9082 and then Is_For_Access_Subtype (Etype (P))
9083 then
9084 Set_Etype (P, Base_Type (Etype (P)));
9085 end if;
9086
9087 Ptyp := Etype (P);
9088 end if;
9089
9090 -- Deal with discriminant check required
9091
9092 if Do_Discriminant_Check (N) then
9093
9094 -- Present the discriminant checking function to the backend, so that
9095 -- it can inline the call to the function.
9096
9097 Add_Inlined_Body
9098 (Discriminant_Checking_Func
9099 (Original_Record_Component (Entity (Selector_Name (N)))));
9100
9101 -- Now reset the flag and generate the call
9102
9103 Set_Do_Discriminant_Check (N, False);
9104 Generate_Discriminant_Check (N);
9105 end if;
9106
9107 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
9108 -- function, then additional actuals must be passed.
9109
9110 if Ada_Version >= Ada_2005
9111 and then Is_Build_In_Place_Function_Call (P)
9112 then
9113 Make_Build_In_Place_Call_In_Anonymous_Context (P);
9114 end if;
9115
9116 -- Gigi cannot handle unchecked conversions that are the prefix of a
9117 -- selected component with discriminants. This must be checked during
9118 -- expansion, because during analysis the type of the selector is not
9119 -- known at the point the prefix is analyzed. If the conversion is the
9120 -- target of an assignment, then we cannot force the evaluation.
9121
9122 if Nkind (Prefix (N)) = N_Unchecked_Type_Conversion
9123 and then Has_Discriminants (Etype (N))
9124 and then not In_Left_Hand_Side (N)
9125 then
9126 Force_Evaluation (Prefix (N));
9127 end if;
9128
9129 -- Remaining processing applies only if selector is a discriminant
9130
9131 if Ekind (Entity (Selector_Name (N))) = E_Discriminant then
9132
9133 -- If the selector is a discriminant of a constrained record type,
9134 -- we may be able to rewrite the expression with the actual value
9135 -- of the discriminant, a useful optimization in some cases.
9136
9137 if Is_Record_Type (Ptyp)
9138 and then Has_Discriminants (Ptyp)
9139 and then Is_Constrained (Ptyp)
9140 then
9141 -- Do this optimization for discrete types only, and not for
9142 -- access types (access discriminants get us into trouble!)
9143
9144 if not Is_Discrete_Type (Etype (N)) then
9145 null;
9146
9147 -- Don't do this on the left hand of an assignment statement.
9148 -- Normally one would think that references like this would not
9149 -- occur, but they do in generated code, and mean that we really
9150 -- do want to assign the discriminant!
9151
9152 elsif Nkind (Par) = N_Assignment_Statement
9153 and then Name (Par) = N
9154 then
9155 null;
9156
9157 -- Don't do this optimization for the prefix of an attribute or
9158 -- the name of an object renaming declaration since these are
9159 -- contexts where we do not want the value anyway.
9160
9161 elsif (Nkind (Par) = N_Attribute_Reference
9162 and then Prefix (Par) = N)
9163 or else Is_Renamed_Object (N)
9164 then
9165 null;
9166
9167 -- Don't do this optimization if we are within the code for a
9168 -- discriminant check, since the whole point of such a check may
9169 -- be to verify the condition on which the code below depends!
9170
9171 elsif Is_In_Discriminant_Check (N) then
9172 null;
9173
9174 -- Green light to see if we can do the optimization. There is
9175 -- still one condition that inhibits the optimization below but
9176 -- now is the time to check the particular discriminant.
9177
9178 else
9179 -- Loop through discriminants to find the matching discriminant
9180 -- constraint to see if we can copy it.
9181
9182 Disc := First_Discriminant (Ptyp);
9183 Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
9184 Discr_Loop : while Present (Dcon) loop
9185 Dval := Node (Dcon);
9186
9187 -- Check if this is the matching discriminant and if the
9188 -- discriminant value is simple enough to make sense to
9189 -- copy. We don't want to copy complex expressions, and
9190 -- indeed to do so can cause trouble (before we put in
9191 -- this guard, a discriminant expression containing an
9192 -- AND THEN was copied, causing problems for coverage
9193 -- analysis tools).
9194
9195 -- However, if the reference is part of the initialization
9196 -- code generated for an object declaration, we must use
9197 -- the discriminant value from the subtype constraint,
9198 -- because the selected component may be a reference to the
9199 -- object being initialized, whose discriminant is not yet
9200 -- set. This only happens in complex cases involving changes
9201 -- or representation.
9202
9203 if Disc = Entity (Selector_Name (N))
9204 and then (Is_Entity_Name (Dval)
9205 or else Compile_Time_Known_Value (Dval)
9206 or else Is_Subtype_Declaration)
9207 then
9208 -- Here we have the matching discriminant. Check for
9209 -- the case of a discriminant of a component that is
9210 -- constrained by an outer discriminant, which cannot
9211 -- be optimized away.
9212
9213 if Denotes_Discriminant
9214 (Dval, Check_Concurrent => True)
9215 then
9216 exit Discr_Loop;
9217
9218 elsif Nkind (Original_Node (Dval)) = N_Selected_Component
9219 and then
9220 Denotes_Discriminant
9221 (Selector_Name (Original_Node (Dval)), True)
9222 then
9223 exit Discr_Loop;
9224
9225 -- Do not retrieve value if constraint is not static. It
9226 -- is generally not useful, and the constraint may be a
9227 -- rewritten outer discriminant in which case it is in
9228 -- fact incorrect.
9229
9230 elsif Is_Entity_Name (Dval)
9231 and then Nkind (Parent (Entity (Dval))) =
9232 N_Object_Declaration
9233 and then Present (Expression (Parent (Entity (Dval))))
9234 and then
9235 not Is_Static_Expression
9236 (Expression (Parent (Entity (Dval))))
9237 then
9238 exit Discr_Loop;
9239
9240 -- In the context of a case statement, the expression may
9241 -- have the base type of the discriminant, and we need to
9242 -- preserve the constraint to avoid spurious errors on
9243 -- missing cases.
9244
9245 elsif Nkind (Parent (N)) = N_Case_Statement
9246 and then Etype (Dval) /= Etype (Disc)
9247 then
9248 Rewrite (N,
9249 Make_Qualified_Expression (Loc,
9250 Subtype_Mark =>
9251 New_Occurrence_Of (Etype (Disc), Loc),
9252 Expression =>
9253 New_Copy_Tree (Dval)));
9254 Analyze_And_Resolve (N, Etype (Disc));
9255
9256 -- In case that comes out as a static expression,
9257 -- reset it (a selected component is never static).
9258
9259 Set_Is_Static_Expression (N, False);
9260 return;
9261
9262 -- Otherwise we can just copy the constraint, but the
9263 -- result is certainly not static! In some cases the
9264 -- discriminant constraint has been analyzed in the
9265 -- context of the original subtype indication, but for
9266 -- itypes the constraint might not have been analyzed
9267 -- yet, and this must be done now.
9268
9269 else
9270 Rewrite (N, New_Copy_Tree (Dval));
9271 Analyze_And_Resolve (N);
9272 Set_Is_Static_Expression (N, False);
9273 return;
9274 end if;
9275 end if;
9276
9277 Next_Elmt (Dcon);
9278 Next_Discriminant (Disc);
9279 end loop Discr_Loop;
9280
9281 -- Note: the above loop should always find a matching
9282 -- discriminant, but if it does not, we just missed an
9283 -- optimization due to some glitch (perhaps a previous
9284 -- error), so ignore.
9285
9286 end if;
9287 end if;
9288
9289 -- The only remaining processing is in the case of a discriminant of
9290 -- a concurrent object, where we rewrite the prefix to denote the
9291 -- corresponding record type. If the type is derived and has renamed
9292 -- discriminants, use corresponding discriminant, which is the one
9293 -- that appears in the corresponding record.
9294
9295 if not Is_Concurrent_Type (Ptyp) then
9296 return;
9297 end if;
9298
9299 Disc := Entity (Selector_Name (N));
9300
9301 if Is_Derived_Type (Ptyp)
9302 and then Present (Corresponding_Discriminant (Disc))
9303 then
9304 Disc := Corresponding_Discriminant (Disc);
9305 end if;
9306
9307 New_N :=
9308 Make_Selected_Component (Loc,
9309 Prefix =>
9310 Unchecked_Convert_To (Corresponding_Record_Type (Ptyp),
9311 New_Copy_Tree (P)),
9312 Selector_Name => Make_Identifier (Loc, Chars (Disc)));
9313
9314 Rewrite (N, New_N);
9315 Analyze (N);
9316 end if;
9317
9318 -- Set Atomic_Sync_Required if necessary for atomic component
9319
9320 if Nkind (N) = N_Selected_Component then
9321 declare
9322 E : constant Entity_Id := Entity (Selector_Name (N));
9323 Set : Boolean;
9324
9325 begin
9326 -- If component is atomic, but type is not, setting depends on
9327 -- disable/enable state for the component.
9328
9329 if Is_Atomic (E) and then not Is_Atomic (Etype (E)) then
9330 Set := not Atomic_Synchronization_Disabled (E);
9331
9332 -- If component is not atomic, but its type is atomic, setting
9333 -- depends on disable/enable state for the type.
9334
9335 elsif not Is_Atomic (E) and then Is_Atomic (Etype (E)) then
9336 Set := not Atomic_Synchronization_Disabled (Etype (E));
9337
9338 -- If both component and type are atomic, we disable if either
9339 -- component or its type have sync disabled.
9340
9341 elsif Is_Atomic (E) and then Is_Atomic (Etype (E)) then
9342 Set := (not Atomic_Synchronization_Disabled (E))
9343 and then
9344 (not Atomic_Synchronization_Disabled (Etype (E)));
9345
9346 else
9347 Set := False;
9348 end if;
9349
9350 -- Set flag if required
9351
9352 if Set then
9353 Activate_Atomic_Synchronization (N);
9354 end if;
9355 end;
9356 end if;
9357 end Expand_N_Selected_Component;
9358
9359 --------------------
9360 -- Expand_N_Slice --
9361 --------------------
9362
9363 procedure Expand_N_Slice (N : Node_Id) is
9364 Loc : constant Source_Ptr := Sloc (N);
9365 Typ : constant Entity_Id := Etype (N);
9366 Pfx : constant Node_Id := Prefix (N);
9367 Ptp : Entity_Id := Etype (Pfx);
9368
9369 function Is_Procedure_Actual (N : Node_Id) return Boolean;
9370 -- Check whether the argument is an actual for a procedure call, in
9371 -- which case the expansion of a bit-packed slice is deferred until the
9372 -- call itself is expanded. The reason this is required is that we might
9373 -- have an IN OUT or OUT parameter, and the copy out is essential, and
9374 -- that copy out would be missed if we created a temporary here in
9375 -- Expand_N_Slice. Note that we don't bother to test specifically for an
9376 -- IN OUT or OUT mode parameter, since it is a bit tricky to do, and it
9377 -- is harmless to defer expansion in the IN case, since the call
9378 -- processing will still generate the appropriate copy in operation,
9379 -- which will take care of the slice.
9380
9381 procedure Make_Temporary_For_Slice;
9382 -- Create a named variable for the value of the slice, in cases where
9383 -- the back-end cannot handle it properly, e.g. when packed types or
9384 -- unaligned slices are involved.
9385
9386 -------------------------
9387 -- Is_Procedure_Actual --
9388 -------------------------
9389
9390 function Is_Procedure_Actual (N : Node_Id) return Boolean is
9391 Par : Node_Id := Parent (N);
9392
9393 begin
9394 loop
9395 -- If our parent is a procedure call we can return
9396
9397 if Nkind (Par) = N_Procedure_Call_Statement then
9398 return True;
9399
9400 -- If our parent is a type conversion, keep climbing the tree,
9401 -- since a type conversion can be a procedure actual. Also keep
9402 -- climbing if parameter association or a qualified expression,
9403 -- since these are additional cases that do can appear on
9404 -- procedure actuals.
9405
9406 elsif Nkind_In (Par, N_Type_Conversion,
9407 N_Parameter_Association,
9408 N_Qualified_Expression)
9409 then
9410 Par := Parent (Par);
9411
9412 -- Any other case is not what we are looking for
9413
9414 else
9415 return False;
9416 end if;
9417 end loop;
9418 end Is_Procedure_Actual;
9419
9420 ------------------------------
9421 -- Make_Temporary_For_Slice --
9422 ------------------------------
9423
9424 procedure Make_Temporary_For_Slice is
9425 Decl : Node_Id;
9426 Ent : constant Entity_Id := Make_Temporary (Loc, 'T', N);
9427
9428 begin
9429 Decl :=
9430 Make_Object_Declaration (Loc,
9431 Defining_Identifier => Ent,
9432 Object_Definition => New_Occurrence_Of (Typ, Loc));
9433
9434 Set_No_Initialization (Decl);
9435
9436 Insert_Actions (N, New_List (
9437 Decl,
9438 Make_Assignment_Statement (Loc,
9439 Name => New_Occurrence_Of (Ent, Loc),
9440 Expression => Relocate_Node (N))));
9441
9442 Rewrite (N, New_Occurrence_Of (Ent, Loc));
9443 Analyze_And_Resolve (N, Typ);
9444 end Make_Temporary_For_Slice;
9445
9446 -- Start of processing for Expand_N_Slice
9447
9448 begin
9449 -- Special handling for access types
9450
9451 if Is_Access_Type (Ptp) then
9452
9453 Ptp := Designated_Type (Ptp);
9454
9455 Rewrite (Pfx,
9456 Make_Explicit_Dereference (Sloc (N),
9457 Prefix => Relocate_Node (Pfx)));
9458
9459 Analyze_And_Resolve (Pfx, Ptp);
9460 end if;
9461
9462 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
9463 -- function, then additional actuals must be passed.
9464
9465 if Ada_Version >= Ada_2005
9466 and then Is_Build_In_Place_Function_Call (Pfx)
9467 then
9468 Make_Build_In_Place_Call_In_Anonymous_Context (Pfx);
9469 end if;
9470
9471 -- The remaining case to be handled is packed slices. We can leave
9472 -- packed slices as they are in the following situations:
9473
9474 -- 1. Right or left side of an assignment (we can handle this
9475 -- situation correctly in the assignment statement expansion).
9476
9477 -- 2. Prefix of indexed component (the slide is optimized away in this
9478 -- case, see the start of Expand_N_Slice.)
9479
9480 -- 3. Object renaming declaration, since we want the name of the
9481 -- slice, not the value.
9482
9483 -- 4. Argument to procedure call, since copy-in/copy-out handling may
9484 -- be required, and this is handled in the expansion of call
9485 -- itself.
9486
9487 -- 5. Prefix of an address attribute (this is an error which is caught
9488 -- elsewhere, and the expansion would interfere with generating the
9489 -- error message).
9490
9491 if not Is_Packed (Typ) then
9492
9493 -- Apply transformation for actuals of a function call, where
9494 -- Expand_Actuals is not used.
9495
9496 if Nkind (Parent (N)) = N_Function_Call
9497 and then Is_Possibly_Unaligned_Slice (N)
9498 then
9499 Make_Temporary_For_Slice;
9500 end if;
9501
9502 elsif Nkind (Parent (N)) = N_Assignment_Statement
9503 or else (Nkind (Parent (Parent (N))) = N_Assignment_Statement
9504 and then Parent (N) = Name (Parent (Parent (N))))
9505 then
9506 return;
9507
9508 elsif Nkind (Parent (N)) = N_Indexed_Component
9509 or else Is_Renamed_Object (N)
9510 or else Is_Procedure_Actual (N)
9511 then
9512 return;
9513
9514 elsif Nkind (Parent (N)) = N_Attribute_Reference
9515 and then Attribute_Name (Parent (N)) = Name_Address
9516 then
9517 return;
9518
9519 else
9520 Make_Temporary_For_Slice;
9521 end if;
9522 end Expand_N_Slice;
9523
9524 ------------------------------
9525 -- Expand_N_Type_Conversion --
9526 ------------------------------
9527
9528 procedure Expand_N_Type_Conversion (N : Node_Id) is
9529 Loc : constant Source_Ptr := Sloc (N);
9530 Operand : constant Node_Id := Expression (N);
9531 Target_Type : constant Entity_Id := Etype (N);
9532 Operand_Type : Entity_Id := Etype (Operand);
9533
9534 procedure Handle_Changed_Representation;
9535 -- This is called in the case of record and array type conversions to
9536 -- see if there is a change of representation to be handled. Change of
9537 -- representation is actually handled at the assignment statement level,
9538 -- and what this procedure does is rewrite node N conversion as an
9539 -- assignment to temporary. If there is no change of representation,
9540 -- then the conversion node is unchanged.
9541
9542 procedure Raise_Accessibility_Error;
9543 -- Called when we know that an accessibility check will fail. Rewrites
9544 -- node N to an appropriate raise statement and outputs warning msgs.
9545 -- The Etype of the raise node is set to Target_Type.
9546
9547 procedure Real_Range_Check;
9548 -- Handles generation of range check for real target value
9549
9550 function Has_Extra_Accessibility (Id : Entity_Id) return Boolean;
9551 -- True iff Present (Effective_Extra_Accessibility (Id)) successfully
9552 -- evaluates to True.
9553
9554 -----------------------------------
9555 -- Handle_Changed_Representation --
9556 -----------------------------------
9557
9558 procedure Handle_Changed_Representation is
9559 Temp : Entity_Id;
9560 Decl : Node_Id;
9561 Odef : Node_Id;
9562 Disc : Node_Id;
9563 N_Ix : Node_Id;
9564 Cons : List_Id;
9565
9566 begin
9567 -- Nothing else to do if no change of representation
9568
9569 if Same_Representation (Operand_Type, Target_Type) then
9570 return;
9571
9572 -- The real change of representation work is done by the assignment
9573 -- statement processing. So if this type conversion is appearing as
9574 -- the expression of an assignment statement, nothing needs to be
9575 -- done to the conversion.
9576
9577 elsif Nkind (Parent (N)) = N_Assignment_Statement then
9578 return;
9579
9580 -- Otherwise we need to generate a temporary variable, and do the
9581 -- change of representation assignment into that temporary variable.
9582 -- The conversion is then replaced by a reference to this variable.
9583
9584 else
9585 Cons := No_List;
9586
9587 -- If type is unconstrained we have to add a constraint, copied
9588 -- from the actual value of the left hand side.
9589
9590 if not Is_Constrained (Target_Type) then
9591 if Has_Discriminants (Operand_Type) then
9592 Disc := First_Discriminant (Operand_Type);
9593
9594 if Disc /= First_Stored_Discriminant (Operand_Type) then
9595 Disc := First_Stored_Discriminant (Operand_Type);
9596 end if;
9597
9598 Cons := New_List;
9599 while Present (Disc) loop
9600 Append_To (Cons,
9601 Make_Selected_Component (Loc,
9602 Prefix =>
9603 Duplicate_Subexpr_Move_Checks (Operand),
9604 Selector_Name =>
9605 Make_Identifier (Loc, Chars (Disc))));
9606 Next_Discriminant (Disc);
9607 end loop;
9608
9609 elsif Is_Array_Type (Operand_Type) then
9610 N_Ix := First_Index (Target_Type);
9611 Cons := New_List;
9612
9613 for J in 1 .. Number_Dimensions (Operand_Type) loop
9614
9615 -- We convert the bounds explicitly. We use an unchecked
9616 -- conversion because bounds checks are done elsewhere.
9617
9618 Append_To (Cons,
9619 Make_Range (Loc,
9620 Low_Bound =>
9621 Unchecked_Convert_To (Etype (N_Ix),
9622 Make_Attribute_Reference (Loc,
9623 Prefix =>
9624 Duplicate_Subexpr_No_Checks
9625 (Operand, Name_Req => True),
9626 Attribute_Name => Name_First,
9627 Expressions => New_List (
9628 Make_Integer_Literal (Loc, J)))),
9629
9630 High_Bound =>
9631 Unchecked_Convert_To (Etype (N_Ix),
9632 Make_Attribute_Reference (Loc,
9633 Prefix =>
9634 Duplicate_Subexpr_No_Checks
9635 (Operand, Name_Req => True),
9636 Attribute_Name => Name_Last,
9637 Expressions => New_List (
9638 Make_Integer_Literal (Loc, J))))));
9639
9640 Next_Index (N_Ix);
9641 end loop;
9642 end if;
9643 end if;
9644
9645 Odef := New_Occurrence_Of (Target_Type, Loc);
9646
9647 if Present (Cons) then
9648 Odef :=
9649 Make_Subtype_Indication (Loc,
9650 Subtype_Mark => Odef,
9651 Constraint =>
9652 Make_Index_Or_Discriminant_Constraint (Loc,
9653 Constraints => Cons));
9654 end if;
9655
9656 Temp := Make_Temporary (Loc, 'C');
9657 Decl :=
9658 Make_Object_Declaration (Loc,
9659 Defining_Identifier => Temp,
9660 Object_Definition => Odef);
9661
9662 Set_No_Initialization (Decl, True);
9663
9664 -- Insert required actions. It is essential to suppress checks
9665 -- since we have suppressed default initialization, which means
9666 -- that the variable we create may have no discriminants.
9667
9668 Insert_Actions (N,
9669 New_List (
9670 Decl,
9671 Make_Assignment_Statement (Loc,
9672 Name => New_Occurrence_Of (Temp, Loc),
9673 Expression => Relocate_Node (N))),
9674 Suppress => All_Checks);
9675
9676 Rewrite (N, New_Occurrence_Of (Temp, Loc));
9677 return;
9678 end if;
9679 end Handle_Changed_Representation;
9680
9681 -------------------------------
9682 -- Raise_Accessibility_Error --
9683 -------------------------------
9684
9685 procedure Raise_Accessibility_Error is
9686 begin
9687 Rewrite (N,
9688 Make_Raise_Program_Error (Sloc (N),
9689 Reason => PE_Accessibility_Check_Failed));
9690 Set_Etype (N, Target_Type);
9691
9692 Error_Msg_N ("?accessibility check failure", N);
9693 Error_Msg_NE
9694 ("\?& will be raised at run time", N, Standard_Program_Error);
9695 end Raise_Accessibility_Error;
9696
9697 ----------------------
9698 -- Real_Range_Check --
9699 ----------------------
9700
9701 -- Case of conversions to floating-point or fixed-point. If range checks
9702 -- are enabled and the target type has a range constraint, we convert:
9703
9704 -- typ (x)
9705
9706 -- to
9707
9708 -- Tnn : typ'Base := typ'Base (x);
9709 -- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
9710 -- Tnn
9711
9712 -- This is necessary when there is a conversion of integer to float or
9713 -- to fixed-point to ensure that the correct checks are made. It is not
9714 -- necessary for float to float where it is enough to simply set the
9715 -- Do_Range_Check flag.
9716
9717 procedure Real_Range_Check is
9718 Btyp : constant Entity_Id := Base_Type (Target_Type);
9719 Lo : constant Node_Id := Type_Low_Bound (Target_Type);
9720 Hi : constant Node_Id := Type_High_Bound (Target_Type);
9721 Xtyp : constant Entity_Id := Etype (Operand);
9722 Conv : Node_Id;
9723 Tnn : Entity_Id;
9724
9725 begin
9726 -- Nothing to do if conversion was rewritten
9727
9728 if Nkind (N) /= N_Type_Conversion then
9729 return;
9730 end if;
9731
9732 -- Nothing to do if range checks suppressed, or target has the same
9733 -- range as the base type (or is the base type).
9734
9735 if Range_Checks_Suppressed (Target_Type)
9736 or else (Lo = Type_Low_Bound (Btyp)
9737 and then
9738 Hi = Type_High_Bound (Btyp))
9739 then
9740 return;
9741 end if;
9742
9743 -- Nothing to do if expression is an entity on which checks have been
9744 -- suppressed.
9745
9746 if Is_Entity_Name (Operand)
9747 and then Range_Checks_Suppressed (Entity (Operand))
9748 then
9749 return;
9750 end if;
9751
9752 -- Nothing to do if bounds are all static and we can tell that the
9753 -- expression is within the bounds of the target. Note that if the
9754 -- operand is of an unconstrained floating-point type, then we do
9755 -- not trust it to be in range (might be infinite)
9756
9757 declare
9758 S_Lo : constant Node_Id := Type_Low_Bound (Xtyp);
9759 S_Hi : constant Node_Id := Type_High_Bound (Xtyp);
9760
9761 begin
9762 if (not Is_Floating_Point_Type (Xtyp)
9763 or else Is_Constrained (Xtyp))
9764 and then Compile_Time_Known_Value (S_Lo)
9765 and then Compile_Time_Known_Value (S_Hi)
9766 and then Compile_Time_Known_Value (Hi)
9767 and then Compile_Time_Known_Value (Lo)
9768 then
9769 declare
9770 D_Lov : constant Ureal := Expr_Value_R (Lo);
9771 D_Hiv : constant Ureal := Expr_Value_R (Hi);
9772 S_Lov : Ureal;
9773 S_Hiv : Ureal;
9774
9775 begin
9776 if Is_Real_Type (Xtyp) then
9777 S_Lov := Expr_Value_R (S_Lo);
9778 S_Hiv := Expr_Value_R (S_Hi);
9779 else
9780 S_Lov := UR_From_Uint (Expr_Value (S_Lo));
9781 S_Hiv := UR_From_Uint (Expr_Value (S_Hi));
9782 end if;
9783
9784 if D_Hiv > D_Lov
9785 and then S_Lov >= D_Lov
9786 and then S_Hiv <= D_Hiv
9787 then
9788 Set_Do_Range_Check (Operand, False);
9789 return;
9790 end if;
9791 end;
9792 end if;
9793 end;
9794
9795 -- For float to float conversions, we are done
9796
9797 if Is_Floating_Point_Type (Xtyp)
9798 and then
9799 Is_Floating_Point_Type (Btyp)
9800 then
9801 return;
9802 end if;
9803
9804 -- Otherwise rewrite the conversion as described above
9805
9806 Conv := Relocate_Node (N);
9807 Rewrite (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc));
9808 Set_Etype (Conv, Btyp);
9809
9810 -- Enable overflow except for case of integer to float conversions,
9811 -- where it is never required, since we can never have overflow in
9812 -- this case.
9813
9814 if not Is_Integer_Type (Etype (Operand)) then
9815 Enable_Overflow_Check (Conv);
9816 end if;
9817
9818 Tnn := Make_Temporary (Loc, 'T', Conv);
9819
9820 Insert_Actions (N, New_List (
9821 Make_Object_Declaration (Loc,
9822 Defining_Identifier => Tnn,
9823 Object_Definition => New_Occurrence_Of (Btyp, Loc),
9824 Constant_Present => True,
9825 Expression => Conv),
9826
9827 Make_Raise_Constraint_Error (Loc,
9828 Condition =>
9829 Make_Or_Else (Loc,
9830 Left_Opnd =>
9831 Make_Op_Lt (Loc,
9832 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
9833 Right_Opnd =>
9834 Make_Attribute_Reference (Loc,
9835 Attribute_Name => Name_First,
9836 Prefix =>
9837 New_Occurrence_Of (Target_Type, Loc))),
9838
9839 Right_Opnd =>
9840 Make_Op_Gt (Loc,
9841 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
9842 Right_Opnd =>
9843 Make_Attribute_Reference (Loc,
9844 Attribute_Name => Name_Last,
9845 Prefix =>
9846 New_Occurrence_Of (Target_Type, Loc)))),
9847 Reason => CE_Range_Check_Failed)));
9848
9849 Rewrite (N, New_Occurrence_Of (Tnn, Loc));
9850 Analyze_And_Resolve (N, Btyp);
9851 end Real_Range_Check;
9852
9853 -----------------------------
9854 -- Has_Extra_Accessibility --
9855 -----------------------------
9856
9857 -- Returns true for a formal of an anonymous access type or for
9858 -- an Ada 2012-style stand-alone object of an anonymous access type.
9859
9860 function Has_Extra_Accessibility (Id : Entity_Id) return Boolean is
9861 begin
9862 if Is_Formal (Id) or else Ekind_In (Id, E_Constant, E_Variable) then
9863 return Present (Effective_Extra_Accessibility (Id));
9864 else
9865 return False;
9866 end if;
9867 end Has_Extra_Accessibility;
9868
9869 -- Start of processing for Expand_N_Type_Conversion
9870
9871 begin
9872 -- Nothing at all to do if conversion is to the identical type so remove
9873 -- the conversion completely, it is useless, except that it may carry
9874 -- an Assignment_OK attribute, which must be propagated to the operand.
9875
9876 if Operand_Type = Target_Type then
9877 if Assignment_OK (N) then
9878 Set_Assignment_OK (Operand);
9879 end if;
9880
9881 Rewrite (N, Relocate_Node (Operand));
9882 goto Done;
9883 end if;
9884
9885 -- Nothing to do if this is the second argument of read. This is a
9886 -- "backwards" conversion that will be handled by the specialized code
9887 -- in attribute processing.
9888
9889 if Nkind (Parent (N)) = N_Attribute_Reference
9890 and then Attribute_Name (Parent (N)) = Name_Read
9891 and then Next (First (Expressions (Parent (N)))) = N
9892 then
9893 goto Done;
9894 end if;
9895
9896 -- Check for case of converting to a type that has an invariant
9897 -- associated with it. This required an invariant check. We convert
9898
9899 -- typ (expr)
9900
9901 -- into
9902
9903 -- do invariant_check (typ (expr)) in typ (expr);
9904
9905 -- using Duplicate_Subexpr to avoid multiple side effects
9906
9907 -- Note: the Comes_From_Source check, and then the resetting of this
9908 -- flag prevents what would otherwise be an infinite recursion.
9909
9910 if Has_Invariants (Target_Type)
9911 and then Present (Invariant_Procedure (Target_Type))
9912 and then Comes_From_Source (N)
9913 then
9914 Set_Comes_From_Source (N, False);
9915 Rewrite (N,
9916 Make_Expression_With_Actions (Loc,
9917 Actions => New_List (
9918 Make_Invariant_Call (Duplicate_Subexpr (N))),
9919 Expression => Duplicate_Subexpr_No_Checks (N)));
9920 Analyze_And_Resolve (N, Target_Type);
9921 goto Done;
9922 end if;
9923
9924 -- Here if we may need to expand conversion
9925
9926 -- If the operand of the type conversion is an arithmetic operation on
9927 -- signed integers, and the based type of the signed integer type in
9928 -- question is smaller than Standard.Integer, we promote both of the
9929 -- operands to type Integer.
9930
9931 -- For example, if we have
9932
9933 -- target-type (opnd1 + opnd2)
9934
9935 -- and opnd1 and opnd2 are of type short integer, then we rewrite
9936 -- this as:
9937
9938 -- target-type (integer(opnd1) + integer(opnd2))
9939
9940 -- We do this because we are always allowed to compute in a larger type
9941 -- if we do the right thing with the result, and in this case we are
9942 -- going to do a conversion which will do an appropriate check to make
9943 -- sure that things are in range of the target type in any case. This
9944 -- avoids some unnecessary intermediate overflows.
9945
9946 -- We might consider a similar transformation in the case where the
9947 -- target is a real type or a 64-bit integer type, and the operand
9948 -- is an arithmetic operation using a 32-bit integer type. However,
9949 -- we do not bother with this case, because it could cause significant
9950 -- inefficiencies on 32-bit machines. On a 64-bit machine it would be
9951 -- much cheaper, but we don't want different behavior on 32-bit and
9952 -- 64-bit machines. Note that the exclusion of the 64-bit case also
9953 -- handles the configurable run-time cases where 64-bit arithmetic
9954 -- may simply be unavailable.
9955
9956 -- Note: this circuit is partially redundant with respect to the circuit
9957 -- in Checks.Apply_Arithmetic_Overflow_Check, but we catch more cases in
9958 -- the processing here. Also we still need the Checks circuit, since we
9959 -- have to be sure not to generate junk overflow checks in the first
9960 -- place, since it would be trick to remove them here!
9961
9962 if Integer_Promotion_Possible (N) then
9963
9964 -- All conditions met, go ahead with transformation
9965
9966 declare
9967 Opnd : Node_Id;
9968 L, R : Node_Id;
9969
9970 begin
9971 R :=
9972 Make_Type_Conversion (Loc,
9973 Subtype_Mark => New_Reference_To (Standard_Integer, Loc),
9974 Expression => Relocate_Node (Right_Opnd (Operand)));
9975
9976 Opnd := New_Op_Node (Nkind (Operand), Loc);
9977 Set_Right_Opnd (Opnd, R);
9978
9979 if Nkind (Operand) in N_Binary_Op then
9980 L :=
9981 Make_Type_Conversion (Loc,
9982 Subtype_Mark => New_Reference_To (Standard_Integer, Loc),
9983 Expression => Relocate_Node (Left_Opnd (Operand)));
9984
9985 Set_Left_Opnd (Opnd, L);
9986 end if;
9987
9988 Rewrite (N,
9989 Make_Type_Conversion (Loc,
9990 Subtype_Mark => Relocate_Node (Subtype_Mark (N)),
9991 Expression => Opnd));
9992
9993 Analyze_And_Resolve (N, Target_Type);
9994 goto Done;
9995 end;
9996 end if;
9997
9998 -- Do validity check if validity checking operands
9999
10000 if Validity_Checks_On
10001 and then Validity_Check_Operands
10002 then
10003 Ensure_Valid (Operand);
10004 end if;
10005
10006 -- Special case of converting from non-standard boolean type
10007
10008 if Is_Boolean_Type (Operand_Type)
10009 and then (Nonzero_Is_True (Operand_Type))
10010 then
10011 Adjust_Condition (Operand);
10012 Set_Etype (Operand, Standard_Boolean);
10013 Operand_Type := Standard_Boolean;
10014 end if;
10015
10016 -- Case of converting to an access type
10017
10018 if Is_Access_Type (Target_Type) then
10019
10020 -- Apply an accessibility check when the conversion operand is an
10021 -- access parameter (or a renaming thereof), unless conversion was
10022 -- expanded from an Unchecked_ or Unrestricted_Access attribute.
10023 -- Note that other checks may still need to be applied below (such
10024 -- as tagged type checks).
10025
10026 if Is_Entity_Name (Operand)
10027 and then Has_Extra_Accessibility (Entity (Operand))
10028 and then Ekind (Etype (Operand)) = E_Anonymous_Access_Type
10029 and then (Nkind (Original_Node (N)) /= N_Attribute_Reference
10030 or else Attribute_Name (Original_Node (N)) = Name_Access)
10031 then
10032 Apply_Accessibility_Check
10033 (Operand, Target_Type, Insert_Node => Operand);
10034
10035 -- If the level of the operand type is statically deeper than the
10036 -- level of the target type, then force Program_Error. Note that this
10037 -- can only occur for cases where the attribute is within the body of
10038 -- an instantiation (otherwise the conversion will already have been
10039 -- rejected as illegal). Note: warnings are issued by the analyzer
10040 -- for the instance cases.
10041
10042 elsif In_Instance_Body
10043 and then Type_Access_Level (Operand_Type) >
10044 Type_Access_Level (Target_Type)
10045 then
10046 Raise_Accessibility_Error;
10047
10048 -- When the operand is a selected access discriminant the check needs
10049 -- to be made against the level of the object denoted by the prefix
10050 -- of the selected name. Force Program_Error for this case as well
10051 -- (this accessibility violation can only happen if within the body
10052 -- of an instantiation).
10053
10054 elsif In_Instance_Body
10055 and then Ekind (Operand_Type) = E_Anonymous_Access_Type
10056 and then Nkind (Operand) = N_Selected_Component
10057 and then Object_Access_Level (Operand) >
10058 Type_Access_Level (Target_Type)
10059 then
10060 Raise_Accessibility_Error;
10061 goto Done;
10062 end if;
10063 end if;
10064
10065 -- Case of conversions of tagged types and access to tagged types
10066
10067 -- When needed, that is to say when the expression is class-wide, Add
10068 -- runtime a tag check for (strict) downward conversion by using the
10069 -- membership test, generating:
10070
10071 -- [constraint_error when Operand not in Target_Type'Class]
10072
10073 -- or in the access type case
10074
10075 -- [constraint_error
10076 -- when Operand /= null
10077 -- and then Operand.all not in
10078 -- Designated_Type (Target_Type)'Class]
10079
10080 if (Is_Access_Type (Target_Type)
10081 and then Is_Tagged_Type (Designated_Type (Target_Type)))
10082 or else Is_Tagged_Type (Target_Type)
10083 then
10084 -- Do not do any expansion in the access type case if the parent is a
10085 -- renaming, since this is an error situation which will be caught by
10086 -- Sem_Ch8, and the expansion can interfere with this error check.
10087
10088 if Is_Access_Type (Target_Type) and then Is_Renamed_Object (N) then
10089 goto Done;
10090 end if;
10091
10092 -- Otherwise, proceed with processing tagged conversion
10093
10094 Tagged_Conversion : declare
10095 Actual_Op_Typ : Entity_Id;
10096 Actual_Targ_Typ : Entity_Id;
10097 Make_Conversion : Boolean := False;
10098 Root_Op_Typ : Entity_Id;
10099
10100 procedure Make_Tag_Check (Targ_Typ : Entity_Id);
10101 -- Create a membership check to test whether Operand is a member
10102 -- of Targ_Typ. If the original Target_Type is an access, include
10103 -- a test for null value. The check is inserted at N.
10104
10105 --------------------
10106 -- Make_Tag_Check --
10107 --------------------
10108
10109 procedure Make_Tag_Check (Targ_Typ : Entity_Id) is
10110 Cond : Node_Id;
10111
10112 begin
10113 -- Generate:
10114 -- [Constraint_Error
10115 -- when Operand /= null
10116 -- and then Operand.all not in Targ_Typ]
10117
10118 if Is_Access_Type (Target_Type) then
10119 Cond :=
10120 Make_And_Then (Loc,
10121 Left_Opnd =>
10122 Make_Op_Ne (Loc,
10123 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
10124 Right_Opnd => Make_Null (Loc)),
10125
10126 Right_Opnd =>
10127 Make_Not_In (Loc,
10128 Left_Opnd =>
10129 Make_Explicit_Dereference (Loc,
10130 Prefix => Duplicate_Subexpr_No_Checks (Operand)),
10131 Right_Opnd => New_Reference_To (Targ_Typ, Loc)));
10132
10133 -- Generate:
10134 -- [Constraint_Error when Operand not in Targ_Typ]
10135
10136 else
10137 Cond :=
10138 Make_Not_In (Loc,
10139 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
10140 Right_Opnd => New_Reference_To (Targ_Typ, Loc));
10141 end if;
10142
10143 Insert_Action (N,
10144 Make_Raise_Constraint_Error (Loc,
10145 Condition => Cond,
10146 Reason => CE_Tag_Check_Failed));
10147 end Make_Tag_Check;
10148
10149 -- Start of processing for Tagged_Conversion
10150
10151 begin
10152 -- Handle entities from the limited view
10153
10154 if Is_Access_Type (Operand_Type) then
10155 Actual_Op_Typ :=
10156 Available_View (Designated_Type (Operand_Type));
10157 else
10158 Actual_Op_Typ := Operand_Type;
10159 end if;
10160
10161 if Is_Access_Type (Target_Type) then
10162 Actual_Targ_Typ :=
10163 Available_View (Designated_Type (Target_Type));
10164 else
10165 Actual_Targ_Typ := Target_Type;
10166 end if;
10167
10168 Root_Op_Typ := Root_Type (Actual_Op_Typ);
10169
10170 -- Ada 2005 (AI-251): Handle interface type conversion
10171
10172 if Is_Interface (Actual_Op_Typ) then
10173 Expand_Interface_Conversion (N, Is_Static => False);
10174 goto Done;
10175 end if;
10176
10177 if not Tag_Checks_Suppressed (Actual_Targ_Typ) then
10178
10179 -- Create a runtime tag check for a downward class-wide type
10180 -- conversion.
10181
10182 if Is_Class_Wide_Type (Actual_Op_Typ)
10183 and then Actual_Op_Typ /= Actual_Targ_Typ
10184 and then Root_Op_Typ /= Actual_Targ_Typ
10185 and then Is_Ancestor (Root_Op_Typ, Actual_Targ_Typ,
10186 Use_Full_View => True)
10187 then
10188 Make_Tag_Check (Class_Wide_Type (Actual_Targ_Typ));
10189 Make_Conversion := True;
10190 end if;
10191
10192 -- AI05-0073: If the result subtype of the function is defined
10193 -- by an access_definition designating a specific tagged type
10194 -- T, a check is made that the result value is null or the tag
10195 -- of the object designated by the result value identifies T.
10196 -- Constraint_Error is raised if this check fails.
10197
10198 if Nkind (Parent (N)) = N_Simple_Return_Statement then
10199 declare
10200 Func : Entity_Id;
10201 Func_Typ : Entity_Id;
10202
10203 begin
10204 -- Climb scope stack looking for the enclosing function
10205
10206 Func := Current_Scope;
10207 while Present (Func)
10208 and then Ekind (Func) /= E_Function
10209 loop
10210 Func := Scope (Func);
10211 end loop;
10212
10213 -- The function's return subtype must be defined using
10214 -- an access definition.
10215
10216 if Nkind (Result_Definition (Parent (Func))) =
10217 N_Access_Definition
10218 then
10219 Func_Typ := Directly_Designated_Type (Etype (Func));
10220
10221 -- The return subtype denotes a specific tagged type,
10222 -- in other words, a non class-wide type.
10223
10224 if Is_Tagged_Type (Func_Typ)
10225 and then not Is_Class_Wide_Type (Func_Typ)
10226 then
10227 Make_Tag_Check (Actual_Targ_Typ);
10228 Make_Conversion := True;
10229 end if;
10230 end if;
10231 end;
10232 end if;
10233
10234 -- We have generated a tag check for either a class-wide type
10235 -- conversion or for AI05-0073.
10236
10237 if Make_Conversion then
10238 declare
10239 Conv : Node_Id;
10240 begin
10241 Conv :=
10242 Make_Unchecked_Type_Conversion (Loc,
10243 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
10244 Expression => Relocate_Node (Expression (N)));
10245 Rewrite (N, Conv);
10246 Analyze_And_Resolve (N, Target_Type);
10247 end;
10248 end if;
10249 end if;
10250 end Tagged_Conversion;
10251
10252 -- Case of other access type conversions
10253
10254 elsif Is_Access_Type (Target_Type) then
10255 Apply_Constraint_Check (Operand, Target_Type);
10256
10257 -- Case of conversions from a fixed-point type
10258
10259 -- These conversions require special expansion and processing, found in
10260 -- the Exp_Fixd package. We ignore cases where Conversion_OK is set,
10261 -- since from a semantic point of view, these are simple integer
10262 -- conversions, which do not need further processing.
10263
10264 elsif Is_Fixed_Point_Type (Operand_Type)
10265 and then not Conversion_OK (N)
10266 then
10267 -- We should never see universal fixed at this case, since the
10268 -- expansion of the constituent divide or multiply should have
10269 -- eliminated the explicit mention of universal fixed.
10270
10271 pragma Assert (Operand_Type /= Universal_Fixed);
10272
10273 -- Check for special case of the conversion to universal real that
10274 -- occurs as a result of the use of a round attribute. In this case,
10275 -- the real type for the conversion is taken from the target type of
10276 -- the Round attribute and the result must be marked as rounded.
10277
10278 if Target_Type = Universal_Real
10279 and then Nkind (Parent (N)) = N_Attribute_Reference
10280 and then Attribute_Name (Parent (N)) = Name_Round
10281 then
10282 Set_Rounded_Result (N);
10283 Set_Etype (N, Etype (Parent (N)));
10284 end if;
10285
10286 -- Otherwise do correct fixed-conversion, but skip these if the
10287 -- Conversion_OK flag is set, because from a semantic point of view
10288 -- these are simple integer conversions needing no further processing
10289 -- (the backend will simply treat them as integers).
10290
10291 if not Conversion_OK (N) then
10292 if Is_Fixed_Point_Type (Etype (N)) then
10293 Expand_Convert_Fixed_To_Fixed (N);
10294 Real_Range_Check;
10295
10296 elsif Is_Integer_Type (Etype (N)) then
10297 Expand_Convert_Fixed_To_Integer (N);
10298
10299 else
10300 pragma Assert (Is_Floating_Point_Type (Etype (N)));
10301 Expand_Convert_Fixed_To_Float (N);
10302 Real_Range_Check;
10303 end if;
10304 end if;
10305
10306 -- Case of conversions to a fixed-point type
10307
10308 -- These conversions require special expansion and processing, found in
10309 -- the Exp_Fixd package. Again, ignore cases where Conversion_OK is set,
10310 -- since from a semantic point of view, these are simple integer
10311 -- conversions, which do not need further processing.
10312
10313 elsif Is_Fixed_Point_Type (Target_Type)
10314 and then not Conversion_OK (N)
10315 then
10316 if Is_Integer_Type (Operand_Type) then
10317 Expand_Convert_Integer_To_Fixed (N);
10318 Real_Range_Check;
10319 else
10320 pragma Assert (Is_Floating_Point_Type (Operand_Type));
10321 Expand_Convert_Float_To_Fixed (N);
10322 Real_Range_Check;
10323 end if;
10324
10325 -- Case of float-to-integer conversions
10326
10327 -- We also handle float-to-fixed conversions with Conversion_OK set
10328 -- since semantically the fixed-point target is treated as though it
10329 -- were an integer in such cases.
10330
10331 elsif Is_Floating_Point_Type (Operand_Type)
10332 and then
10333 (Is_Integer_Type (Target_Type)
10334 or else
10335 (Is_Fixed_Point_Type (Target_Type) and then Conversion_OK (N)))
10336 then
10337 -- One more check here, gcc is still not able to do conversions of
10338 -- this type with proper overflow checking, and so gigi is doing an
10339 -- approximation of what is required by doing floating-point compares
10340 -- with the end-point. But that can lose precision in some cases, and
10341 -- give a wrong result. Converting the operand to Universal_Real is
10342 -- helpful, but still does not catch all cases with 64-bit integers
10343 -- on targets with only 64-bit floats.
10344
10345 -- The above comment seems obsoleted by Apply_Float_Conversion_Check
10346 -- Can this code be removed ???
10347
10348 if Do_Range_Check (Operand) then
10349 Rewrite (Operand,
10350 Make_Type_Conversion (Loc,
10351 Subtype_Mark =>
10352 New_Occurrence_Of (Universal_Real, Loc),
10353 Expression =>
10354 Relocate_Node (Operand)));
10355
10356 Set_Etype (Operand, Universal_Real);
10357 Enable_Range_Check (Operand);
10358 Set_Do_Range_Check (Expression (Operand), False);
10359 end if;
10360
10361 -- Case of array conversions
10362
10363 -- Expansion of array conversions, add required length/range checks but
10364 -- only do this if there is no change of representation. For handling of
10365 -- this case, see Handle_Changed_Representation.
10366
10367 elsif Is_Array_Type (Target_Type) then
10368 if Is_Constrained (Target_Type) then
10369 Apply_Length_Check (Operand, Target_Type);
10370 else
10371 Apply_Range_Check (Operand, Target_Type);
10372 end if;
10373
10374 Handle_Changed_Representation;
10375
10376 -- Case of conversions of discriminated types
10377
10378 -- Add required discriminant checks if target is constrained. Again this
10379 -- change is skipped if we have a change of representation.
10380
10381 elsif Has_Discriminants (Target_Type)
10382 and then Is_Constrained (Target_Type)
10383 then
10384 Apply_Discriminant_Check (Operand, Target_Type);
10385 Handle_Changed_Representation;
10386
10387 -- Case of all other record conversions. The only processing required
10388 -- is to check for a change of representation requiring the special
10389 -- assignment processing.
10390
10391 elsif Is_Record_Type (Target_Type) then
10392
10393 -- Ada 2005 (AI-216): Program_Error is raised when converting from
10394 -- a derived Unchecked_Union type to an unconstrained type that is
10395 -- not Unchecked_Union if the operand lacks inferable discriminants.
10396
10397 if Is_Derived_Type (Operand_Type)
10398 and then Is_Unchecked_Union (Base_Type (Operand_Type))
10399 and then not Is_Constrained (Target_Type)
10400 and then not Is_Unchecked_Union (Base_Type (Target_Type))
10401 and then not Has_Inferable_Discriminants (Operand)
10402 then
10403 -- To prevent Gigi from generating illegal code, we generate a
10404 -- Program_Error node, but we give it the target type of the
10405 -- conversion (is this requirement documented somewhere ???)
10406
10407 declare
10408 PE : constant Node_Id := Make_Raise_Program_Error (Loc,
10409 Reason => PE_Unchecked_Union_Restriction);
10410
10411 begin
10412 Set_Etype (PE, Target_Type);
10413 Rewrite (N, PE);
10414
10415 end;
10416 else
10417 Handle_Changed_Representation;
10418 end if;
10419
10420 -- Case of conversions of enumeration types
10421
10422 elsif Is_Enumeration_Type (Target_Type) then
10423
10424 -- Special processing is required if there is a change of
10425 -- representation (from enumeration representation clauses).
10426
10427 if not Same_Representation (Target_Type, Operand_Type) then
10428
10429 -- Convert: x(y) to x'val (ytyp'val (y))
10430
10431 Rewrite (N,
10432 Make_Attribute_Reference (Loc,
10433 Prefix => New_Occurrence_Of (Target_Type, Loc),
10434 Attribute_Name => Name_Val,
10435 Expressions => New_List (
10436 Make_Attribute_Reference (Loc,
10437 Prefix => New_Occurrence_Of (Operand_Type, Loc),
10438 Attribute_Name => Name_Pos,
10439 Expressions => New_List (Operand)))));
10440
10441 Analyze_And_Resolve (N, Target_Type);
10442 end if;
10443
10444 -- Case of conversions to floating-point
10445
10446 elsif Is_Floating_Point_Type (Target_Type) then
10447 Real_Range_Check;
10448 end if;
10449
10450 -- At this stage, either the conversion node has been transformed into
10451 -- some other equivalent expression, or left as a conversion that can be
10452 -- handled by Gigi, in the following cases:
10453
10454 -- Conversions with no change of representation or type
10455
10456 -- Numeric conversions involving integer, floating- and fixed-point
10457 -- values. Fixed-point values are allowed only if Conversion_OK is
10458 -- set, i.e. if the fixed-point values are to be treated as integers.
10459
10460 -- No other conversions should be passed to Gigi
10461
10462 -- Check: are these rules stated in sinfo??? if so, why restate here???
10463
10464 -- The only remaining step is to generate a range check if we still have
10465 -- a type conversion at this stage and Do_Range_Check is set. For now we
10466 -- do this only for conversions of discrete types.
10467
10468 if Nkind (N) = N_Type_Conversion
10469 and then Is_Discrete_Type (Etype (N))
10470 then
10471 declare
10472 Expr : constant Node_Id := Expression (N);
10473 Ftyp : Entity_Id;
10474 Ityp : Entity_Id;
10475
10476 begin
10477 if Do_Range_Check (Expr)
10478 and then Is_Discrete_Type (Etype (Expr))
10479 then
10480 Set_Do_Range_Check (Expr, False);
10481
10482 -- Before we do a range check, we have to deal with treating a
10483 -- fixed-point operand as an integer. The way we do this is
10484 -- simply to do an unchecked conversion to an appropriate
10485 -- integer type large enough to hold the result.
10486
10487 -- This code is not active yet, because we are only dealing
10488 -- with discrete types so far ???
10489
10490 if Nkind (Expr) in N_Has_Treat_Fixed_As_Integer
10491 and then Treat_Fixed_As_Integer (Expr)
10492 then
10493 Ftyp := Base_Type (Etype (Expr));
10494
10495 if Esize (Ftyp) >= Esize (Standard_Integer) then
10496 Ityp := Standard_Long_Long_Integer;
10497 else
10498 Ityp := Standard_Integer;
10499 end if;
10500
10501 Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
10502 end if;
10503
10504 -- Reset overflow flag, since the range check will include
10505 -- dealing with possible overflow, and generate the check. If
10506 -- Address is either a source type or target type, suppress
10507 -- range check to avoid typing anomalies when it is a visible
10508 -- integer type.
10509
10510 Set_Do_Overflow_Check (N, False);
10511 if not Is_Descendent_Of_Address (Etype (Expr))
10512 and then not Is_Descendent_Of_Address (Target_Type)
10513 then
10514 Generate_Range_Check
10515 (Expr, Target_Type, CE_Range_Check_Failed);
10516 end if;
10517 end if;
10518 end;
10519 end if;
10520
10521 -- Final step, if the result is a type conversion involving Vax_Float
10522 -- types, then it is subject for further special processing.
10523
10524 if Nkind (N) = N_Type_Conversion
10525 and then (Vax_Float (Operand_Type) or else Vax_Float (Target_Type))
10526 then
10527 Expand_Vax_Conversion (N);
10528 goto Done;
10529 end if;
10530
10531 -- Here at end of processing
10532
10533 <<Done>>
10534 -- Apply predicate check if required. Note that we can't just call
10535 -- Apply_Predicate_Check here, because the type looks right after
10536 -- the conversion and it would omit the check. The Comes_From_Source
10537 -- guard is necessary to prevent infinite recursions when we generate
10538 -- internal conversions for the purpose of checking predicates.
10539
10540 if Present (Predicate_Function (Target_Type))
10541 and then Target_Type /= Operand_Type
10542 and then Comes_From_Source (N)
10543 then
10544 declare
10545 New_Expr : constant Node_Id := Duplicate_Subexpr (N);
10546
10547 begin
10548 -- Avoid infinite recursion on the subsequent expansion of
10549 -- of the copy of the original type conversion.
10550
10551 Set_Comes_From_Source (New_Expr, False);
10552 Insert_Action (N, Make_Predicate_Check (Target_Type, New_Expr));
10553 end;
10554 end if;
10555 end Expand_N_Type_Conversion;
10556
10557 -----------------------------------
10558 -- Expand_N_Unchecked_Expression --
10559 -----------------------------------
10560
10561 -- Remove the unchecked expression node from the tree. Its job was simply
10562 -- to make sure that its constituent expression was handled with checks
10563 -- off, and now that that is done, we can remove it from the tree, and
10564 -- indeed must, since Gigi does not expect to see these nodes.
10565
10566 procedure Expand_N_Unchecked_Expression (N : Node_Id) is
10567 Exp : constant Node_Id := Expression (N);
10568 begin
10569 Set_Assignment_OK (Exp, Assignment_OK (N) or else Assignment_OK (Exp));
10570 Rewrite (N, Exp);
10571 end Expand_N_Unchecked_Expression;
10572
10573 ----------------------------------------
10574 -- Expand_N_Unchecked_Type_Conversion --
10575 ----------------------------------------
10576
10577 -- If this cannot be handled by Gigi and we haven't already made a
10578 -- temporary for it, do it now.
10579
10580 procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id) is
10581 Target_Type : constant Entity_Id := Etype (N);
10582 Operand : constant Node_Id := Expression (N);
10583 Operand_Type : constant Entity_Id := Etype (Operand);
10584
10585 begin
10586 -- Nothing at all to do if conversion is to the identical type so remove
10587 -- the conversion completely, it is useless, except that it may carry
10588 -- an Assignment_OK indication which must be propagated to the operand.
10589
10590 if Operand_Type = Target_Type then
10591
10592 -- Code duplicates Expand_N_Unchecked_Expression above, factor???
10593
10594 if Assignment_OK (N) then
10595 Set_Assignment_OK (Operand);
10596 end if;
10597
10598 Rewrite (N, Relocate_Node (Operand));
10599 return;
10600 end if;
10601
10602 -- If we have a conversion of a compile time known value to a target
10603 -- type and the value is in range of the target type, then we can simply
10604 -- replace the construct by an integer literal of the correct type. We
10605 -- only apply this to integer types being converted. Possibly it may
10606 -- apply in other cases, but it is too much trouble to worry about.
10607
10608 -- Note that we do not do this transformation if the Kill_Range_Check
10609 -- flag is set, since then the value may be outside the expected range.
10610 -- This happens in the Normalize_Scalars case.
10611
10612 -- We also skip this if either the target or operand type is biased
10613 -- because in this case, the unchecked conversion is supposed to
10614 -- preserve the bit pattern, not the integer value.
10615
10616 if Is_Integer_Type (Target_Type)
10617 and then not Has_Biased_Representation (Target_Type)
10618 and then Is_Integer_Type (Operand_Type)
10619 and then not Has_Biased_Representation (Operand_Type)
10620 and then Compile_Time_Known_Value (Operand)
10621 and then not Kill_Range_Check (N)
10622 then
10623 declare
10624 Val : constant Uint := Expr_Value (Operand);
10625
10626 begin
10627 if Compile_Time_Known_Value (Type_Low_Bound (Target_Type))
10628 and then
10629 Compile_Time_Known_Value (Type_High_Bound (Target_Type))
10630 and then
10631 Val >= Expr_Value (Type_Low_Bound (Target_Type))
10632 and then
10633 Val <= Expr_Value (Type_High_Bound (Target_Type))
10634 then
10635 Rewrite (N, Make_Integer_Literal (Sloc (N), Val));
10636
10637 -- If Address is the target type, just set the type to avoid a
10638 -- spurious type error on the literal when Address is a visible
10639 -- integer type.
10640
10641 if Is_Descendent_Of_Address (Target_Type) then
10642 Set_Etype (N, Target_Type);
10643 else
10644 Analyze_And_Resolve (N, Target_Type);
10645 end if;
10646
10647 return;
10648 end if;
10649 end;
10650 end if;
10651
10652 -- Nothing to do if conversion is safe
10653
10654 if Safe_Unchecked_Type_Conversion (N) then
10655 return;
10656 end if;
10657
10658 -- Otherwise force evaluation unless Assignment_OK flag is set (this
10659 -- flag indicates ??? -- more comments needed here)
10660
10661 if Assignment_OK (N) then
10662 null;
10663 else
10664 Force_Evaluation (N);
10665 end if;
10666 end Expand_N_Unchecked_Type_Conversion;
10667
10668 ----------------------------
10669 -- Expand_Record_Equality --
10670 ----------------------------
10671
10672 -- For non-variant records, Equality is expanded when needed into:
10673
10674 -- and then Lhs.Discr1 = Rhs.Discr1
10675 -- and then ...
10676 -- and then Lhs.Discrn = Rhs.Discrn
10677 -- and then Lhs.Cmp1 = Rhs.Cmp1
10678 -- and then ...
10679 -- and then Lhs.Cmpn = Rhs.Cmpn
10680
10681 -- The expression is folded by the back-end for adjacent fields. This
10682 -- function is called for tagged record in only one occasion: for imple-
10683 -- menting predefined primitive equality (see Predefined_Primitives_Bodies)
10684 -- otherwise the primitive "=" is used directly.
10685
10686 function Expand_Record_Equality
10687 (Nod : Node_Id;
10688 Typ : Entity_Id;
10689 Lhs : Node_Id;
10690 Rhs : Node_Id;
10691 Bodies : List_Id) return Node_Id
10692 is
10693 Loc : constant Source_Ptr := Sloc (Nod);
10694
10695 Result : Node_Id;
10696 C : Entity_Id;
10697
10698 First_Time : Boolean := True;
10699
10700 function Suitable_Element (C : Entity_Id) return Entity_Id;
10701 -- Return the first field to compare beginning with C, skipping the
10702 -- inherited components.
10703
10704 ----------------------
10705 -- Suitable_Element --
10706 ----------------------
10707
10708 function Suitable_Element (C : Entity_Id) return Entity_Id is
10709 begin
10710 if No (C) then
10711 return Empty;
10712
10713 elsif Ekind (C) /= E_Discriminant
10714 and then Ekind (C) /= E_Component
10715 then
10716 return Suitable_Element (Next_Entity (C));
10717
10718 elsif Is_Tagged_Type (Typ)
10719 and then C /= Original_Record_Component (C)
10720 then
10721 return Suitable_Element (Next_Entity (C));
10722
10723 elsif Chars (C) = Name_uTag then
10724 return Suitable_Element (Next_Entity (C));
10725
10726 -- The .NET/JVM version of type Root_Controlled contains two fields
10727 -- which should not be considered part of the object. To achieve
10728 -- proper equiality between two controlled objects on .NET/JVM, skip
10729 -- field _parent whenever it is of type Root_Controlled.
10730
10731 elsif Chars (C) = Name_uParent
10732 and then VM_Target /= No_VM
10733 and then Etype (C) = RTE (RE_Root_Controlled)
10734 then
10735 return Suitable_Element (Next_Entity (C));
10736
10737 elsif Is_Interface (Etype (C)) then
10738 return Suitable_Element (Next_Entity (C));
10739
10740 else
10741 return C;
10742 end if;
10743 end Suitable_Element;
10744
10745 -- Start of processing for Expand_Record_Equality
10746
10747 begin
10748 -- Generates the following code: (assuming that Typ has one Discr and
10749 -- component C2 is also a record)
10750
10751 -- True
10752 -- and then Lhs.Discr1 = Rhs.Discr1
10753 -- and then Lhs.C1 = Rhs.C1
10754 -- and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
10755 -- and then ...
10756 -- and then Lhs.Cmpn = Rhs.Cmpn
10757
10758 Result := New_Reference_To (Standard_True, Loc);
10759 C := Suitable_Element (First_Entity (Typ));
10760 while Present (C) loop
10761 declare
10762 New_Lhs : Node_Id;
10763 New_Rhs : Node_Id;
10764 Check : Node_Id;
10765
10766 begin
10767 if First_Time then
10768 First_Time := False;
10769 New_Lhs := Lhs;
10770 New_Rhs := Rhs;
10771 else
10772 New_Lhs := New_Copy_Tree (Lhs);
10773 New_Rhs := New_Copy_Tree (Rhs);
10774 end if;
10775
10776 Check :=
10777 Expand_Composite_Equality (Nod, Etype (C),
10778 Lhs =>
10779 Make_Selected_Component (Loc,
10780 Prefix => New_Lhs,
10781 Selector_Name => New_Reference_To (C, Loc)),
10782 Rhs =>
10783 Make_Selected_Component (Loc,
10784 Prefix => New_Rhs,
10785 Selector_Name => New_Reference_To (C, Loc)),
10786 Bodies => Bodies);
10787
10788 -- If some (sub)component is an unchecked_union, the whole
10789 -- operation will raise program error.
10790
10791 if Nkind (Check) = N_Raise_Program_Error then
10792 Result := Check;
10793 Set_Etype (Result, Standard_Boolean);
10794 exit;
10795 else
10796 Result :=
10797 Make_And_Then (Loc,
10798 Left_Opnd => Result,
10799 Right_Opnd => Check);
10800 end if;
10801 end;
10802
10803 C := Suitable_Element (Next_Entity (C));
10804 end loop;
10805
10806 return Result;
10807 end Expand_Record_Equality;
10808
10809 ---------------------------
10810 -- Expand_Set_Membership --
10811 ---------------------------
10812
10813 procedure Expand_Set_Membership (N : Node_Id) is
10814 Lop : constant Node_Id := Left_Opnd (N);
10815 Alt : Node_Id;
10816 Res : Node_Id;
10817
10818 function Make_Cond (Alt : Node_Id) return Node_Id;
10819 -- If the alternative is a subtype mark, create a simple membership
10820 -- test. Otherwise create an equality test for it.
10821
10822 ---------------
10823 -- Make_Cond --
10824 ---------------
10825
10826 function Make_Cond (Alt : Node_Id) return Node_Id is
10827 Cond : Node_Id;
10828 L : constant Node_Id := New_Copy (Lop);
10829 R : constant Node_Id := Relocate_Node (Alt);
10830
10831 begin
10832 if (Is_Entity_Name (Alt) and then Is_Type (Entity (Alt)))
10833 or else Nkind (Alt) = N_Range
10834 then
10835 Cond :=
10836 Make_In (Sloc (Alt),
10837 Left_Opnd => L,
10838 Right_Opnd => R);
10839 else
10840 Cond :=
10841 Make_Op_Eq (Sloc (Alt),
10842 Left_Opnd => L,
10843 Right_Opnd => R);
10844 end if;
10845
10846 return Cond;
10847 end Make_Cond;
10848
10849 -- Start of processing for Expand_Set_Membership
10850
10851 begin
10852 Remove_Side_Effects (Lop);
10853
10854 Alt := Last (Alternatives (N));
10855 Res := Make_Cond (Alt);
10856
10857 Prev (Alt);
10858 while Present (Alt) loop
10859 Res :=
10860 Make_Or_Else (Sloc (Alt),
10861 Left_Opnd => Make_Cond (Alt),
10862 Right_Opnd => Res);
10863 Prev (Alt);
10864 end loop;
10865
10866 Rewrite (N, Res);
10867 Analyze_And_Resolve (N, Standard_Boolean);
10868 end Expand_Set_Membership;
10869
10870 -----------------------------------
10871 -- Expand_Short_Circuit_Operator --
10872 -----------------------------------
10873
10874 -- Deal with special expansion if actions are present for the right operand
10875 -- and deal with optimizing case of arguments being True or False. We also
10876 -- deal with the special case of non-standard boolean values.
10877
10878 procedure Expand_Short_Circuit_Operator (N : Node_Id) is
10879 Loc : constant Source_Ptr := Sloc (N);
10880 Typ : constant Entity_Id := Etype (N);
10881 Left : constant Node_Id := Left_Opnd (N);
10882 Right : constant Node_Id := Right_Opnd (N);
10883 LocR : constant Source_Ptr := Sloc (Right);
10884 Actlist : List_Id;
10885
10886 Shortcut_Value : constant Boolean := Nkind (N) = N_Or_Else;
10887 Shortcut_Ent : constant Entity_Id := Boolean_Literals (Shortcut_Value);
10888 -- If Left = Shortcut_Value then Right need not be evaluated
10889
10890 function Make_Test_Expr (Opnd : Node_Id) return Node_Id;
10891 -- For Opnd a boolean expression, return a Boolean expression equivalent
10892 -- to Opnd /= Shortcut_Value.
10893
10894 --------------------
10895 -- Make_Test_Expr --
10896 --------------------
10897
10898 function Make_Test_Expr (Opnd : Node_Id) return Node_Id is
10899 begin
10900 if Shortcut_Value then
10901 return Make_Op_Not (Sloc (Opnd), Opnd);
10902 else
10903 return Opnd;
10904 end if;
10905 end Make_Test_Expr;
10906
10907 Op_Var : Entity_Id;
10908 -- Entity for a temporary variable holding the value of the operator,
10909 -- used for expansion in the case where actions are present.
10910
10911 -- Start of processing for Expand_Short_Circuit_Operator
10912
10913 begin
10914 -- Deal with non-standard booleans
10915
10916 if Is_Boolean_Type (Typ) then
10917 Adjust_Condition (Left);
10918 Adjust_Condition (Right);
10919 Set_Etype (N, Standard_Boolean);
10920 end if;
10921
10922 -- Check for cases where left argument is known to be True or False
10923
10924 if Compile_Time_Known_Value (Left) then
10925
10926 -- Mark SCO for left condition as compile time known
10927
10928 if Generate_SCO and then Comes_From_Source (Left) then
10929 Set_SCO_Condition (Left, Expr_Value_E (Left) = Standard_True);
10930 end if;
10931
10932 -- Rewrite True AND THEN Right / False OR ELSE Right to Right.
10933 -- Any actions associated with Right will be executed unconditionally
10934 -- and can thus be inserted into the tree unconditionally.
10935
10936 if Expr_Value_E (Left) /= Shortcut_Ent then
10937 if Present (Actions (N)) then
10938 Insert_Actions (N, Actions (N));
10939 end if;
10940
10941 Rewrite (N, Right);
10942
10943 -- Rewrite False AND THEN Right / True OR ELSE Right to Left.
10944 -- In this case we can forget the actions associated with Right,
10945 -- since they will never be executed.
10946
10947 else
10948 Kill_Dead_Code (Right);
10949 Kill_Dead_Code (Actions (N));
10950 Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
10951 end if;
10952
10953 Adjust_Result_Type (N, Typ);
10954 return;
10955 end if;
10956
10957 -- If Actions are present for the right operand, we have to do some
10958 -- special processing. We can't just let these actions filter back into
10959 -- code preceding the short circuit (which is what would have happened
10960 -- if we had not trapped them in the short-circuit form), since they
10961 -- must only be executed if the right operand of the short circuit is
10962 -- executed and not otherwise.
10963
10964 -- the temporary variable C.
10965
10966 if Present (Actions (N)) then
10967 Actlist := Actions (N);
10968
10969 -- The old approach is to expand:
10970
10971 -- left AND THEN right
10972
10973 -- into
10974
10975 -- C : Boolean := False;
10976 -- IF left THEN
10977 -- Actions;
10978 -- IF right THEN
10979 -- C := True;
10980 -- END IF;
10981 -- END IF;
10982
10983 -- and finally rewrite the operator into a reference to C. Similarly
10984 -- for left OR ELSE right, with negated values. Note that this
10985 -- rewrite causes some difficulties for coverage analysis because
10986 -- of the introduction of the new variable C, which obscures the
10987 -- structure of the test.
10988
10989 -- We use this "old approach" if use of N_Expression_With_Actions
10990 -- is False (see description in Opt of when this is or is not set).
10991
10992 if not Use_Expression_With_Actions then
10993 Op_Var := Make_Temporary (Loc, 'C', Related_Node => N);
10994
10995 Insert_Action (N,
10996 Make_Object_Declaration (Loc,
10997 Defining_Identifier =>
10998 Op_Var,
10999 Object_Definition =>
11000 New_Occurrence_Of (Standard_Boolean, Loc),
11001 Expression =>
11002 New_Occurrence_Of (Shortcut_Ent, Loc)));
11003
11004 Append_To (Actlist,
11005 Make_Implicit_If_Statement (Right,
11006 Condition => Make_Test_Expr (Right),
11007 Then_Statements => New_List (
11008 Make_Assignment_Statement (LocR,
11009 Name => New_Occurrence_Of (Op_Var, LocR),
11010 Expression =>
11011 New_Occurrence_Of
11012 (Boolean_Literals (not Shortcut_Value), LocR)))));
11013
11014 Insert_Action (N,
11015 Make_Implicit_If_Statement (Left,
11016 Condition => Make_Test_Expr (Left),
11017 Then_Statements => Actlist));
11018
11019 Rewrite (N, New_Occurrence_Of (Op_Var, Loc));
11020 Analyze_And_Resolve (N, Standard_Boolean);
11021
11022 -- The new approach, activated for now by the use of debug flag
11023 -- -gnatd.X is to use the new Expression_With_Actions node for the
11024 -- right operand of the short-circuit form. This should solve the
11025 -- traceability problems for coverage analysis.
11026
11027 else
11028 Rewrite (Right,
11029 Make_Expression_With_Actions (LocR,
11030 Expression => Relocate_Node (Right),
11031 Actions => Actlist));
11032 Set_Actions (N, No_List);
11033 Analyze_And_Resolve (Right, Standard_Boolean);
11034 end if;
11035
11036 Adjust_Result_Type (N, Typ);
11037 return;
11038 end if;
11039
11040 -- No actions present, check for cases of right argument True/False
11041
11042 if Compile_Time_Known_Value (Right) then
11043
11044 -- Mark SCO for left condition as compile time known
11045
11046 if Generate_SCO and then Comes_From_Source (Right) then
11047 Set_SCO_Condition (Right, Expr_Value_E (Right) = Standard_True);
11048 end if;
11049
11050 -- Change (Left and then True), (Left or else False) to Left.
11051 -- Note that we know there are no actions associated with the right
11052 -- operand, since we just checked for this case above.
11053
11054 if Expr_Value_E (Right) /= Shortcut_Ent then
11055 Rewrite (N, Left);
11056
11057 -- Change (Left and then False), (Left or else True) to Right,
11058 -- making sure to preserve any side effects associated with the Left
11059 -- operand.
11060
11061 else
11062 Remove_Side_Effects (Left);
11063 Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
11064 end if;
11065 end if;
11066
11067 Adjust_Result_Type (N, Typ);
11068 end Expand_Short_Circuit_Operator;
11069
11070 -------------------------------------
11071 -- Fixup_Universal_Fixed_Operation --
11072 -------------------------------------
11073
11074 procedure Fixup_Universal_Fixed_Operation (N : Node_Id) is
11075 Conv : constant Node_Id := Parent (N);
11076
11077 begin
11078 -- We must have a type conversion immediately above us
11079
11080 pragma Assert (Nkind (Conv) = N_Type_Conversion);
11081
11082 -- Normally the type conversion gives our target type. The exception
11083 -- occurs in the case of the Round attribute, where the conversion
11084 -- will be to universal real, and our real type comes from the Round
11085 -- attribute (as well as an indication that we must round the result)
11086
11087 if Nkind (Parent (Conv)) = N_Attribute_Reference
11088 and then Attribute_Name (Parent (Conv)) = Name_Round
11089 then
11090 Set_Etype (N, Etype (Parent (Conv)));
11091 Set_Rounded_Result (N);
11092
11093 -- Normal case where type comes from conversion above us
11094
11095 else
11096 Set_Etype (N, Etype (Conv));
11097 end if;
11098 end Fixup_Universal_Fixed_Operation;
11099
11100 ---------------------------------
11101 -- Has_Inferable_Discriminants --
11102 ---------------------------------
11103
11104 function Has_Inferable_Discriminants (N : Node_Id) return Boolean is
11105
11106 function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean;
11107 -- Determines whether the left-most prefix of a selected component is a
11108 -- formal parameter in a subprogram. Assumes N is a selected component.
11109
11110 --------------------------------
11111 -- Prefix_Is_Formal_Parameter --
11112 --------------------------------
11113
11114 function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean is
11115 Sel_Comp : Node_Id;
11116
11117 begin
11118 -- Move to the left-most prefix by climbing up the tree
11119
11120 Sel_Comp := N;
11121 while Present (Parent (Sel_Comp))
11122 and then Nkind (Parent (Sel_Comp)) = N_Selected_Component
11123 loop
11124 Sel_Comp := Parent (Sel_Comp);
11125 end loop;
11126
11127 return Ekind (Entity (Prefix (Sel_Comp))) in Formal_Kind;
11128 end Prefix_Is_Formal_Parameter;
11129
11130 -- Start of processing for Has_Inferable_Discriminants
11131
11132 begin
11133 -- For selected components, the subtype of the selector must be a
11134 -- constrained Unchecked_Union. If the component is subject to a
11135 -- per-object constraint, then the enclosing object must have inferable
11136 -- discriminants.
11137
11138 if Nkind (N) = N_Selected_Component then
11139 if Has_Per_Object_Constraint (Entity (Selector_Name (N))) then
11140
11141 -- A small hack. If we have a per-object constrained selected
11142 -- component of a formal parameter, return True since we do not
11143 -- know the actual parameter association yet.
11144
11145 if Prefix_Is_Formal_Parameter (N) then
11146 return True;
11147
11148 -- Otherwise, check the enclosing object and the selector
11149
11150 else
11151 return Has_Inferable_Discriminants (Prefix (N))
11152 and then Has_Inferable_Discriminants (Selector_Name (N));
11153 end if;
11154
11155 -- The call to Has_Inferable_Discriminants will determine whether
11156 -- the selector has a constrained Unchecked_Union nominal type.
11157
11158 else
11159 return Has_Inferable_Discriminants (Selector_Name (N));
11160 end if;
11161
11162 -- A qualified expression has inferable discriminants if its subtype
11163 -- mark is a constrained Unchecked_Union subtype.
11164
11165 elsif Nkind (N) = N_Qualified_Expression then
11166 return Is_Unchecked_Union (Etype (Subtype_Mark (N)))
11167 and then Is_Constrained (Etype (Subtype_Mark (N)));
11168
11169 -- For all other names, it is sufficient to have a constrained
11170 -- Unchecked_Union nominal subtype.
11171
11172 else
11173 return Is_Unchecked_Union (Base_Type (Etype (N)))
11174 and then Is_Constrained (Etype (N));
11175 end if;
11176 end Has_Inferable_Discriminants;
11177
11178 -------------------------------
11179 -- Insert_Dereference_Action --
11180 -------------------------------
11181
11182 procedure Insert_Dereference_Action (N : Node_Id) is
11183
11184 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
11185 -- Return true if type of P is derived from Checked_Pool;
11186
11187 -----------------------------
11188 -- Is_Checked_Storage_Pool --
11189 -----------------------------
11190
11191 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean is
11192 T : Entity_Id;
11193
11194 begin
11195 if No (P) then
11196 return False;
11197 end if;
11198
11199 T := Etype (P);
11200 while T /= Etype (T) loop
11201 if Is_RTE (T, RE_Checked_Pool) then
11202 return True;
11203 else
11204 T := Etype (T);
11205 end if;
11206 end loop;
11207
11208 return False;
11209 end Is_Checked_Storage_Pool;
11210
11211 -- Local variables
11212
11213 Typ : constant Entity_Id := Etype (N);
11214 Desig : constant Entity_Id := Available_View (Designated_Type (Typ));
11215 Loc : constant Source_Ptr := Sloc (N);
11216 Pool : constant Entity_Id := Associated_Storage_Pool (Typ);
11217 Pnod : constant Node_Id := Parent (N);
11218
11219 Addr : Entity_Id;
11220 Alig : Entity_Id;
11221 Deref : Node_Id;
11222 Size : Entity_Id;
11223 Stmt : Node_Id;
11224
11225 -- Start of processing for Insert_Dereference_Action
11226
11227 begin
11228 pragma Assert (Nkind (Pnod) = N_Explicit_Dereference);
11229
11230 -- Do not re-expand a dereference which has already been processed by
11231 -- this routine.
11232
11233 if Has_Dereference_Action (Pnod) then
11234 return;
11235
11236 -- Do not perform this type of expansion for internally-generated
11237 -- dereferences.
11238
11239 elsif not Comes_From_Source (Original_Node (Pnod)) then
11240 return;
11241
11242 -- A dereference action is only applicable to objects which have been
11243 -- allocated on a checked pool.
11244
11245 elsif not Is_Checked_Storage_Pool (Pool) then
11246 return;
11247 end if;
11248
11249 -- Extract the address of the dereferenced object. Generate:
11250
11251 -- Addr : System.Address := <N>'Pool_Address;
11252
11253 Addr := Make_Temporary (Loc, 'P');
11254
11255 Insert_Action (N,
11256 Make_Object_Declaration (Loc,
11257 Defining_Identifier => Addr,
11258 Object_Definition =>
11259 New_Reference_To (RTE (RE_Address), Loc),
11260 Expression =>
11261 Make_Attribute_Reference (Loc,
11262 Prefix => Duplicate_Subexpr_Move_Checks (N),
11263 Attribute_Name => Name_Pool_Address)));
11264
11265 -- Calculate the size of the dereferenced object. Generate:
11266
11267 -- Size : Storage_Count := <N>.all'Size / Storage_Unit;
11268
11269 Deref :=
11270 Make_Explicit_Dereference (Loc,
11271 Prefix => Duplicate_Subexpr_Move_Checks (N));
11272 Set_Has_Dereference_Action (Deref);
11273
11274 Size := Make_Temporary (Loc, 'S');
11275
11276 Insert_Action (N,
11277 Make_Object_Declaration (Loc,
11278 Defining_Identifier => Size,
11279
11280 Object_Definition =>
11281 New_Reference_To (RTE (RE_Storage_Count), Loc),
11282
11283 Expression =>
11284 Make_Op_Divide (Loc,
11285 Left_Opnd =>
11286 Make_Attribute_Reference (Loc,
11287 Prefix => Deref,
11288 Attribute_Name => Name_Size),
11289 Right_Opnd =>
11290 Make_Integer_Literal (Loc, System_Storage_Unit))));
11291
11292 -- Calculate the alignment of the dereferenced object. Generate:
11293 -- Alig : constant Storage_Count := <N>.all'Alignment;
11294
11295 Deref :=
11296 Make_Explicit_Dereference (Loc,
11297 Prefix => Duplicate_Subexpr_Move_Checks (N));
11298 Set_Has_Dereference_Action (Deref);
11299
11300 Alig := Make_Temporary (Loc, 'A');
11301
11302 Insert_Action (N,
11303 Make_Object_Declaration (Loc,
11304 Defining_Identifier => Alig,
11305 Object_Definition =>
11306 New_Reference_To (RTE (RE_Storage_Count), Loc),
11307 Expression =>
11308 Make_Attribute_Reference (Loc,
11309 Prefix => Deref,
11310 Attribute_Name => Name_Alignment)));
11311
11312 -- A dereference of a controlled object requires special processing. The
11313 -- finalization machinery requests additional space from the underlying
11314 -- pool to allocate and hide two pointers. As a result, a checked pool
11315 -- may mark the wrong memory as valid. Since checked pools do not have
11316 -- knowledge of hidden pointers, we have to bring the two pointers back
11317 -- in view in order to restore the original state of the object.
11318
11319 if Needs_Finalization (Desig) then
11320
11321 -- Adjust the address and size of the dereferenced object. Generate:
11322 -- Adjust_Controlled_Dereference (Addr, Size, Alig);
11323
11324 Stmt :=
11325 Make_Procedure_Call_Statement (Loc,
11326 Name =>
11327 New_Reference_To (RTE (RE_Adjust_Controlled_Dereference), Loc),
11328 Parameter_Associations => New_List (
11329 New_Reference_To (Addr, Loc),
11330 New_Reference_To (Size, Loc),
11331 New_Reference_To (Alig, Loc)));
11332
11333 -- Class-wide types complicate things because we cannot determine
11334 -- statically whether the actual object is truly controlled. We must
11335 -- generate a runtime check to detect this property. Generate:
11336 --
11337 -- if Needs_Finalization (<N>.all'Tag) then
11338 -- <Stmt>;
11339 -- end if;
11340
11341 if Is_Class_Wide_Type (Desig) then
11342 Deref :=
11343 Make_Explicit_Dereference (Loc,
11344 Prefix => Duplicate_Subexpr_Move_Checks (N));
11345 Set_Has_Dereference_Action (Deref);
11346
11347 Stmt :=
11348 Make_If_Statement (Loc,
11349 Condition =>
11350 Make_Function_Call (Loc,
11351 Name =>
11352 New_Reference_To (RTE (RE_Needs_Finalization), Loc),
11353 Parameter_Associations => New_List (
11354 Make_Attribute_Reference (Loc,
11355 Prefix => Deref,
11356 Attribute_Name => Name_Tag))),
11357 Then_Statements => New_List (Stmt));
11358 end if;
11359
11360 Insert_Action (N, Stmt);
11361 end if;
11362
11363 -- Generate:
11364 -- Dereference (Pool, Addr, Size, Alig);
11365
11366 Insert_Action (N,
11367 Make_Procedure_Call_Statement (Loc,
11368 Name =>
11369 New_Reference_To
11370 (Find_Prim_Op (Etype (Pool), Name_Dereference), Loc),
11371 Parameter_Associations => New_List (
11372 New_Reference_To (Pool, Loc),
11373 New_Reference_To (Addr, Loc),
11374 New_Reference_To (Size, Loc),
11375 New_Reference_To (Alig, Loc))));
11376
11377 -- Mark the explicit dereference as processed to avoid potential
11378 -- infinite expansion.
11379
11380 Set_Has_Dereference_Action (Pnod);
11381
11382 exception
11383 when RE_Not_Available =>
11384 return;
11385 end Insert_Dereference_Action;
11386
11387 --------------------------------
11388 -- Integer_Promotion_Possible --
11389 --------------------------------
11390
11391 function Integer_Promotion_Possible (N : Node_Id) return Boolean is
11392 Operand : constant Node_Id := Expression (N);
11393 Operand_Type : constant Entity_Id := Etype (Operand);
11394 Root_Operand_Type : constant Entity_Id := Root_Type (Operand_Type);
11395
11396 begin
11397 pragma Assert (Nkind (N) = N_Type_Conversion);
11398
11399 return
11400
11401 -- We only do the transformation for source constructs. We assume
11402 -- that the expander knows what it is doing when it generates code.
11403
11404 Comes_From_Source (N)
11405
11406 -- If the operand type is Short_Integer or Short_Short_Integer,
11407 -- then we will promote to Integer, which is available on all
11408 -- targets, and is sufficient to ensure no intermediate overflow.
11409 -- Furthermore it is likely to be as efficient or more efficient
11410 -- than using the smaller type for the computation so we do this
11411 -- unconditionally.
11412
11413 and then
11414 (Root_Operand_Type = Base_Type (Standard_Short_Integer)
11415 or else
11416 Root_Operand_Type = Base_Type (Standard_Short_Short_Integer))
11417
11418 -- Test for interesting operation, which includes addition,
11419 -- division, exponentiation, multiplication, subtraction, absolute
11420 -- value and unary negation. Unary "+" is omitted since it is a
11421 -- no-op and thus can't overflow.
11422
11423 and then Nkind_In (Operand, N_Op_Abs,
11424 N_Op_Add,
11425 N_Op_Divide,
11426 N_Op_Expon,
11427 N_Op_Minus,
11428 N_Op_Multiply,
11429 N_Op_Subtract);
11430 end Integer_Promotion_Possible;
11431
11432 ------------------------------
11433 -- Make_Array_Comparison_Op --
11434 ------------------------------
11435
11436 -- This is a hand-coded expansion of the following generic function:
11437
11438 -- generic
11439 -- type elem is (<>);
11440 -- type index is (<>);
11441 -- type a is array (index range <>) of elem;
11442
11443 -- function Gnnn (X : a; Y: a) return boolean is
11444 -- J : index := Y'first;
11445
11446 -- begin
11447 -- if X'length = 0 then
11448 -- return false;
11449
11450 -- elsif Y'length = 0 then
11451 -- return true;
11452
11453 -- else
11454 -- for I in X'range loop
11455 -- if X (I) = Y (J) then
11456 -- if J = Y'last then
11457 -- exit;
11458 -- else
11459 -- J := index'succ (J);
11460 -- end if;
11461
11462 -- else
11463 -- return X (I) > Y (J);
11464 -- end if;
11465 -- end loop;
11466
11467 -- return X'length > Y'length;
11468 -- end if;
11469 -- end Gnnn;
11470
11471 -- Note that since we are essentially doing this expansion by hand, we
11472 -- do not need to generate an actual or formal generic part, just the
11473 -- instantiated function itself.
11474
11475 function Make_Array_Comparison_Op
11476 (Typ : Entity_Id;
11477 Nod : Node_Id) return Node_Id
11478 is
11479 Loc : constant Source_Ptr := Sloc (Nod);
11480
11481 X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uX);
11482 Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uY);
11483 I : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uI);
11484 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
11485
11486 Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ)));
11487
11488 Loop_Statement : Node_Id;
11489 Loop_Body : Node_Id;
11490 If_Stat : Node_Id;
11491 Inner_If : Node_Id;
11492 Final_Expr : Node_Id;
11493 Func_Body : Node_Id;
11494 Func_Name : Entity_Id;
11495 Formals : List_Id;
11496 Length1 : Node_Id;
11497 Length2 : Node_Id;
11498
11499 begin
11500 -- if J = Y'last then
11501 -- exit;
11502 -- else
11503 -- J := index'succ (J);
11504 -- end if;
11505
11506 Inner_If :=
11507 Make_Implicit_If_Statement (Nod,
11508 Condition =>
11509 Make_Op_Eq (Loc,
11510 Left_Opnd => New_Reference_To (J, Loc),
11511 Right_Opnd =>
11512 Make_Attribute_Reference (Loc,
11513 Prefix => New_Reference_To (Y, Loc),
11514 Attribute_Name => Name_Last)),
11515
11516 Then_Statements => New_List (
11517 Make_Exit_Statement (Loc)),
11518
11519 Else_Statements =>
11520 New_List (
11521 Make_Assignment_Statement (Loc,
11522 Name => New_Reference_To (J, Loc),
11523 Expression =>
11524 Make_Attribute_Reference (Loc,
11525 Prefix => New_Reference_To (Index, Loc),
11526 Attribute_Name => Name_Succ,
11527 Expressions => New_List (New_Reference_To (J, Loc))))));
11528
11529 -- if X (I) = Y (J) then
11530 -- if ... end if;
11531 -- else
11532 -- return X (I) > Y (J);
11533 -- end if;
11534
11535 Loop_Body :=
11536 Make_Implicit_If_Statement (Nod,
11537 Condition =>
11538 Make_Op_Eq (Loc,
11539 Left_Opnd =>
11540 Make_Indexed_Component (Loc,
11541 Prefix => New_Reference_To (X, Loc),
11542 Expressions => New_List (New_Reference_To (I, Loc))),
11543
11544 Right_Opnd =>
11545 Make_Indexed_Component (Loc,
11546 Prefix => New_Reference_To (Y, Loc),
11547 Expressions => New_List (New_Reference_To (J, Loc)))),
11548
11549 Then_Statements => New_List (Inner_If),
11550
11551 Else_Statements => New_List (
11552 Make_Simple_Return_Statement (Loc,
11553 Expression =>
11554 Make_Op_Gt (Loc,
11555 Left_Opnd =>
11556 Make_Indexed_Component (Loc,
11557 Prefix => New_Reference_To (X, Loc),
11558 Expressions => New_List (New_Reference_To (I, Loc))),
11559
11560 Right_Opnd =>
11561 Make_Indexed_Component (Loc,
11562 Prefix => New_Reference_To (Y, Loc),
11563 Expressions => New_List (
11564 New_Reference_To (J, Loc)))))));
11565
11566 -- for I in X'range loop
11567 -- if ... end if;
11568 -- end loop;
11569
11570 Loop_Statement :=
11571 Make_Implicit_Loop_Statement (Nod,
11572 Identifier => Empty,
11573
11574 Iteration_Scheme =>
11575 Make_Iteration_Scheme (Loc,
11576 Loop_Parameter_Specification =>
11577 Make_Loop_Parameter_Specification (Loc,
11578 Defining_Identifier => I,
11579 Discrete_Subtype_Definition =>
11580 Make_Attribute_Reference (Loc,
11581 Prefix => New_Reference_To (X, Loc),
11582 Attribute_Name => Name_Range))),
11583
11584 Statements => New_List (Loop_Body));
11585
11586 -- if X'length = 0 then
11587 -- return false;
11588 -- elsif Y'length = 0 then
11589 -- return true;
11590 -- else
11591 -- for ... loop ... end loop;
11592 -- return X'length > Y'length;
11593 -- end if;
11594
11595 Length1 :=
11596 Make_Attribute_Reference (Loc,
11597 Prefix => New_Reference_To (X, Loc),
11598 Attribute_Name => Name_Length);
11599
11600 Length2 :=
11601 Make_Attribute_Reference (Loc,
11602 Prefix => New_Reference_To (Y, Loc),
11603 Attribute_Name => Name_Length);
11604
11605 Final_Expr :=
11606 Make_Op_Gt (Loc,
11607 Left_Opnd => Length1,
11608 Right_Opnd => Length2);
11609
11610 If_Stat :=
11611 Make_Implicit_If_Statement (Nod,
11612 Condition =>
11613 Make_Op_Eq (Loc,
11614 Left_Opnd =>
11615 Make_Attribute_Reference (Loc,
11616 Prefix => New_Reference_To (X, Loc),
11617 Attribute_Name => Name_Length),
11618 Right_Opnd =>
11619 Make_Integer_Literal (Loc, 0)),
11620
11621 Then_Statements =>
11622 New_List (
11623 Make_Simple_Return_Statement (Loc,
11624 Expression => New_Reference_To (Standard_False, Loc))),
11625
11626 Elsif_Parts => New_List (
11627 Make_Elsif_Part (Loc,
11628 Condition =>
11629 Make_Op_Eq (Loc,
11630 Left_Opnd =>
11631 Make_Attribute_Reference (Loc,
11632 Prefix => New_Reference_To (Y, Loc),
11633 Attribute_Name => Name_Length),
11634 Right_Opnd =>
11635 Make_Integer_Literal (Loc, 0)),
11636
11637 Then_Statements =>
11638 New_List (
11639 Make_Simple_Return_Statement (Loc,
11640 Expression => New_Reference_To (Standard_True, Loc))))),
11641
11642 Else_Statements => New_List (
11643 Loop_Statement,
11644 Make_Simple_Return_Statement (Loc,
11645 Expression => Final_Expr)));
11646
11647 -- (X : a; Y: a)
11648
11649 Formals := New_List (
11650 Make_Parameter_Specification (Loc,
11651 Defining_Identifier => X,
11652 Parameter_Type => New_Reference_To (Typ, Loc)),
11653
11654 Make_Parameter_Specification (Loc,
11655 Defining_Identifier => Y,
11656 Parameter_Type => New_Reference_To (Typ, Loc)));
11657
11658 -- function Gnnn (...) return boolean is
11659 -- J : index := Y'first;
11660 -- begin
11661 -- if ... end if;
11662 -- end Gnnn;
11663
11664 Func_Name := Make_Temporary (Loc, 'G');
11665
11666 Func_Body :=
11667 Make_Subprogram_Body (Loc,
11668 Specification =>
11669 Make_Function_Specification (Loc,
11670 Defining_Unit_Name => Func_Name,
11671 Parameter_Specifications => Formals,
11672 Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
11673
11674 Declarations => New_List (
11675 Make_Object_Declaration (Loc,
11676 Defining_Identifier => J,
11677 Object_Definition => New_Reference_To (Index, Loc),
11678 Expression =>
11679 Make_Attribute_Reference (Loc,
11680 Prefix => New_Reference_To (Y, Loc),
11681 Attribute_Name => Name_First))),
11682
11683 Handled_Statement_Sequence =>
11684 Make_Handled_Sequence_Of_Statements (Loc,
11685 Statements => New_List (If_Stat)));
11686
11687 return Func_Body;
11688 end Make_Array_Comparison_Op;
11689
11690 ---------------------------
11691 -- Make_Boolean_Array_Op --
11692 ---------------------------
11693
11694 -- For logical operations on boolean arrays, expand in line the following,
11695 -- replacing 'and' with 'or' or 'xor' where needed:
11696
11697 -- function Annn (A : typ; B: typ) return typ is
11698 -- C : typ;
11699 -- begin
11700 -- for J in A'range loop
11701 -- C (J) := A (J) op B (J);
11702 -- end loop;
11703 -- return C;
11704 -- end Annn;
11705
11706 -- Here typ is the boolean array type
11707
11708 function Make_Boolean_Array_Op
11709 (Typ : Entity_Id;
11710 N : Node_Id) return Node_Id
11711 is
11712 Loc : constant Source_Ptr := Sloc (N);
11713
11714 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
11715 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
11716 C : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uC);
11717 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
11718
11719 A_J : Node_Id;
11720 B_J : Node_Id;
11721 C_J : Node_Id;
11722 Op : Node_Id;
11723
11724 Formals : List_Id;
11725 Func_Name : Entity_Id;
11726 Func_Body : Node_Id;
11727 Loop_Statement : Node_Id;
11728
11729 begin
11730 A_J :=
11731 Make_Indexed_Component (Loc,
11732 Prefix => New_Reference_To (A, Loc),
11733 Expressions => New_List (New_Reference_To (J, Loc)));
11734
11735 B_J :=
11736 Make_Indexed_Component (Loc,
11737 Prefix => New_Reference_To (B, Loc),
11738 Expressions => New_List (New_Reference_To (J, Loc)));
11739
11740 C_J :=
11741 Make_Indexed_Component (Loc,
11742 Prefix => New_Reference_To (C, Loc),
11743 Expressions => New_List (New_Reference_To (J, Loc)));
11744
11745 if Nkind (N) = N_Op_And then
11746 Op :=
11747 Make_Op_And (Loc,
11748 Left_Opnd => A_J,
11749 Right_Opnd => B_J);
11750
11751 elsif Nkind (N) = N_Op_Or then
11752 Op :=
11753 Make_Op_Or (Loc,
11754 Left_Opnd => A_J,
11755 Right_Opnd => B_J);
11756
11757 else
11758 Op :=
11759 Make_Op_Xor (Loc,
11760 Left_Opnd => A_J,
11761 Right_Opnd => B_J);
11762 end if;
11763
11764 Loop_Statement :=
11765 Make_Implicit_Loop_Statement (N,
11766 Identifier => Empty,
11767
11768 Iteration_Scheme =>
11769 Make_Iteration_Scheme (Loc,
11770 Loop_Parameter_Specification =>
11771 Make_Loop_Parameter_Specification (Loc,
11772 Defining_Identifier => J,
11773 Discrete_Subtype_Definition =>
11774 Make_Attribute_Reference (Loc,
11775 Prefix => New_Reference_To (A, Loc),
11776 Attribute_Name => Name_Range))),
11777
11778 Statements => New_List (
11779 Make_Assignment_Statement (Loc,
11780 Name => C_J,
11781 Expression => Op)));
11782
11783 Formals := New_List (
11784 Make_Parameter_Specification (Loc,
11785 Defining_Identifier => A,
11786 Parameter_Type => New_Reference_To (Typ, Loc)),
11787
11788 Make_Parameter_Specification (Loc,
11789 Defining_Identifier => B,
11790 Parameter_Type => New_Reference_To (Typ, Loc)));
11791
11792 Func_Name := Make_Temporary (Loc, 'A');
11793 Set_Is_Inlined (Func_Name);
11794
11795 Func_Body :=
11796 Make_Subprogram_Body (Loc,
11797 Specification =>
11798 Make_Function_Specification (Loc,
11799 Defining_Unit_Name => Func_Name,
11800 Parameter_Specifications => Formals,
11801 Result_Definition => New_Reference_To (Typ, Loc)),
11802
11803 Declarations => New_List (
11804 Make_Object_Declaration (Loc,
11805 Defining_Identifier => C,
11806 Object_Definition => New_Reference_To (Typ, Loc))),
11807
11808 Handled_Statement_Sequence =>
11809 Make_Handled_Sequence_Of_Statements (Loc,
11810 Statements => New_List (
11811 Loop_Statement,
11812 Make_Simple_Return_Statement (Loc,
11813 Expression => New_Reference_To (C, Loc)))));
11814
11815 return Func_Body;
11816 end Make_Boolean_Array_Op;
11817
11818 -----------------------------------------
11819 -- Minimized_Eliminated_Overflow_Check --
11820 -----------------------------------------
11821
11822 function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean is
11823 begin
11824 return
11825 Is_Signed_Integer_Type (Etype (N))
11826 and then Do_Overflow_Check (N)
11827 and then Overflow_Check_Mode (Empty) in Minimized_Or_Eliminated;
11828 end Minimized_Eliminated_Overflow_Check;
11829
11830 --------------------------------
11831 -- Optimize_Length_Comparison --
11832 --------------------------------
11833
11834 procedure Optimize_Length_Comparison (N : Node_Id) is
11835 Loc : constant Source_Ptr := Sloc (N);
11836 Typ : constant Entity_Id := Etype (N);
11837 Result : Node_Id;
11838
11839 Left : Node_Id;
11840 Right : Node_Id;
11841 -- First and Last attribute reference nodes, which end up as left and
11842 -- right operands of the optimized result.
11843
11844 Is_Zero : Boolean;
11845 -- True for comparison operand of zero
11846
11847 Comp : Node_Id;
11848 -- Comparison operand, set only if Is_Zero is false
11849
11850 Ent : Entity_Id;
11851 -- Entity whose length is being compared
11852
11853 Index : Node_Id;
11854 -- Integer_Literal node for length attribute expression, or Empty
11855 -- if there is no such expression present.
11856
11857 Ityp : Entity_Id;
11858 -- Type of array index to which 'Length is applied
11859
11860 Op : Node_Kind := Nkind (N);
11861 -- Kind of comparison operator, gets flipped if operands backwards
11862
11863 function Is_Optimizable (N : Node_Id) return Boolean;
11864 -- Tests N to see if it is an optimizable comparison value (defined as
11865 -- constant zero or one, or something else where the value is known to
11866 -- be positive and in the range of 32-bits, and where the corresponding
11867 -- Length value is also known to be 32-bits. If result is true, sets
11868 -- Is_Zero, Ityp, and Comp accordingly.
11869
11870 function Is_Entity_Length (N : Node_Id) return Boolean;
11871 -- Tests if N is a length attribute applied to a simple entity. If so,
11872 -- returns True, and sets Ent to the entity, and Index to the integer
11873 -- literal provided as an attribute expression, or to Empty if none.
11874 -- Also returns True if the expression is a generated type conversion
11875 -- whose expression is of the desired form. This latter case arises
11876 -- when Apply_Universal_Integer_Attribute_Check installs a conversion
11877 -- to check for being in range, which is not needed in this context.
11878 -- Returns False if neither condition holds.
11879
11880 function Prepare_64 (N : Node_Id) return Node_Id;
11881 -- Given a discrete expression, returns a Long_Long_Integer typed
11882 -- expression representing the underlying value of the expression.
11883 -- This is done with an unchecked conversion to the result type. We
11884 -- use unchecked conversion to handle the enumeration type case.
11885
11886 ----------------------
11887 -- Is_Entity_Length --
11888 ----------------------
11889
11890 function Is_Entity_Length (N : Node_Id) return Boolean is
11891 begin
11892 if Nkind (N) = N_Attribute_Reference
11893 and then Attribute_Name (N) = Name_Length
11894 and then Is_Entity_Name (Prefix (N))
11895 then
11896 Ent := Entity (Prefix (N));
11897
11898 if Present (Expressions (N)) then
11899 Index := First (Expressions (N));
11900 else
11901 Index := Empty;
11902 end if;
11903
11904 return True;
11905
11906 elsif Nkind (N) = N_Type_Conversion
11907 and then not Comes_From_Source (N)
11908 then
11909 return Is_Entity_Length (Expression (N));
11910
11911 else
11912 return False;
11913 end if;
11914 end Is_Entity_Length;
11915
11916 --------------------
11917 -- Is_Optimizable --
11918 --------------------
11919
11920 function Is_Optimizable (N : Node_Id) return Boolean is
11921 Val : Uint;
11922 OK : Boolean;
11923 Lo : Uint;
11924 Hi : Uint;
11925 Indx : Node_Id;
11926
11927 begin
11928 if Compile_Time_Known_Value (N) then
11929 Val := Expr_Value (N);
11930
11931 if Val = Uint_0 then
11932 Is_Zero := True;
11933 Comp := Empty;
11934 return True;
11935
11936 elsif Val = Uint_1 then
11937 Is_Zero := False;
11938 Comp := Empty;
11939 return True;
11940 end if;
11941 end if;
11942
11943 -- Here we have to make sure of being within 32-bits
11944
11945 Determine_Range (N, OK, Lo, Hi, Assume_Valid => True);
11946
11947 if not OK
11948 or else Lo < Uint_1
11949 or else Hi > UI_From_Int (Int'Last)
11950 then
11951 return False;
11952 end if;
11953
11954 -- Comparison value was within range, so now we must check the index
11955 -- value to make sure it is also within 32-bits.
11956
11957 Indx := First_Index (Etype (Ent));
11958
11959 if Present (Index) then
11960 for J in 2 .. UI_To_Int (Intval (Index)) loop
11961 Next_Index (Indx);
11962 end loop;
11963 end if;
11964
11965 Ityp := Etype (Indx);
11966
11967 if Esize (Ityp) > 32 then
11968 return False;
11969 end if;
11970
11971 Is_Zero := False;
11972 Comp := N;
11973 return True;
11974 end Is_Optimizable;
11975
11976 ----------------
11977 -- Prepare_64 --
11978 ----------------
11979
11980 function Prepare_64 (N : Node_Id) return Node_Id is
11981 begin
11982 return Unchecked_Convert_To (Standard_Long_Long_Integer, N);
11983 end Prepare_64;
11984
11985 -- Start of processing for Optimize_Length_Comparison
11986
11987 begin
11988 -- Nothing to do if not a comparison
11989
11990 if Op not in N_Op_Compare then
11991 return;
11992 end if;
11993
11994 -- Nothing to do if special -gnatd.P debug flag set
11995
11996 if Debug_Flag_Dot_PP then
11997 return;
11998 end if;
11999
12000 -- Ent'Length op 0/1
12001
12002 if Is_Entity_Length (Left_Opnd (N))
12003 and then Is_Optimizable (Right_Opnd (N))
12004 then
12005 null;
12006
12007 -- 0/1 op Ent'Length
12008
12009 elsif Is_Entity_Length (Right_Opnd (N))
12010 and then Is_Optimizable (Left_Opnd (N))
12011 then
12012 -- Flip comparison to opposite sense
12013
12014 case Op is
12015 when N_Op_Lt => Op := N_Op_Gt;
12016 when N_Op_Le => Op := N_Op_Ge;
12017 when N_Op_Gt => Op := N_Op_Lt;
12018 when N_Op_Ge => Op := N_Op_Le;
12019 when others => null;
12020 end case;
12021
12022 -- Else optimization not possible
12023
12024 else
12025 return;
12026 end if;
12027
12028 -- Fall through if we will do the optimization
12029
12030 -- Cases to handle:
12031
12032 -- X'Length = 0 => X'First > X'Last
12033 -- X'Length = 1 => X'First = X'Last
12034 -- X'Length = n => X'First + (n - 1) = X'Last
12035
12036 -- X'Length /= 0 => X'First <= X'Last
12037 -- X'Length /= 1 => X'First /= X'Last
12038 -- X'Length /= n => X'First + (n - 1) /= X'Last
12039
12040 -- X'Length >= 0 => always true, warn
12041 -- X'Length >= 1 => X'First <= X'Last
12042 -- X'Length >= n => X'First + (n - 1) <= X'Last
12043
12044 -- X'Length > 0 => X'First <= X'Last
12045 -- X'Length > 1 => X'First < X'Last
12046 -- X'Length > n => X'First + (n - 1) < X'Last
12047
12048 -- X'Length <= 0 => X'First > X'Last (warn, could be =)
12049 -- X'Length <= 1 => X'First >= X'Last
12050 -- X'Length <= n => X'First + (n - 1) >= X'Last
12051
12052 -- X'Length < 0 => always false (warn)
12053 -- X'Length < 1 => X'First > X'Last
12054 -- X'Length < n => X'First + (n - 1) > X'Last
12055
12056 -- Note: for the cases of n (not constant 0,1), we require that the
12057 -- corresponding index type be integer or shorter (i.e. not 64-bit),
12058 -- and the same for the comparison value. Then we do the comparison
12059 -- using 64-bit arithmetic (actually long long integer), so that we
12060 -- cannot have overflow intefering with the result.
12061
12062 -- First deal with warning cases
12063
12064 if Is_Zero then
12065 case Op is
12066
12067 -- X'Length >= 0
12068
12069 when N_Op_Ge =>
12070 Rewrite (N,
12071 Convert_To (Typ, New_Occurrence_Of (Standard_True, Loc)));
12072 Analyze_And_Resolve (N, Typ);
12073 Warn_On_Known_Condition (N);
12074 return;
12075
12076 -- X'Length < 0
12077
12078 when N_Op_Lt =>
12079 Rewrite (N,
12080 Convert_To (Typ, New_Occurrence_Of (Standard_False, Loc)));
12081 Analyze_And_Resolve (N, Typ);
12082 Warn_On_Known_Condition (N);
12083 return;
12084
12085 when N_Op_Le =>
12086 if Constant_Condition_Warnings
12087 and then Comes_From_Source (Original_Node (N))
12088 then
12089 Error_Msg_N ("could replace by ""'=""?", N);
12090 end if;
12091
12092 Op := N_Op_Eq;
12093
12094 when others =>
12095 null;
12096 end case;
12097 end if;
12098
12099 -- Build the First reference we will use
12100
12101 Left :=
12102 Make_Attribute_Reference (Loc,
12103 Prefix => New_Occurrence_Of (Ent, Loc),
12104 Attribute_Name => Name_First);
12105
12106 if Present (Index) then
12107 Set_Expressions (Left, New_List (New_Copy (Index)));
12108 end if;
12109
12110 -- If general value case, then do the addition of (n - 1), and
12111 -- also add the needed conversions to type Long_Long_Integer.
12112
12113 if Present (Comp) then
12114 Left :=
12115 Make_Op_Add (Loc,
12116 Left_Opnd => Prepare_64 (Left),
12117 Right_Opnd =>
12118 Make_Op_Subtract (Loc,
12119 Left_Opnd => Prepare_64 (Comp),
12120 Right_Opnd => Make_Integer_Literal (Loc, 1)));
12121 end if;
12122
12123 -- Build the Last reference we will use
12124
12125 Right :=
12126 Make_Attribute_Reference (Loc,
12127 Prefix => New_Occurrence_Of (Ent, Loc),
12128 Attribute_Name => Name_Last);
12129
12130 if Present (Index) then
12131 Set_Expressions (Right, New_List (New_Copy (Index)));
12132 end if;
12133
12134 -- If general operand, convert Last reference to Long_Long_Integer
12135
12136 if Present (Comp) then
12137 Right := Prepare_64 (Right);
12138 end if;
12139
12140 -- Check for cases to optimize
12141
12142 -- X'Length = 0 => X'First > X'Last
12143 -- X'Length < 1 => X'First > X'Last
12144 -- X'Length < n => X'First + (n - 1) > X'Last
12145
12146 if (Is_Zero and then Op = N_Op_Eq)
12147 or else (not Is_Zero and then Op = N_Op_Lt)
12148 then
12149 Result :=
12150 Make_Op_Gt (Loc,
12151 Left_Opnd => Left,
12152 Right_Opnd => Right);
12153
12154 -- X'Length = 1 => X'First = X'Last
12155 -- X'Length = n => X'First + (n - 1) = X'Last
12156
12157 elsif not Is_Zero and then Op = N_Op_Eq then
12158 Result :=
12159 Make_Op_Eq (Loc,
12160 Left_Opnd => Left,
12161 Right_Opnd => Right);
12162
12163 -- X'Length /= 0 => X'First <= X'Last
12164 -- X'Length > 0 => X'First <= X'Last
12165
12166 elsif Is_Zero and (Op = N_Op_Ne or else Op = N_Op_Gt) then
12167 Result :=
12168 Make_Op_Le (Loc,
12169 Left_Opnd => Left,
12170 Right_Opnd => Right);
12171
12172 -- X'Length /= 1 => X'First /= X'Last
12173 -- X'Length /= n => X'First + (n - 1) /= X'Last
12174
12175 elsif not Is_Zero and then Op = N_Op_Ne then
12176 Result :=
12177 Make_Op_Ne (Loc,
12178 Left_Opnd => Left,
12179 Right_Opnd => Right);
12180
12181 -- X'Length >= 1 => X'First <= X'Last
12182 -- X'Length >= n => X'First + (n - 1) <= X'Last
12183
12184 elsif not Is_Zero and then Op = N_Op_Ge then
12185 Result :=
12186 Make_Op_Le (Loc,
12187 Left_Opnd => Left,
12188 Right_Opnd => Right);
12189
12190 -- X'Length > 1 => X'First < X'Last
12191 -- X'Length > n => X'First + (n = 1) < X'Last
12192
12193 elsif not Is_Zero and then Op = N_Op_Gt then
12194 Result :=
12195 Make_Op_Lt (Loc,
12196 Left_Opnd => Left,
12197 Right_Opnd => Right);
12198
12199 -- X'Length <= 1 => X'First >= X'Last
12200 -- X'Length <= n => X'First + (n - 1) >= X'Last
12201
12202 elsif not Is_Zero and then Op = N_Op_Le then
12203 Result :=
12204 Make_Op_Ge (Loc,
12205 Left_Opnd => Left,
12206 Right_Opnd => Right);
12207
12208 -- Should not happen at this stage
12209
12210 else
12211 raise Program_Error;
12212 end if;
12213
12214 -- Rewrite and finish up
12215
12216 Rewrite (N, Result);
12217 Analyze_And_Resolve (N, Typ);
12218 return;
12219 end Optimize_Length_Comparison;
12220
12221 ------------------------
12222 -- Rewrite_Comparison --
12223 ------------------------
12224
12225 procedure Rewrite_Comparison (N : Node_Id) is
12226 Warning_Generated : Boolean := False;
12227 -- Set to True if first pass with Assume_Valid generates a warning in
12228 -- which case we skip the second pass to avoid warning overloaded.
12229
12230 Result : Node_Id;
12231 -- Set to Standard_True or Standard_False
12232
12233 begin
12234 if Nkind (N) = N_Type_Conversion then
12235 Rewrite_Comparison (Expression (N));
12236 return;
12237
12238 elsif Nkind (N) not in N_Op_Compare then
12239 return;
12240 end if;
12241
12242 -- Now start looking at the comparison in detail. We potentially go
12243 -- through this loop twice. The first time, Assume_Valid is set False
12244 -- in the call to Compile_Time_Compare. If this call results in a
12245 -- clear result of always True or Always False, that's decisive and
12246 -- we are done. Otherwise we repeat the processing with Assume_Valid
12247 -- set to True to generate additional warnings. We can skip that step
12248 -- if Constant_Condition_Warnings is False.
12249
12250 for AV in False .. True loop
12251 declare
12252 Typ : constant Entity_Id := Etype (N);
12253 Op1 : constant Node_Id := Left_Opnd (N);
12254 Op2 : constant Node_Id := Right_Opnd (N);
12255
12256 Res : constant Compare_Result :=
12257 Compile_Time_Compare (Op1, Op2, Assume_Valid => AV);
12258 -- Res indicates if compare outcome can be compile time determined
12259
12260 True_Result : Boolean;
12261 False_Result : Boolean;
12262
12263 begin
12264 case N_Op_Compare (Nkind (N)) is
12265 when N_Op_Eq =>
12266 True_Result := Res = EQ;
12267 False_Result := Res = LT or else Res = GT or else Res = NE;
12268
12269 when N_Op_Ge =>
12270 True_Result := Res in Compare_GE;
12271 False_Result := Res = LT;
12272
12273 if Res = LE
12274 and then Constant_Condition_Warnings
12275 and then Comes_From_Source (Original_Node (N))
12276 and then Nkind (Original_Node (N)) = N_Op_Ge
12277 and then not In_Instance
12278 and then Is_Integer_Type (Etype (Left_Opnd (N)))
12279 and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
12280 then
12281 Error_Msg_N
12282 ("can never be greater than, could replace by ""'=""?", N);
12283 Warning_Generated := True;
12284 end if;
12285
12286 when N_Op_Gt =>
12287 True_Result := Res = GT;
12288 False_Result := Res in Compare_LE;
12289
12290 when N_Op_Lt =>
12291 True_Result := Res = LT;
12292 False_Result := Res in Compare_GE;
12293
12294 when N_Op_Le =>
12295 True_Result := Res in Compare_LE;
12296 False_Result := Res = GT;
12297
12298 if Res = GE
12299 and then Constant_Condition_Warnings
12300 and then Comes_From_Source (Original_Node (N))
12301 and then Nkind (Original_Node (N)) = N_Op_Le
12302 and then not In_Instance
12303 and then Is_Integer_Type (Etype (Left_Opnd (N)))
12304 and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
12305 then
12306 Error_Msg_N
12307 ("can never be less than, could replace by ""'=""?", N);
12308 Warning_Generated := True;
12309 end if;
12310
12311 when N_Op_Ne =>
12312 True_Result := Res = NE or else Res = GT or else Res = LT;
12313 False_Result := Res = EQ;
12314 end case;
12315
12316 -- If this is the first iteration, then we actually convert the
12317 -- comparison into True or False, if the result is certain.
12318
12319 if AV = False then
12320 if True_Result or False_Result then
12321 Result := Boolean_Literals (True_Result);
12322 Rewrite (N,
12323 Convert_To (Typ,
12324 New_Occurrence_Of (Result, Sloc (N))));
12325 Analyze_And_Resolve (N, Typ);
12326 Warn_On_Known_Condition (N);
12327 return;
12328 end if;
12329
12330 -- If this is the second iteration (AV = True), and the original
12331 -- node comes from source and we are not in an instance, then give
12332 -- a warning if we know result would be True or False. Note: we
12333 -- know Constant_Condition_Warnings is set if we get here.
12334
12335 elsif Comes_From_Source (Original_Node (N))
12336 and then not In_Instance
12337 then
12338 if True_Result then
12339 Error_Msg_N
12340 ("condition can only be False if invalid values present?",
12341 N);
12342 elsif False_Result then
12343 Error_Msg_N
12344 ("condition can only be True if invalid values present?",
12345 N);
12346 end if;
12347 end if;
12348 end;
12349
12350 -- Skip second iteration if not warning on constant conditions or
12351 -- if the first iteration already generated a warning of some kind or
12352 -- if we are in any case assuming all values are valid (so that the
12353 -- first iteration took care of the valid case).
12354
12355 exit when not Constant_Condition_Warnings;
12356 exit when Warning_Generated;
12357 exit when Assume_No_Invalid_Values;
12358 end loop;
12359 end Rewrite_Comparison;
12360
12361 ----------------------------
12362 -- Safe_In_Place_Array_Op --
12363 ----------------------------
12364
12365 function Safe_In_Place_Array_Op
12366 (Lhs : Node_Id;
12367 Op1 : Node_Id;
12368 Op2 : Node_Id) return Boolean
12369 is
12370 Target : Entity_Id;
12371
12372 function Is_Safe_Operand (Op : Node_Id) return Boolean;
12373 -- Operand is safe if it cannot overlap part of the target of the
12374 -- operation. If the operand and the target are identical, the operand
12375 -- is safe. The operand can be empty in the case of negation.
12376
12377 function Is_Unaliased (N : Node_Id) return Boolean;
12378 -- Check that N is a stand-alone entity
12379
12380 ------------------
12381 -- Is_Unaliased --
12382 ------------------
12383
12384 function Is_Unaliased (N : Node_Id) return Boolean is
12385 begin
12386 return
12387 Is_Entity_Name (N)
12388 and then No (Address_Clause (Entity (N)))
12389 and then No (Renamed_Object (Entity (N)));
12390 end Is_Unaliased;
12391
12392 ---------------------
12393 -- Is_Safe_Operand --
12394 ---------------------
12395
12396 function Is_Safe_Operand (Op : Node_Id) return Boolean is
12397 begin
12398 if No (Op) then
12399 return True;
12400
12401 elsif Is_Entity_Name (Op) then
12402 return Is_Unaliased (Op);
12403
12404 elsif Nkind_In (Op, N_Indexed_Component, N_Selected_Component) then
12405 return Is_Unaliased (Prefix (Op));
12406
12407 elsif Nkind (Op) = N_Slice then
12408 return
12409 Is_Unaliased (Prefix (Op))
12410 and then Entity (Prefix (Op)) /= Target;
12411
12412 elsif Nkind (Op) = N_Op_Not then
12413 return Is_Safe_Operand (Right_Opnd (Op));
12414
12415 else
12416 return False;
12417 end if;
12418 end Is_Safe_Operand;
12419
12420 -- Start of processing for Safe_In_Place_Array_Op
12421
12422 begin
12423 -- Skip this processing if the component size is different from system
12424 -- storage unit (since at least for NOT this would cause problems).
12425
12426 if Component_Size (Etype (Lhs)) /= System_Storage_Unit then
12427 return False;
12428
12429 -- Cannot do in place stuff on VM_Target since cannot pass addresses
12430
12431 elsif VM_Target /= No_VM then
12432 return False;
12433
12434 -- Cannot do in place stuff if non-standard Boolean representation
12435
12436 elsif Has_Non_Standard_Rep (Component_Type (Etype (Lhs))) then
12437 return False;
12438
12439 elsif not Is_Unaliased (Lhs) then
12440 return False;
12441
12442 else
12443 Target := Entity (Lhs);
12444 return Is_Safe_Operand (Op1) and then Is_Safe_Operand (Op2);
12445 end if;
12446 end Safe_In_Place_Array_Op;
12447
12448 -----------------------
12449 -- Tagged_Membership --
12450 -----------------------
12451
12452 -- There are two different cases to consider depending on whether the right
12453 -- operand is a class-wide type or not. If not we just compare the actual
12454 -- tag of the left expr to the target type tag:
12455 --
12456 -- Left_Expr.Tag = Right_Type'Tag;
12457 --
12458 -- If it is a class-wide type we use the RT function CW_Membership which is
12459 -- usually implemented by looking in the ancestor tables contained in the
12460 -- dispatch table pointed by Left_Expr.Tag for Typ'Tag
12461
12462 -- Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
12463 -- function IW_Membership which is usually implemented by looking in the
12464 -- table of abstract interface types plus the ancestor table contained in
12465 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
12466
12467 procedure Tagged_Membership
12468 (N : Node_Id;
12469 SCIL_Node : out Node_Id;
12470 Result : out Node_Id)
12471 is
12472 Left : constant Node_Id := Left_Opnd (N);
12473 Right : constant Node_Id := Right_Opnd (N);
12474 Loc : constant Source_Ptr := Sloc (N);
12475
12476 Full_R_Typ : Entity_Id;
12477 Left_Type : Entity_Id;
12478 New_Node : Node_Id;
12479 Right_Type : Entity_Id;
12480 Obj_Tag : Node_Id;
12481
12482 begin
12483 SCIL_Node := Empty;
12484
12485 -- Handle entities from the limited view
12486
12487 Left_Type := Available_View (Etype (Left));
12488 Right_Type := Available_View (Etype (Right));
12489
12490 -- In the case where the type is an access type, the test is applied
12491 -- using the designated types (needed in Ada 2012 for implicit anonymous
12492 -- access conversions, for AI05-0149).
12493
12494 if Is_Access_Type (Right_Type) then
12495 Left_Type := Designated_Type (Left_Type);
12496 Right_Type := Designated_Type (Right_Type);
12497 end if;
12498
12499 if Is_Class_Wide_Type (Left_Type) then
12500 Left_Type := Root_Type (Left_Type);
12501 end if;
12502
12503 if Is_Class_Wide_Type (Right_Type) then
12504 Full_R_Typ := Underlying_Type (Root_Type (Right_Type));
12505 else
12506 Full_R_Typ := Underlying_Type (Right_Type);
12507 end if;
12508
12509 Obj_Tag :=
12510 Make_Selected_Component (Loc,
12511 Prefix => Relocate_Node (Left),
12512 Selector_Name =>
12513 New_Reference_To (First_Tag_Component (Left_Type), Loc));
12514
12515 if Is_Class_Wide_Type (Right_Type) then
12516
12517 -- No need to issue a run-time check if we statically know that the
12518 -- result of this membership test is always true. For example,
12519 -- considering the following declarations:
12520
12521 -- type Iface is interface;
12522 -- type T is tagged null record;
12523 -- type DT is new T and Iface with null record;
12524
12525 -- Obj1 : T;
12526 -- Obj2 : DT;
12527
12528 -- These membership tests are always true:
12529
12530 -- Obj1 in T'Class
12531 -- Obj2 in T'Class;
12532 -- Obj2 in Iface'Class;
12533
12534 -- We do not need to handle cases where the membership is illegal.
12535 -- For example:
12536
12537 -- Obj1 in DT'Class; -- Compile time error
12538 -- Obj1 in Iface'Class; -- Compile time error
12539
12540 if not Is_Class_Wide_Type (Left_Type)
12541 and then (Is_Ancestor (Etype (Right_Type), Left_Type,
12542 Use_Full_View => True)
12543 or else (Is_Interface (Etype (Right_Type))
12544 and then Interface_Present_In_Ancestor
12545 (Typ => Left_Type,
12546 Iface => Etype (Right_Type))))
12547 then
12548 Result := New_Reference_To (Standard_True, Loc);
12549 return;
12550 end if;
12551
12552 -- Ada 2005 (AI-251): Class-wide applied to interfaces
12553
12554 if Is_Interface (Etype (Class_Wide_Type (Right_Type)))
12555
12556 -- Support to: "Iface_CW_Typ in Typ'Class"
12557
12558 or else Is_Interface (Left_Type)
12559 then
12560 -- Issue error if IW_Membership operation not available in a
12561 -- configurable run time setting.
12562
12563 if not RTE_Available (RE_IW_Membership) then
12564 Error_Msg_CRT
12565 ("dynamic membership test on interface types", N);
12566 Result := Empty;
12567 return;
12568 end if;
12569
12570 Result :=
12571 Make_Function_Call (Loc,
12572 Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
12573 Parameter_Associations => New_List (
12574 Make_Attribute_Reference (Loc,
12575 Prefix => Obj_Tag,
12576 Attribute_Name => Name_Address),
12577 New_Reference_To (
12578 Node (First_Elmt (Access_Disp_Table (Full_R_Typ))),
12579 Loc)));
12580
12581 -- Ada 95: Normal case
12582
12583 else
12584 Build_CW_Membership (Loc,
12585 Obj_Tag_Node => Obj_Tag,
12586 Typ_Tag_Node =>
12587 New_Reference_To (
12588 Node (First_Elmt (Access_Disp_Table (Full_R_Typ))), Loc),
12589 Related_Nod => N,
12590 New_Node => New_Node);
12591
12592 -- Generate the SCIL node for this class-wide membership test.
12593 -- Done here because the previous call to Build_CW_Membership
12594 -- relocates Obj_Tag.
12595
12596 if Generate_SCIL then
12597 SCIL_Node := Make_SCIL_Membership_Test (Sloc (N));
12598 Set_SCIL_Entity (SCIL_Node, Etype (Right_Type));
12599 Set_SCIL_Tag_Value (SCIL_Node, Obj_Tag);
12600 end if;
12601
12602 Result := New_Node;
12603 end if;
12604
12605 -- Right_Type is not a class-wide type
12606
12607 else
12608 -- No need to check the tag of the object if Right_Typ is abstract
12609
12610 if Is_Abstract_Type (Right_Type) then
12611 Result := New_Reference_To (Standard_False, Loc);
12612
12613 else
12614 Result :=
12615 Make_Op_Eq (Loc,
12616 Left_Opnd => Obj_Tag,
12617 Right_Opnd =>
12618 New_Reference_To
12619 (Node (First_Elmt (Access_Disp_Table (Full_R_Typ))), Loc));
12620 end if;
12621 end if;
12622 end Tagged_Membership;
12623
12624 ------------------------------
12625 -- Unary_Op_Validity_Checks --
12626 ------------------------------
12627
12628 procedure Unary_Op_Validity_Checks (N : Node_Id) is
12629 begin
12630 if Validity_Checks_On and Validity_Check_Operands then
12631 Ensure_Valid (Right_Opnd (N));
12632 end if;
12633 end Unary_Op_Validity_Checks;
12634
12635 end Exp_Ch4;