1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
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. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
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;
49 with Namet; use Namet;
50 with Nlists; use Nlists;
51 with Nmake; use Nmake;
53 with Par_SCO; use Par_SCO;
54 with Restrict; use Restrict;
55 with Rident; use Rident;
56 with Rtsfind; use Rtsfind;
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;
79 package body Exp_Ch4 is
81 -----------------------
82 -- Local Subprograms --
83 -----------------------
85 procedure Binary_Op_Validity_Checks (N : Node_Id);
86 pragma Inline (Binary_Op_Validity_Checks);
87 -- Performs validity checks for a binary operator
89 procedure Build_Boolean_Array_Proc_Call
93 -- If a boolean array assignment can be done in place, build call to
94 -- corresponding library procedure.
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.
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.
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.
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
119 function Expand_Array_Equality
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.
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.
140 procedure Expand_Short_Circuit_Operator (N : Node_Id);
141 -- Common expansion processing for short-circuit boolean operators
143 function Expand_Composite_Equality
148 Bodies : List_Id) return Node_Id;
149 -- Local recursive function used to expand equality for nested composite
150 -- types. Used by Expand_Record/Array_Equality, Bodies is a list on which
151 -- to attach bodies of local functions that are created in the process.
152 -- This is the responsibility of the caller to insert those bodies at the
153 -- right place. Nod provides the Sloc value for generated code. Lhs and Rhs
154 -- are the left and right sides for the comparison, and Typ is the type of
155 -- the arrays to compare.
157 procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id);
158 -- Routine to expand concatenation of a sequence of two or more operands
159 -- (in the list Operands) and replace node Cnode with the result of the
160 -- concatenation. The operands can be of any appropriate type, and can
161 -- include both arrays and singleton elements.
163 procedure Fixup_Universal_Fixed_Operation (N : Node_Id);
164 -- N is a N_Op_Divide or N_Op_Multiply node whose result is universal
165 -- fixed. We do not have such a type at runtime, so the purpose of this
166 -- routine is to find the real type by looking up the tree. We also
167 -- determine if the operation must be rounded.
169 function Has_Inferable_Discriminants (N : Node_Id) return Boolean;
170 -- Ada 2005 (AI-216): A view of an Unchecked_Union object has inferable
171 -- discriminants if it has a constrained nominal type, unless the object
172 -- is a component of an enclosing Unchecked_Union object that is subject
173 -- to a per-object constraint and the enclosing object lacks inferable
176 -- An expression of an Unchecked_Union type has inferable discriminants
177 -- if it is either a name of an object with inferable discriminants or a
178 -- qualified expression whose subtype mark denotes a constrained subtype.
180 procedure Insert_Dereference_Action (N : Node_Id);
181 -- N is an expression whose type is an access. When the type of the
182 -- associated storage pool is derived from Checked_Pool, generate a
183 -- call to the 'Dereference' primitive operation.
185 function Make_Array_Comparison_Op
187 Nod : Node_Id) return Node_Id;
188 -- Comparisons between arrays are expanded in line. This function produces
189 -- the body of the implementation of (a > b), where a and b are one-
190 -- dimensional arrays of some discrete type. The original node is then
191 -- expanded into the appropriate call to this function. Nod provides the
192 -- Sloc value for the generated code.
194 function Make_Boolean_Array_Op
196 N : Node_Id) return Node_Id;
197 -- Boolean operations on boolean arrays are expanded in line. This function
198 -- produce the body for the node N, which is (a and b), (a or b), or (a xor
199 -- b). It is used only the normal case and not the packed case. The type
200 -- involved, Typ, is the Boolean array type, and the logical operations in
201 -- the body are simple boolean operations. Note that Typ is always a
202 -- constrained type (the caller has ensured this by using
203 -- Convert_To_Actual_Subtype if necessary).
205 procedure Optimize_Length_Comparison (N : Node_Id);
206 -- Given an expression, if it is of the form X'Length op N (or the other
207 -- way round), where N is known at compile time to be 0 or 1, and X is a
208 -- simple entity, and op is a comparison operator, optimizes it into a
209 -- comparison of First and Last.
211 procedure Rewrite_Comparison (N : Node_Id);
212 -- If N is the node for a comparison whose outcome can be determined at
213 -- compile time, then the node N can be rewritten with True or False. If
214 -- the outcome cannot be determined at compile time, the call has no
215 -- effect. If N is a type conversion, then this processing is applied to
216 -- its expression. If N is neither comparison nor a type conversion, the
217 -- call has no effect.
219 procedure Tagged_Membership
221 SCIL_Node : out Node_Id;
222 Result : out Node_Id);
223 -- Construct the expression corresponding to the tagged membership test.
224 -- Deals with a second operand being (or not) a class-wide type.
226 function Safe_In_Place_Array_Op
229 Op2 : Node_Id) return Boolean;
230 -- In the context of an assignment, where the right-hand side is a boolean
231 -- operation on arrays, check whether operation can be performed in place.
233 procedure Unary_Op_Validity_Checks (N : Node_Id);
234 pragma Inline (Unary_Op_Validity_Checks);
235 -- Performs validity checks for a unary operator
237 -------------------------------
238 -- Binary_Op_Validity_Checks --
239 -------------------------------
241 procedure Binary_Op_Validity_Checks (N : Node_Id) is
243 if Validity_Checks_On and Validity_Check_Operands then
244 Ensure_Valid (Left_Opnd (N));
245 Ensure_Valid (Right_Opnd (N));
247 end Binary_Op_Validity_Checks;
249 ------------------------------------
250 -- Build_Boolean_Array_Proc_Call --
251 ------------------------------------
253 procedure Build_Boolean_Array_Proc_Call
258 Loc : constant Source_Ptr := Sloc (N);
259 Kind : constant Node_Kind := Nkind (Expression (N));
260 Target : constant Node_Id :=
261 Make_Attribute_Reference (Loc,
263 Attribute_Name => Name_Address);
265 Arg1 : Node_Id := Op1;
266 Arg2 : Node_Id := Op2;
268 Proc_Name : Entity_Id;
271 if Kind = N_Op_Not then
272 if Nkind (Op1) in N_Binary_Op then
274 -- Use negated version of the binary operators
276 if Nkind (Op1) = N_Op_And then
277 Proc_Name := RTE (RE_Vector_Nand);
279 elsif Nkind (Op1) = N_Op_Or then
280 Proc_Name := RTE (RE_Vector_Nor);
282 else pragma Assert (Nkind (Op1) = N_Op_Xor);
283 Proc_Name := RTE (RE_Vector_Xor);
287 Make_Procedure_Call_Statement (Loc,
288 Name => New_Occurrence_Of (Proc_Name, Loc),
290 Parameter_Associations => New_List (
292 Make_Attribute_Reference (Loc,
293 Prefix => Left_Opnd (Op1),
294 Attribute_Name => Name_Address),
296 Make_Attribute_Reference (Loc,
297 Prefix => Right_Opnd (Op1),
298 Attribute_Name => Name_Address),
300 Make_Attribute_Reference (Loc,
301 Prefix => Left_Opnd (Op1),
302 Attribute_Name => Name_Length)));
305 Proc_Name := RTE (RE_Vector_Not);
308 Make_Procedure_Call_Statement (Loc,
309 Name => New_Occurrence_Of (Proc_Name, Loc),
310 Parameter_Associations => New_List (
313 Make_Attribute_Reference (Loc,
315 Attribute_Name => Name_Address),
317 Make_Attribute_Reference (Loc,
319 Attribute_Name => Name_Length)));
323 -- We use the following equivalences:
325 -- (not X) or (not Y) = not (X and Y) = Nand (X, Y)
326 -- (not X) and (not Y) = not (X or Y) = Nor (X, Y)
327 -- (not X) xor (not Y) = X xor Y
328 -- X xor (not Y) = not (X xor Y) = Nxor (X, Y)
330 if Nkind (Op1) = N_Op_Not then
331 Arg1 := Right_Opnd (Op1);
332 Arg2 := Right_Opnd (Op2);
333 if Kind = N_Op_And then
334 Proc_Name := RTE (RE_Vector_Nor);
335 elsif Kind = N_Op_Or then
336 Proc_Name := RTE (RE_Vector_Nand);
338 Proc_Name := RTE (RE_Vector_Xor);
342 if Kind = N_Op_And then
343 Proc_Name := RTE (RE_Vector_And);
344 elsif Kind = N_Op_Or then
345 Proc_Name := RTE (RE_Vector_Or);
346 elsif Nkind (Op2) = N_Op_Not then
347 Proc_Name := RTE (RE_Vector_Nxor);
348 Arg2 := Right_Opnd (Op2);
350 Proc_Name := RTE (RE_Vector_Xor);
355 Make_Procedure_Call_Statement (Loc,
356 Name => New_Occurrence_Of (Proc_Name, Loc),
357 Parameter_Associations => New_List (
359 Make_Attribute_Reference (Loc,
361 Attribute_Name => Name_Address),
362 Make_Attribute_Reference (Loc,
364 Attribute_Name => Name_Address),
365 Make_Attribute_Reference (Loc,
367 Attribute_Name => Name_Length)));
370 Rewrite (N, Call_Node);
374 when RE_Not_Available =>
376 end Build_Boolean_Array_Proc_Call;
378 ------------------------------
379 -- Current_Anonymous_Master --
380 ------------------------------
382 function Current_Anonymous_Master return Entity_Id is
384 Fin_Mas_Id : Entity_Id;
391 Unit_Id := Cunit_Entity (Current_Sem_Unit);
393 -- Find the entity of the current unit
395 if Ekind (Unit_Id) = E_Subprogram_Body then
397 -- When processing subprogram bodies, the proper scope is always that
400 Subp_Body := Unit_Id;
401 while Present (Subp_Body)
402 and then Nkind (Subp_Body) /= N_Subprogram_Body
404 Subp_Body := Parent (Subp_Body);
407 Unit_Id := Corresponding_Spec (Subp_Body);
410 Loc := Sloc (Unit_Id);
411 Unit_Decl := Unit (Cunit (Current_Sem_Unit));
413 -- Find the declarations list of the current unit
415 if Nkind (Unit_Decl) = N_Package_Declaration then
416 Unit_Decl := Specification (Unit_Decl);
417 Decls := Visible_Declarations (Unit_Decl);
420 Decls := New_List (Make_Null_Statement (Loc));
421 Set_Visible_Declarations (Unit_Decl, Decls);
423 elsif Is_Empty_List (Decls) then
424 Append_To (Decls, Make_Null_Statement (Loc));
428 Decls := Declarations (Unit_Decl);
431 Decls := New_List (Make_Null_Statement (Loc));
432 Set_Declarations (Unit_Decl, Decls);
434 elsif Is_Empty_List (Decls) then
435 Append_To (Decls, Make_Null_Statement (Loc));
439 -- The current unit has an existing anonymous master, traverse its
440 -- declarations and locate the entity.
442 if Has_Anonymous_Master (Unit_Id) then
443 Fin_Mas_Id := First_Entity (Unit_Id);
444 while Present (Fin_Mas_Id) loop
446 -- Look for the first variable whose type is Finalization_Master
448 if Ekind (Fin_Mas_Id) = E_Variable
449 and then Etype (Fin_Mas_Id) = RTE (RE_Finalization_Master)
454 Next_Entity (Fin_Mas_Id);
459 -- Create a new anonymous master
463 First_Decl : constant Node_Id := First (Decls);
467 -- Since the master and its associated initialization is inserted
468 -- at top level, use the scope of the unit when analyzing.
470 Push_Scope (Unit_Id);
472 -- Create the finalization master
475 Make_Defining_Identifier (Loc,
476 Chars => New_External_Name (Chars (Unit_Id), "AM"));
479 -- <Fin_Mas_Id> : Finalization_Master;
482 Make_Object_Declaration (Loc,
483 Defining_Identifier => Fin_Mas_Id,
485 New_Reference_To (RTE (RE_Finalization_Master), Loc));
487 Insert_Before_And_Analyze (First_Decl, Action);
489 -- Mark the unit to prevent the generation of multiple masters
491 Set_Has_Anonymous_Master (Unit_Id);
493 -- Do not set the base pool and mode of operation on .NET/JVM
494 -- since those targets do not support pools and all VM masters
495 -- are heterogeneous by default.
497 if VM_Target = No_VM then
501 -- (<Fin_Mas_Id>, Global_Pool_Object'Unrestricted_Access);
504 Make_Procedure_Call_Statement (Loc,
506 New_Reference_To (RTE (RE_Set_Base_Pool), Loc),
508 Parameter_Associations => New_List (
509 New_Reference_To (Fin_Mas_Id, Loc),
510 Make_Attribute_Reference (Loc,
512 New_Reference_To (RTE (RE_Global_Pool_Object), Loc),
513 Attribute_Name => Name_Unrestricted_Access)));
515 Insert_Before_And_Analyze (First_Decl, Action);
518 -- Set_Is_Heterogeneous (<Fin_Mas_Id>);
521 Make_Procedure_Call_Statement (Loc,
523 New_Reference_To (RTE (RE_Set_Is_Heterogeneous), Loc),
524 Parameter_Associations => New_List (
525 New_Reference_To (Fin_Mas_Id, Loc)));
527 Insert_Before_And_Analyze (First_Decl, Action);
530 -- Restore the original state of the scope stack
537 end Current_Anonymous_Master;
539 --------------------------------
540 -- Displace_Allocator_Pointer --
541 --------------------------------
543 procedure Displace_Allocator_Pointer (N : Node_Id) is
544 Loc : constant Source_Ptr := Sloc (N);
545 Orig_Node : constant Node_Id := Original_Node (N);
551 -- Do nothing in case of VM targets: the virtual machine will handle
552 -- interfaces directly.
554 if not Tagged_Type_Expansion then
558 pragma Assert (Nkind (N) = N_Identifier
559 and then Nkind (Orig_Node) = N_Allocator);
561 PtrT := Etype (Orig_Node);
562 Dtyp := Available_View (Designated_Type (PtrT));
563 Etyp := Etype (Expression (Orig_Node));
565 if Is_Class_Wide_Type (Dtyp)
566 and then Is_Interface (Dtyp)
568 -- If the type of the allocator expression is not an interface type
569 -- we can generate code to reference the record component containing
570 -- the pointer to the secondary dispatch table.
572 if not Is_Interface (Etyp) then
574 Saved_Typ : constant Entity_Id := Etype (Orig_Node);
577 -- 1) Get access to the allocated object
580 Make_Explicit_Dereference (Loc,
585 -- 2) Add the conversion to displace the pointer to reference
586 -- the secondary dispatch table.
588 Rewrite (N, Convert_To (Dtyp, Relocate_Node (N)));
589 Analyze_And_Resolve (N, Dtyp);
591 -- 3) The 'access to the secondary dispatch table will be used
592 -- as the value returned by the allocator.
595 Make_Attribute_Reference (Loc,
596 Prefix => Relocate_Node (N),
597 Attribute_Name => Name_Access));
598 Set_Etype (N, Saved_Typ);
602 -- If the type of the allocator expression is an interface type we
603 -- generate a run-time call to displace "this" to reference the
604 -- component containing the pointer to the secondary dispatch table
605 -- or else raise Constraint_Error if the actual object does not
606 -- implement the target interface. This case corresponds with the
607 -- following example:
609 -- function Op (Obj : Iface_1'Class) return access Iface_2'Class is
611 -- return new Iface_2'Class'(Obj);
616 Unchecked_Convert_To (PtrT,
617 Make_Function_Call (Loc,
618 Name => New_Reference_To (RTE (RE_Displace), Loc),
619 Parameter_Associations => New_List (
620 Unchecked_Convert_To (RTE (RE_Address),
626 (Access_Disp_Table (Etype (Base_Type (Dtyp))))),
628 Analyze_And_Resolve (N, PtrT);
631 end Displace_Allocator_Pointer;
633 ---------------------------------
634 -- Expand_Allocator_Expression --
635 ---------------------------------
637 procedure Expand_Allocator_Expression (N : Node_Id) is
638 Loc : constant Source_Ptr := Sloc (N);
639 Exp : constant Node_Id := Expression (Expression (N));
640 PtrT : constant Entity_Id := Etype (N);
641 DesigT : constant Entity_Id := Designated_Type (PtrT);
643 procedure Apply_Accessibility_Check
645 Built_In_Place : Boolean := False);
646 -- Ada 2005 (AI-344): For an allocator with a class-wide designated
647 -- type, generate an accessibility check to verify that the level of the
648 -- type of the created object is not deeper than the level of the access
649 -- type. If the type of the qualified expression is class- wide, then
650 -- always generate the check (except in the case where it is known to be
651 -- unnecessary, see comment below). Otherwise, only generate the check
652 -- if the level of the qualified expression type is statically deeper
653 -- than the access type.
655 -- Although the static accessibility will generally have been performed
656 -- as a legality check, it won't have been done in cases where the
657 -- allocator appears in generic body, so a run-time check is needed in
658 -- general. One special case is when the access type is declared in the
659 -- same scope as the class-wide allocator, in which case the check can
660 -- never fail, so it need not be generated.
662 -- As an open issue, there seem to be cases where the static level
663 -- associated with the class-wide object's underlying type is not
664 -- sufficient to perform the proper accessibility check, such as for
665 -- allocators in nested subprograms or accept statements initialized by
666 -- class-wide formals when the actual originates outside at a deeper
667 -- static level. The nested subprogram case might require passing
668 -- accessibility levels along with class-wide parameters, and the task
669 -- case seems to be an actual gap in the language rules that needs to
670 -- be fixed by the ARG. ???
672 -------------------------------
673 -- Apply_Accessibility_Check --
674 -------------------------------
676 procedure Apply_Accessibility_Check
678 Built_In_Place : Boolean := False)
683 if Ada_Version >= Ada_2005
684 and then Is_Class_Wide_Type (DesigT)
685 and then not Scope_Suppress (Accessibility_Check)
687 (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
689 (Is_Class_Wide_Type (Etype (Exp))
690 and then Scope (PtrT) /= Current_Scope))
692 -- If the allocator was built in place Ref is already a reference
693 -- to the access object initialized to the result of the allocator
694 -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). Otherwise
695 -- it is the entity associated with the object containing the
696 -- address of the allocated object.
698 if Built_In_Place then
699 New_Node := New_Copy (Ref);
701 New_Node := New_Reference_To (Ref, Loc);
705 Make_Attribute_Reference (Loc,
707 Attribute_Name => Name_Tag);
709 if Tagged_Type_Expansion then
710 New_Node := Build_Get_Access_Level (Loc, New_Node);
712 elsif VM_Target /= No_VM then
714 Make_Function_Call (Loc,
715 Name => New_Reference_To (RTE (RE_Get_Access_Level), Loc),
716 Parameter_Associations => New_List (New_Node));
718 -- Cannot generate the runtime check
725 Make_Raise_Program_Error (Loc,
728 Left_Opnd => New_Node,
730 Make_Integer_Literal (Loc, Type_Access_Level (PtrT))),
731 Reason => PE_Accessibility_Check_Failed));
733 end Apply_Accessibility_Check;
737 Aggr_In_Place : constant Boolean := Is_Delayed_Aggregate (Exp);
738 Indic : constant Node_Id := Subtype_Mark (Expression (N));
739 T : constant Entity_Id := Entity (Indic);
741 Tag_Assign : Node_Id;
745 TagT : Entity_Id := Empty;
746 -- Type used as source for tag assignment
748 TagR : Node_Id := Empty;
749 -- Target reference for tag assignment
751 -- Start of processing for Expand_Allocator_Expression
754 -- WOuld be nice to comment the branches of this very long if ???
756 if Is_Tagged_Type (T)
757 or else Needs_Finalization (T)
759 if Is_CPP_Constructor_Call (Exp) then
762 -- Pnnn : constant ptr_T := new (T);
763 -- Init (Pnnn.all,...);
765 -- Allocate the object without an expression
767 Node := Relocate_Node (N);
768 Set_Expression (Node, New_Reference_To (Etype (Exp), Loc));
770 -- Avoid its expansion to avoid generating a call to the default
775 Temp := Make_Temporary (Loc, 'P', N);
778 Make_Object_Declaration (Loc,
779 Defining_Identifier => Temp,
780 Constant_Present => True,
781 Object_Definition => New_Reference_To (PtrT, Loc),
783 Insert_Action (N, Temp_Decl);
785 Apply_Accessibility_Check (Temp);
787 -- Locate the enclosing list and insert the C++ constructor call
794 while not Is_List_Member (P) loop
798 Insert_List_After_And_Analyze (P,
799 Build_Initialization_Call (Loc,
801 Make_Explicit_Dereference (Loc,
802 Prefix => New_Reference_To (Temp, Loc)),
804 Constructor_Ref => Exp));
807 Rewrite (N, New_Reference_To (Temp, Loc));
808 Analyze_And_Resolve (N, PtrT);
812 -- Ada 2005 (AI-318-02): If the initialization expression is a call
813 -- to a build-in-place function, then access to the allocated object
814 -- must be passed to the function. Currently we limit such functions
815 -- to those with constrained limited result subtypes, but eventually
816 -- we plan to expand the allowed forms of functions that are treated
817 -- as build-in-place.
819 if Ada_Version >= Ada_2005
820 and then Is_Build_In_Place_Function_Call (Exp)
822 Make_Build_In_Place_Call_In_Allocator (N, Exp);
823 Apply_Accessibility_Check (N, Built_In_Place => True);
827 -- Actions inserted before:
828 -- Temp : constant ptr_T := new T'(Expression);
829 -- Temp._tag = T'tag; -- when not class-wide
830 -- [Deep_]Adjust (Temp.all);
832 -- We analyze by hand the new internal allocator to avoid any
833 -- recursion and inappropriate call to Initialize
835 -- We don't want to remove side effects when the expression must be
836 -- built in place. In the case of a build-in-place function call,
837 -- that could lead to a duplication of the call, which was already
838 -- substituted for the allocator.
840 if not Aggr_In_Place then
841 Remove_Side_Effects (Exp);
844 Temp := Make_Temporary (Loc, 'P', N);
846 -- For a class wide allocation generate the following code:
848 -- type Equiv_Record is record ... end record;
849 -- implicit subtype CW is <Class_Wide_Subytpe>;
850 -- temp : PtrT := new CW'(CW!(expr));
852 if Is_Class_Wide_Type (T) then
853 Expand_Subtype_From_Expr (Empty, T, Indic, Exp);
855 -- Ada 2005 (AI-251): If the expression is a class-wide interface
856 -- object we generate code to move up "this" to reference the
857 -- base of the object before allocating the new object.
859 -- Note that Exp'Address is recursively expanded into a call
860 -- to Base_Address (Exp.Tag)
862 if Is_Class_Wide_Type (Etype (Exp))
863 and then Is_Interface (Etype (Exp))
864 and then Tagged_Type_Expansion
868 Unchecked_Convert_To (Entity (Indic),
869 Make_Explicit_Dereference (Loc,
870 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
871 Make_Attribute_Reference (Loc,
873 Attribute_Name => Name_Address)))));
877 Unchecked_Convert_To (Entity (Indic), Exp));
880 Analyze_And_Resolve (Expression (N), Entity (Indic));
883 -- Processing for allocators returning non-interface types
885 if not Is_Interface (Directly_Designated_Type (PtrT)) then
886 if Aggr_In_Place then
888 Make_Object_Declaration (Loc,
889 Defining_Identifier => Temp,
890 Object_Definition => New_Reference_To (PtrT, Loc),
894 New_Reference_To (Etype (Exp), Loc)));
896 -- Copy the Comes_From_Source flag for the allocator we just
897 -- built, since logically this allocator is a replacement of
898 -- the original allocator node. This is for proper handling of
899 -- restriction No_Implicit_Heap_Allocations.
901 Set_Comes_From_Source
902 (Expression (Temp_Decl), Comes_From_Source (N));
904 Set_No_Initialization (Expression (Temp_Decl));
905 Insert_Action (N, Temp_Decl);
907 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
908 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
910 -- Attach the object to the associated finalization master.
911 -- This is done manually on .NET/JVM since those compilers do
912 -- no support pools and can't benefit from internally generated
913 -- Allocate / Deallocate procedures.
915 if VM_Target /= No_VM
916 and then Is_Controlled (DesigT)
917 and then Present (Finalization_Master (PtrT))
922 New_Reference_To (Temp, Loc),
927 Node := Relocate_Node (N);
931 Make_Object_Declaration (Loc,
932 Defining_Identifier => Temp,
933 Constant_Present => True,
934 Object_Definition => New_Reference_To (PtrT, Loc),
937 Insert_Action (N, Temp_Decl);
938 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
940 -- Attach the object to the associated finalization master.
941 -- This is done manually on .NET/JVM since those compilers do
942 -- no support pools and can't benefit from internally generated
943 -- Allocate / Deallocate procedures.
945 if VM_Target /= No_VM
946 and then Is_Controlled (DesigT)
947 and then Present (Finalization_Master (PtrT))
952 New_Reference_To (Temp, Loc),
957 -- Ada 2005 (AI-251): Handle allocators whose designated type is an
958 -- interface type. In this case we use the type of the qualified
959 -- expression to allocate the object.
963 Def_Id : constant Entity_Id := Make_Temporary (Loc, 'T');
968 Make_Full_Type_Declaration (Loc,
969 Defining_Identifier => Def_Id,
971 Make_Access_To_Object_Definition (Loc,
973 Null_Exclusion_Present => False,
974 Constant_Present => False,
975 Subtype_Indication =>
976 New_Reference_To (Etype (Exp), Loc)));
978 Insert_Action (N, New_Decl);
980 -- Inherit the allocation-related attributes from the original
983 Set_Finalization_Master (Def_Id, Finalization_Master (PtrT));
985 Set_Associated_Storage_Pool (Def_Id,
986 Associated_Storage_Pool (PtrT));
988 -- Declare the object using the previous type declaration
990 if Aggr_In_Place then
992 Make_Object_Declaration (Loc,
993 Defining_Identifier => Temp,
994 Object_Definition => New_Reference_To (Def_Id, Loc),
997 New_Reference_To (Etype (Exp), Loc)));
999 -- Copy the Comes_From_Source flag for the allocator we just
1000 -- built, since logically this allocator is a replacement of
1001 -- the original allocator node. This is for proper handling
1002 -- of restriction No_Implicit_Heap_Allocations.
1004 Set_Comes_From_Source
1005 (Expression (Temp_Decl), Comes_From_Source (N));
1007 Set_No_Initialization (Expression (Temp_Decl));
1008 Insert_Action (N, Temp_Decl);
1010 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
1011 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
1014 Node := Relocate_Node (N);
1015 Set_Analyzed (Node);
1018 Make_Object_Declaration (Loc,
1019 Defining_Identifier => Temp,
1020 Constant_Present => True,
1021 Object_Definition => New_Reference_To (Def_Id, Loc),
1022 Expression => Node);
1024 Insert_Action (N, Temp_Decl);
1025 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
1028 -- Generate an additional object containing the address of the
1029 -- returned object. The type of this second object declaration
1030 -- is the correct type required for the common processing that
1031 -- is still performed by this subprogram. The displacement of
1032 -- this pointer to reference the component associated with the
1033 -- interface type will be done at the end of common processing.
1036 Make_Object_Declaration (Loc,
1037 Defining_Identifier => Make_Temporary (Loc, 'P'),
1038 Object_Definition => New_Reference_To (PtrT, Loc),
1040 Unchecked_Convert_To (PtrT,
1041 New_Reference_To (Temp, Loc)));
1043 Insert_Action (N, New_Decl);
1045 Temp_Decl := New_Decl;
1046 Temp := Defining_Identifier (New_Decl);
1050 Apply_Accessibility_Check (Temp);
1052 -- Generate the tag assignment
1054 -- Suppress the tag assignment when VM_Target because VM tags are
1055 -- represented implicitly in objects.
1057 if not Tagged_Type_Expansion then
1060 -- Ada 2005 (AI-251): Suppress the tag assignment with class-wide
1061 -- interface objects because in this case the tag does not change.
1063 elsif Is_Interface (Directly_Designated_Type (Etype (N))) then
1064 pragma Assert (Is_Class_Wide_Type
1065 (Directly_Designated_Type (Etype (N))));
1068 elsif Is_Tagged_Type (T) and then not Is_Class_Wide_Type (T) then
1070 TagR := New_Reference_To (Temp, Loc);
1072 elsif Is_Private_Type (T)
1073 and then Is_Tagged_Type (Underlying_Type (T))
1075 TagT := Underlying_Type (T);
1077 Unchecked_Convert_To (Underlying_Type (T),
1078 Make_Explicit_Dereference (Loc,
1079 Prefix => New_Reference_To (Temp, Loc)));
1082 if Present (TagT) then
1084 Full_T : constant Entity_Id := Underlying_Type (TagT);
1087 Make_Assignment_Statement (Loc,
1089 Make_Selected_Component (Loc,
1092 New_Reference_To (First_Tag_Component (Full_T), Loc)),
1094 Unchecked_Convert_To (RTE (RE_Tag),
1097 (First_Elmt (Access_Disp_Table (Full_T))), Loc)));
1100 -- The previous assignment has to be done in any case
1102 Set_Assignment_OK (Name (Tag_Assign));
1103 Insert_Action (N, Tag_Assign);
1106 if Needs_Finalization (DesigT)
1107 and then Needs_Finalization (T)
1109 -- Generate an Adjust call if the object will be moved. In Ada
1110 -- 2005, the object may be inherently limited, in which case
1111 -- there is no Adjust procedure, and the object is built in
1112 -- place. In Ada 95, the object can be limited but not
1113 -- inherently limited if this allocator came from a return
1114 -- statement (we're allocating the result on the secondary
1115 -- stack). In that case, the object will be moved, so we _do_
1118 if not Aggr_In_Place
1119 and then not Is_Immutably_Limited_Type (T)
1125 -- An unchecked conversion is needed in the classwide
1126 -- case because the designated type can be an ancestor
1127 -- of the subtype mark of the allocator.
1129 Unchecked_Convert_To (T,
1130 Make_Explicit_Dereference (Loc,
1131 Prefix => New_Reference_To (Temp, Loc))),
1136 -- Set_Finalize_Address (<PtrT>FM, <T>FD'Unrestricted_Access);
1138 -- Since .NET/JVM compilers do not support address arithmetic,
1139 -- this call is skipped. The same is done for CodePeer because
1140 -- primitive Finalize_Address is never generated.
1142 if VM_Target = No_VM
1143 and then not CodePeer_Mode
1144 and then Present (Finalization_Master (PtrT))
1147 Make_Set_Finalize_Address_Call
1154 Rewrite (N, New_Reference_To (Temp, Loc));
1155 Analyze_And_Resolve (N, PtrT);
1157 -- Ada 2005 (AI-251): Displace the pointer to reference the record
1158 -- component containing the secondary dispatch table of the interface
1161 if Is_Interface (Directly_Designated_Type (PtrT)) then
1162 Displace_Allocator_Pointer (N);
1165 elsif Aggr_In_Place then
1166 Temp := Make_Temporary (Loc, 'P', N);
1168 Make_Object_Declaration (Loc,
1169 Defining_Identifier => Temp,
1170 Object_Definition => New_Reference_To (PtrT, Loc),
1172 Make_Allocator (Loc,
1173 Expression => New_Reference_To (Etype (Exp), Loc)));
1175 -- Copy the Comes_From_Source flag for the allocator we just built,
1176 -- since logically this allocator is a replacement of the original
1177 -- allocator node. This is for proper handling of restriction
1178 -- No_Implicit_Heap_Allocations.
1180 Set_Comes_From_Source
1181 (Expression (Temp_Decl), Comes_From_Source (N));
1183 Set_No_Initialization (Expression (Temp_Decl));
1184 Insert_Action (N, Temp_Decl);
1186 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
1187 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
1189 -- Attach the object to the associated finalization master. Thisis
1190 -- done manually on .NET/JVM since those compilers do no support
1191 -- pools and cannot benefit from internally generated Allocate and
1192 -- Deallocate procedures.
1194 if VM_Target /= No_VM
1195 and then Is_Controlled (DesigT)
1196 and then Present (Finalization_Master (PtrT))
1200 (Obj_Ref => New_Reference_To (Temp, Loc),
1204 Rewrite (N, New_Reference_To (Temp, Loc));
1205 Analyze_And_Resolve (N, PtrT);
1207 elsif Is_Access_Type (T)
1208 and then Can_Never_Be_Null (T)
1210 Install_Null_Excluding_Check (Exp);
1212 elsif Is_Access_Type (DesigT)
1213 and then Nkind (Exp) = N_Allocator
1214 and then Nkind (Expression (Exp)) /= N_Qualified_Expression
1216 -- Apply constraint to designated subtype indication
1218 Apply_Constraint_Check (Expression (Exp),
1219 Designated_Type (DesigT),
1220 No_Sliding => True);
1222 if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then
1224 -- Propagate constraint_error to enclosing allocator
1226 Rewrite (Exp, New_Copy (Expression (Exp)));
1230 Build_Allocate_Deallocate_Proc (N, True);
1233 -- type A is access T1;
1234 -- X : A := new T2'(...);
1235 -- T1 and T2 can be different subtypes, and we might need to check
1236 -- both constraints. First check against the type of the qualified
1239 Apply_Constraint_Check (Exp, T, No_Sliding => True);
1241 if Do_Range_Check (Exp) then
1242 Set_Do_Range_Check (Exp, False);
1243 Generate_Range_Check (Exp, DesigT, CE_Range_Check_Failed);
1246 -- A check is also needed in cases where the designated subtype is
1247 -- constrained and differs from the subtype given in the qualified
1248 -- expression. Note that the check on the qualified expression does
1249 -- not allow sliding, but this check does (a relaxation from Ada 83).
1251 if Is_Constrained (DesigT)
1252 and then not Subtypes_Statically_Match (T, DesigT)
1254 Apply_Constraint_Check
1255 (Exp, DesigT, No_Sliding => False);
1257 if Do_Range_Check (Exp) then
1258 Set_Do_Range_Check (Exp, False);
1259 Generate_Range_Check (Exp, DesigT, CE_Range_Check_Failed);
1263 -- For an access to unconstrained packed array, GIGI needs to see an
1264 -- expression with a constrained subtype in order to compute the
1265 -- proper size for the allocator.
1267 if Is_Array_Type (T)
1268 and then not Is_Constrained (T)
1269 and then Is_Packed (T)
1272 ConstrT : constant Entity_Id := Make_Temporary (Loc, 'A');
1273 Internal_Exp : constant Node_Id := Relocate_Node (Exp);
1276 Make_Subtype_Declaration (Loc,
1277 Defining_Identifier => ConstrT,
1278 Subtype_Indication =>
1279 Make_Subtype_From_Expr (Internal_Exp, T)));
1280 Freeze_Itype (ConstrT, Exp);
1281 Rewrite (Exp, OK_Convert_To (ConstrT, Internal_Exp));
1285 -- Ada 2005 (AI-318-02): If the initialization expression is a call
1286 -- to a build-in-place function, then access to the allocated object
1287 -- must be passed to the function. Currently we limit such functions
1288 -- to those with constrained limited result subtypes, but eventually
1289 -- we plan to expand the allowed forms of functions that are treated
1290 -- as build-in-place.
1292 if Ada_Version >= Ada_2005
1293 and then Is_Build_In_Place_Function_Call (Exp)
1295 Make_Build_In_Place_Call_In_Allocator (N, Exp);
1300 when RE_Not_Available =>
1302 end Expand_Allocator_Expression;
1304 -----------------------------
1305 -- Expand_Array_Comparison --
1306 -----------------------------
1308 -- Expansion is only required in the case of array types. For the unpacked
1309 -- case, an appropriate runtime routine is called. For packed cases, and
1310 -- also in some other cases where a runtime routine cannot be called, the
1311 -- form of the expansion is:
1313 -- [body for greater_nn; boolean_expression]
1315 -- The body is built by Make_Array_Comparison_Op, and the form of the
1316 -- Boolean expression depends on the operator involved.
1318 procedure Expand_Array_Comparison (N : Node_Id) is
1319 Loc : constant Source_Ptr := Sloc (N);
1320 Op1 : Node_Id := Left_Opnd (N);
1321 Op2 : Node_Id := Right_Opnd (N);
1322 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
1323 Ctyp : constant Entity_Id := Component_Type (Typ1);
1326 Func_Body : Node_Id;
1327 Func_Name : Entity_Id;
1331 Byte_Addressable : constant Boolean := System_Storage_Unit = Byte'Size;
1332 -- True for byte addressable target
1334 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean;
1335 -- Returns True if the length of the given operand is known to be less
1336 -- than 4. Returns False if this length is known to be four or greater
1337 -- or is not known at compile time.
1339 ------------------------
1340 -- Length_Less_Than_4 --
1341 ------------------------
1343 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean is
1344 Otyp : constant Entity_Id := Etype (Opnd);
1347 if Ekind (Otyp) = E_String_Literal_Subtype then
1348 return String_Literal_Length (Otyp) < 4;
1352 Ityp : constant Entity_Id := Etype (First_Index (Otyp));
1353 Lo : constant Node_Id := Type_Low_Bound (Ityp);
1354 Hi : constant Node_Id := Type_High_Bound (Ityp);
1359 if Compile_Time_Known_Value (Lo) then
1360 Lov := Expr_Value (Lo);
1365 if Compile_Time_Known_Value (Hi) then
1366 Hiv := Expr_Value (Hi);
1371 return Hiv < Lov + 3;
1374 end Length_Less_Than_4;
1376 -- Start of processing for Expand_Array_Comparison
1379 -- Deal first with unpacked case, where we can call a runtime routine
1380 -- except that we avoid this for targets for which are not addressable
1381 -- by bytes, and for the JVM/CIL, since they do not support direct
1382 -- addressing of array components.
1384 if not Is_Bit_Packed_Array (Typ1)
1385 and then Byte_Addressable
1386 and then VM_Target = No_VM
1388 -- The call we generate is:
1390 -- Compare_Array_xn[_Unaligned]
1391 -- (left'address, right'address, left'length, right'length) <op> 0
1393 -- x = U for unsigned, S for signed
1394 -- n = 8,16,32,64 for component size
1395 -- Add _Unaligned if length < 4 and component size is 8.
1396 -- <op> is the standard comparison operator
1398 if Component_Size (Typ1) = 8 then
1399 if Length_Less_Than_4 (Op1)
1401 Length_Less_Than_4 (Op2)
1403 if Is_Unsigned_Type (Ctyp) then
1404 Comp := RE_Compare_Array_U8_Unaligned;
1406 Comp := RE_Compare_Array_S8_Unaligned;
1410 if Is_Unsigned_Type (Ctyp) then
1411 Comp := RE_Compare_Array_U8;
1413 Comp := RE_Compare_Array_S8;
1417 elsif Component_Size (Typ1) = 16 then
1418 if Is_Unsigned_Type (Ctyp) then
1419 Comp := RE_Compare_Array_U16;
1421 Comp := RE_Compare_Array_S16;
1424 elsif Component_Size (Typ1) = 32 then
1425 if Is_Unsigned_Type (Ctyp) then
1426 Comp := RE_Compare_Array_U32;
1428 Comp := RE_Compare_Array_S32;
1431 else pragma Assert (Component_Size (Typ1) = 64);
1432 if Is_Unsigned_Type (Ctyp) then
1433 Comp := RE_Compare_Array_U64;
1435 Comp := RE_Compare_Array_S64;
1439 Remove_Side_Effects (Op1, Name_Req => True);
1440 Remove_Side_Effects (Op2, Name_Req => True);
1443 Make_Function_Call (Sloc (Op1),
1444 Name => New_Occurrence_Of (RTE (Comp), Loc),
1446 Parameter_Associations => New_List (
1447 Make_Attribute_Reference (Loc,
1448 Prefix => Relocate_Node (Op1),
1449 Attribute_Name => Name_Address),
1451 Make_Attribute_Reference (Loc,
1452 Prefix => Relocate_Node (Op2),
1453 Attribute_Name => Name_Address),
1455 Make_Attribute_Reference (Loc,
1456 Prefix => Relocate_Node (Op1),
1457 Attribute_Name => Name_Length),
1459 Make_Attribute_Reference (Loc,
1460 Prefix => Relocate_Node (Op2),
1461 Attribute_Name => Name_Length))));
1464 Make_Integer_Literal (Sloc (Op2),
1467 Analyze_And_Resolve (Op1, Standard_Integer);
1468 Analyze_And_Resolve (Op2, Standard_Integer);
1472 -- Cases where we cannot make runtime call
1474 -- For (a <= b) we convert to not (a > b)
1476 if Chars (N) = Name_Op_Le then
1482 Right_Opnd => Op2)));
1483 Analyze_And_Resolve (N, Standard_Boolean);
1486 -- For < the Boolean expression is
1487 -- greater__nn (op2, op1)
1489 elsif Chars (N) = Name_Op_Lt then
1490 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1494 Op1 := Right_Opnd (N);
1495 Op2 := Left_Opnd (N);
1497 -- For (a >= b) we convert to not (a < b)
1499 elsif Chars (N) = Name_Op_Ge then
1505 Right_Opnd => Op2)));
1506 Analyze_And_Resolve (N, Standard_Boolean);
1509 -- For > the Boolean expression is
1510 -- greater__nn (op1, op2)
1513 pragma Assert (Chars (N) = Name_Op_Gt);
1514 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1517 Func_Name := Defining_Unit_Name (Specification (Func_Body));
1519 Make_Function_Call (Loc,
1520 Name => New_Reference_To (Func_Name, Loc),
1521 Parameter_Associations => New_List (Op1, Op2));
1523 Insert_Action (N, Func_Body);
1525 Analyze_And_Resolve (N, Standard_Boolean);
1528 when RE_Not_Available =>
1530 end Expand_Array_Comparison;
1532 ---------------------------
1533 -- Expand_Array_Equality --
1534 ---------------------------
1536 -- Expand an equality function for multi-dimensional arrays. Here is an
1537 -- example of such a function for Nb_Dimension = 2
1539 -- function Enn (A : atyp; B : btyp) return boolean is
1541 -- if (A'length (1) = 0 or else A'length (2) = 0)
1543 -- (B'length (1) = 0 or else B'length (2) = 0)
1545 -- return True; -- RM 4.5.2(22)
1548 -- if A'length (1) /= B'length (1)
1550 -- A'length (2) /= B'length (2)
1552 -- return False; -- RM 4.5.2(23)
1556 -- A1 : Index_T1 := A'first (1);
1557 -- B1 : Index_T1 := B'first (1);
1561 -- A2 : Index_T2 := A'first (2);
1562 -- B2 : Index_T2 := B'first (2);
1565 -- if A (A1, A2) /= B (B1, B2) then
1569 -- exit when A2 = A'last (2);
1570 -- A2 := Index_T2'succ (A2);
1571 -- B2 := Index_T2'succ (B2);
1575 -- exit when A1 = A'last (1);
1576 -- A1 := Index_T1'succ (A1);
1577 -- B1 := Index_T1'succ (B1);
1584 -- Note on the formal types used (atyp and btyp). If either of the arrays
1585 -- is of a private type, we use the underlying type, and do an unchecked
1586 -- conversion of the actual. If either of the arrays has a bound depending
1587 -- on a discriminant, then we use the base type since otherwise we have an
1588 -- escaped discriminant in the function.
1590 -- If both arrays are constrained and have the same bounds, we can generate
1591 -- a loop with an explicit iteration scheme using a 'Range attribute over
1594 function Expand_Array_Equality
1599 Typ : Entity_Id) return Node_Id
1601 Loc : constant Source_Ptr := Sloc (Nod);
1602 Decls : constant List_Id := New_List;
1603 Index_List1 : constant List_Id := New_List;
1604 Index_List2 : constant List_Id := New_List;
1608 Func_Name : Entity_Id;
1609 Func_Body : Node_Id;
1611 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
1612 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
1616 -- The parameter types to be used for the formals
1621 Num : Int) return Node_Id;
1622 -- This builds the attribute reference Arr'Nam (Expr)
1624 function Component_Equality (Typ : Entity_Id) return Node_Id;
1625 -- Create one statement to compare corresponding components, designated
1626 -- by a full set of indexes.
1628 function Get_Arg_Type (N : Node_Id) return Entity_Id;
1629 -- Given one of the arguments, computes the appropriate type to be used
1630 -- for that argument in the corresponding function formal
1632 function Handle_One_Dimension
1634 Index : Node_Id) return Node_Id;
1635 -- This procedure returns the following code
1638 -- Bn : Index_T := B'First (N);
1642 -- exit when An = A'Last (N);
1643 -- An := Index_T'Succ (An)
1644 -- Bn := Index_T'Succ (Bn)
1648 -- If both indexes are constrained and identical, the procedure
1649 -- returns a simpler loop:
1651 -- for An in A'Range (N) loop
1655 -- N is the dimension for which we are generating a loop. Index is the
1656 -- N'th index node, whose Etype is Index_Type_n in the above code. The
1657 -- xxx statement is either the loop or declare for the next dimension
1658 -- or if this is the last dimension the comparison of corresponding
1659 -- components of the arrays.
1661 -- The actual way the code works is to return the comparison of
1662 -- corresponding components for the N+1 call. That's neater!
1664 function Test_Empty_Arrays return Node_Id;
1665 -- This function constructs the test for both arrays being empty
1666 -- (A'length (1) = 0 or else A'length (2) = 0 or else ...)
1668 -- (B'length (1) = 0 or else B'length (2) = 0 or else ...)
1670 function Test_Lengths_Correspond return Node_Id;
1671 -- This function constructs the test for arrays having different lengths
1672 -- in at least one index position, in which case the resulting code is:
1674 -- A'length (1) /= B'length (1)
1676 -- A'length (2) /= B'length (2)
1687 Num : Int) return Node_Id
1691 Make_Attribute_Reference (Loc,
1692 Attribute_Name => Nam,
1693 Prefix => New_Reference_To (Arr, Loc),
1694 Expressions => New_List (Make_Integer_Literal (Loc, Num)));
1697 ------------------------
1698 -- Component_Equality --
1699 ------------------------
1701 function Component_Equality (Typ : Entity_Id) return Node_Id is
1706 -- if a(i1...) /= b(j1...) then return false; end if;
1709 Make_Indexed_Component (Loc,
1710 Prefix => Make_Identifier (Loc, Chars (A)),
1711 Expressions => Index_List1);
1714 Make_Indexed_Component (Loc,
1715 Prefix => Make_Identifier (Loc, Chars (B)),
1716 Expressions => Index_List2);
1718 Test := Expand_Composite_Equality
1719 (Nod, Component_Type (Typ), L, R, Decls);
1721 -- If some (sub)component is an unchecked_union, the whole operation
1722 -- will raise program error.
1724 if Nkind (Test) = N_Raise_Program_Error then
1726 -- This node is going to be inserted at a location where a
1727 -- statement is expected: clear its Etype so analysis will set
1728 -- it to the expected Standard_Void_Type.
1730 Set_Etype (Test, Empty);
1735 Make_Implicit_If_Statement (Nod,
1736 Condition => Make_Op_Not (Loc, Right_Opnd => Test),
1737 Then_Statements => New_List (
1738 Make_Simple_Return_Statement (Loc,
1739 Expression => New_Occurrence_Of (Standard_False, Loc))));
1741 end Component_Equality;
1747 function Get_Arg_Type (N : Node_Id) return Entity_Id is
1758 T := Underlying_Type (T);
1760 X := First_Index (T);
1761 while Present (X) loop
1762 if Denotes_Discriminant (Type_Low_Bound (Etype (X)))
1764 Denotes_Discriminant (Type_High_Bound (Etype (X)))
1777 --------------------------
1778 -- Handle_One_Dimension --
1779 ---------------------------
1781 function Handle_One_Dimension
1783 Index : Node_Id) return Node_Id
1785 Need_Separate_Indexes : constant Boolean :=
1787 or else not Is_Constrained (Ltyp);
1788 -- If the index types are identical, and we are working with
1789 -- constrained types, then we can use the same index for both
1792 An : constant Entity_Id := Make_Temporary (Loc, 'A');
1795 Index_T : Entity_Id;
1800 if N > Number_Dimensions (Ltyp) then
1801 return Component_Equality (Ltyp);
1804 -- Case where we generate a loop
1806 Index_T := Base_Type (Etype (Index));
1808 if Need_Separate_Indexes then
1809 Bn := Make_Temporary (Loc, 'B');
1814 Append (New_Reference_To (An, Loc), Index_List1);
1815 Append (New_Reference_To (Bn, Loc), Index_List2);
1817 Stm_List := New_List (
1818 Handle_One_Dimension (N + 1, Next_Index (Index)));
1820 if Need_Separate_Indexes then
1822 -- Generate guard for loop, followed by increments of indexes
1824 Append_To (Stm_List,
1825 Make_Exit_Statement (Loc,
1828 Left_Opnd => New_Reference_To (An, Loc),
1829 Right_Opnd => Arr_Attr (A, Name_Last, N))));
1831 Append_To (Stm_List,
1832 Make_Assignment_Statement (Loc,
1833 Name => New_Reference_To (An, Loc),
1835 Make_Attribute_Reference (Loc,
1836 Prefix => New_Reference_To (Index_T, Loc),
1837 Attribute_Name => Name_Succ,
1838 Expressions => New_List (New_Reference_To (An, Loc)))));
1840 Append_To (Stm_List,
1841 Make_Assignment_Statement (Loc,
1842 Name => New_Reference_To (Bn, Loc),
1844 Make_Attribute_Reference (Loc,
1845 Prefix => New_Reference_To (Index_T, Loc),
1846 Attribute_Name => Name_Succ,
1847 Expressions => New_List (New_Reference_To (Bn, Loc)))));
1850 -- If separate indexes, we need a declare block for An and Bn, and a
1851 -- loop without an iteration scheme.
1853 if Need_Separate_Indexes then
1855 Make_Implicit_Loop_Statement (Nod, Statements => Stm_List);
1858 Make_Block_Statement (Loc,
1859 Declarations => New_List (
1860 Make_Object_Declaration (Loc,
1861 Defining_Identifier => An,
1862 Object_Definition => New_Reference_To (Index_T, Loc),
1863 Expression => Arr_Attr (A, Name_First, N)),
1865 Make_Object_Declaration (Loc,
1866 Defining_Identifier => Bn,
1867 Object_Definition => New_Reference_To (Index_T, Loc),
1868 Expression => Arr_Attr (B, Name_First, N))),
1870 Handled_Statement_Sequence =>
1871 Make_Handled_Sequence_Of_Statements (Loc,
1872 Statements => New_List (Loop_Stm)));
1874 -- If no separate indexes, return loop statement with explicit
1875 -- iteration scheme on its own
1879 Make_Implicit_Loop_Statement (Nod,
1880 Statements => Stm_List,
1882 Make_Iteration_Scheme (Loc,
1883 Loop_Parameter_Specification =>
1884 Make_Loop_Parameter_Specification (Loc,
1885 Defining_Identifier => An,
1886 Discrete_Subtype_Definition =>
1887 Arr_Attr (A, Name_Range, N))));
1890 end Handle_One_Dimension;
1892 -----------------------
1893 -- Test_Empty_Arrays --
1894 -----------------------
1896 function Test_Empty_Arrays return Node_Id is
1906 for J in 1 .. Number_Dimensions (Ltyp) loop
1909 Left_Opnd => Arr_Attr (A, Name_Length, J),
1910 Right_Opnd => Make_Integer_Literal (Loc, 0));
1914 Left_Opnd => Arr_Attr (B, Name_Length, J),
1915 Right_Opnd => Make_Integer_Literal (Loc, 0));
1924 Left_Opnd => Relocate_Node (Alist),
1925 Right_Opnd => Atest);
1929 Left_Opnd => Relocate_Node (Blist),
1930 Right_Opnd => Btest);
1937 Right_Opnd => Blist);
1938 end Test_Empty_Arrays;
1940 -----------------------------
1941 -- Test_Lengths_Correspond --
1942 -----------------------------
1944 function Test_Lengths_Correspond return Node_Id is
1950 for J in 1 .. Number_Dimensions (Ltyp) loop
1953 Left_Opnd => Arr_Attr (A, Name_Length, J),
1954 Right_Opnd => Arr_Attr (B, Name_Length, J));
1961 Left_Opnd => Relocate_Node (Result),
1962 Right_Opnd => Rtest);
1967 end Test_Lengths_Correspond;
1969 -- Start of processing for Expand_Array_Equality
1972 Ltyp := Get_Arg_Type (Lhs);
1973 Rtyp := Get_Arg_Type (Rhs);
1975 -- For now, if the argument types are not the same, go to the base type,
1976 -- since the code assumes that the formals have the same type. This is
1977 -- fixable in future ???
1979 if Ltyp /= Rtyp then
1980 Ltyp := Base_Type (Ltyp);
1981 Rtyp := Base_Type (Rtyp);
1982 pragma Assert (Ltyp = Rtyp);
1985 -- Build list of formals for function
1987 Formals := New_List (
1988 Make_Parameter_Specification (Loc,
1989 Defining_Identifier => A,
1990 Parameter_Type => New_Reference_To (Ltyp, Loc)),
1992 Make_Parameter_Specification (Loc,
1993 Defining_Identifier => B,
1994 Parameter_Type => New_Reference_To (Rtyp, Loc)));
1996 Func_Name := Make_Temporary (Loc, 'E');
1998 -- Build statement sequence for function
2001 Make_Subprogram_Body (Loc,
2003 Make_Function_Specification (Loc,
2004 Defining_Unit_Name => Func_Name,
2005 Parameter_Specifications => Formals,
2006 Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
2008 Declarations => Decls,
2010 Handled_Statement_Sequence =>
2011 Make_Handled_Sequence_Of_Statements (Loc,
2012 Statements => New_List (
2014 Make_Implicit_If_Statement (Nod,
2015 Condition => Test_Empty_Arrays,
2016 Then_Statements => New_List (
2017 Make_Simple_Return_Statement (Loc,
2019 New_Occurrence_Of (Standard_True, Loc)))),
2021 Make_Implicit_If_Statement (Nod,
2022 Condition => Test_Lengths_Correspond,
2023 Then_Statements => New_List (
2024 Make_Simple_Return_Statement (Loc,
2026 New_Occurrence_Of (Standard_False, Loc)))),
2028 Handle_One_Dimension (1, First_Index (Ltyp)),
2030 Make_Simple_Return_Statement (Loc,
2031 Expression => New_Occurrence_Of (Standard_True, Loc)))));
2033 Set_Has_Completion (Func_Name, True);
2034 Set_Is_Inlined (Func_Name);
2036 -- If the array type is distinct from the type of the arguments, it
2037 -- is the full view of a private type. Apply an unchecked conversion
2038 -- to insure that analysis of the call succeeds.
2048 or else Base_Type (Etype (Lhs)) /= Base_Type (Ltyp)
2050 L := OK_Convert_To (Ltyp, Lhs);
2054 or else Base_Type (Etype (Rhs)) /= Base_Type (Rtyp)
2056 R := OK_Convert_To (Rtyp, Rhs);
2059 Actuals := New_List (L, R);
2062 Append_To (Bodies, Func_Body);
2065 Make_Function_Call (Loc,
2066 Name => New_Reference_To (Func_Name, Loc),
2067 Parameter_Associations => Actuals);
2068 end Expand_Array_Equality;
2070 -----------------------------
2071 -- Expand_Boolean_Operator --
2072 -----------------------------
2074 -- Note that we first get the actual subtypes of the operands, since we
2075 -- always want to deal with types that have bounds.
2077 procedure Expand_Boolean_Operator (N : Node_Id) is
2078 Typ : constant Entity_Id := Etype (N);
2081 -- Special case of bit packed array where both operands are known to be
2082 -- properly aligned. In this case we use an efficient run time routine
2083 -- to carry out the operation (see System.Bit_Ops).
2085 if Is_Bit_Packed_Array (Typ)
2086 and then not Is_Possibly_Unaligned_Object (Left_Opnd (N))
2087 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
2089 Expand_Packed_Boolean_Operator (N);
2093 -- For the normal non-packed case, the general expansion is to build
2094 -- function for carrying out the comparison (use Make_Boolean_Array_Op)
2095 -- and then inserting it into the tree. The original operator node is
2096 -- then rewritten as a call to this function. We also use this in the
2097 -- packed case if either operand is a possibly unaligned object.
2100 Loc : constant Source_Ptr := Sloc (N);
2101 L : constant Node_Id := Relocate_Node (Left_Opnd (N));
2102 R : constant Node_Id := Relocate_Node (Right_Opnd (N));
2103 Func_Body : Node_Id;
2104 Func_Name : Entity_Id;
2107 Convert_To_Actual_Subtype (L);
2108 Convert_To_Actual_Subtype (R);
2109 Ensure_Defined (Etype (L), N);
2110 Ensure_Defined (Etype (R), N);
2111 Apply_Length_Check (R, Etype (L));
2113 if Nkind (N) = N_Op_Xor then
2114 Silly_Boolean_Array_Xor_Test (N, Etype (L));
2117 if Nkind (Parent (N)) = N_Assignment_Statement
2118 and then Safe_In_Place_Array_Op (Name (Parent (N)), L, R)
2120 Build_Boolean_Array_Proc_Call (Parent (N), L, R);
2122 elsif Nkind (Parent (N)) = N_Op_Not
2123 and then Nkind (N) = N_Op_And
2125 Safe_In_Place_Array_Op (Name (Parent (Parent (N))), L, R)
2130 Func_Body := Make_Boolean_Array_Op (Etype (L), N);
2131 Func_Name := Defining_Unit_Name (Specification (Func_Body));
2132 Insert_Action (N, Func_Body);
2134 -- Now rewrite the expression with a call
2137 Make_Function_Call (Loc,
2138 Name => New_Reference_To (Func_Name, Loc),
2139 Parameter_Associations =>
2142 Make_Type_Conversion
2143 (Loc, New_Reference_To (Etype (L), Loc), R))));
2145 Analyze_And_Resolve (N, Typ);
2148 end Expand_Boolean_Operator;
2150 -------------------------------
2151 -- Expand_Composite_Equality --
2152 -------------------------------
2154 -- This function is only called for comparing internal fields of composite
2155 -- types when these fields are themselves composites. This is a special
2156 -- case because it is not possible to respect normal Ada visibility rules.
2158 function Expand_Composite_Equality
2163 Bodies : List_Id) return Node_Id
2165 Loc : constant Source_Ptr := Sloc (Nod);
2166 Full_Type : Entity_Id;
2170 function Find_Primitive_Eq return Node_Id;
2171 -- AI05-0123: Locate primitive equality for type if it exists, and
2172 -- build the corresponding call. If operation is abstract, replace
2173 -- call with an explicit raise. Return Empty if there is no primitive.
2175 -----------------------
2176 -- Find_Primitive_Eq --
2177 -----------------------
2179 function Find_Primitive_Eq return Node_Id is
2184 Prim_E := First_Elmt (Collect_Primitive_Operations (Typ));
2185 while Present (Prim_E) loop
2186 Prim := Node (Prim_E);
2188 -- Locate primitive equality with the right signature
2190 if Chars (Prim) = Name_Op_Eq
2191 and then Etype (First_Formal (Prim)) =
2192 Etype (Next_Formal (First_Formal (Prim)))
2193 and then Etype (Prim) = Standard_Boolean
2195 if Is_Abstract_Subprogram (Prim) then
2197 Make_Raise_Program_Error (Loc,
2198 Reason => PE_Explicit_Raise);
2202 Make_Function_Call (Loc,
2203 Name => New_Reference_To (Prim, Loc),
2204 Parameter_Associations => New_List (Lhs, Rhs));
2211 -- If not found, predefined operation will be used
2214 end Find_Primitive_Eq;
2216 -- Start of processing for Expand_Composite_Equality
2219 if Is_Private_Type (Typ) then
2220 Full_Type := Underlying_Type (Typ);
2225 -- Defense against malformed private types with no completion the error
2226 -- will be diagnosed later by check_completion
2228 if No (Full_Type) then
2229 return New_Reference_To (Standard_False, Loc);
2232 Full_Type := Base_Type (Full_Type);
2234 if Is_Array_Type (Full_Type) then
2236 -- If the operand is an elementary type other than a floating-point
2237 -- type, then we can simply use the built-in block bitwise equality,
2238 -- since the predefined equality operators always apply and bitwise
2239 -- equality is fine for all these cases.
2241 if Is_Elementary_Type (Component_Type (Full_Type))
2242 and then not Is_Floating_Point_Type (Component_Type (Full_Type))
2244 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
2246 -- For composite component types, and floating-point types, use the
2247 -- expansion. This deals with tagged component types (where we use
2248 -- the applicable equality routine) and floating-point, (where we
2249 -- need to worry about negative zeroes), and also the case of any
2250 -- composite type recursively containing such fields.
2253 return Expand_Array_Equality (Nod, Lhs, Rhs, Bodies, Full_Type);
2256 elsif Is_Tagged_Type (Full_Type) then
2258 -- Call the primitive operation "=" of this type
2260 if Is_Class_Wide_Type (Full_Type) then
2261 Full_Type := Root_Type (Full_Type);
2264 -- If this is derived from an untagged private type completed with a
2265 -- tagged type, it does not have a full view, so we use the primitive
2266 -- operations of the private type. This check should no longer be
2267 -- necessary when these types receive their full views ???
2269 if Is_Private_Type (Typ)
2270 and then not Is_Tagged_Type (Typ)
2271 and then not Is_Controlled (Typ)
2272 and then Is_Derived_Type (Typ)
2273 and then No (Full_View (Typ))
2275 Prim := First_Elmt (Collect_Primitive_Operations (Typ));
2277 Prim := First_Elmt (Primitive_Operations (Full_Type));
2281 Eq_Op := Node (Prim);
2282 exit when Chars (Eq_Op) = Name_Op_Eq
2283 and then Etype (First_Formal (Eq_Op)) =
2284 Etype (Next_Formal (First_Formal (Eq_Op)))
2285 and then Base_Type (Etype (Eq_Op)) = Standard_Boolean;
2287 pragma Assert (Present (Prim));
2290 Eq_Op := Node (Prim);
2293 Make_Function_Call (Loc,
2294 Name => New_Reference_To (Eq_Op, Loc),
2295 Parameter_Associations =>
2297 (Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Lhs),
2298 Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Rhs)));
2300 elsif Is_Record_Type (Full_Type) then
2301 Eq_Op := TSS (Full_Type, TSS_Composite_Equality);
2303 if Present (Eq_Op) then
2304 if Etype (First_Formal (Eq_Op)) /= Full_Type then
2306 -- Inherited equality from parent type. Convert the actuals to
2307 -- match signature of operation.
2310 T : constant Entity_Id := Etype (First_Formal (Eq_Op));
2314 Make_Function_Call (Loc,
2315 Name => New_Reference_To (Eq_Op, Loc),
2316 Parameter_Associations => New_List (
2317 OK_Convert_To (T, Lhs),
2318 OK_Convert_To (T, Rhs)));
2322 -- Comparison between Unchecked_Union components
2324 if Is_Unchecked_Union (Full_Type) then
2326 Lhs_Type : Node_Id := Full_Type;
2327 Rhs_Type : Node_Id := Full_Type;
2328 Lhs_Discr_Val : Node_Id;
2329 Rhs_Discr_Val : Node_Id;
2334 if Nkind (Lhs) = N_Selected_Component then
2335 Lhs_Type := Etype (Entity (Selector_Name (Lhs)));
2340 if Nkind (Rhs) = N_Selected_Component then
2341 Rhs_Type := Etype (Entity (Selector_Name (Rhs)));
2344 -- Lhs of the composite equality
2346 if Is_Constrained (Lhs_Type) then
2348 -- Since the enclosing record type can never be an
2349 -- Unchecked_Union (this code is executed for records
2350 -- that do not have variants), we may reference its
2353 if Nkind (Lhs) = N_Selected_Component
2354 and then Has_Per_Object_Constraint (
2355 Entity (Selector_Name (Lhs)))
2358 Make_Selected_Component (Loc,
2359 Prefix => Prefix (Lhs),
2362 (Get_Discriminant_Value
2363 (First_Discriminant (Lhs_Type),
2365 Stored_Constraint (Lhs_Type))));
2370 (Get_Discriminant_Value
2371 (First_Discriminant (Lhs_Type),
2373 Stored_Constraint (Lhs_Type)));
2377 -- It is not possible to infer the discriminant since
2378 -- the subtype is not constrained.
2381 Make_Raise_Program_Error (Loc,
2382 Reason => PE_Unchecked_Union_Restriction);
2385 -- Rhs of the composite equality
2387 if Is_Constrained (Rhs_Type) then
2388 if Nkind (Rhs) = N_Selected_Component
2389 and then Has_Per_Object_Constraint
2390 (Entity (Selector_Name (Rhs)))
2393 Make_Selected_Component (Loc,
2394 Prefix => Prefix (Rhs),
2397 (Get_Discriminant_Value
2398 (First_Discriminant (Rhs_Type),
2400 Stored_Constraint (Rhs_Type))));
2405 (Get_Discriminant_Value
2406 (First_Discriminant (Rhs_Type),
2408 Stored_Constraint (Rhs_Type)));
2413 Make_Raise_Program_Error (Loc,
2414 Reason => PE_Unchecked_Union_Restriction);
2417 -- Call the TSS equality function with the inferred
2418 -- discriminant values.
2421 Make_Function_Call (Loc,
2422 Name => New_Reference_To (Eq_Op, Loc),
2423 Parameter_Associations => New_List (
2432 Make_Function_Call (Loc,
2433 Name => New_Reference_To (Eq_Op, Loc),
2434 Parameter_Associations => New_List (Lhs, Rhs));
2438 elsif Ada_Version >= Ada_2012 then
2440 -- if no TSS has been created for the type, check whether there is
2441 -- a primitive equality declared for it.
2444 Ada_2012_Op : constant Node_Id := Find_Primitive_Eq;
2447 if Present (Ada_2012_Op) then
2451 -- Use predefined equality if no user-defined primitive exists
2453 return Make_Op_Eq (Loc, Lhs, Rhs);
2458 return Expand_Record_Equality (Nod, Full_Type, Lhs, Rhs, Bodies);
2462 -- If not array or record type, it is predefined equality.
2464 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
2466 end Expand_Composite_Equality;
2468 ------------------------
2469 -- Expand_Concatenate --
2470 ------------------------
2472 procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id) is
2473 Loc : constant Source_Ptr := Sloc (Cnode);
2475 Atyp : constant Entity_Id := Base_Type (Etype (Cnode));
2476 -- Result type of concatenation
2478 Ctyp : constant Entity_Id := Base_Type (Component_Type (Etype (Cnode)));
2479 -- Component type. Elements of this component type can appear as one
2480 -- of the operands of concatenation as well as arrays.
2482 Istyp : constant Entity_Id := Etype (First_Index (Atyp));
2485 Ityp : constant Entity_Id := Base_Type (Istyp);
2486 -- Index type. This is the base type of the index subtype, and is used
2487 -- for all computed bounds (which may be out of range of Istyp in the
2488 -- case of null ranges).
2491 -- This is the type we use to do arithmetic to compute the bounds and
2492 -- lengths of operands. The choice of this type is a little subtle and
2493 -- is discussed in a separate section at the start of the body code.
2495 Concatenation_Error : exception;
2496 -- Raised if concatenation is sure to raise a CE
2498 Result_May_Be_Null : Boolean := True;
2499 -- Reset to False if at least one operand is encountered which is known
2500 -- at compile time to be non-null. Used for handling the special case
2501 -- of setting the high bound to the last operand high bound for a null
2502 -- result, thus ensuring a proper high bound in the super-flat case.
2504 N : constant Nat := List_Length (Opnds);
2505 -- Number of concatenation operands including possibly null operands
2508 -- Number of operands excluding any known to be null, except that the
2509 -- last operand is always retained, in case it provides the bounds for
2513 -- Current operand being processed in the loop through operands. After
2514 -- this loop is complete, always contains the last operand (which is not
2515 -- the same as Operands (NN), since null operands are skipped).
2517 -- Arrays describing the operands, only the first NN entries of each
2518 -- array are set (NN < N when we exclude known null operands).
2520 Is_Fixed_Length : array (1 .. N) of Boolean;
2521 -- True if length of corresponding operand known at compile time
2523 Operands : array (1 .. N) of Node_Id;
2524 -- Set to the corresponding entry in the Opnds list (but note that null
2525 -- operands are excluded, so not all entries in the list are stored).
2527 Fixed_Length : array (1 .. N) of Uint;
2528 -- Set to length of operand. Entries in this array are set only if the
2529 -- corresponding entry in Is_Fixed_Length is True.
2531 Opnd_Low_Bound : array (1 .. N) of Node_Id;
2532 -- Set to lower bound of operand. Either an integer literal in the case
2533 -- where the bound is known at compile time, else actual lower bound.
2534 -- The operand low bound is of type Ityp.
2536 Var_Length : array (1 .. N) of Entity_Id;
2537 -- Set to an entity of type Natural that contains the length of an
2538 -- operand whose length is not known at compile time. Entries in this
2539 -- array are set only if the corresponding entry in Is_Fixed_Length
2540 -- is False. The entity is of type Artyp.
2542 Aggr_Length : array (0 .. N) of Node_Id;
2543 -- The J'th entry in an expression node that represents the total length
2544 -- of operands 1 through J. It is either an integer literal node, or a
2545 -- reference to a constant entity with the right value, so it is fine
2546 -- to just do a Copy_Node to get an appropriate copy. The extra zero'th
2547 -- entry always is set to zero. The length is of type Artyp.
2549 Low_Bound : Node_Id;
2550 -- A tree node representing the low bound of the result (of type Ityp).
2551 -- This is either an integer literal node, or an identifier reference to
2552 -- a constant entity initialized to the appropriate value.
2554 Last_Opnd_High_Bound : Node_Id;
2555 -- A tree node representing the high bound of the last operand. This
2556 -- need only be set if the result could be null. It is used for the
2557 -- special case of setting the right high bound for a null result.
2558 -- This is of type Ityp.
2560 High_Bound : Node_Id;
2561 -- A tree node representing the high bound of the result (of type Ityp)
2564 -- Result of the concatenation (of type Ityp)
2566 Actions : constant List_Id := New_List;
2567 -- Collect actions to be inserted if Save_Space is False
2569 Save_Space : Boolean;
2570 pragma Warnings (Off, Save_Space);
2571 -- Set to True if we are saving generated code space by calling routines
2572 -- in packages System.Concat_n.
2574 Known_Non_Null_Operand_Seen : Boolean;
2575 -- Set True during generation of the assignments of operands into
2576 -- result once an operand known to be non-null has been seen.
2578 function Make_Artyp_Literal (Val : Nat) return Node_Id;
2579 -- This function makes an N_Integer_Literal node that is returned in
2580 -- analyzed form with the type set to Artyp. Importantly this literal
2581 -- is not flagged as static, so that if we do computations with it that
2582 -- result in statically detected out of range conditions, we will not
2583 -- generate error messages but instead warning messages.
2585 function To_Artyp (X : Node_Id) return Node_Id;
2586 -- Given a node of type Ityp, returns the corresponding value of type
2587 -- Artyp. For non-enumeration types, this is a plain integer conversion.
2588 -- For enum types, the Pos of the value is returned.
2590 function To_Ityp (X : Node_Id) return Node_Id;
2591 -- The inverse function (uses Val in the case of enumeration types)
2593 ------------------------
2594 -- Make_Artyp_Literal --
2595 ------------------------
2597 function Make_Artyp_Literal (Val : Nat) return Node_Id is
2598 Result : constant Node_Id := Make_Integer_Literal (Loc, Val);
2600 Set_Etype (Result, Artyp);
2601 Set_Analyzed (Result, True);
2602 Set_Is_Static_Expression (Result, False);
2604 end Make_Artyp_Literal;
2610 function To_Artyp (X : Node_Id) return Node_Id is
2612 if Ityp = Base_Type (Artyp) then
2615 elsif Is_Enumeration_Type (Ityp) then
2617 Make_Attribute_Reference (Loc,
2618 Prefix => New_Occurrence_Of (Ityp, Loc),
2619 Attribute_Name => Name_Pos,
2620 Expressions => New_List (X));
2623 return Convert_To (Artyp, X);
2631 function To_Ityp (X : Node_Id) return Node_Id is
2633 if Is_Enumeration_Type (Ityp) then
2635 Make_Attribute_Reference (Loc,
2636 Prefix => New_Occurrence_Of (Ityp, Loc),
2637 Attribute_Name => Name_Val,
2638 Expressions => New_List (X));
2640 -- Case where we will do a type conversion
2643 if Ityp = Base_Type (Artyp) then
2646 return Convert_To (Ityp, X);
2651 -- Local Declarations
2653 Opnd_Typ : Entity_Id;
2660 -- Start of processing for Expand_Concatenate
2663 -- Choose an appropriate computational type
2665 -- We will be doing calculations of lengths and bounds in this routine
2666 -- and computing one from the other in some cases, e.g. getting the high
2667 -- bound by adding the length-1 to the low bound.
2669 -- We can't just use the index type, or even its base type for this
2670 -- purpose for two reasons. First it might be an enumeration type which
2671 -- is not suitable for computations of any kind, and second it may
2672 -- simply not have enough range. For example if the index type is
2673 -- -128..+127 then lengths can be up to 256, which is out of range of
2676 -- For enumeration types, we can simply use Standard_Integer, this is
2677 -- sufficient since the actual number of enumeration literals cannot
2678 -- possibly exceed the range of integer (remember we will be doing the
2679 -- arithmetic with POS values, not representation values).
2681 if Is_Enumeration_Type (Ityp) then
2682 Artyp := Standard_Integer;
2684 -- If index type is Positive, we use the standard unsigned type, to give
2685 -- more room on the top of the range, obviating the need for an overflow
2686 -- check when creating the upper bound. This is needed to avoid junk
2687 -- overflow checks in the common case of String types.
2689 -- ??? Disabled for now
2691 -- elsif Istyp = Standard_Positive then
2692 -- Artyp := Standard_Unsigned;
2694 -- For modular types, we use a 32-bit modular type for types whose size
2695 -- is in the range 1-31 bits. For 32-bit unsigned types, we use the
2696 -- identity type, and for larger unsigned types we use 64-bits.
2698 elsif Is_Modular_Integer_Type (Ityp) then
2699 if RM_Size (Ityp) < RM_Size (Standard_Unsigned) then
2700 Artyp := Standard_Unsigned;
2701 elsif RM_Size (Ityp) = RM_Size (Standard_Unsigned) then
2704 Artyp := RTE (RE_Long_Long_Unsigned);
2707 -- Similar treatment for signed types
2710 if RM_Size (Ityp) < RM_Size (Standard_Integer) then
2711 Artyp := Standard_Integer;
2712 elsif RM_Size (Ityp) = RM_Size (Standard_Integer) then
2715 Artyp := Standard_Long_Long_Integer;
2719 -- Supply dummy entry at start of length array
2721 Aggr_Length (0) := Make_Artyp_Literal (0);
2723 -- Go through operands setting up the above arrays
2727 Opnd := Remove_Head (Opnds);
2728 Opnd_Typ := Etype (Opnd);
2730 -- The parent got messed up when we put the operands in a list,
2731 -- so now put back the proper parent for the saved operand, that
2732 -- is to say the concatenation node, to make sure that each operand
2733 -- is seen as a subexpression, e.g. if actions must be inserted.
2735 Set_Parent (Opnd, Cnode);
2737 -- Set will be True when we have setup one entry in the array
2741 -- Singleton element (or character literal) case
2743 if Base_Type (Opnd_Typ) = Ctyp then
2745 Operands (NN) := Opnd;
2746 Is_Fixed_Length (NN) := True;
2747 Fixed_Length (NN) := Uint_1;
2748 Result_May_Be_Null := False;
2750 -- Set low bound of operand (no need to set Last_Opnd_High_Bound
2751 -- since we know that the result cannot be null).
2753 Opnd_Low_Bound (NN) :=
2754 Make_Attribute_Reference (Loc,
2755 Prefix => New_Reference_To (Istyp, Loc),
2756 Attribute_Name => Name_First);
2760 -- String literal case (can only occur for strings of course)
2762 elsif Nkind (Opnd) = N_String_Literal then
2763 Len := String_Literal_Length (Opnd_Typ);
2766 Result_May_Be_Null := False;
2769 -- Capture last operand high bound if result could be null
2771 if J = N and then Result_May_Be_Null then
2772 Last_Opnd_High_Bound :=
2775 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)),
2776 Right_Opnd => Make_Integer_Literal (Loc, 1));
2779 -- Skip null string literal
2781 if J < N and then Len = 0 then
2786 Operands (NN) := Opnd;
2787 Is_Fixed_Length (NN) := True;
2789 -- Set length and bounds
2791 Fixed_Length (NN) := Len;
2793 Opnd_Low_Bound (NN) :=
2794 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));
2801 -- Check constrained case with known bounds
2803 if Is_Constrained (Opnd_Typ) then
2805 Index : constant Node_Id := First_Index (Opnd_Typ);
2806 Indx_Typ : constant Entity_Id := Etype (Index);
2807 Lo : constant Node_Id := Type_Low_Bound (Indx_Typ);
2808 Hi : constant Node_Id := Type_High_Bound (Indx_Typ);
2811 -- Fixed length constrained array type with known at compile
2812 -- time bounds is last case of fixed length operand.
2814 if Compile_Time_Known_Value (Lo)
2816 Compile_Time_Known_Value (Hi)
2819 Loval : constant Uint := Expr_Value (Lo);
2820 Hival : constant Uint := Expr_Value (Hi);
2821 Len : constant Uint :=
2822 UI_Max (Hival - Loval + 1, Uint_0);
2826 Result_May_Be_Null := False;
2829 -- Capture last operand bound if result could be null
2831 if J = N and then Result_May_Be_Null then
2832 Last_Opnd_High_Bound :=
2834 Make_Integer_Literal (Loc, Expr_Value (Hi)));
2837 -- Exclude null length case unless last operand
2839 if J < N and then Len = 0 then
2844 Operands (NN) := Opnd;
2845 Is_Fixed_Length (NN) := True;
2846 Fixed_Length (NN) := Len;
2848 Opnd_Low_Bound (NN) :=
2850 (Make_Integer_Literal (Loc, Expr_Value (Lo)));
2857 -- All cases where the length is not known at compile time, or the
2858 -- special case of an operand which is known to be null but has a
2859 -- lower bound other than 1 or is other than a string type.
2864 -- Capture operand bounds
2866 Opnd_Low_Bound (NN) :=
2867 Make_Attribute_Reference (Loc,
2869 Duplicate_Subexpr (Opnd, Name_Req => True),
2870 Attribute_Name => Name_First);
2872 if J = N and Result_May_Be_Null then
2873 Last_Opnd_High_Bound :=
2875 Make_Attribute_Reference (Loc,
2877 Duplicate_Subexpr (Opnd, Name_Req => True),
2878 Attribute_Name => Name_Last));
2881 -- Capture length of operand in entity
2883 Operands (NN) := Opnd;
2884 Is_Fixed_Length (NN) := False;
2886 Var_Length (NN) := Make_Temporary (Loc, 'L');
2889 Make_Object_Declaration (Loc,
2890 Defining_Identifier => Var_Length (NN),
2891 Constant_Present => True,
2892 Object_Definition => New_Occurrence_Of (Artyp, Loc),
2894 Make_Attribute_Reference (Loc,
2896 Duplicate_Subexpr (Opnd, Name_Req => True),
2897 Attribute_Name => Name_Length)));
2901 -- Set next entry in aggregate length array
2903 -- For first entry, make either integer literal for fixed length
2904 -- or a reference to the saved length for variable length.
2907 if Is_Fixed_Length (1) then
2908 Aggr_Length (1) := Make_Integer_Literal (Loc, Fixed_Length (1));
2910 Aggr_Length (1) := New_Reference_To (Var_Length (1), Loc);
2913 -- If entry is fixed length and only fixed lengths so far, make
2914 -- appropriate new integer literal adding new length.
2916 elsif Is_Fixed_Length (NN)
2917 and then Nkind (Aggr_Length (NN - 1)) = N_Integer_Literal
2920 Make_Integer_Literal (Loc,
2921 Intval => Fixed_Length (NN) + Intval (Aggr_Length (NN - 1)));
2923 -- All other cases, construct an addition node for the length and
2924 -- create an entity initialized to this length.
2927 Ent := Make_Temporary (Loc, 'L');
2929 if Is_Fixed_Length (NN) then
2930 Clen := Make_Integer_Literal (Loc, Fixed_Length (NN));
2932 Clen := New_Reference_To (Var_Length (NN), Loc);
2936 Make_Object_Declaration (Loc,
2937 Defining_Identifier => Ent,
2938 Constant_Present => True,
2939 Object_Definition => New_Occurrence_Of (Artyp, Loc),
2942 Left_Opnd => New_Copy (Aggr_Length (NN - 1)),
2943 Right_Opnd => Clen)));
2945 Aggr_Length (NN) := Make_Identifier (Loc, Chars => Chars (Ent));
2952 -- If we have only skipped null operands, return the last operand
2959 -- If we have only one non-null operand, return it and we are done.
2960 -- There is one case in which this cannot be done, and that is when
2961 -- the sole operand is of the element type, in which case it must be
2962 -- converted to an array, and the easiest way of doing that is to go
2963 -- through the normal general circuit.
2966 and then Base_Type (Etype (Operands (1))) /= Ctyp
2968 Result := Operands (1);
2972 -- Cases where we have a real concatenation
2974 -- Next step is to find the low bound for the result array that we
2975 -- will allocate. The rules for this are in (RM 4.5.6(5-7)).
2977 -- If the ultimate ancestor of the index subtype is a constrained array
2978 -- definition, then the lower bound is that of the index subtype as
2979 -- specified by (RM 4.5.3(6)).
2981 -- The right test here is to go to the root type, and then the ultimate
2982 -- ancestor is the first subtype of this root type.
2984 if Is_Constrained (First_Subtype (Root_Type (Atyp))) then
2986 Make_Attribute_Reference (Loc,
2988 New_Occurrence_Of (First_Subtype (Root_Type (Atyp)), Loc),
2989 Attribute_Name => Name_First);
2991 -- If the first operand in the list has known length we know that
2992 -- the lower bound of the result is the lower bound of this operand.
2994 elsif Is_Fixed_Length (1) then
2995 Low_Bound := Opnd_Low_Bound (1);
2997 -- OK, we don't know the lower bound, we have to build a horrible
2998 -- expression actions node of the form
3000 -- if Cond1'Length /= 0 then
3003 -- if Opnd2'Length /= 0 then
3008 -- The nesting ends either when we hit an operand whose length is known
3009 -- at compile time, or on reaching the last operand, whose low bound we
3010 -- take unconditionally whether or not it is null. It's easiest to do
3011 -- this with a recursive procedure:
3015 function Get_Known_Bound (J : Nat) return Node_Id;
3016 -- Returns the lower bound determined by operands J .. NN
3018 ---------------------
3019 -- Get_Known_Bound --
3020 ---------------------
3022 function Get_Known_Bound (J : Nat) return Node_Id is
3024 if Is_Fixed_Length (J) or else J = NN then
3025 return New_Copy (Opnd_Low_Bound (J));
3029 Make_Conditional_Expression (Loc,
3030 Expressions => New_List (
3033 Left_Opnd => New_Reference_To (Var_Length (J), Loc),
3034 Right_Opnd => Make_Integer_Literal (Loc, 0)),
3036 New_Copy (Opnd_Low_Bound (J)),
3037 Get_Known_Bound (J + 1)));
3039 end Get_Known_Bound;
3042 Ent := Make_Temporary (Loc, 'L');
3045 Make_Object_Declaration (Loc,
3046 Defining_Identifier => Ent,
3047 Constant_Present => True,
3048 Object_Definition => New_Occurrence_Of (Ityp, Loc),
3049 Expression => Get_Known_Bound (1)));
3051 Low_Bound := New_Reference_To (Ent, Loc);
3055 -- Now we can safely compute the upper bound, normally
3056 -- Low_Bound + Length - 1.
3061 Left_Opnd => To_Artyp (New_Copy (Low_Bound)),
3063 Make_Op_Subtract (Loc,
3064 Left_Opnd => New_Copy (Aggr_Length (NN)),
3065 Right_Opnd => Make_Artyp_Literal (1))));
3067 -- Note that calculation of the high bound may cause overflow in some
3068 -- very weird cases, so in the general case we need an overflow check on
3069 -- the high bound. We can avoid this for the common case of string types
3070 -- and other types whose index is Positive, since we chose a wider range
3071 -- for the arithmetic type.
3073 if Istyp /= Standard_Positive then
3074 Activate_Overflow_Check (High_Bound);
3077 -- Handle the exceptional case where the result is null, in which case
3078 -- case the bounds come from the last operand (so that we get the proper
3079 -- bounds if the last operand is super-flat).
3081 if Result_May_Be_Null then
3083 Make_Conditional_Expression (Loc,
3084 Expressions => New_List (
3086 Left_Opnd => New_Copy (Aggr_Length (NN)),
3087 Right_Opnd => Make_Artyp_Literal (0)),
3088 Last_Opnd_High_Bound,
3092 -- Here is where we insert the saved up actions
3094 Insert_Actions (Cnode, Actions, Suppress => All_Checks);
3096 -- Now we construct an array object with appropriate bounds. We mark
3097 -- the target as internal to prevent useless initialization when
3098 -- Initialize_Scalars is enabled. Also since this is the actual result
3099 -- entity, we make sure we have debug information for the result.
3101 Ent := Make_Temporary (Loc, 'S');
3102 Set_Is_Internal (Ent);
3103 Set_Needs_Debug_Info (Ent);
3105 -- If the bound is statically known to be out of range, we do not want
3106 -- to abort, we want a warning and a runtime constraint error. Note that
3107 -- we have arranged that the result will not be treated as a static
3108 -- constant, so we won't get an illegality during this insertion.
3110 Insert_Action (Cnode,
3111 Make_Object_Declaration (Loc,
3112 Defining_Identifier => Ent,
3113 Object_Definition =>
3114 Make_Subtype_Indication (Loc,
3115 Subtype_Mark => New_Occurrence_Of (Atyp, Loc),
3117 Make_Index_Or_Discriminant_Constraint (Loc,
3118 Constraints => New_List (
3120 Low_Bound => Low_Bound,
3121 High_Bound => High_Bound))))),
3122 Suppress => All_Checks);
3124 -- If the result of the concatenation appears as the initializing
3125 -- expression of an object declaration, we can just rename the
3126 -- result, rather than copying it.
3128 Set_OK_To_Rename (Ent);
3130 -- Catch the static out of range case now
3132 if Raises_Constraint_Error (High_Bound) then
3133 raise Concatenation_Error;
3136 -- Now we will generate the assignments to do the actual concatenation
3138 -- There is one case in which we will not do this, namely when all the
3139 -- following conditions are met:
3141 -- The result type is Standard.String
3143 -- There are nine or fewer retained (non-null) operands
3145 -- The optimization level is -O0
3147 -- The corresponding System.Concat_n.Str_Concat_n routine is
3148 -- available in the run time.
3150 -- The debug flag gnatd.c is not set
3152 -- If all these conditions are met then we generate a call to the
3153 -- relevant concatenation routine. The purpose of this is to avoid
3154 -- undesirable code bloat at -O0.
3156 if Atyp = Standard_String
3157 and then NN in 2 .. 9
3158 and then (Opt.Optimization_Level = 0 or else Debug_Flag_Dot_CC)
3159 and then not Debug_Flag_Dot_C
3162 RR : constant array (Nat range 2 .. 9) of RE_Id :=
3173 if RTE_Available (RR (NN)) then
3175 Opnds : constant List_Id :=
3176 New_List (New_Occurrence_Of (Ent, Loc));
3179 for J in 1 .. NN loop
3180 if Is_List_Member (Operands (J)) then
3181 Remove (Operands (J));
3184 if Base_Type (Etype (Operands (J))) = Ctyp then
3186 Make_Aggregate (Loc,
3187 Component_Associations => New_List (
3188 Make_Component_Association (Loc,
3189 Choices => New_List (
3190 Make_Integer_Literal (Loc, 1)),
3191 Expression => Operands (J)))));
3194 Append_To (Opnds, Operands (J));
3198 Insert_Action (Cnode,
3199 Make_Procedure_Call_Statement (Loc,
3200 Name => New_Reference_To (RTE (RR (NN)), Loc),
3201 Parameter_Associations => Opnds));
3203 Result := New_Reference_To (Ent, Loc);
3210 -- Not special case so generate the assignments
3212 Known_Non_Null_Operand_Seen := False;
3214 for J in 1 .. NN loop
3216 Lo : constant Node_Id :=
3218 Left_Opnd => To_Artyp (New_Copy (Low_Bound)),
3219 Right_Opnd => Aggr_Length (J - 1));
3221 Hi : constant Node_Id :=
3223 Left_Opnd => To_Artyp (New_Copy (Low_Bound)),
3225 Make_Op_Subtract (Loc,
3226 Left_Opnd => Aggr_Length (J),
3227 Right_Opnd => Make_Artyp_Literal (1)));
3230 -- Singleton case, simple assignment
3232 if Base_Type (Etype (Operands (J))) = Ctyp then
3233 Known_Non_Null_Operand_Seen := True;
3234 Insert_Action (Cnode,
3235 Make_Assignment_Statement (Loc,
3237 Make_Indexed_Component (Loc,
3238 Prefix => New_Occurrence_Of (Ent, Loc),
3239 Expressions => New_List (To_Ityp (Lo))),
3240 Expression => Operands (J)),
3241 Suppress => All_Checks);
3243 -- Array case, slice assignment, skipped when argument is fixed
3244 -- length and known to be null.
3246 elsif (not Is_Fixed_Length (J)) or else (Fixed_Length (J) > 0) then
3249 Make_Assignment_Statement (Loc,
3253 New_Occurrence_Of (Ent, Loc),
3256 Low_Bound => To_Ityp (Lo),
3257 High_Bound => To_Ityp (Hi))),
3258 Expression => Operands (J));
3260 if Is_Fixed_Length (J) then
3261 Known_Non_Null_Operand_Seen := True;
3263 elsif not Known_Non_Null_Operand_Seen then
3265 -- Here if operand length is not statically known and no
3266 -- operand known to be non-null has been processed yet.
3267 -- If operand length is 0, we do not need to perform the
3268 -- assignment, and we must avoid the evaluation of the
3269 -- high bound of the slice, since it may underflow if the
3270 -- low bound is Ityp'First.
3273 Make_Implicit_If_Statement (Cnode,
3277 New_Occurrence_Of (Var_Length (J), Loc),
3278 Right_Opnd => Make_Integer_Literal (Loc, 0)),
3279 Then_Statements => New_List (Assign));
3282 Insert_Action (Cnode, Assign, Suppress => All_Checks);
3288 -- Finally we build the result, which is a reference to the array object
3290 Result := New_Reference_To (Ent, Loc);
3293 Rewrite (Cnode, Result);
3294 Analyze_And_Resolve (Cnode, Atyp);
3297 when Concatenation_Error =>
3299 -- Kill warning generated for the declaration of the static out of
3300 -- range high bound, and instead generate a Constraint_Error with
3301 -- an appropriate specific message.
3303 Kill_Dead_Code (Declaration_Node (Entity (High_Bound)));
3304 Apply_Compile_Time_Constraint_Error
3306 Msg => "concatenation result upper bound out of range?",
3307 Reason => CE_Range_Check_Failed);
3308 -- Set_Etype (Cnode, Atyp);
3309 end Expand_Concatenate;
3311 ------------------------
3312 -- Expand_N_Allocator --
3313 ------------------------
3315 procedure Expand_N_Allocator (N : Node_Id) is
3316 PtrT : constant Entity_Id := Etype (N);
3317 Dtyp : constant Entity_Id := Available_View (Designated_Type (PtrT));
3318 Etyp : constant Entity_Id := Etype (Expression (N));
3319 Loc : constant Source_Ptr := Sloc (N);
3325 procedure Rewrite_Coextension (N : Node_Id);
3326 -- Static coextensions have the same lifetime as the entity they
3327 -- constrain. Such occurrences can be rewritten as aliased objects
3328 -- and their unrestricted access used instead of the coextension.
3330 function Size_In_Storage_Elements (E : Entity_Id) return Node_Id;
3331 -- Given a constrained array type E, returns a node representing the
3332 -- code to compute the size in storage elements for the given type.
3333 -- This is done without using the attribute (which malfunctions for
3336 -------------------------
3337 -- Rewrite_Coextension --
3338 -------------------------
3340 procedure Rewrite_Coextension (N : Node_Id) is
3341 Temp_Id : constant Node_Id := Make_Temporary (Loc, 'C');
3342 Temp_Decl : Node_Id;
3343 Insert_Nod : Node_Id;
3347 -- Cnn : aliased Etyp;
3350 Make_Object_Declaration (Loc,
3351 Defining_Identifier => Temp_Id,
3352 Aliased_Present => True,
3353 Object_Definition => New_Occurrence_Of (Etyp, Loc));
3355 if Nkind (Expression (N)) = N_Qualified_Expression then
3356 Set_Expression (Temp_Decl, Expression (Expression (N)));
3359 -- Find the proper insertion node for the declaration
3361 Insert_Nod := Parent (N);
3362 while Present (Insert_Nod) loop
3364 Nkind (Insert_Nod) in N_Statement_Other_Than_Procedure_Call
3365 or else Nkind (Insert_Nod) = N_Procedure_Call_Statement
3366 or else Nkind (Insert_Nod) in N_Declaration;
3368 Insert_Nod := Parent (Insert_Nod);
3371 Insert_Before (Insert_Nod, Temp_Decl);
3372 Analyze (Temp_Decl);
3375 Make_Attribute_Reference (Loc,
3376 Prefix => New_Occurrence_Of (Temp_Id, Loc),
3377 Attribute_Name => Name_Unrestricted_Access));
3379 Analyze_And_Resolve (N, PtrT);
3380 end Rewrite_Coextension;
3382 ------------------------------
3383 -- Size_In_Storage_Elements --
3384 ------------------------------
3386 function Size_In_Storage_Elements (E : Entity_Id) return Node_Id is
3388 -- Logically this just returns E'Max_Size_In_Storage_Elements.
3389 -- However, the reason for the existence of this function is
3390 -- to construct a test for sizes too large, which means near the
3391 -- 32-bit limit on a 32-bit machine, and precisely the trouble
3392 -- is that we get overflows when sizes are greater than 2**31.
3394 -- So what we end up doing for array types is to use the expression:
3396 -- number-of-elements * component_type'Max_Size_In_Storage_Elements
3398 -- which avoids this problem. All this is a bit bogus, but it does
3399 -- mean we catch common cases of trying to allocate arrays that
3400 -- are too large, and which in the absence of a check results in
3401 -- undetected chaos ???
3408 for J in 1 .. Number_Dimensions (E) loop
3410 Make_Attribute_Reference (Loc,
3411 Prefix => New_Occurrence_Of (E, Loc),
3412 Attribute_Name => Name_Length,
3413 Expressions => New_List (Make_Integer_Literal (Loc, J)));
3420 Make_Op_Multiply (Loc,
3427 Make_Op_Multiply (Loc,
3430 Make_Attribute_Reference (Loc,
3431 Prefix => New_Occurrence_Of (Component_Type (E), Loc),
3432 Attribute_Name => Name_Max_Size_In_Storage_Elements));
3434 end Size_In_Storage_Elements;
3436 -- Start of processing for Expand_N_Allocator
3439 -- RM E.2.3(22). We enforce that the expected type of an allocator
3440 -- shall not be a remote access-to-class-wide-limited-private type
3442 -- Why is this being done at expansion time, seems clearly wrong ???
3444 Validate_Remote_Access_To_Class_Wide_Type (N);
3446 -- Processing for anonymous access-to-controlled types. These access
3447 -- types receive a special finalization master which appears in the
3448 -- declarations of the enclosing semantic unit. This expansion is done
3449 -- now to ensure that any additional types generated by this routine
3450 -- or Expand_Allocator_Expression inherit the proper type attributes.
3452 if Ekind (PtrT) = E_Anonymous_Access_Type
3453 and then Needs_Finalization (Dtyp)
3455 -- Anonymous access-to-controlled types allocate on the global pool.
3456 -- Do not set this attribute on .NET/JVM since those targets do not
3459 if No (Associated_Storage_Pool (PtrT))
3460 and then VM_Target = No_VM
3462 Set_Associated_Storage_Pool
3463 (PtrT, Get_Global_Pool_For_Access_Type (PtrT));
3466 -- The finalization master must be inserted and analyzed as part of
3467 -- the current semantic unit.
3469 if No (Finalization_Master (PtrT)) then
3470 Set_Finalization_Master (PtrT, Current_Anonymous_Master);
3474 -- Set the storage pool and find the appropriate version of Allocate to
3477 Pool := Associated_Storage_Pool (Root_Type (PtrT));
3478 Set_Storage_Pool (N, Pool);
3480 if Present (Pool) then
3481 if Is_RTE (Pool, RE_SS_Pool) then
3482 if VM_Target = No_VM then
3483 Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));
3486 elsif Is_Class_Wide_Type (Etype (Pool)) then
3487 Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));
3490 Set_Procedure_To_Call (N,
3491 Find_Prim_Op (Etype (Pool), Name_Allocate));
3495 -- Under certain circumstances we can replace an allocator by an access
3496 -- to statically allocated storage. The conditions, as noted in AARM
3497 -- 3.10 (10c) are as follows:
3499 -- Size and initial value is known at compile time
3500 -- Access type is access-to-constant
3502 -- The allocator is not part of a constraint on a record component,
3503 -- because in that case the inserted actions are delayed until the
3504 -- record declaration is fully analyzed, which is too late for the
3505 -- analysis of the rewritten allocator.
3507 if Is_Access_Constant (PtrT)
3508 and then Nkind (Expression (N)) = N_Qualified_Expression
3509 and then Compile_Time_Known_Value (Expression (Expression (N)))
3510 and then Size_Known_At_Compile_Time
3511 (Etype (Expression (Expression (N))))
3512 and then not Is_Record_Type (Current_Scope)
3514 -- Here we can do the optimization. For the allocator
3518 -- We insert an object declaration
3520 -- Tnn : aliased x := y;
3522 -- and replace the allocator by Tnn'Unrestricted_Access. Tnn is
3523 -- marked as requiring static allocation.
3525 Temp := Make_Temporary (Loc, 'T', Expression (Expression (N)));
3526 Desig := Subtype_Mark (Expression (N));
3528 -- If context is constrained, use constrained subtype directly,
3529 -- so that the constant is not labelled as having a nominally
3530 -- unconstrained subtype.
3532 if Entity (Desig) = Base_Type (Dtyp) then
3533 Desig := New_Occurrence_Of (Dtyp, Loc);
3537 Make_Object_Declaration (Loc,
3538 Defining_Identifier => Temp,
3539 Aliased_Present => True,
3540 Constant_Present => Is_Access_Constant (PtrT),
3541 Object_Definition => Desig,
3542 Expression => Expression (Expression (N))));
3545 Make_Attribute_Reference (Loc,
3546 Prefix => New_Occurrence_Of (Temp, Loc),
3547 Attribute_Name => Name_Unrestricted_Access));
3549 Analyze_And_Resolve (N, PtrT);
3551 -- We set the variable as statically allocated, since we don't want
3552 -- it going on the stack of the current procedure!
3554 Set_Is_Statically_Allocated (Temp);
3558 -- Same if the allocator is an access discriminant for a local object:
3559 -- instead of an allocator we create a local value and constrain the
3560 -- enclosing object with the corresponding access attribute.
3562 if Is_Static_Coextension (N) then
3563 Rewrite_Coextension (N);
3567 -- Check for size too large, we do this because the back end misses
3568 -- proper checks here and can generate rubbish allocation calls when
3569 -- we are near the limit. We only do this for the 32-bit address case
3570 -- since that is from a practical point of view where we see a problem.
3572 if System_Address_Size = 32
3573 and then not Storage_Checks_Suppressed (PtrT)
3574 and then not Storage_Checks_Suppressed (Dtyp)
3575 and then not Storage_Checks_Suppressed (Etyp)
3577 -- The check we want to generate should look like
3579 -- if Etyp'Max_Size_In_Storage_Elements > 3.5 gigabytes then
3580 -- raise Storage_Error;
3583 -- where 3.5 gigabytes is a constant large enough to accommodate any
3584 -- reasonable request for. But we can't do it this way because at
3585 -- least at the moment we don't compute this attribute right, and
3586 -- can silently give wrong results when the result gets large. Since
3587 -- this is all about large results, that's bad, so instead we only
3588 -- apply the check for constrained arrays, and manually compute the
3589 -- value of the attribute ???
3591 if Is_Array_Type (Etyp) and then Is_Constrained (Etyp) then
3593 Make_Raise_Storage_Error (Loc,
3596 Left_Opnd => Size_In_Storage_Elements (Etyp),
3598 Make_Integer_Literal (Loc, Uint_7 * (Uint_2 ** 29))),
3599 Reason => SE_Object_Too_Large));
3603 -- Handle case of qualified expression (other than optimization above)
3604 -- First apply constraint checks, because the bounds or discriminants
3605 -- in the aggregate might not match the subtype mark in the allocator.
3607 if Nkind (Expression (N)) = N_Qualified_Expression then
3608 Apply_Constraint_Check
3609 (Expression (Expression (N)), Etype (Expression (N)));
3611 Expand_Allocator_Expression (N);
3615 -- If the allocator is for a type which requires initialization, and
3616 -- there is no initial value (i.e. operand is a subtype indication
3617 -- rather than a qualified expression), then we must generate a call to
3618 -- the initialization routine using an expressions action node:
3620 -- [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
3622 -- Here ptr_T is the pointer type for the allocator, and T is the
3623 -- subtype of the allocator. A special case arises if the designated
3624 -- type of the access type is a task or contains tasks. In this case
3625 -- the call to Init (Temp.all ...) is replaced by code that ensures
3626 -- that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
3627 -- for details). In addition, if the type T is a task T, then the
3628 -- first argument to Init must be converted to the task record type.
3631 T : constant Entity_Id := Entity (Expression (N));
3637 Init_Arg1 : Node_Id;
3638 Temp_Decl : Node_Id;
3639 Temp_Type : Entity_Id;
3642 if No_Initialization (N) then
3644 -- Even though this might be a simple allocation, create a custom
3645 -- Allocate if the context requires it. Since .NET/JVM compilers
3646 -- do not support pools, this step is skipped.
3648 if VM_Target = No_VM
3649 and then Present (Finalization_Master (PtrT))
3651 Build_Allocate_Deallocate_Proc
3653 Is_Allocate => True);
3656 -- Case of no initialization procedure present
3658 elsif not Has_Non_Null_Base_Init_Proc (T) then
3660 -- Case of simple initialization required
3662 if Needs_Simple_Initialization (T) then
3663 Check_Restriction (No_Default_Initialization, N);
3664 Rewrite (Expression (N),
3665 Make_Qualified_Expression (Loc,
3666 Subtype_Mark => New_Occurrence_Of (T, Loc),
3667 Expression => Get_Simple_Init_Val (T, N)));
3669 Analyze_And_Resolve (Expression (Expression (N)), T);
3670 Analyze_And_Resolve (Expression (N), T);
3671 Set_Paren_Count (Expression (Expression (N)), 1);
3672 Expand_N_Allocator (N);
3674 -- No initialization required
3680 -- Case of initialization procedure present, must be called
3683 Check_Restriction (No_Default_Initialization, N);
3685 if not Restriction_Active (No_Default_Initialization) then
3686 Init := Base_Init_Proc (T);
3688 Temp := Make_Temporary (Loc, 'P');
3690 -- Construct argument list for the initialization routine call
3693 Make_Explicit_Dereference (Loc,
3695 New_Reference_To (Temp, Loc));
3697 Set_Assignment_OK (Init_Arg1);
3700 -- The initialization procedure expects a specific type. if the
3701 -- context is access to class wide, indicate that the object
3702 -- being allocated has the right specific type.
3704 if Is_Class_Wide_Type (Dtyp) then
3705 Init_Arg1 := Unchecked_Convert_To (T, Init_Arg1);
3708 -- If designated type is a concurrent type or if it is private
3709 -- type whose definition is a concurrent type, the first
3710 -- argument in the Init routine has to be unchecked conversion
3711 -- to the corresponding record type. If the designated type is
3712 -- a derived type, also convert the argument to its root type.
3714 if Is_Concurrent_Type (T) then
3716 Unchecked_Convert_To (
3717 Corresponding_Record_Type (T), Init_Arg1);
3719 elsif Is_Private_Type (T)
3720 and then Present (Full_View (T))
3721 and then Is_Concurrent_Type (Full_View (T))
3724 Unchecked_Convert_To
3725 (Corresponding_Record_Type (Full_View (T)), Init_Arg1);
3727 elsif Etype (First_Formal (Init)) /= Base_Type (T) then
3729 Ftyp : constant Entity_Id := Etype (First_Formal (Init));
3732 Init_Arg1 := OK_Convert_To (Etype (Ftyp), Init_Arg1);
3733 Set_Etype (Init_Arg1, Ftyp);
3737 Args := New_List (Init_Arg1);
3739 -- For the task case, pass the Master_Id of the access type as
3740 -- the value of the _Master parameter, and _Chain as the value
3741 -- of the _Chain parameter (_Chain will be defined as part of
3742 -- the generated code for the allocator).
3744 -- In Ada 2005, the context may be a function that returns an
3745 -- anonymous access type. In that case the Master_Id has been
3746 -- created when expanding the function declaration.
3748 if Has_Task (T) then
3749 if No (Master_Id (Base_Type (PtrT))) then
3751 -- The designated type was an incomplete type, and the
3752 -- access type did not get expanded. Salvage it now.
3754 if not Restriction_Active (No_Task_Hierarchy) then
3755 pragma Assert (Present (Parent (Base_Type (PtrT))));
3756 Expand_N_Full_Type_Declaration
3757 (Parent (Base_Type (PtrT)));
3761 -- If the context of the allocator is a declaration or an
3762 -- assignment, we can generate a meaningful image for it,
3763 -- even though subsequent assignments might remove the
3764 -- connection between task and entity. We build this image
3765 -- when the left-hand side is a simple variable, a simple
3766 -- indexed assignment or a simple selected component.
3768 if Nkind (Parent (N)) = N_Assignment_Statement then
3770 Nam : constant Node_Id := Name (Parent (N));
3773 if Is_Entity_Name (Nam) then
3775 Build_Task_Image_Decls
3778 (Entity (Nam), Sloc (Nam)), T);
3780 elsif Nkind_In (Nam, N_Indexed_Component,
3781 N_Selected_Component)
3782 and then Is_Entity_Name (Prefix (Nam))
3785 Build_Task_Image_Decls
3786 (Loc, Nam, Etype (Prefix (Nam)));
3788 Decls := Build_Task_Image_Decls (Loc, T, T);
3792 elsif Nkind (Parent (N)) = N_Object_Declaration then
3794 Build_Task_Image_Decls
3795 (Loc, Defining_Identifier (Parent (N)), T);
3798 Decls := Build_Task_Image_Decls (Loc, T, T);
3801 if Restriction_Active (No_Task_Hierarchy) then
3803 New_Occurrence_Of (RTE (RE_Library_Task_Level), Loc));
3807 (Master_Id (Base_Type (Root_Type (PtrT))), Loc));
3810 Append_To (Args, Make_Identifier (Loc, Name_uChain));
3812 Decl := Last (Decls);
3814 New_Occurrence_Of (Defining_Identifier (Decl), Loc));
3816 -- Has_Task is false, Decls not used
3822 -- Add discriminants if discriminated type
3825 Dis : Boolean := False;
3829 if Has_Discriminants (T) then
3833 elsif Is_Private_Type (T)
3834 and then Present (Full_View (T))
3835 and then Has_Discriminants (Full_View (T))
3838 Typ := Full_View (T);
3843 -- If the allocated object will be constrained by the
3844 -- default values for discriminants, then build a subtype
3845 -- with those defaults, and change the allocated subtype
3846 -- to that. Note that this happens in fewer cases in Ada
3849 if not Is_Constrained (Typ)
3850 and then Present (Discriminant_Default_Value
3851 (First_Discriminant (Typ)))
3852 and then (Ada_Version < Ada_2005
3854 not Has_Constrained_Partial_View (Typ))
3856 Typ := Build_Default_Subtype (Typ, N);
3857 Set_Expression (N, New_Reference_To (Typ, Loc));
3860 Discr := First_Elmt (Discriminant_Constraint (Typ));
3861 while Present (Discr) loop
3862 Nod := Node (Discr);
3863 Append (New_Copy_Tree (Node (Discr)), Args);
3865 -- AI-416: when the discriminant constraint is an
3866 -- anonymous access type make sure an accessibility
3867 -- check is inserted if necessary (3.10.2(22.q/2))
3869 if Ada_Version >= Ada_2005
3871 Ekind (Etype (Nod)) = E_Anonymous_Access_Type
3873 Apply_Accessibility_Check
3874 (Nod, Typ, Insert_Node => Nod);
3882 -- We set the allocator as analyzed so that when we analyze the
3883 -- expression actions node, we do not get an unwanted recursive
3884 -- expansion of the allocator expression.
3886 Set_Analyzed (N, True);
3887 Nod := Relocate_Node (N);
3889 -- Here is the transformation:
3890 -- input: new Ctrl_Typ
3891 -- output: Temp : constant Ctrl_Typ_Ptr := new Ctrl_Typ;
3892 -- Ctrl_TypIP (Temp.all, ...);
3893 -- [Deep_]Initialize (Temp.all);
3895 -- Here Ctrl_Typ_Ptr is the pointer type for the allocator, and
3896 -- is the subtype of the allocator.
3899 Make_Object_Declaration (Loc,
3900 Defining_Identifier => Temp,
3901 Constant_Present => True,
3902 Object_Definition => New_Reference_To (Temp_Type, Loc),
3905 Set_Assignment_OK (Temp_Decl);
3906 Insert_Action (N, Temp_Decl, Suppress => All_Checks);
3908 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
3910 -- If the designated type is a task type or contains tasks,
3911 -- create block to activate created tasks, and insert
3912 -- declaration for Task_Image variable ahead of call.
3914 if Has_Task (T) then
3916 L : constant List_Id := New_List;
3919 Build_Task_Allocate_Block (L, Nod, Args);
3921 Insert_List_Before (First (Declarations (Blk)), Decls);
3922 Insert_Actions (N, L);
3927 Make_Procedure_Call_Statement (Loc,
3928 Name => New_Reference_To (Init, Loc),
3929 Parameter_Associations => Args));
3932 if Needs_Finalization (T) then
3935 -- [Deep_]Initialize (Init_Arg1);
3939 (Obj_Ref => New_Copy_Tree (Init_Arg1),
3942 if Present (Finalization_Master (PtrT)) then
3944 -- Special processing for .NET/JVM, the allocated object
3945 -- is attached to the finalization master. Generate:
3947 -- Attach (<PtrT>FM, Root_Controlled_Ptr (Init_Arg1));
3949 -- Types derived from [Limited_]Controlled are the only
3950 -- ones considered since they have fields Prev and Next.
3952 if VM_Target /= No_VM then
3953 if Is_Controlled (T) then
3956 (Obj_Ref => New_Copy_Tree (Init_Arg1),
3960 -- Default case, generate:
3962 -- Set_Finalize_Address
3963 -- (<PtrT>FM, <T>FD'Unrestricted_Access);
3965 -- Do not generate the above for CodePeer compilations
3966 -- because primitive Finalize_Address is never built.
3968 elsif not CodePeer_Mode then
3970 Make_Set_Finalize_Address_Call
3978 Rewrite (N, New_Reference_To (Temp, Loc));
3979 Analyze_And_Resolve (N, PtrT);
3984 -- Ada 2005 (AI-251): If the allocator is for a class-wide interface
3985 -- object that has been rewritten as a reference, we displace "this"
3986 -- to reference properly its secondary dispatch table.
3988 if Nkind (N) = N_Identifier
3989 and then Is_Interface (Dtyp)
3991 Displace_Allocator_Pointer (N);
3995 when RE_Not_Available =>
3997 end Expand_N_Allocator;
3999 -----------------------
4000 -- Expand_N_And_Then --
4001 -----------------------
4003 procedure Expand_N_And_Then (N : Node_Id)
4004 renames Expand_Short_Circuit_Operator;
4006 ------------------------------
4007 -- Expand_N_Case_Expression --
4008 ------------------------------
4010 procedure Expand_N_Case_Expression (N : Node_Id) is
4011 Loc : constant Source_Ptr := Sloc (N);
4012 Typ : constant Entity_Id := Etype (N);
4024 -- case X is when A => AX, when B => BX ...
4039 -- However, this expansion is wrong for limited types, and also
4040 -- wrong for unconstrained types (since the bounds may not be the
4041 -- same in all branches). Furthermore it involves an extra copy
4042 -- for large objects. So we take care of this by using the following
4043 -- modified expansion for non-scalar types:
4046 -- type Pnn is access all typ;
4050 -- T := AX'Unrestricted_Access;
4052 -- T := BX'Unrestricted_Access;
4058 Make_Case_Statement (Loc,
4059 Expression => Expression (N),
4060 Alternatives => New_List);
4062 Actions := New_List;
4066 if Is_Scalar_Type (Typ) then
4070 Pnn := Make_Temporary (Loc, 'P');
4072 Make_Full_Type_Declaration (Loc,
4073 Defining_Identifier => Pnn,
4075 Make_Access_To_Object_Definition (Loc,
4076 All_Present => True,
4077 Subtype_Indication =>
4078 New_Reference_To (Typ, Loc))));
4082 Tnn := Make_Temporary (Loc, 'T');
4084 Make_Object_Declaration (Loc,
4085 Defining_Identifier => Tnn,
4086 Object_Definition => New_Occurrence_Of (Ttyp, Loc)));
4088 -- Now process the alternatives
4090 Alt := First (Alternatives (N));
4091 while Present (Alt) loop
4093 Aexp : Node_Id := Expression (Alt);
4094 Aloc : constant Source_Ptr := Sloc (Aexp);
4097 -- Propagate declarations inserted in the node by Insert_Actions
4098 -- (for example, temporaries generated to remove side effects).
4100 Append_List_To (Actions, Sinfo.Actions (Alt));
4102 if not Is_Scalar_Type (Typ) then
4104 Make_Attribute_Reference (Aloc,
4105 Prefix => Relocate_Node (Aexp),
4106 Attribute_Name => Name_Unrestricted_Access);
4110 (Alternatives (Cstmt),
4111 Make_Case_Statement_Alternative (Sloc (Alt),
4112 Discrete_Choices => Discrete_Choices (Alt),
4113 Statements => New_List (
4114 Make_Assignment_Statement (Aloc,
4115 Name => New_Occurrence_Of (Tnn, Loc),
4116 Expression => Aexp))));
4122 Append_To (Actions, Cstmt);
4124 -- Construct and return final expression with actions
4126 if Is_Scalar_Type (Typ) then
4127 Fexp := New_Occurrence_Of (Tnn, Loc);
4130 Make_Explicit_Dereference (Loc,
4131 Prefix => New_Occurrence_Of (Tnn, Loc));
4135 Make_Expression_With_Actions (Loc,
4137 Actions => Actions));
4139 Analyze_And_Resolve (N, Typ);
4140 end Expand_N_Case_Expression;
4142 -------------------------------------
4143 -- Expand_N_Conditional_Expression --
4144 -------------------------------------
4146 -- Deal with limited types and expression actions
4148 procedure Expand_N_Conditional_Expression (N : Node_Id) is
4149 Loc : constant Source_Ptr := Sloc (N);
4150 Cond : constant Node_Id := First (Expressions (N));
4151 Thenx : constant Node_Id := Next (Cond);
4152 Elsex : constant Node_Id := Next (Thenx);
4153 Typ : constant Entity_Id := Etype (N);
4164 -- Fold at compile time if condition known. We have already folded
4165 -- static conditional expressions, but it is possible to fold any
4166 -- case in which the condition is known at compile time, even though
4167 -- the result is non-static.
4169 -- Note that we don't do the fold of such cases in Sem_Elab because
4170 -- it can cause infinite loops with the expander adding a conditional
4171 -- expression, and Sem_Elab circuitry removing it repeatedly.
4173 if Compile_Time_Known_Value (Cond) then
4174 if Is_True (Expr_Value (Cond)) then
4176 Actions := Then_Actions (N);
4179 Actions := Else_Actions (N);
4184 if Present (Actions) then
4186 -- If we are not allowed to use Expression_With_Actions, just
4187 -- skip the optimization, it is not critical for correctness.
4189 if not Use_Expression_With_Actions then
4190 goto Skip_Optimization;
4194 Make_Expression_With_Actions (Loc,
4195 Expression => Relocate_Node (Expr),
4196 Actions => Actions));
4197 Analyze_And_Resolve (N, Typ);
4200 Rewrite (N, Relocate_Node (Expr));
4203 -- Note that the result is never static (legitimate cases of static
4204 -- conditional expressions were folded in Sem_Eval).
4206 Set_Is_Static_Expression (N, False);
4210 <<Skip_Optimization>>
4212 -- If the type is limited or unconstrained, we expand as follows to
4213 -- avoid any possibility of improper copies.
4215 -- Note: it may be possible to avoid this special processing if the
4216 -- back end uses its own mechanisms for handling by-reference types ???
4218 -- type Ptr is access all Typ;
4222 -- Cnn := then-expr'Unrestricted_Access;
4225 -- Cnn := else-expr'Unrestricted_Access;
4228 -- and replace the conditional expression by a reference to Cnn.all.
4230 -- This special case can be skipped if the back end handles limited
4231 -- types properly and ensures that no incorrect copies are made.
4233 if Is_By_Reference_Type (Typ)
4234 and then not Back_End_Handles_Limited_Types
4236 Cnn := Make_Temporary (Loc, 'C', N);
4239 Make_Full_Type_Declaration (Loc,
4240 Defining_Identifier =>
4241 Make_Temporary (Loc, 'A'),
4243 Make_Access_To_Object_Definition (Loc,
4244 All_Present => True,
4245 Subtype_Indication => New_Reference_To (Typ, Loc)));
4247 Insert_Action (N, P_Decl);
4250 Make_Object_Declaration (Loc,
4251 Defining_Identifier => Cnn,
4252 Object_Definition =>
4253 New_Occurrence_Of (Defining_Identifier (P_Decl), Loc));
4256 Make_Implicit_If_Statement (N,
4257 Condition => Relocate_Node (Cond),
4259 Then_Statements => New_List (
4260 Make_Assignment_Statement (Sloc (Thenx),
4261 Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
4263 Make_Attribute_Reference (Loc,
4264 Attribute_Name => Name_Unrestricted_Access,
4265 Prefix => Relocate_Node (Thenx)))),
4267 Else_Statements => New_List (
4268 Make_Assignment_Statement (Sloc (Elsex),
4269 Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
4271 Make_Attribute_Reference (Loc,
4272 Attribute_Name => Name_Unrestricted_Access,
4273 Prefix => Relocate_Node (Elsex)))));
4276 Make_Explicit_Dereference (Loc,
4277 Prefix => New_Occurrence_Of (Cnn, Loc));
4279 -- For other types, we only need to expand if there are other actions
4280 -- associated with either branch.
4282 elsif Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
4284 -- We have two approaches to handling this. If we are allowed to use
4285 -- N_Expression_With_Actions, then we can just wrap the actions into
4286 -- the appropriate expression.
4288 if Use_Expression_With_Actions then
4289 if Present (Then_Actions (N)) then
4291 Make_Expression_With_Actions (Sloc (Thenx),
4292 Actions => Then_Actions (N),
4293 Expression => Relocate_Node (Thenx)));
4294 Set_Then_Actions (N, No_List);
4295 Analyze_And_Resolve (Thenx, Typ);
4298 if Present (Else_Actions (N)) then
4300 Make_Expression_With_Actions (Sloc (Elsex),
4301 Actions => Else_Actions (N),
4302 Expression => Relocate_Node (Elsex)));
4303 Set_Else_Actions (N, No_List);
4304 Analyze_And_Resolve (Elsex, Typ);
4309 -- if we can't use N_Expression_With_Actions nodes, then we insert
4310 -- the following sequence of actions (using Insert_Actions):
4315 -- Cnn := then-expr;
4321 -- and replace the conditional expression by a reference to Cnn
4324 Cnn := Make_Temporary (Loc, 'C', N);
4327 Make_Object_Declaration (Loc,
4328 Defining_Identifier => Cnn,
4329 Object_Definition => New_Occurrence_Of (Typ, Loc));
4332 Make_Implicit_If_Statement (N,
4333 Condition => Relocate_Node (Cond),
4335 Then_Statements => New_List (
4336 Make_Assignment_Statement (Sloc (Thenx),
4337 Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
4338 Expression => Relocate_Node (Thenx))),
4340 Else_Statements => New_List (
4341 Make_Assignment_Statement (Sloc (Elsex),
4342 Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
4343 Expression => Relocate_Node (Elsex))));
4345 Set_Assignment_OK (Name (First (Then_Statements (New_If))));
4346 Set_Assignment_OK (Name (First (Else_Statements (New_If))));
4348 New_N := New_Occurrence_Of (Cnn, Loc);
4351 -- If no actions then no expansion needed, gigi will handle it using
4352 -- the same approach as a C conditional expression.
4358 -- Fall through here for either the limited expansion, or the case of
4359 -- inserting actions for non-limited types. In both these cases, we must
4360 -- move the SLOC of the parent If statement to the newly created one and
4361 -- change it to the SLOC of the expression which, after expansion, will
4362 -- correspond to what is being evaluated.
4364 if Present (Parent (N))
4365 and then Nkind (Parent (N)) = N_If_Statement
4367 Set_Sloc (New_If, Sloc (Parent (N)));
4368 Set_Sloc (Parent (N), Loc);
4371 -- Make sure Then_Actions and Else_Actions are appropriately moved
4372 -- to the new if statement.
4374 if Present (Then_Actions (N)) then
4376 (First (Then_Statements (New_If)), Then_Actions (N));
4379 if Present (Else_Actions (N)) then
4381 (First (Else_Statements (New_If)), Else_Actions (N));
4384 Insert_Action (N, Decl);
4385 Insert_Action (N, New_If);
4387 Analyze_And_Resolve (N, Typ);
4388 end Expand_N_Conditional_Expression;
4390 -----------------------------------
4391 -- Expand_N_Explicit_Dereference --
4392 -----------------------------------
4394 procedure Expand_N_Explicit_Dereference (N : Node_Id) is
4396 -- Insert explicit dereference call for the checked storage pool case
4398 Insert_Dereference_Action (Prefix (N));
4399 end Expand_N_Explicit_Dereference;
4401 --------------------------------------
4402 -- Expand_N_Expression_With_Actions --
4403 --------------------------------------
4405 procedure Expand_N_Expression_With_Actions (N : Node_Id) is
4407 procedure Process_Transient_Object (Decl : Node_Id);
4408 -- Given the declaration of a controlled transient declared inside the
4409 -- Actions list of an Expression_With_Actions, generate all necessary
4410 -- types and hooks in order to properly finalize the transient. This
4411 -- mechanism works in conjunction with Build_Finalizer.
4413 ------------------------------
4414 -- Process_Transient_Object --
4415 ------------------------------
4417 procedure Process_Transient_Object (Decl : Node_Id) is
4419 function Find_Insertion_Node return Node_Id;
4420 -- Complex if statements may be converted into nested EWAs. In this
4421 -- case, any generated code must be inserted before the if statement
4422 -- to ensure proper visibility of the "hook" objects. This routine
4423 -- returns the top most short circuit operator or the parent of the
4424 -- EWA if no nesting was detected.
4426 -------------------------
4427 -- Find_Insertion_Node --
4428 -------------------------
4430 function Find_Insertion_Node return Node_Id is
4434 -- Climb up the branches of a complex if statement
4436 while Nkind_In (Parent (Par), N_And_Then, N_Op_Not, N_Or_Else) loop
4437 Par := Parent (Par);
4441 end Find_Insertion_Node;
4443 Ins_Nod : constant Node_Id := Find_Insertion_Node;
4444 Loc : constant Source_Ptr := Sloc (Decl);
4445 Obj_Id : constant Entity_Id := Defining_Identifier (Decl);
4446 Obj_Typ : constant Entity_Id := Etype (Obj_Id);
4447 Desig_Typ : Entity_Id;
4451 Temp_Decl : Node_Id;
4455 -- Step 1: Create the access type which provides a reference to
4456 -- the transient object.
4458 if Is_Access_Type (Obj_Typ) then
4459 Desig_Typ := Directly_Designated_Type (Obj_Typ);
4461 Desig_Typ := Obj_Typ;
4465 -- Ann : access [all] <Desig_Typ>;
4467 Ptr_Id := Make_Temporary (Loc, 'A');
4470 Make_Full_Type_Declaration (Loc,
4471 Defining_Identifier => Ptr_Id,
4473 Make_Access_To_Object_Definition (Loc,
4475 Ekind (Obj_Typ) = E_General_Access_Type,
4476 Subtype_Indication => New_Reference_To (Desig_Typ, Loc)));
4478 Insert_Action (Ins_Nod, Ptr_Decl);
4481 -- Step 2: Create a temporary which acts as a hook to the transient
4482 -- object. Generate:
4484 -- Temp : Ptr_Id := null;
4486 Temp_Id := Make_Temporary (Loc, 'T');
4489 Make_Object_Declaration (Loc,
4490 Defining_Identifier => Temp_Id,
4491 Object_Definition => New_Reference_To (Ptr_Id, Loc));
4493 Insert_Action (Ins_Nod, Temp_Decl);
4494 Analyze (Temp_Decl);
4496 -- Mark this temporary as created for the purposes of "exporting" the
4497 -- transient declaration out of the Actions list. This signals the
4498 -- machinery in Build_Finalizer to recognize this special case.
4500 Set_Return_Flag_Or_Transient_Decl (Temp_Id, Decl);
4502 -- Step 3: "Hook" the transient object to the temporary
4504 if Is_Access_Type (Obj_Typ) then
4505 Expr := Convert_To (Ptr_Id, New_Reference_To (Obj_Id, Loc));
4508 Make_Attribute_Reference (Loc,
4509 Prefix => New_Reference_To (Obj_Id, Loc),
4510 Attribute_Name => Name_Unrestricted_Access);
4514 -- Temp := Ptr_Id (Obj_Id);
4516 -- Temp := Obj_Id'Unrestricted_Access;
4518 Insert_After_And_Analyze (Decl,
4519 Make_Assignment_Statement (Loc,
4520 Name => New_Reference_To (Temp_Id, Loc),
4521 Expression => Expr));
4522 end Process_Transient_Object;
4526 -- Start of processing for Expand_N_Expression_With_Actions
4529 Decl := First (Actions (N));
4530 while Present (Decl) loop
4531 if Nkind (Decl) = N_Object_Declaration
4532 and then Is_Finalizable_Transient (Decl, N)
4534 Process_Transient_Object (Decl);
4539 end Expand_N_Expression_With_Actions;
4545 procedure Expand_N_In (N : Node_Id) is
4546 Loc : constant Source_Ptr := Sloc (N);
4547 Restyp : constant Entity_Id := Etype (N);
4548 Lop : constant Node_Id := Left_Opnd (N);
4549 Rop : constant Node_Id := Right_Opnd (N);
4550 Static : constant Boolean := Is_OK_Static_Expression (N);
4555 procedure Expand_Set_Membership;
4556 -- For each choice we create a simple equality or membership test.
4557 -- The whole membership is rewritten connecting these with OR ELSE.
4559 ---------------------------
4560 -- Expand_Set_Membership --
4561 ---------------------------
4563 procedure Expand_Set_Membership is
4567 function Make_Cond (Alt : Node_Id) return Node_Id;
4568 -- If the alternative is a subtype mark, create a simple membership
4569 -- test. Otherwise create an equality test for it.
4575 function Make_Cond (Alt : Node_Id) return Node_Id is
4577 L : constant Node_Id := New_Copy (Lop);
4578 R : constant Node_Id := Relocate_Node (Alt);
4581 if (Is_Entity_Name (Alt) and then Is_Type (Entity (Alt)))
4582 or else Nkind (Alt) = N_Range
4585 Make_In (Sloc (Alt),
4590 Make_Op_Eq (Sloc (Alt),
4598 -- Start of processing for Expand_Set_Membership
4601 Alt := Last (Alternatives (N));
4602 Res := Make_Cond (Alt);
4605 while Present (Alt) loop
4607 Make_Or_Else (Sloc (Alt),
4608 Left_Opnd => Make_Cond (Alt),
4614 Analyze_And_Resolve (N, Standard_Boolean);
4615 end Expand_Set_Membership;
4617 procedure Substitute_Valid_Check;
4618 -- Replaces node N by Lop'Valid. This is done when we have an explicit
4619 -- test for the left operand being in range of its subtype.
4621 ----------------------------
4622 -- Substitute_Valid_Check --
4623 ----------------------------
4625 procedure Substitute_Valid_Check is
4628 Make_Attribute_Reference (Loc,
4629 Prefix => Relocate_Node (Lop),
4630 Attribute_Name => Name_Valid));
4632 Analyze_And_Resolve (N, Restyp);
4634 Error_Msg_N ("?explicit membership test may be optimized away", N);
4635 Error_Msg_N -- CODEFIX
4636 ("\?use ''Valid attribute instead", N);
4638 end Substitute_Valid_Check;
4640 -- Start of processing for Expand_N_In
4643 -- If set membership case, expand with separate procedure
4645 if Present (Alternatives (N)) then
4646 Remove_Side_Effects (Lop);
4647 Expand_Set_Membership;
4651 -- Not set membership, proceed with expansion
4653 Ltyp := Etype (Left_Opnd (N));
4654 Rtyp := Etype (Right_Opnd (N));
4656 -- Check case of explicit test for an expression in range of its
4657 -- subtype. This is suspicious usage and we replace it with a 'Valid
4658 -- test and give a warning. For floating point types however, this is a
4659 -- standard way to check for finite numbers, and using 'Valid would
4660 -- typically be a pessimization. Also skip this test for predicated
4661 -- types, since it is perfectly reasonable to check if a value meets
4664 if Is_Scalar_Type (Ltyp)
4665 and then not Is_Floating_Point_Type (Ltyp)
4666 and then Nkind (Rop) in N_Has_Entity
4667 and then Ltyp = Entity (Rop)
4668 and then Comes_From_Source (N)
4669 and then VM_Target = No_VM
4670 and then not (Is_Discrete_Type (Ltyp)
4671 and then Present (Predicate_Function (Ltyp)))
4673 Substitute_Valid_Check;
4677 -- Do validity check on operands
4679 if Validity_Checks_On and Validity_Check_Operands then
4680 Ensure_Valid (Left_Opnd (N));
4681 Validity_Check_Range (Right_Opnd (N));
4684 -- Case of explicit range
4686 if Nkind (Rop) = N_Range then
4688 Lo : constant Node_Id := Low_Bound (Rop);
4689 Hi : constant Node_Id := High_Bound (Rop);
4691 Lo_Orig : constant Node_Id := Original_Node (Lo);
4692 Hi_Orig : constant Node_Id := Original_Node (Hi);
4694 Lcheck : Compare_Result;
4695 Ucheck : Compare_Result;
4697 Warn1 : constant Boolean :=
4698 Constant_Condition_Warnings
4699 and then Comes_From_Source (N)
4700 and then not In_Instance;
4701 -- This must be true for any of the optimization warnings, we
4702 -- clearly want to give them only for source with the flag on. We
4703 -- also skip these warnings in an instance since it may be the
4704 -- case that different instantiations have different ranges.
4706 Warn2 : constant Boolean :=
4708 and then Nkind (Original_Node (Rop)) = N_Range
4709 and then Is_Integer_Type (Etype (Lo));
4710 -- For the case where only one bound warning is elided, we also
4711 -- insist on an explicit range and an integer type. The reason is
4712 -- that the use of enumeration ranges including an end point is
4713 -- common, as is the use of a subtype name, one of whose bounds is
4714 -- the same as the type of the expression.
4717 -- If test is explicit x'First .. x'Last, replace by valid check
4719 -- Could use some individual comments for this complex test ???
4721 if Is_Scalar_Type (Ltyp)
4722 and then Nkind (Lo_Orig) = N_Attribute_Reference
4723 and then Attribute_Name (Lo_Orig) = Name_First
4724 and then Nkind (Prefix (Lo_Orig)) in N_Has_Entity
4725 and then Entity (Prefix (Lo_Orig)) = Ltyp
4726 and then Nkind (Hi_Orig) = N_Attribute_Reference
4727 and then Attribute_Name (Hi_Orig) = Name_Last
4728 and then Nkind (Prefix (Hi_Orig)) in N_Has_Entity
4729 and then Entity (Prefix (Hi_Orig)) = Ltyp
4730 and then Comes_From_Source (N)
4731 and then VM_Target = No_VM
4733 Substitute_Valid_Check;
4737 -- If bounds of type are known at compile time, and the end points
4738 -- are known at compile time and identical, this is another case
4739 -- for substituting a valid test. We only do this for discrete
4740 -- types, since it won't arise in practice for float types.
4742 if Comes_From_Source (N)
4743 and then Is_Discrete_Type (Ltyp)
4744 and then Compile_Time_Known_Value (Type_High_Bound (Ltyp))
4745 and then Compile_Time_Known_Value (Type_Low_Bound (Ltyp))
4746 and then Compile_Time_Known_Value (Lo)
4747 and then Compile_Time_Known_Value (Hi)
4748 and then Expr_Value (Type_High_Bound (Ltyp)) = Expr_Value (Hi)
4749 and then Expr_Value (Type_Low_Bound (Ltyp)) = Expr_Value (Lo)
4751 -- Kill warnings in instances, since they may be cases where we
4752 -- have a test in the generic that makes sense with some types
4753 -- and not with other types.
4755 and then not In_Instance
4757 Substitute_Valid_Check;
4761 -- If we have an explicit range, do a bit of optimization based on
4762 -- range analysis (we may be able to kill one or both checks).
4764 Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => False);
4765 Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => False);
4767 -- If either check is known to fail, replace result by False since
4768 -- the other check does not matter. Preserve the static flag for
4769 -- legality checks, because we are constant-folding beyond RM 4.9.
4771 if Lcheck = LT or else Ucheck = GT then
4773 Error_Msg_N ("?range test optimized away", N);
4774 Error_Msg_N ("\?value is known to be out of range", N);
4777 Rewrite (N, New_Reference_To (Standard_False, Loc));
4778 Analyze_And_Resolve (N, Restyp);
4779 Set_Is_Static_Expression (N, Static);
4782 -- If both checks are known to succeed, replace result by True,
4783 -- since we know we are in range.
4785 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
4787 Error_Msg_N ("?range test optimized away", N);
4788 Error_Msg_N ("\?value is known to be in range", N);
4791 Rewrite (N, New_Reference_To (Standard_True, Loc));
4792 Analyze_And_Resolve (N, Restyp);
4793 Set_Is_Static_Expression (N, Static);
4796 -- If lower bound check succeeds and upper bound check is not
4797 -- known to succeed or fail, then replace the range check with
4798 -- a comparison against the upper bound.
4800 elsif Lcheck in Compare_GE then
4801 if Warn2 and then not In_Instance then
4802 Error_Msg_N ("?lower bound test optimized away", Lo);
4803 Error_Msg_N ("\?value is known to be in range", Lo);
4809 Right_Opnd => High_Bound (Rop)));
4810 Analyze_And_Resolve (N, Restyp);
4813 -- If upper bound check succeeds and lower bound check is not
4814 -- known to succeed or fail, then replace the range check with
4815 -- a comparison against the lower bound.
4817 elsif Ucheck in Compare_LE then
4818 if Warn2 and then not In_Instance then
4819 Error_Msg_N ("?upper bound test optimized away", Hi);
4820 Error_Msg_N ("\?value is known to be in range", Hi);
4826 Right_Opnd => Low_Bound (Rop)));
4827 Analyze_And_Resolve (N, Restyp);
4831 -- We couldn't optimize away the range check, but there is one
4832 -- more issue. If we are checking constant conditionals, then we
4833 -- see if we can determine the outcome assuming everything is
4834 -- valid, and if so give an appropriate warning.
4836 if Warn1 and then not Assume_No_Invalid_Values then
4837 Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => True);
4838 Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => True);
4840 -- Result is out of range for valid value
4842 if Lcheck = LT or else Ucheck = GT then
4844 ("?value can only be in range if it is invalid", N);
4846 -- Result is in range for valid value
4848 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
4850 ("?value can only be out of range if it is invalid", N);
4852 -- Lower bound check succeeds if value is valid
4854 elsif Warn2 and then Lcheck in Compare_GE then
4856 ("?lower bound check only fails if it is invalid", Lo);
4858 -- Upper bound check succeeds if value is valid
4860 elsif Warn2 and then Ucheck in Compare_LE then
4862 ("?upper bound check only fails for invalid values", Hi);
4867 -- For all other cases of an explicit range, nothing to be done
4871 -- Here right operand is a subtype mark
4875 Typ : Entity_Id := Etype (Rop);
4876 Is_Acc : constant Boolean := Is_Access_Type (Typ);
4877 Cond : Node_Id := Empty;
4879 Obj : Node_Id := Lop;
4880 SCIL_Node : Node_Id;
4883 Remove_Side_Effects (Obj);
4885 -- For tagged type, do tagged membership operation
4887 if Is_Tagged_Type (Typ) then
4889 -- No expansion will be performed when VM_Target, as the VM
4890 -- back-ends will handle the membership tests directly (tags
4891 -- are not explicitly represented in Java objects, so the
4892 -- normal tagged membership expansion is not what we want).
4894 if Tagged_Type_Expansion then
4895 Tagged_Membership (N, SCIL_Node, New_N);
4897 Analyze_And_Resolve (N, Restyp);
4899 -- Update decoration of relocated node referenced by the
4902 if Generate_SCIL and then Present (SCIL_Node) then
4903 Set_SCIL_Node (N, SCIL_Node);
4909 -- If type is scalar type, rewrite as x in t'First .. t'Last.
4910 -- This reason we do this is that the bounds may have the wrong
4911 -- type if they come from the original type definition. Also this
4912 -- way we get all the processing above for an explicit range.
4914 -- Don't do this for predicated types, since in this case we
4915 -- want to check the predicate!
4917 elsif Is_Scalar_Type (Typ) then
4918 if No (Predicate_Function (Typ)) then
4922 Make_Attribute_Reference (Loc,
4923 Attribute_Name => Name_First,
4924 Prefix => New_Reference_To (Typ, Loc)),
4927 Make_Attribute_Reference (Loc,
4928 Attribute_Name => Name_Last,
4929 Prefix => New_Reference_To (Typ, Loc))));
4930 Analyze_And_Resolve (N, Restyp);
4935 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
4936 -- a membership test if the subtype mark denotes a constrained
4937 -- Unchecked_Union subtype and the expression lacks inferable
4940 elsif Is_Unchecked_Union (Base_Type (Typ))
4941 and then Is_Constrained (Typ)
4942 and then not Has_Inferable_Discriminants (Lop)
4945 Make_Raise_Program_Error (Loc,
4946 Reason => PE_Unchecked_Union_Restriction));
4948 -- Prevent Gigi from generating incorrect code by rewriting the
4951 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
4955 -- Here we have a non-scalar type
4958 Typ := Designated_Type (Typ);
4961 if not Is_Constrained (Typ) then
4962 Rewrite (N, New_Reference_To (Standard_True, Loc));
4963 Analyze_And_Resolve (N, Restyp);
4965 -- For the constrained array case, we have to check the subscripts
4966 -- for an exact match if the lengths are non-zero (the lengths
4967 -- must match in any case).
4969 elsif Is_Array_Type (Typ) then
4970 Check_Subscripts : declare
4971 function Build_Attribute_Reference
4974 Dim : Nat) return Node_Id;
4975 -- Build attribute reference E'Nam (Dim)
4977 -------------------------------
4978 -- Build_Attribute_Reference --
4979 -------------------------------
4981 function Build_Attribute_Reference
4984 Dim : Nat) return Node_Id
4988 Make_Attribute_Reference (Loc,
4990 Attribute_Name => Nam,
4991 Expressions => New_List (
4992 Make_Integer_Literal (Loc, Dim)));
4993 end Build_Attribute_Reference;
4995 -- Start of processing for Check_Subscripts
4998 for J in 1 .. Number_Dimensions (Typ) loop
4999 Evolve_And_Then (Cond,
5002 Build_Attribute_Reference
5003 (Duplicate_Subexpr_No_Checks (Obj),
5006 Build_Attribute_Reference
5007 (New_Occurrence_Of (Typ, Loc), Name_First, J)));
5009 Evolve_And_Then (Cond,
5012 Build_Attribute_Reference
5013 (Duplicate_Subexpr_No_Checks (Obj),
5016 Build_Attribute_Reference
5017 (New_Occurrence_Of (Typ, Loc), Name_Last, J)));
5026 Right_Opnd => Make_Null (Loc)),
5027 Right_Opnd => Cond);
5031 Analyze_And_Resolve (N, Restyp);
5032 end Check_Subscripts;
5034 -- These are the cases where constraint checks may be required,
5035 -- e.g. records with possible discriminants
5038 -- Expand the test into a series of discriminant comparisons.
5039 -- The expression that is built is the negation of the one that
5040 -- is used for checking discriminant constraints.
5042 Obj := Relocate_Node (Left_Opnd (N));
5044 if Has_Discriminants (Typ) then
5045 Cond := Make_Op_Not (Loc,
5046 Right_Opnd => Build_Discriminant_Checks (Obj, Typ));
5049 Cond := Make_Or_Else (Loc,
5053 Right_Opnd => Make_Null (Loc)),
5054 Right_Opnd => Cond);
5058 Cond := New_Occurrence_Of (Standard_True, Loc);
5062 Analyze_And_Resolve (N, Restyp);
5065 -- Ada 2012 (AI05-0149): Handle membership tests applied to an
5066 -- expression of an anonymous access type. This can involve an
5067 -- accessibility test and a tagged type membership test in the
5068 -- case of tagged designated types.
5070 if Ada_Version >= Ada_2012
5072 and then Ekind (Ltyp) = E_Anonymous_Access_Type
5075 Expr_Entity : Entity_Id := Empty;
5077 Param_Level : Node_Id;
5078 Type_Level : Node_Id;
5081 if Is_Entity_Name (Lop) then
5082 Expr_Entity := Param_Entity (Lop);
5084 if not Present (Expr_Entity) then
5085 Expr_Entity := Entity (Lop);
5089 -- If a conversion of the anonymous access value to the
5090 -- tested type would be illegal, then the result is False.
5092 if not Valid_Conversion
5093 (Lop, Rtyp, Lop, Report_Errs => False)
5095 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
5096 Analyze_And_Resolve (N, Restyp);
5098 -- Apply an accessibility check if the access object has an
5099 -- associated access level and when the level of the type is
5100 -- less deep than the level of the access parameter. This
5101 -- only occur for access parameters and stand-alone objects
5102 -- of an anonymous access type.
5105 if Present (Expr_Entity)
5108 (Effective_Extra_Accessibility (Expr_Entity))
5109 and then UI_Gt (Object_Access_Level (Lop),
5110 Type_Access_Level (Rtyp))
5114 (Effective_Extra_Accessibility (Expr_Entity), Loc);
5117 Make_Integer_Literal (Loc, Type_Access_Level (Rtyp));
5119 -- Return True only if the accessibility level of the
5120 -- expression entity is not deeper than the level of
5121 -- the tested access type.
5125 Left_Opnd => Relocate_Node (N),
5126 Right_Opnd => Make_Op_Le (Loc,
5127 Left_Opnd => Param_Level,
5128 Right_Opnd => Type_Level)));
5130 Analyze_And_Resolve (N);
5133 -- If the designated type is tagged, do tagged membership
5136 -- *** NOTE: we have to check not null before doing the
5137 -- tagged membership test (but maybe that can be done
5138 -- inside Tagged_Membership?).
5140 if Is_Tagged_Type (Typ) then
5143 Left_Opnd => Relocate_Node (N),
5147 Right_Opnd => Make_Null (Loc))));
5149 -- No expansion will be performed when VM_Target, as
5150 -- the VM back-ends will handle the membership tests
5151 -- directly (tags are not explicitly represented in
5152 -- Java objects, so the normal tagged membership
5153 -- expansion is not what we want).
5155 if Tagged_Type_Expansion then
5157 -- Note that we have to pass Original_Node, because
5158 -- the membership test might already have been
5159 -- rewritten by earlier parts of membership test.
5162 (Original_Node (N), SCIL_Node, New_N);
5164 -- Update decoration of relocated node referenced
5165 -- by the SCIL node.
5167 if Generate_SCIL and then Present (SCIL_Node) then
5168 Set_SCIL_Node (New_N, SCIL_Node);
5173 Left_Opnd => Relocate_Node (N),
5174 Right_Opnd => New_N));
5176 Analyze_And_Resolve (N, Restyp);
5185 -- At this point, we have done the processing required for the basic
5186 -- membership test, but not yet dealt with the predicate.
5190 -- If a predicate is present, then we do the predicate test, but we
5191 -- most certainly want to omit this if we are within the predicate
5192 -- function itself, since otherwise we have an infinite recursion!
5195 PFunc : constant Entity_Id := Predicate_Function (Rtyp);
5199 and then Current_Scope /= PFunc
5203 Left_Opnd => Relocate_Node (N),
5204 Right_Opnd => Make_Predicate_Call (Rtyp, Lop)));
5206 -- Analyze new expression, mark left operand as analyzed to
5207 -- avoid infinite recursion adding predicate calls.
5209 Set_Analyzed (Left_Opnd (N));
5210 Analyze_And_Resolve (N, Standard_Boolean);
5212 -- All done, skip attempt at compile time determination of result
5219 --------------------------------
5220 -- Expand_N_Indexed_Component --
5221 --------------------------------
5223 procedure Expand_N_Indexed_Component (N : Node_Id) is
5224 Loc : constant Source_Ptr := Sloc (N);
5225 Typ : constant Entity_Id := Etype (N);
5226 P : constant Node_Id := Prefix (N);
5227 T : constant Entity_Id := Etype (P);
5230 -- A special optimization, if we have an indexed component that is
5231 -- selecting from a slice, then we can eliminate the slice, since, for
5232 -- example, x (i .. j)(k) is identical to x(k). The only difference is
5233 -- the range check required by the slice. The range check for the slice
5234 -- itself has already been generated. The range check for the
5235 -- subscripting operation is ensured by converting the subject to
5236 -- the subtype of the slice.
5238 -- This optimization not only generates better code, avoiding slice
5239 -- messing especially in the packed case, but more importantly bypasses
5240 -- some problems in handling this peculiar case, for example, the issue
5241 -- of dealing specially with object renamings.
5243 if Nkind (P) = N_Slice then
5245 Make_Indexed_Component (Loc,
5246 Prefix => Prefix (P),
5247 Expressions => New_List (
5249 (Etype (First_Index (Etype (P))),
5250 First (Expressions (N))))));
5251 Analyze_And_Resolve (N, Typ);
5255 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
5256 -- function, then additional actuals must be passed.
5258 if Ada_Version >= Ada_2005
5259 and then Is_Build_In_Place_Function_Call (P)
5261 Make_Build_In_Place_Call_In_Anonymous_Context (P);
5264 -- If the prefix is an access type, then we unconditionally rewrite if
5265 -- as an explicit dereference. This simplifies processing for several
5266 -- cases, including packed array cases and certain cases in which checks
5267 -- must be generated. We used to try to do this only when it was
5268 -- necessary, but it cleans up the code to do it all the time.
5270 if Is_Access_Type (T) then
5271 Insert_Explicit_Dereference (P);
5272 Analyze_And_Resolve (P, Designated_Type (T));
5275 -- Generate index and validity checks
5277 Generate_Index_Checks (N);
5279 if Validity_Checks_On and then Validity_Check_Subscripts then
5280 Apply_Subscript_Validity_Checks (N);
5283 -- All done for the non-packed case
5285 if not Is_Packed (Etype (Prefix (N))) then
5289 -- For packed arrays that are not bit-packed (i.e. the case of an array
5290 -- with one or more index types with a non-contiguous enumeration type),
5291 -- we can always use the normal packed element get circuit.
5293 if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
5294 Expand_Packed_Element_Reference (N);
5298 -- For a reference to a component of a bit packed array, we have to
5299 -- convert it to a reference to the corresponding Packed_Array_Type.
5300 -- We only want to do this for simple references, and not for:
5302 -- Left side of assignment, or prefix of left side of assignment, or
5303 -- prefix of the prefix, to handle packed arrays of packed arrays,
5304 -- This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
5306 -- Renaming objects in renaming associations
5307 -- This case is handled when a use of the renamed variable occurs
5309 -- Actual parameters for a procedure call
5310 -- This case is handled in Exp_Ch6.Expand_Actuals
5312 -- The second expression in a 'Read attribute reference
5314 -- The prefix of an address or bit or size attribute reference
5316 -- The following circuit detects these exceptions
5319 Child : Node_Id := N;
5320 Parnt : Node_Id := Parent (N);
5324 if Nkind (Parnt) = N_Unchecked_Expression then
5327 elsif Nkind_In (Parnt, N_Object_Renaming_Declaration,
5328 N_Procedure_Call_Statement)
5329 or else (Nkind (Parnt) = N_Parameter_Association
5331 Nkind (Parent (Parnt)) = N_Procedure_Call_Statement)
5335 elsif Nkind (Parnt) = N_Attribute_Reference
5336 and then (Attribute_Name (Parnt) = Name_Address
5338 Attribute_Name (Parnt) = Name_Bit
5340 Attribute_Name (Parnt) = Name_Size)
5341 and then Prefix (Parnt) = Child
5345 elsif Nkind (Parnt) = N_Assignment_Statement
5346 and then Name (Parnt) = Child
5350 -- If the expression is an index of an indexed component, it must
5351 -- be expanded regardless of context.
5353 elsif Nkind (Parnt) = N_Indexed_Component
5354 and then Child /= Prefix (Parnt)
5356 Expand_Packed_Element_Reference (N);
5359 elsif Nkind (Parent (Parnt)) = N_Assignment_Statement
5360 and then Name (Parent (Parnt)) = Parnt
5364 elsif Nkind (Parnt) = N_Attribute_Reference
5365 and then Attribute_Name (Parnt) = Name_Read
5366 and then Next (First (Expressions (Parnt))) = Child
5370 elsif Nkind_In (Parnt, N_Indexed_Component, N_Selected_Component)
5371 and then Prefix (Parnt) = Child
5376 Expand_Packed_Element_Reference (N);
5380 -- Keep looking up tree for unchecked expression, or if we are the
5381 -- prefix of a possible assignment left side.
5384 Parnt := Parent (Child);
5387 end Expand_N_Indexed_Component;
5389 ---------------------
5390 -- Expand_N_Not_In --
5391 ---------------------
5393 -- Replace a not in b by not (a in b) so that the expansions for (a in b)
5394 -- can be done. This avoids needing to duplicate this expansion code.
5396 procedure Expand_N_Not_In (N : Node_Id) is
5397 Loc : constant Source_Ptr := Sloc (N);
5398 Typ : constant Entity_Id := Etype (N);
5399 Cfs : constant Boolean := Comes_From_Source (N);
5406 Left_Opnd => Left_Opnd (N),
5407 Right_Opnd => Right_Opnd (N))));
5409 -- If this is a set membership, preserve list of alternatives
5411 Set_Alternatives (Right_Opnd (N), Alternatives (Original_Node (N)));
5413 -- We want this to appear as coming from source if original does (see
5414 -- transformations in Expand_N_In).
5416 Set_Comes_From_Source (N, Cfs);
5417 Set_Comes_From_Source (Right_Opnd (N), Cfs);
5419 -- Now analyze transformed node
5421 Analyze_And_Resolve (N, Typ);
5422 end Expand_N_Not_In;
5428 -- The only replacement required is for the case of a null of a type that
5429 -- is an access to protected subprogram, or a subtype thereof. We represent
5430 -- such access values as a record, and so we must replace the occurrence of
5431 -- null by the equivalent record (with a null address and a null pointer in
5432 -- it), so that the backend creates the proper value.
5434 procedure Expand_N_Null (N : Node_Id) is
5435 Loc : constant Source_Ptr := Sloc (N);
5436 Typ : constant Entity_Id := Base_Type (Etype (N));
5440 if Is_Access_Protected_Subprogram_Type (Typ) then
5442 Make_Aggregate (Loc,
5443 Expressions => New_List (
5444 New_Occurrence_Of (RTE (RE_Null_Address), Loc),
5448 Analyze_And_Resolve (N, Equivalent_Type (Typ));
5450 -- For subsequent semantic analysis, the node must retain its type.
5451 -- Gigi in any case replaces this type by the corresponding record
5452 -- type before processing the node.
5458 when RE_Not_Available =>
5462 ---------------------
5463 -- Expand_N_Op_Abs --
5464 ---------------------
5466 procedure Expand_N_Op_Abs (N : Node_Id) is
5467 Loc : constant Source_Ptr := Sloc (N);
5468 Expr : constant Node_Id := Right_Opnd (N);
5471 Unary_Op_Validity_Checks (N);
5473 -- Deal with software overflow checking
5475 if not Backend_Overflow_Checks_On_Target
5476 and then Is_Signed_Integer_Type (Etype (N))
5477 and then Do_Overflow_Check (N)
5479 -- The only case to worry about is when the argument is equal to the
5480 -- largest negative number, so what we do is to insert the check:
5482 -- [constraint_error when Expr = typ'Base'First]
5484 -- with the usual Duplicate_Subexpr use coding for expr
5487 Make_Raise_Constraint_Error (Loc,
5490 Left_Opnd => Duplicate_Subexpr (Expr),
5492 Make_Attribute_Reference (Loc,
5494 New_Occurrence_Of (Base_Type (Etype (Expr)), Loc),
5495 Attribute_Name => Name_First)),
5496 Reason => CE_Overflow_Check_Failed));
5499 -- Vax floating-point types case
5501 if Vax_Float (Etype (N)) then
5502 Expand_Vax_Arith (N);
5504 end Expand_N_Op_Abs;
5506 ---------------------
5507 -- Expand_N_Op_Add --
5508 ---------------------
5510 procedure Expand_N_Op_Add (N : Node_Id) is
5511 Typ : constant Entity_Id := Etype (N);
5514 Binary_Op_Validity_Checks (N);
5516 -- N + 0 = 0 + N = N for integer types
5518 if Is_Integer_Type (Typ) then
5519 if Compile_Time_Known_Value (Right_Opnd (N))
5520 and then Expr_Value (Right_Opnd (N)) = Uint_0
5522 Rewrite (N, Left_Opnd (N));
5525 elsif Compile_Time_Known_Value (Left_Opnd (N))
5526 and then Expr_Value (Left_Opnd (N)) = Uint_0
5528 Rewrite (N, Right_Opnd (N));
5533 -- Arithmetic overflow checks for signed integer/fixed point types
5535 if Is_Signed_Integer_Type (Typ)
5536 or else Is_Fixed_Point_Type (Typ)
5538 Apply_Arithmetic_Overflow_Check (N);
5541 -- Vax floating-point types case
5543 elsif Vax_Float (Typ) then
5544 Expand_Vax_Arith (N);
5546 end Expand_N_Op_Add;
5548 ---------------------
5549 -- Expand_N_Op_And --
5550 ---------------------
5552 procedure Expand_N_Op_And (N : Node_Id) is
5553 Typ : constant Entity_Id := Etype (N);
5556 Binary_Op_Validity_Checks (N);
5558 if Is_Array_Type (Etype (N)) then
5559 Expand_Boolean_Operator (N);
5561 elsif Is_Boolean_Type (Etype (N)) then
5563 -- Replace AND by AND THEN if Short_Circuit_And_Or active and the
5564 -- type is standard Boolean (do not mess with AND that uses a non-
5565 -- standard Boolean type, because something strange is going on).
5567 if Short_Circuit_And_Or and then Typ = Standard_Boolean then
5569 Make_And_Then (Sloc (N),
5570 Left_Opnd => Relocate_Node (Left_Opnd (N)),
5571 Right_Opnd => Relocate_Node (Right_Opnd (N))));
5572 Analyze_And_Resolve (N, Typ);
5574 -- Otherwise, adjust conditions
5577 Adjust_Condition (Left_Opnd (N));
5578 Adjust_Condition (Right_Opnd (N));
5579 Set_Etype (N, Standard_Boolean);
5580 Adjust_Result_Type (N, Typ);
5583 elsif Is_Intrinsic_Subprogram (Entity (N)) then
5584 Expand_Intrinsic_Call (N, Entity (N));
5587 end Expand_N_Op_And;
5589 ------------------------
5590 -- Expand_N_Op_Concat --
5591 ------------------------
5593 procedure Expand_N_Op_Concat (N : Node_Id) is
5595 -- List of operands to be concatenated
5598 -- Node which is to be replaced by the result of concatenating the nodes
5599 -- in the list Opnds.
5602 -- Ensure validity of both operands
5604 Binary_Op_Validity_Checks (N);
5606 -- If we are the left operand of a concatenation higher up the tree,
5607 -- then do nothing for now, since we want to deal with a series of
5608 -- concatenations as a unit.
5610 if Nkind (Parent (N)) = N_Op_Concat
5611 and then N = Left_Opnd (Parent (N))
5616 -- We get here with a concatenation whose left operand may be a
5617 -- concatenation itself with a consistent type. We need to process
5618 -- these concatenation operands from left to right, which means
5619 -- from the deepest node in the tree to the highest node.
5622 while Nkind (Left_Opnd (Cnode)) = N_Op_Concat loop
5623 Cnode := Left_Opnd (Cnode);
5626 -- Now Cnode is the deepest concatenation, and its parents are the
5627 -- concatenation nodes above, so now we process bottom up, doing the
5628 -- operations. We gather a string that is as long as possible up to five
5631 -- The outer loop runs more than once if more than one concatenation
5632 -- type is involved.
5635 Opnds := New_List (Left_Opnd (Cnode), Right_Opnd (Cnode));
5636 Set_Parent (Opnds, N);
5638 -- The inner loop gathers concatenation operands
5640 Inner : while Cnode /= N
5641 and then Base_Type (Etype (Cnode)) =
5642 Base_Type (Etype (Parent (Cnode)))
5644 Cnode := Parent (Cnode);
5645 Append (Right_Opnd (Cnode), Opnds);
5648 Expand_Concatenate (Cnode, Opnds);
5650 exit Outer when Cnode = N;
5651 Cnode := Parent (Cnode);
5653 end Expand_N_Op_Concat;
5655 ------------------------
5656 -- Expand_N_Op_Divide --
5657 ------------------------
5659 procedure Expand_N_Op_Divide (N : Node_Id) is
5660 Loc : constant Source_Ptr := Sloc (N);
5661 Lopnd : constant Node_Id := Left_Opnd (N);
5662 Ropnd : constant Node_Id := Right_Opnd (N);
5663 Ltyp : constant Entity_Id := Etype (Lopnd);
5664 Rtyp : constant Entity_Id := Etype (Ropnd);
5665 Typ : Entity_Id := Etype (N);
5666 Rknow : constant Boolean := Is_Integer_Type (Typ)
5668 Compile_Time_Known_Value (Ropnd);
5672 Binary_Op_Validity_Checks (N);
5675 Rval := Expr_Value (Ropnd);
5678 -- N / 1 = N for integer types
5680 if Rknow and then Rval = Uint_1 then
5685 -- Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
5686 -- Is_Power_Of_2_For_Shift is set means that we know that our left
5687 -- operand is an unsigned integer, as required for this to work.
5689 if Nkind (Ropnd) = N_Op_Expon
5690 and then Is_Power_Of_2_For_Shift (Ropnd)
5692 -- We cannot do this transformation in configurable run time mode if we
5693 -- have 64-bit integers and long shifts are not available.
5697 or else Support_Long_Shifts_On_Target)
5700 Make_Op_Shift_Right (Loc,
5703 Convert_To (Standard_Natural, Right_Opnd (Ropnd))));
5704 Analyze_And_Resolve (N, Typ);
5708 -- Do required fixup of universal fixed operation
5710 if Typ = Universal_Fixed then
5711 Fixup_Universal_Fixed_Operation (N);
5715 -- Divisions with fixed-point results
5717 if Is_Fixed_Point_Type (Typ) then
5719 -- No special processing if Treat_Fixed_As_Integer is set, since
5720 -- from a semantic point of view such operations are simply integer
5721 -- operations and will be treated that way.
5723 if not Treat_Fixed_As_Integer (N) then
5724 if Is_Integer_Type (Rtyp) then
5725 Expand_Divide_Fixed_By_Integer_Giving_Fixed (N);
5727 Expand_Divide_Fixed_By_Fixed_Giving_Fixed (N);
5731 -- Other cases of division of fixed-point operands. Again we exclude the
5732 -- case where Treat_Fixed_As_Integer is set.
5734 elsif (Is_Fixed_Point_Type (Ltyp) or else
5735 Is_Fixed_Point_Type (Rtyp))
5736 and then not Treat_Fixed_As_Integer (N)
5738 if Is_Integer_Type (Typ) then
5739 Expand_Divide_Fixed_By_Fixed_Giving_Integer (N);
5741 pragma Assert (Is_Floating_Point_Type (Typ));
5742 Expand_Divide_Fixed_By_Fixed_Giving_Float (N);
5745 -- Mixed-mode operations can appear in a non-static universal context,
5746 -- in which case the integer argument must be converted explicitly.
5748 elsif Typ = Universal_Real
5749 and then Is_Integer_Type (Rtyp)
5752 Convert_To (Universal_Real, Relocate_Node (Ropnd)));
5754 Analyze_And_Resolve (Ropnd, Universal_Real);
5756 elsif Typ = Universal_Real
5757 and then Is_Integer_Type (Ltyp)
5760 Convert_To (Universal_Real, Relocate_Node (Lopnd)));
5762 Analyze_And_Resolve (Lopnd, Universal_Real);
5764 -- Non-fixed point cases, do integer zero divide and overflow checks
5766 elsif Is_Integer_Type (Typ) then
5767 Apply_Divide_Check (N);
5769 -- Deal with Vax_Float
5771 elsif Vax_Float (Typ) then
5772 Expand_Vax_Arith (N);
5775 end Expand_N_Op_Divide;
5777 --------------------
5778 -- Expand_N_Op_Eq --
5779 --------------------
5781 procedure Expand_N_Op_Eq (N : Node_Id) is
5782 Loc : constant Source_Ptr := Sloc (N);
5783 Typ : constant Entity_Id := Etype (N);
5784 Lhs : constant Node_Id := Left_Opnd (N);
5785 Rhs : constant Node_Id := Right_Opnd (N);
5786 Bodies : constant List_Id := New_List;
5787 A_Typ : constant Entity_Id := Etype (Lhs);
5789 Typl : Entity_Id := A_Typ;
5790 Op_Name : Entity_Id;
5793 procedure Build_Equality_Call (Eq : Entity_Id);
5794 -- If a constructed equality exists for the type or for its parent,
5795 -- build and analyze call, adding conversions if the operation is
5798 function Has_Unconstrained_UU_Component (Typ : Node_Id) return Boolean;
5799 -- Determines whether a type has a subcomponent of an unconstrained
5800 -- Unchecked_Union subtype. Typ is a record type.
5802 -------------------------
5803 -- Build_Equality_Call --
5804 -------------------------
5806 procedure Build_Equality_Call (Eq : Entity_Id) is
5807 Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
5808 L_Exp : Node_Id := Relocate_Node (Lhs);
5809 R_Exp : Node_Id := Relocate_Node (Rhs);
5812 if Base_Type (Op_Type) /= Base_Type (A_Typ)
5813 and then not Is_Class_Wide_Type (A_Typ)
5815 L_Exp := OK_Convert_To (Op_Type, L_Exp);
5816 R_Exp := OK_Convert_To (Op_Type, R_Exp);
5819 -- If we have an Unchecked_Union, we need to add the inferred
5820 -- discriminant values as actuals in the function call. At this
5821 -- point, the expansion has determined that both operands have
5822 -- inferable discriminants.
5824 if Is_Unchecked_Union (Op_Type) then
5826 Lhs_Type : constant Node_Id := Etype (L_Exp);
5827 Rhs_Type : constant Node_Id := Etype (R_Exp);
5828 Lhs_Discr_Val : Node_Id;
5829 Rhs_Discr_Val : Node_Id;
5832 -- Per-object constrained selected components require special
5833 -- attention. If the enclosing scope of the component is an
5834 -- Unchecked_Union, we cannot reference its discriminants
5835 -- directly. This is why we use the two extra parameters of
5836 -- the equality function of the enclosing Unchecked_Union.
5838 -- type UU_Type (Discr : Integer := 0) is
5841 -- pragma Unchecked_Union (UU_Type);
5843 -- 1. Unchecked_Union enclosing record:
5845 -- type Enclosing_UU_Type (Discr : Integer := 0) is record
5847 -- Comp : UU_Type (Discr);
5849 -- end Enclosing_UU_Type;
5850 -- pragma Unchecked_Union (Enclosing_UU_Type);
5852 -- Obj1 : Enclosing_UU_Type;
5853 -- Obj2 : Enclosing_UU_Type (1);
5855 -- [. . .] Obj1 = Obj2 [. . .]
5859 -- if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
5861 -- A and B are the formal parameters of the equality function
5862 -- of Enclosing_UU_Type. The function always has two extra
5863 -- formals to capture the inferred discriminant values.
5865 -- 2. Non-Unchecked_Union enclosing record:
5868 -- Enclosing_Non_UU_Type (Discr : Integer := 0)
5871 -- Comp : UU_Type (Discr);
5873 -- end Enclosing_Non_UU_Type;
5875 -- Obj1 : Enclosing_Non_UU_Type;
5876 -- Obj2 : Enclosing_Non_UU_Type (1);
5878 -- ... Obj1 = Obj2 ...
5882 -- if not (uu_typeEQ (obj1.comp, obj2.comp,
5883 -- obj1.discr, obj2.discr)) then
5885 -- In this case we can directly reference the discriminants of
5886 -- the enclosing record.
5890 if Nkind (Lhs) = N_Selected_Component
5891 and then Has_Per_Object_Constraint
5892 (Entity (Selector_Name (Lhs)))
5894 -- Enclosing record is an Unchecked_Union, use formal A
5896 if Is_Unchecked_Union
5897 (Scope (Entity (Selector_Name (Lhs))))
5899 Lhs_Discr_Val := Make_Identifier (Loc, Name_A);
5901 -- Enclosing record is of a non-Unchecked_Union type, it is
5902 -- possible to reference the discriminant.
5906 Make_Selected_Component (Loc,
5907 Prefix => Prefix (Lhs),
5910 (Get_Discriminant_Value
5911 (First_Discriminant (Lhs_Type),
5913 Stored_Constraint (Lhs_Type))));
5916 -- Comment needed here ???
5919 -- Infer the discriminant value
5923 (Get_Discriminant_Value
5924 (First_Discriminant (Lhs_Type),
5926 Stored_Constraint (Lhs_Type)));
5931 if Nkind (Rhs) = N_Selected_Component
5932 and then Has_Per_Object_Constraint
5933 (Entity (Selector_Name (Rhs)))
5935 if Is_Unchecked_Union
5936 (Scope (Entity (Selector_Name (Rhs))))
5938 Rhs_Discr_Val := Make_Identifier (Loc, Name_B);
5942 Make_Selected_Component (Loc,
5943 Prefix => Prefix (Rhs),
5945 New_Copy (Get_Discriminant_Value (
5946 First_Discriminant (Rhs_Type),
5948 Stored_Constraint (Rhs_Type))));
5953 New_Copy (Get_Discriminant_Value (
5954 First_Discriminant (Rhs_Type),
5956 Stored_Constraint (Rhs_Type)));
5961 Make_Function_Call (Loc,
5962 Name => New_Reference_To (Eq, Loc),
5963 Parameter_Associations => New_List (
5970 -- Normal case, not an unchecked union
5974 Make_Function_Call (Loc,
5975 Name => New_Reference_To (Eq, Loc),
5976 Parameter_Associations => New_List (L_Exp, R_Exp)));
5979 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
5980 end Build_Equality_Call;
5982 ------------------------------------
5983 -- Has_Unconstrained_UU_Component --
5984 ------------------------------------
5986 function Has_Unconstrained_UU_Component
5987 (Typ : Node_Id) return Boolean
5989 Tdef : constant Node_Id :=
5990 Type_Definition (Declaration_Node (Base_Type (Typ)));
5994 function Component_Is_Unconstrained_UU
5995 (Comp : Node_Id) return Boolean;
5996 -- Determines whether the subtype of the component is an
5997 -- unconstrained Unchecked_Union.
5999 function Variant_Is_Unconstrained_UU
6000 (Variant : Node_Id) return Boolean;
6001 -- Determines whether a component of the variant has an unconstrained
6002 -- Unchecked_Union subtype.
6004 -----------------------------------
6005 -- Component_Is_Unconstrained_UU --
6006 -----------------------------------
6008 function Component_Is_Unconstrained_UU
6009 (Comp : Node_Id) return Boolean
6012 if Nkind (Comp) /= N_Component_Declaration then
6017 Sindic : constant Node_Id :=
6018 Subtype_Indication (Component_Definition (Comp));
6021 -- Unconstrained nominal type. In the case of a constraint
6022 -- present, the node kind would have been N_Subtype_Indication.
6024 if Nkind (Sindic) = N_Identifier then
6025 return Is_Unchecked_Union (Base_Type (Etype (Sindic)));
6030 end Component_Is_Unconstrained_UU;
6032 ---------------------------------
6033 -- Variant_Is_Unconstrained_UU --
6034 ---------------------------------
6036 function Variant_Is_Unconstrained_UU
6037 (Variant : Node_Id) return Boolean
6039 Clist : constant Node_Id := Component_List (Variant);
6042 if Is_Empty_List (Component_Items (Clist)) then
6046 -- We only need to test one component
6049 Comp : Node_Id := First (Component_Items (Clist));
6052 while Present (Comp) loop
6053 if Component_Is_Unconstrained_UU (Comp) then
6061 -- None of the components withing the variant were of
6062 -- unconstrained Unchecked_Union type.
6065 end Variant_Is_Unconstrained_UU;
6067 -- Start of processing for Has_Unconstrained_UU_Component
6070 if Null_Present (Tdef) then
6074 Clist := Component_List (Tdef);
6075 Vpart := Variant_Part (Clist);
6077 -- Inspect available components
6079 if Present (Component_Items (Clist)) then
6081 Comp : Node_Id := First (Component_Items (Clist));
6084 while Present (Comp) loop
6086 -- One component is sufficient
6088 if Component_Is_Unconstrained_UU (Comp) then
6097 -- Inspect available components withing variants
6099 if Present (Vpart) then
6101 Variant : Node_Id := First (Variants (Vpart));
6104 while Present (Variant) loop
6106 -- One component within a variant is sufficient
6108 if Variant_Is_Unconstrained_UU (Variant) then
6117 -- Neither the available components, nor the components inside the
6118 -- variant parts were of an unconstrained Unchecked_Union subtype.
6121 end Has_Unconstrained_UU_Component;
6123 -- Start of processing for Expand_N_Op_Eq
6126 Binary_Op_Validity_Checks (N);
6128 if Ekind (Typl) = E_Private_Type then
6129 Typl := Underlying_Type (Typl);
6130 elsif Ekind (Typl) = E_Private_Subtype then
6131 Typl := Underlying_Type (Base_Type (Typl));
6136 -- It may happen in error situations that the underlying type is not
6137 -- set. The error will be detected later, here we just defend the
6144 Typl := Base_Type (Typl);
6146 -- Boolean types (requiring handling of non-standard case)
6148 if Is_Boolean_Type (Typl) then
6149 Adjust_Condition (Left_Opnd (N));
6150 Adjust_Condition (Right_Opnd (N));
6151 Set_Etype (N, Standard_Boolean);
6152 Adjust_Result_Type (N, Typ);
6156 elsif Is_Array_Type (Typl) then
6158 -- If we are doing full validity checking, and it is possible for the
6159 -- array elements to be invalid then expand out array comparisons to
6160 -- make sure that we check the array elements.
6162 if Validity_Check_Operands
6163 and then not Is_Known_Valid (Component_Type (Typl))
6166 Save_Force_Validity_Checks : constant Boolean :=
6167 Force_Validity_Checks;
6169 Force_Validity_Checks := True;
6171 Expand_Array_Equality
6173 Relocate_Node (Lhs),
6174 Relocate_Node (Rhs),
6177 Insert_Actions (N, Bodies);
6178 Analyze_And_Resolve (N, Standard_Boolean);
6179 Force_Validity_Checks := Save_Force_Validity_Checks;
6182 -- Packed case where both operands are known aligned
6184 elsif Is_Bit_Packed_Array (Typl)
6185 and then not Is_Possibly_Unaligned_Object (Lhs)
6186 and then not Is_Possibly_Unaligned_Object (Rhs)
6188 Expand_Packed_Eq (N);
6190 -- Where the component type is elementary we can use a block bit
6191 -- comparison (if supported on the target) exception in the case
6192 -- of floating-point (negative zero issues require element by
6193 -- element comparison), and atomic types (where we must be sure
6194 -- to load elements independently) and possibly unaligned arrays.
6196 elsif Is_Elementary_Type (Component_Type (Typl))
6197 and then not Is_Floating_Point_Type (Component_Type (Typl))
6198 and then not Is_Atomic (Component_Type (Typl))
6199 and then not Is_Possibly_Unaligned_Object (Lhs)
6200 and then not Is_Possibly_Unaligned_Object (Rhs)
6201 and then Support_Composite_Compare_On_Target
6205 -- For composite and floating-point cases, expand equality loop to
6206 -- make sure of using proper comparisons for tagged types, and
6207 -- correctly handling the floating-point case.
6211 Expand_Array_Equality
6213 Relocate_Node (Lhs),
6214 Relocate_Node (Rhs),
6217 Insert_Actions (N, Bodies, Suppress => All_Checks);
6218 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
6223 elsif Is_Record_Type (Typl) then
6225 -- For tagged types, use the primitive "="
6227 if Is_Tagged_Type (Typl) then
6229 -- No need to do anything else compiling under restriction
6230 -- No_Dispatching_Calls. During the semantic analysis we
6231 -- already notified such violation.
6233 if Restriction_Active (No_Dispatching_Calls) then
6237 -- If this is derived from an untagged private type completed with
6238 -- a tagged type, it does not have a full view, so we use the
6239 -- primitive operations of the private type. This check should no
6240 -- longer be necessary when these types get their full views???
6242 if Is_Private_Type (A_Typ)
6243 and then not Is_Tagged_Type (A_Typ)
6244 and then Is_Derived_Type (A_Typ)
6245 and then No (Full_View (A_Typ))
6247 -- Search for equality operation, checking that the operands
6248 -- have the same type. Note that we must find a matching entry,
6249 -- or something is very wrong!
6251 Prim := First_Elmt (Collect_Primitive_Operations (A_Typ));
6253 while Present (Prim) loop
6254 exit when Chars (Node (Prim)) = Name_Op_Eq
6255 and then Etype (First_Formal (Node (Prim))) =
6256 Etype (Next_Formal (First_Formal (Node (Prim))))
6258 Base_Type (Etype (Node (Prim))) = Standard_Boolean;
6263 pragma Assert (Present (Prim));
6264 Op_Name := Node (Prim);
6266 -- Find the type's predefined equality or an overriding
6267 -- user- defined equality. The reason for not simply calling
6268 -- Find_Prim_Op here is that there may be a user-defined
6269 -- overloaded equality op that precedes the equality that we want,
6270 -- so we have to explicitly search (e.g., there could be an
6271 -- equality with two different parameter types).
6274 if Is_Class_Wide_Type (Typl) then
6275 Typl := Root_Type (Typl);
6278 Prim := First_Elmt (Primitive_Operations (Typl));
6279 while Present (Prim) loop
6280 exit when Chars (Node (Prim)) = Name_Op_Eq
6281 and then Etype (First_Formal (Node (Prim))) =
6282 Etype (Next_Formal (First_Formal (Node (Prim))))
6284 Base_Type (Etype (Node (Prim))) = Standard_Boolean;
6289 pragma Assert (Present (Prim));
6290 Op_Name := Node (Prim);
6293 Build_Equality_Call (Op_Name);
6295 -- Ada 2005 (AI-216): Program_Error is raised when evaluating the
6296 -- predefined equality operator for a type which has a subcomponent
6297 -- of an Unchecked_Union type whose nominal subtype is unconstrained.
6299 elsif Has_Unconstrained_UU_Component (Typl) then
6301 Make_Raise_Program_Error (Loc,
6302 Reason => PE_Unchecked_Union_Restriction));
6304 -- Prevent Gigi from generating incorrect code by rewriting the
6305 -- equality as a standard False.
6308 New_Occurrence_Of (Standard_False, Loc));
6310 elsif Is_Unchecked_Union (Typl) then
6312 -- If we can infer the discriminants of the operands, we make a
6313 -- call to the TSS equality function.
6315 if Has_Inferable_Discriminants (Lhs)
6317 Has_Inferable_Discriminants (Rhs)
6320 (TSS (Root_Type (Typl), TSS_Composite_Equality));
6323 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
6324 -- the predefined equality operator for an Unchecked_Union type
6325 -- if either of the operands lack inferable discriminants.
6328 Make_Raise_Program_Error (Loc,
6329 Reason => PE_Unchecked_Union_Restriction));
6331 -- Prevent Gigi from generating incorrect code by rewriting
6332 -- the equality as a standard False.
6335 New_Occurrence_Of (Standard_False, Loc));
6339 -- If a type support function is present (for complex cases), use it
6341 elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
6343 (TSS (Root_Type (Typl), TSS_Composite_Equality));
6345 -- Otherwise expand the component by component equality. Note that
6346 -- we never use block-bit comparisons for records, because of the
6347 -- problems with gaps. The backend will often be able to recombine
6348 -- the separate comparisons that we generate here.
6351 Remove_Side_Effects (Lhs);
6352 Remove_Side_Effects (Rhs);
6354 Expand_Record_Equality (N, Typl, Lhs, Rhs, Bodies));
6356 Insert_Actions (N, Bodies, Suppress => All_Checks);
6357 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
6361 -- Test if result is known at compile time
6363 Rewrite_Comparison (N);
6365 -- If we still have comparison for Vax_Float, process it
6367 if Vax_Float (Typl) and then Nkind (N) in N_Op_Compare then
6368 Expand_Vax_Comparison (N);
6372 Optimize_Length_Comparison (N);
6375 -----------------------
6376 -- Expand_N_Op_Expon --
6377 -----------------------
6379 procedure Expand_N_Op_Expon (N : Node_Id) is
6380 Loc : constant Source_Ptr := Sloc (N);
6381 Typ : constant Entity_Id := Etype (N);
6382 Rtyp : constant Entity_Id := Root_Type (Typ);
6383 Base : constant Node_Id := Relocate_Node (Left_Opnd (N));
6384 Bastyp : constant Node_Id := Etype (Base);
6385 Exp : constant Node_Id := Relocate_Node (Right_Opnd (N));
6386 Exptyp : constant Entity_Id := Etype (Exp);
6387 Ovflo : constant Boolean := Do_Overflow_Check (N);
6396 Binary_Op_Validity_Checks (N);
6398 -- CodePeer and GNATprove want to see the unexpanded N_Op_Expon node
6400 if CodePeer_Mode or Alfa_Mode then
6404 -- If either operand is of a private type, then we have the use of an
6405 -- intrinsic operator, and we get rid of the privateness, by using root
6406 -- types of underlying types for the actual operation. Otherwise the
6407 -- private types will cause trouble if we expand multiplications or
6408 -- shifts etc. We also do this transformation if the result type is
6409 -- different from the base type.
6411 if Is_Private_Type (Etype (Base))
6412 or else Is_Private_Type (Typ)
6413 or else Is_Private_Type (Exptyp)
6414 or else Rtyp /= Root_Type (Bastyp)
6417 Bt : constant Entity_Id := Root_Type (Underlying_Type (Bastyp));
6418 Et : constant Entity_Id := Root_Type (Underlying_Type (Exptyp));
6422 Unchecked_Convert_To (Typ,
6424 Left_Opnd => Unchecked_Convert_To (Bt, Base),
6425 Right_Opnd => Unchecked_Convert_To (Et, Exp))));
6426 Analyze_And_Resolve (N, Typ);
6431 -- Test for case of known right argument
6433 if Compile_Time_Known_Value (Exp) then
6434 Expv := Expr_Value (Exp);
6436 -- We only fold small non-negative exponents. You might think we
6437 -- could fold small negative exponents for the real case, but we
6438 -- can't because we are required to raise Constraint_Error for
6439 -- the case of 0.0 ** (negative) even if Machine_Overflows = False.
6440 -- See ACVC test C4A012B.
6442 if Expv >= 0 and then Expv <= 4 then
6444 -- X ** 0 = 1 (or 1.0)
6448 -- Call Remove_Side_Effects to ensure that any side effects
6449 -- in the ignored left operand (in particular function calls
6450 -- to user defined functions) are properly executed.
6452 Remove_Side_Effects (Base);
6454 if Ekind (Typ) in Integer_Kind then
6455 Xnode := Make_Integer_Literal (Loc, Intval => 1);
6457 Xnode := Make_Real_Literal (Loc, Ureal_1);
6469 Make_Op_Multiply (Loc,
6470 Left_Opnd => Duplicate_Subexpr (Base),
6471 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
6473 -- X ** 3 = X * X * X
6477 Make_Op_Multiply (Loc,
6479 Make_Op_Multiply (Loc,
6480 Left_Opnd => Duplicate_Subexpr (Base),
6481 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)),
6482 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
6485 -- En : constant base'type := base * base;
6490 Temp := Make_Temporary (Loc, 'E', Base);
6492 Insert_Actions (N, New_List (
6493 Make_Object_Declaration (Loc,
6494 Defining_Identifier => Temp,
6495 Constant_Present => True,
6496 Object_Definition => New_Reference_To (Typ, Loc),
6498 Make_Op_Multiply (Loc,
6499 Left_Opnd => Duplicate_Subexpr (Base),
6500 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)))));
6503 Make_Op_Multiply (Loc,
6504 Left_Opnd => New_Reference_To (Temp, Loc),
6505 Right_Opnd => New_Reference_To (Temp, Loc));
6509 Analyze_And_Resolve (N, Typ);
6514 -- Case of (2 ** expression) appearing as an argument of an integer
6515 -- multiplication, or as the right argument of a division of a non-
6516 -- negative integer. In such cases we leave the node untouched, setting
6517 -- the flag Is_Natural_Power_Of_2_for_Shift set, then the expansion
6518 -- of the higher level node converts it into a shift.
6520 -- Another case is 2 ** N in any other context. We simply convert
6521 -- this to 1 * 2 ** N, and then the above transformation applies.
6523 -- Note: this transformation is not applicable for a modular type with
6524 -- a non-binary modulus in the multiplication case, since we get a wrong
6525 -- result if the shift causes an overflow before the modular reduction.
6527 if Nkind (Base) = N_Integer_Literal
6528 and then Intval (Base) = 2
6529 and then Is_Integer_Type (Root_Type (Exptyp))
6530 and then Esize (Root_Type (Exptyp)) <= Esize (Standard_Integer)
6531 and then Is_Unsigned_Type (Exptyp)
6534 -- First the multiply and divide cases
6536 if Nkind_In (Parent (N), N_Op_Divide, N_Op_Multiply) then
6538 P : constant Node_Id := Parent (N);
6539 L : constant Node_Id := Left_Opnd (P);
6540 R : constant Node_Id := Right_Opnd (P);
6543 if (Nkind (P) = N_Op_Multiply
6544 and then not Non_Binary_Modulus (Typ)
6546 ((Is_Integer_Type (Etype (L)) and then R = N)
6548 (Is_Integer_Type (Etype (R)) and then L = N))
6549 and then not Do_Overflow_Check (P))
6551 (Nkind (P) = N_Op_Divide
6552 and then Is_Integer_Type (Etype (L))
6553 and then Is_Unsigned_Type (Etype (L))
6555 and then not Do_Overflow_Check (P))
6557 Set_Is_Power_Of_2_For_Shift (N);
6562 -- Now the other cases
6564 elsif not Non_Binary_Modulus (Typ) then
6566 Make_Op_Multiply (Loc,
6567 Left_Opnd => Make_Integer_Literal (Loc, 1),
6568 Right_Opnd => Relocate_Node (N)));
6569 Analyze_And_Resolve (N, Typ);
6574 -- Fall through if exponentiation must be done using a runtime routine
6576 -- First deal with modular case
6578 if Is_Modular_Integer_Type (Rtyp) then
6580 -- Non-binary case, we call the special exponentiation routine for
6581 -- the non-binary case, converting the argument to Long_Long_Integer
6582 -- and passing the modulus value. Then the result is converted back
6583 -- to the base type.
6585 if Non_Binary_Modulus (Rtyp) then
6588 Make_Function_Call (Loc,
6589 Name => New_Reference_To (RTE (RE_Exp_Modular), Loc),
6590 Parameter_Associations => New_List (
6591 Convert_To (Standard_Integer, Base),
6592 Make_Integer_Literal (Loc, Modulus (Rtyp)),
6595 -- Binary case, in this case, we call one of two routines, either the
6596 -- unsigned integer case, or the unsigned long long integer case,
6597 -- with a final "and" operation to do the required mod.
6600 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
6601 Ent := RTE (RE_Exp_Unsigned);
6603 Ent := RTE (RE_Exp_Long_Long_Unsigned);
6610 Make_Function_Call (Loc,
6611 Name => New_Reference_To (Ent, Loc),
6612 Parameter_Associations => New_List (
6613 Convert_To (Etype (First_Formal (Ent)), Base),
6616 Make_Integer_Literal (Loc, Modulus (Rtyp) - 1))));
6620 -- Common exit point for modular type case
6622 Analyze_And_Resolve (N, Typ);
6625 -- Signed integer cases, done using either Integer or Long_Long_Integer.
6626 -- It is not worth having routines for Short_[Short_]Integer, since for
6627 -- most machines it would not help, and it would generate more code that
6628 -- might need certification when a certified run time is required.
6630 -- In the integer cases, we have two routines, one for when overflow
6631 -- checks are required, and one when they are not required, since there
6632 -- is a real gain in omitting checks on many machines.
6634 elsif Rtyp = Base_Type (Standard_Long_Long_Integer)
6635 or else (Rtyp = Base_Type (Standard_Long_Integer)
6637 Esize (Standard_Long_Integer) > Esize (Standard_Integer))
6638 or else (Rtyp = Universal_Integer)
6640 Etyp := Standard_Long_Long_Integer;
6643 Rent := RE_Exp_Long_Long_Integer;
6645 Rent := RE_Exn_Long_Long_Integer;
6648 elsif Is_Signed_Integer_Type (Rtyp) then
6649 Etyp := Standard_Integer;
6652 Rent := RE_Exp_Integer;
6654 Rent := RE_Exn_Integer;
6657 -- Floating-point cases, always done using Long_Long_Float. We do not
6658 -- need separate routines for the overflow case here, since in the case
6659 -- of floating-point, we generate infinities anyway as a rule (either
6660 -- that or we automatically trap overflow), and if there is an infinity
6661 -- generated and a range check is required, the check will fail anyway.
6664 pragma Assert (Is_Floating_Point_Type (Rtyp));
6665 Etyp := Standard_Long_Long_Float;
6666 Rent := RE_Exn_Long_Long_Float;
6669 -- Common processing for integer cases and floating-point cases.
6670 -- If we are in the right type, we can call runtime routine directly
6673 and then Rtyp /= Universal_Integer
6674 and then Rtyp /= Universal_Real
6677 Make_Function_Call (Loc,
6678 Name => New_Reference_To (RTE (Rent), Loc),
6679 Parameter_Associations => New_List (Base, Exp)));
6681 -- Otherwise we have to introduce conversions (conversions are also
6682 -- required in the universal cases, since the runtime routine is
6683 -- typed using one of the standard types).
6688 Make_Function_Call (Loc,
6689 Name => New_Reference_To (RTE (Rent), Loc),
6690 Parameter_Associations => New_List (
6691 Convert_To (Etyp, Base),
6695 Analyze_And_Resolve (N, Typ);
6699 when RE_Not_Available =>
6701 end Expand_N_Op_Expon;
6703 --------------------
6704 -- Expand_N_Op_Ge --
6705 --------------------
6707 procedure Expand_N_Op_Ge (N : Node_Id) is
6708 Typ : constant Entity_Id := Etype (N);
6709 Op1 : constant Node_Id := Left_Opnd (N);
6710 Op2 : constant Node_Id := Right_Opnd (N);
6711 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
6714 Binary_Op_Validity_Checks (N);
6716 if Is_Array_Type (Typ1) then
6717 Expand_Array_Comparison (N);
6721 if Is_Boolean_Type (Typ1) then
6722 Adjust_Condition (Op1);
6723 Adjust_Condition (Op2);
6724 Set_Etype (N, Standard_Boolean);
6725 Adjust_Result_Type (N, Typ);
6728 Rewrite_Comparison (N);
6730 -- If we still have comparison, and Vax_Float type, process it
6732 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
6733 Expand_Vax_Comparison (N);
6737 Optimize_Length_Comparison (N);
6740 --------------------
6741 -- Expand_N_Op_Gt --
6742 --------------------
6744 procedure Expand_N_Op_Gt (N : Node_Id) is
6745 Typ : constant Entity_Id := Etype (N);
6746 Op1 : constant Node_Id := Left_Opnd (N);
6747 Op2 : constant Node_Id := Right_Opnd (N);
6748 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
6751 Binary_Op_Validity_Checks (N);
6753 if Is_Array_Type (Typ1) then
6754 Expand_Array_Comparison (N);
6758 if Is_Boolean_Type (Typ1) then
6759 Adjust_Condition (Op1);
6760 Adjust_Condition (Op2);
6761 Set_Etype (N, Standard_Boolean);
6762 Adjust_Result_Type (N, Typ);
6765 Rewrite_Comparison (N);
6767 -- If we still have comparison, and Vax_Float type, process it
6769 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
6770 Expand_Vax_Comparison (N);
6774 Optimize_Length_Comparison (N);
6777 --------------------
6778 -- Expand_N_Op_Le --
6779 --------------------
6781 procedure Expand_N_Op_Le (N : Node_Id) is
6782 Typ : constant Entity_Id := Etype (N);
6783 Op1 : constant Node_Id := Left_Opnd (N);
6784 Op2 : constant Node_Id := Right_Opnd (N);
6785 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
6788 Binary_Op_Validity_Checks (N);
6790 if Is_Array_Type (Typ1) then
6791 Expand_Array_Comparison (N);
6795 if Is_Boolean_Type (Typ1) then
6796 Adjust_Condition (Op1);
6797 Adjust_Condition (Op2);
6798 Set_Etype (N, Standard_Boolean);
6799 Adjust_Result_Type (N, Typ);
6802 Rewrite_Comparison (N);
6804 -- If we still have comparison, and Vax_Float type, process it
6806 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
6807 Expand_Vax_Comparison (N);
6811 Optimize_Length_Comparison (N);
6814 --------------------
6815 -- Expand_N_Op_Lt --
6816 --------------------
6818 procedure Expand_N_Op_Lt (N : Node_Id) is
6819 Typ : constant Entity_Id := Etype (N);
6820 Op1 : constant Node_Id := Left_Opnd (N);
6821 Op2 : constant Node_Id := Right_Opnd (N);
6822 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
6825 Binary_Op_Validity_Checks (N);
6827 if Is_Array_Type (Typ1) then
6828 Expand_Array_Comparison (N);
6832 if Is_Boolean_Type (Typ1) then
6833 Adjust_Condition (Op1);
6834 Adjust_Condition (Op2);
6835 Set_Etype (N, Standard_Boolean);
6836 Adjust_Result_Type (N, Typ);
6839 Rewrite_Comparison (N);
6841 -- If we still have comparison, and Vax_Float type, process it
6843 if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then
6844 Expand_Vax_Comparison (N);
6848 Optimize_Length_Comparison (N);
6851 -----------------------
6852 -- Expand_N_Op_Minus --
6853 -----------------------
6855 procedure Expand_N_Op_Minus (N : Node_Id) is
6856 Loc : constant Source_Ptr := Sloc (N);
6857 Typ : constant Entity_Id := Etype (N);
6860 Unary_Op_Validity_Checks (N);
6862 if not Backend_Overflow_Checks_On_Target
6863 and then Is_Signed_Integer_Type (Etype (N))
6864 and then Do_Overflow_Check (N)
6866 -- Software overflow checking expands -expr into (0 - expr)
6869 Make_Op_Subtract (Loc,
6870 Left_Opnd => Make_Integer_Literal (Loc, 0),
6871 Right_Opnd => Right_Opnd (N)));
6873 Analyze_And_Resolve (N, Typ);
6875 -- Vax floating-point types case
6877 elsif Vax_Float (Etype (N)) then
6878 Expand_Vax_Arith (N);
6880 end Expand_N_Op_Minus;
6882 ---------------------
6883 -- Expand_N_Op_Mod --
6884 ---------------------
6886 procedure Expand_N_Op_Mod (N : Node_Id) is
6887 Loc : constant Source_Ptr := Sloc (N);
6888 Typ : constant Entity_Id := Etype (N);
6889 Left : constant Node_Id := Left_Opnd (N);
6890 Right : constant Node_Id := Right_Opnd (N);
6891 DOC : constant Boolean := Do_Overflow_Check (N);
6892 DDC : constant Boolean := Do_Division_Check (N);
6902 pragma Warnings (Off, Lhi);
6905 Binary_Op_Validity_Checks (N);
6907 Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);
6908 Determine_Range (Left, LOK, Llo, Lhi, Assume_Valid => True);
6910 -- Convert mod to rem if operands are known non-negative. We do this
6911 -- since it is quite likely that this will improve the quality of code,
6912 -- (the operation now corresponds to the hardware remainder), and it
6913 -- does not seem likely that it could be harmful.
6915 if LOK and then Llo >= 0
6917 ROK and then Rlo >= 0
6920 Make_Op_Rem (Sloc (N),
6921 Left_Opnd => Left_Opnd (N),
6922 Right_Opnd => Right_Opnd (N)));
6924 -- Instead of reanalyzing the node we do the analysis manually. This
6925 -- avoids anomalies when the replacement is done in an instance and
6926 -- is epsilon more efficient.
6928 Set_Entity (N, Standard_Entity (S_Op_Rem));
6930 Set_Do_Overflow_Check (N, DOC);
6931 Set_Do_Division_Check (N, DDC);
6932 Expand_N_Op_Rem (N);
6935 -- Otherwise, normal mod processing
6938 if Is_Integer_Type (Etype (N)) then
6939 Apply_Divide_Check (N);
6942 -- Apply optimization x mod 1 = 0. We don't really need that with
6943 -- gcc, but it is useful with other back ends (e.g. AAMP), and is
6944 -- certainly harmless.
6946 if Is_Integer_Type (Etype (N))
6947 and then Compile_Time_Known_Value (Right)
6948 and then Expr_Value (Right) = Uint_1
6950 -- Call Remove_Side_Effects to ensure that any side effects in
6951 -- the ignored left operand (in particular function calls to
6952 -- user defined functions) are properly executed.
6954 Remove_Side_Effects (Left);
6956 Rewrite (N, Make_Integer_Literal (Loc, 0));
6957 Analyze_And_Resolve (N, Typ);
6961 -- Deal with annoying case of largest negative number remainder
6962 -- minus one. Gigi does not handle this case correctly, because
6963 -- it generates a divide instruction which may trap in this case.
6965 -- In fact the check is quite easy, if the right operand is -1, then
6966 -- the mod value is always 0, and we can just ignore the left operand
6967 -- completely in this case.
6969 -- The operand type may be private (e.g. in the expansion of an
6970 -- intrinsic operation) so we must use the underlying type to get the
6971 -- bounds, and convert the literals explicitly.
6975 (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
6977 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
6979 ((not LOK) or else (Llo = LLB))
6982 Make_Conditional_Expression (Loc,
6983 Expressions => New_List (
6985 Left_Opnd => Duplicate_Subexpr (Right),
6987 Unchecked_Convert_To (Typ,
6988 Make_Integer_Literal (Loc, -1))),
6989 Unchecked_Convert_To (Typ,
6990 Make_Integer_Literal (Loc, Uint_0)),
6991 Relocate_Node (N))));
6993 Set_Analyzed (Next (Next (First (Expressions (N)))));
6994 Analyze_And_Resolve (N, Typ);
6997 end Expand_N_Op_Mod;
6999 --------------------------
7000 -- Expand_N_Op_Multiply --
7001 --------------------------
7003 procedure Expand_N_Op_Multiply (N : Node_Id) is
7004 Loc : constant Source_Ptr := Sloc (N);
7005 Lop : constant Node_Id := Left_Opnd (N);
7006 Rop : constant Node_Id := Right_Opnd (N);
7008 Lp2 : constant Boolean :=
7009 Nkind (Lop) = N_Op_Expon
7010 and then Is_Power_Of_2_For_Shift (Lop);
7012 Rp2 : constant Boolean :=
7013 Nkind (Rop) = N_Op_Expon
7014 and then Is_Power_Of_2_For_Shift (Rop);
7016 Ltyp : constant Entity_Id := Etype (Lop);
7017 Rtyp : constant Entity_Id := Etype (Rop);
7018 Typ : Entity_Id := Etype (N);
7021 Binary_Op_Validity_Checks (N);
7023 -- Special optimizations for integer types
7025 if Is_Integer_Type (Typ) then
7027 -- N * 0 = 0 for integer types
7029 if Compile_Time_Known_Value (Rop)
7030 and then Expr_Value (Rop) = Uint_0
7032 -- Call Remove_Side_Effects to ensure that any side effects in
7033 -- the ignored left operand (in particular function calls to
7034 -- user defined functions) are properly executed.
7036 Remove_Side_Effects (Lop);
7038 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
7039 Analyze_And_Resolve (N, Typ);
7043 -- Similar handling for 0 * N = 0
7045 if Compile_Time_Known_Value (Lop)
7046 and then Expr_Value (Lop) = Uint_0
7048 Remove_Side_Effects (Rop);
7049 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
7050 Analyze_And_Resolve (N, Typ);
7054 -- N * 1 = 1 * N = N for integer types
7056 -- This optimisation is not done if we are going to
7057 -- rewrite the product 1 * 2 ** N to a shift.
7059 if Compile_Time_Known_Value (Rop)
7060 and then Expr_Value (Rop) = Uint_1
7066 elsif Compile_Time_Known_Value (Lop)
7067 and then Expr_Value (Lop) = Uint_1
7075 -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
7076 -- Is_Power_Of_2_For_Shift is set means that we know that our left
7077 -- operand is an integer, as required for this to work.
7082 -- Convert 2 ** A * 2 ** B into 2 ** (A + B)
7086 Left_Opnd => Make_Integer_Literal (Loc, 2),
7089 Left_Opnd => Right_Opnd (Lop),
7090 Right_Opnd => Right_Opnd (Rop))));
7091 Analyze_And_Resolve (N, Typ);
7096 Make_Op_Shift_Left (Loc,
7099 Convert_To (Standard_Natural, Right_Opnd (Rop))));
7100 Analyze_And_Resolve (N, Typ);
7104 -- Same processing for the operands the other way round
7108 Make_Op_Shift_Left (Loc,
7111 Convert_To (Standard_Natural, Right_Opnd (Lop))));
7112 Analyze_And_Resolve (N, Typ);
7116 -- Do required fixup of universal fixed operation
7118 if Typ = Universal_Fixed then
7119 Fixup_Universal_Fixed_Operation (N);
7123 -- Multiplications with fixed-point results
7125 if Is_Fixed_Point_Type (Typ) then
7127 -- No special processing if Treat_Fixed_As_Integer is set, since from
7128 -- a semantic point of view such operations are simply integer
7129 -- operations and will be treated that way.
7131 if not Treat_Fixed_As_Integer (N) then
7133 -- Case of fixed * integer => fixed
7135 if Is_Integer_Type (Rtyp) then
7136 Expand_Multiply_Fixed_By_Integer_Giving_Fixed (N);
7138 -- Case of integer * fixed => fixed
7140 elsif Is_Integer_Type (Ltyp) then
7141 Expand_Multiply_Integer_By_Fixed_Giving_Fixed (N);
7143 -- Case of fixed * fixed => fixed
7146 Expand_Multiply_Fixed_By_Fixed_Giving_Fixed (N);
7150 -- Other cases of multiplication of fixed-point operands. Again we
7151 -- exclude the cases where Treat_Fixed_As_Integer flag is set.
7153 elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
7154 and then not Treat_Fixed_As_Integer (N)
7156 if Is_Integer_Type (Typ) then
7157 Expand_Multiply_Fixed_By_Fixed_Giving_Integer (N);
7159 pragma Assert (Is_Floating_Point_Type (Typ));
7160 Expand_Multiply_Fixed_By_Fixed_Giving_Float (N);
7163 -- Mixed-mode operations can appear in a non-static universal context,
7164 -- in which case the integer argument must be converted explicitly.
7166 elsif Typ = Universal_Real
7167 and then Is_Integer_Type (Rtyp)
7169 Rewrite (Rop, Convert_To (Universal_Real, Relocate_Node (Rop)));
7171 Analyze_And_Resolve (Rop, Universal_Real);
7173 elsif Typ = Universal_Real
7174 and then Is_Integer_Type (Ltyp)
7176 Rewrite (Lop, Convert_To (Universal_Real, Relocate_Node (Lop)));
7178 Analyze_And_Resolve (Lop, Universal_Real);
7180 -- Non-fixed point cases, check software overflow checking required
7182 elsif Is_Signed_Integer_Type (Etype (N)) then
7183 Apply_Arithmetic_Overflow_Check (N);
7185 -- Deal with VAX float case
7187 elsif Vax_Float (Typ) then
7188 Expand_Vax_Arith (N);
7191 end Expand_N_Op_Multiply;
7193 --------------------
7194 -- Expand_N_Op_Ne --
7195 --------------------
7197 procedure Expand_N_Op_Ne (N : Node_Id) is
7198 Typ : constant Entity_Id := Etype (Left_Opnd (N));
7201 -- Case of elementary type with standard operator
7203 if Is_Elementary_Type (Typ)
7204 and then Sloc (Entity (N)) = Standard_Location
7206 Binary_Op_Validity_Checks (N);
7208 -- Boolean types (requiring handling of non-standard case)
7210 if Is_Boolean_Type (Typ) then
7211 Adjust_Condition (Left_Opnd (N));
7212 Adjust_Condition (Right_Opnd (N));
7213 Set_Etype (N, Standard_Boolean);
7214 Adjust_Result_Type (N, Typ);
7217 Rewrite_Comparison (N);
7219 -- If we still have comparison for Vax_Float, process it
7221 if Vax_Float (Typ) and then Nkind (N) in N_Op_Compare then
7222 Expand_Vax_Comparison (N);
7226 -- For all cases other than elementary types, we rewrite node as the
7227 -- negation of an equality operation, and reanalyze. The equality to be
7228 -- used is defined in the same scope and has the same signature. This
7229 -- signature must be set explicitly since in an instance it may not have
7230 -- the same visibility as in the generic unit. This avoids duplicating
7231 -- or factoring the complex code for record/array equality tests etc.
7235 Loc : constant Source_Ptr := Sloc (N);
7237 Ne : constant Entity_Id := Entity (N);
7240 Binary_Op_Validity_Checks (N);
7246 Left_Opnd => Left_Opnd (N),
7247 Right_Opnd => Right_Opnd (N)));
7248 Set_Paren_Count (Right_Opnd (Neg), 1);
7250 if Scope (Ne) /= Standard_Standard then
7251 Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
7254 -- For navigation purposes, we want to treat the inequality as an
7255 -- implicit reference to the corresponding equality. Preserve the
7256 -- Comes_From_ source flag to generate proper Xref entries.
7258 Preserve_Comes_From_Source (Neg, N);
7259 Preserve_Comes_From_Source (Right_Opnd (Neg), N);
7261 Analyze_And_Resolve (N, Standard_Boolean);
7265 Optimize_Length_Comparison (N);
7268 ---------------------
7269 -- Expand_N_Op_Not --
7270 ---------------------
7272 -- If the argument is other than a Boolean array type, there is no special
7273 -- expansion required, except for VMS operations on signed integers.
7275 -- For the packed case, we call the special routine in Exp_Pakd, except
7276 -- that if the component size is greater than one, we use the standard
7277 -- routine generating a gruesome loop (it is so peculiar to have packed
7278 -- arrays with non-standard Boolean representations anyway, so it does not
7279 -- matter that we do not handle this case efficiently).
7281 -- For the unpacked case (and for the special packed case where we have non
7282 -- standard Booleans, as discussed above), we generate and insert into the
7283 -- tree the following function definition:
7285 -- function Nnnn (A : arr) is
7288 -- for J in a'range loop
7289 -- B (J) := not A (J);
7294 -- Here arr is the actual subtype of the parameter (and hence always
7295 -- constrained). Then we replace the not with a call to this function.
7297 procedure Expand_N_Op_Not (N : Node_Id) is
7298 Loc : constant Source_Ptr := Sloc (N);
7299 Typ : constant Entity_Id := Etype (N);
7308 Func_Name : Entity_Id;
7309 Loop_Statement : Node_Id;
7312 Unary_Op_Validity_Checks (N);
7314 -- For boolean operand, deal with non-standard booleans
7316 if Is_Boolean_Type (Typ) then
7317 Adjust_Condition (Right_Opnd (N));
7318 Set_Etype (N, Standard_Boolean);
7319 Adjust_Result_Type (N, Typ);
7323 -- For the VMS "not" on signed integer types, use conversion to and from
7324 -- a predefined modular type.
7326 if Is_VMS_Operator (Entity (N)) then
7332 -- If this is a derived type, retrieve original VMS type so that
7333 -- the proper sized type is used for intermediate values.
7335 if Is_Derived_Type (Typ) then
7336 Rtyp := First_Subtype (Etype (Typ));
7341 -- The proper unsigned type must have a size compatible with the
7342 -- operand, to prevent misalignment.
7344 if RM_Size (Rtyp) <= 8 then
7345 Utyp := RTE (RE_Unsigned_8);
7347 elsif RM_Size (Rtyp) <= 16 then
7348 Utyp := RTE (RE_Unsigned_16);
7350 elsif RM_Size (Rtyp) = RM_Size (Standard_Unsigned) then
7351 Utyp := RTE (RE_Unsigned_32);
7354 Utyp := RTE (RE_Long_Long_Unsigned);
7358 Unchecked_Convert_To (Typ,
7360 Unchecked_Convert_To (Utyp, Right_Opnd (N)))));
7361 Analyze_And_Resolve (N, Typ);
7366 -- Only array types need any other processing
7368 if not Is_Array_Type (Typ) then
7372 -- Case of array operand. If bit packed with a component size of 1,
7373 -- handle it in Exp_Pakd if the operand is known to be aligned.
7375 if Is_Bit_Packed_Array (Typ)
7376 and then Component_Size (Typ) = 1
7377 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
7379 Expand_Packed_Not (N);
7383 -- Case of array operand which is not bit-packed. If the context is
7384 -- a safe assignment, call in-place operation, If context is a larger
7385 -- boolean expression in the context of a safe assignment, expansion is
7386 -- done by enclosing operation.
7388 Opnd := Relocate_Node (Right_Opnd (N));
7389 Convert_To_Actual_Subtype (Opnd);
7390 Arr := Etype (Opnd);
7391 Ensure_Defined (Arr, N);
7392 Silly_Boolean_Array_Not_Test (N, Arr);
7394 if Nkind (Parent (N)) = N_Assignment_Statement then
7395 if Safe_In_Place_Array_Op (Name (Parent (N)), N, Empty) then
7396 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
7399 -- Special case the negation of a binary operation
7401 elsif Nkind_In (Opnd, N_Op_And, N_Op_Or, N_Op_Xor)
7402 and then Safe_In_Place_Array_Op
7403 (Name (Parent (N)), Left_Opnd (Opnd), Right_Opnd (Opnd))
7405 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
7409 elsif Nkind (Parent (N)) in N_Binary_Op
7410 and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
7413 Op1 : constant Node_Id := Left_Opnd (Parent (N));
7414 Op2 : constant Node_Id := Right_Opnd (Parent (N));
7415 Lhs : constant Node_Id := Name (Parent (Parent (N)));
7418 if Safe_In_Place_Array_Op (Lhs, Op1, Op2) then
7420 -- (not A) op (not B) can be reduced to a single call
7422 if N = Op1 and then Nkind (Op2) = N_Op_Not then
7425 elsif N = Op2 and then Nkind (Op1) = N_Op_Not then
7428 -- A xor (not B) can also be special-cased
7430 elsif N = Op2 and then Nkind (Parent (N)) = N_Op_Xor then
7437 A := Make_Defining_Identifier (Loc, Name_uA);
7438 B := Make_Defining_Identifier (Loc, Name_uB);
7439 J := Make_Defining_Identifier (Loc, Name_uJ);
7442 Make_Indexed_Component (Loc,
7443 Prefix => New_Reference_To (A, Loc),
7444 Expressions => New_List (New_Reference_To (J, Loc)));
7447 Make_Indexed_Component (Loc,
7448 Prefix => New_Reference_To (B, Loc),
7449 Expressions => New_List (New_Reference_To (J, Loc)));
7452 Make_Implicit_Loop_Statement (N,
7453 Identifier => Empty,
7456 Make_Iteration_Scheme (Loc,
7457 Loop_Parameter_Specification =>
7458 Make_Loop_Parameter_Specification (Loc,
7459 Defining_Identifier => J,
7460 Discrete_Subtype_Definition =>
7461 Make_Attribute_Reference (Loc,
7462 Prefix => Make_Identifier (Loc, Chars (A)),
7463 Attribute_Name => Name_Range))),
7465 Statements => New_List (
7466 Make_Assignment_Statement (Loc,
7468 Expression => Make_Op_Not (Loc, A_J))));
7470 Func_Name := Make_Temporary (Loc, 'N');
7471 Set_Is_Inlined (Func_Name);
7474 Make_Subprogram_Body (Loc,
7476 Make_Function_Specification (Loc,
7477 Defining_Unit_Name => Func_Name,
7478 Parameter_Specifications => New_List (
7479 Make_Parameter_Specification (Loc,
7480 Defining_Identifier => A,
7481 Parameter_Type => New_Reference_To (Typ, Loc))),
7482 Result_Definition => New_Reference_To (Typ, Loc)),
7484 Declarations => New_List (
7485 Make_Object_Declaration (Loc,
7486 Defining_Identifier => B,
7487 Object_Definition => New_Reference_To (Arr, Loc))),
7489 Handled_Statement_Sequence =>
7490 Make_Handled_Sequence_Of_Statements (Loc,
7491 Statements => New_List (
7493 Make_Simple_Return_Statement (Loc,
7494 Expression => Make_Identifier (Loc, Chars (B)))))));
7497 Make_Function_Call (Loc,
7498 Name => New_Reference_To (Func_Name, Loc),
7499 Parameter_Associations => New_List (Opnd)));
7501 Analyze_And_Resolve (N, Typ);
7502 end Expand_N_Op_Not;
7504 --------------------
7505 -- Expand_N_Op_Or --
7506 --------------------
7508 procedure Expand_N_Op_Or (N : Node_Id) is
7509 Typ : constant Entity_Id := Etype (N);
7512 Binary_Op_Validity_Checks (N);
7514 if Is_Array_Type (Etype (N)) then
7515 Expand_Boolean_Operator (N);
7517 elsif Is_Boolean_Type (Etype (N)) then
7519 -- Replace OR by OR ELSE if Short_Circuit_And_Or active and the type
7520 -- is standard Boolean (do not mess with AND that uses a non-standard
7521 -- Boolean type, because something strange is going on).
7523 if Short_Circuit_And_Or and then Typ = Standard_Boolean then
7525 Make_Or_Else (Sloc (N),
7526 Left_Opnd => Relocate_Node (Left_Opnd (N)),
7527 Right_Opnd => Relocate_Node (Right_Opnd (N))));
7528 Analyze_And_Resolve (N, Typ);
7530 -- Otherwise, adjust conditions
7533 Adjust_Condition (Left_Opnd (N));
7534 Adjust_Condition (Right_Opnd (N));
7535 Set_Etype (N, Standard_Boolean);
7536 Adjust_Result_Type (N, Typ);
7539 elsif Is_Intrinsic_Subprogram (Entity (N)) then
7540 Expand_Intrinsic_Call (N, Entity (N));
7545 ----------------------
7546 -- Expand_N_Op_Plus --
7547 ----------------------
7549 procedure Expand_N_Op_Plus (N : Node_Id) is
7551 Unary_Op_Validity_Checks (N);
7552 end Expand_N_Op_Plus;
7554 ---------------------
7555 -- Expand_N_Op_Rem --
7556 ---------------------
7558 procedure Expand_N_Op_Rem (N : Node_Id) is
7559 Loc : constant Source_Ptr := Sloc (N);
7560 Typ : constant Entity_Id := Etype (N);
7562 Left : constant Node_Id := Left_Opnd (N);
7563 Right : constant Node_Id := Right_Opnd (N);
7571 -- Set if corresponding operand can be negative
7573 pragma Unreferenced (Hi);
7576 Binary_Op_Validity_Checks (N);
7578 if Is_Integer_Type (Etype (N)) then
7579 Apply_Divide_Check (N);
7582 -- Apply optimization x rem 1 = 0. We don't really need that with gcc,
7583 -- but it is useful with other back ends (e.g. AAMP), and is certainly
7586 if Is_Integer_Type (Etype (N))
7587 and then Compile_Time_Known_Value (Right)
7588 and then Expr_Value (Right) = Uint_1
7590 -- Call Remove_Side_Effects to ensure that any side effects in the
7591 -- ignored left operand (in particular function calls to user defined
7592 -- functions) are properly executed.
7594 Remove_Side_Effects (Left);
7596 Rewrite (N, Make_Integer_Literal (Loc, 0));
7597 Analyze_And_Resolve (N, Typ);
7601 -- Deal with annoying case of largest negative number remainder minus
7602 -- one. Gigi does not handle this case correctly, because it generates
7603 -- a divide instruction which may trap in this case.
7605 -- In fact the check is quite easy, if the right operand is -1, then
7606 -- the remainder is always 0, and we can just ignore the left operand
7607 -- completely in this case.
7609 Determine_Range (Right, OK, Lo, Hi, Assume_Valid => True);
7610 Lneg := (not OK) or else Lo < 0;
7612 Determine_Range (Left, OK, Lo, Hi, Assume_Valid => True);
7613 Rneg := (not OK) or else Lo < 0;
7615 -- We won't mess with trying to find out if the left operand can really
7616 -- be the largest negative number (that's a pain in the case of private
7617 -- types and this is really marginal). We will just assume that we need
7618 -- the test if the left operand can be negative at all.
7620 if Lneg and Rneg then
7622 Make_Conditional_Expression (Loc,
7623 Expressions => New_List (
7625 Left_Opnd => Duplicate_Subexpr (Right),
7627 Unchecked_Convert_To (Typ, Make_Integer_Literal (Loc, -1))),
7629 Unchecked_Convert_To (Typ,
7630 Make_Integer_Literal (Loc, Uint_0)),
7632 Relocate_Node (N))));
7634 Set_Analyzed (Next (Next (First (Expressions (N)))));
7635 Analyze_And_Resolve (N, Typ);
7637 end Expand_N_Op_Rem;
7639 -----------------------------
7640 -- Expand_N_Op_Rotate_Left --
7641 -----------------------------
7643 procedure Expand_N_Op_Rotate_Left (N : Node_Id) is
7645 Binary_Op_Validity_Checks (N);
7646 end Expand_N_Op_Rotate_Left;
7648 ------------------------------
7649 -- Expand_N_Op_Rotate_Right --
7650 ------------------------------
7652 procedure Expand_N_Op_Rotate_Right (N : Node_Id) is
7654 Binary_Op_Validity_Checks (N);
7655 end Expand_N_Op_Rotate_Right;
7657 ----------------------------
7658 -- Expand_N_Op_Shift_Left --
7659 ----------------------------
7661 procedure Expand_N_Op_Shift_Left (N : Node_Id) is
7663 Binary_Op_Validity_Checks (N);
7664 end Expand_N_Op_Shift_Left;
7666 -----------------------------
7667 -- Expand_N_Op_Shift_Right --
7668 -----------------------------
7670 procedure Expand_N_Op_Shift_Right (N : Node_Id) is
7672 Binary_Op_Validity_Checks (N);
7673 end Expand_N_Op_Shift_Right;
7675 ----------------------------------------
7676 -- Expand_N_Op_Shift_Right_Arithmetic --
7677 ----------------------------------------
7679 procedure Expand_N_Op_Shift_Right_Arithmetic (N : Node_Id) is
7681 Binary_Op_Validity_Checks (N);
7682 end Expand_N_Op_Shift_Right_Arithmetic;
7684 --------------------------
7685 -- Expand_N_Op_Subtract --
7686 --------------------------
7688 procedure Expand_N_Op_Subtract (N : Node_Id) is
7689 Typ : constant Entity_Id := Etype (N);
7692 Binary_Op_Validity_Checks (N);
7694 -- N - 0 = N for integer types
7696 if Is_Integer_Type (Typ)
7697 and then Compile_Time_Known_Value (Right_Opnd (N))
7698 and then Expr_Value (Right_Opnd (N)) = 0
7700 Rewrite (N, Left_Opnd (N));
7704 -- Arithmetic overflow checks for signed integer/fixed point types
7706 if Is_Signed_Integer_Type (Typ)
7708 Is_Fixed_Point_Type (Typ)
7710 Apply_Arithmetic_Overflow_Check (N);
7712 -- VAX floating-point types case
7714 elsif Vax_Float (Typ) then
7715 Expand_Vax_Arith (N);
7717 end Expand_N_Op_Subtract;
7719 ---------------------
7720 -- Expand_N_Op_Xor --
7721 ---------------------
7723 procedure Expand_N_Op_Xor (N : Node_Id) is
7724 Typ : constant Entity_Id := Etype (N);
7727 Binary_Op_Validity_Checks (N);
7729 if Is_Array_Type (Etype (N)) then
7730 Expand_Boolean_Operator (N);
7732 elsif Is_Boolean_Type (Etype (N)) then
7733 Adjust_Condition (Left_Opnd (N));
7734 Adjust_Condition (Right_Opnd (N));
7735 Set_Etype (N, Standard_Boolean);
7736 Adjust_Result_Type (N, Typ);
7738 elsif Is_Intrinsic_Subprogram (Entity (N)) then
7739 Expand_Intrinsic_Call (N, Entity (N));
7742 end Expand_N_Op_Xor;
7744 ----------------------
7745 -- Expand_N_Or_Else --
7746 ----------------------
7748 procedure Expand_N_Or_Else (N : Node_Id)
7749 renames Expand_Short_Circuit_Operator;
7751 -----------------------------------
7752 -- Expand_N_Qualified_Expression --
7753 -----------------------------------
7755 procedure Expand_N_Qualified_Expression (N : Node_Id) is
7756 Operand : constant Node_Id := Expression (N);
7757 Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));
7760 -- Do validity check if validity checking operands
7762 if Validity_Checks_On
7763 and then Validity_Check_Operands
7765 Ensure_Valid (Operand);
7768 -- Apply possible constraint check
7770 Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);
7772 if Do_Range_Check (Operand) then
7773 Set_Do_Range_Check (Operand, False);
7774 Generate_Range_Check (Operand, Target_Type, CE_Range_Check_Failed);
7776 end Expand_N_Qualified_Expression;
7778 ------------------------------------
7779 -- Expand_N_Quantified_Expression --
7780 ------------------------------------
7784 -- for all X in range => Cond
7789 -- for X in range loop
7796 -- Conversely, an existentially quantified expression:
7798 -- for some X in range => Cond
7803 -- for X in range loop
7810 -- In both cases, the iteration may be over a container in which case it is
7811 -- given by an iterator specification, not a loop parameter specification.
7813 procedure Expand_N_Quantified_Expression (N : Node_Id) is
7814 Loc : constant Source_Ptr := Sloc (N);
7815 Is_Universal : constant Boolean := All_Present (N);
7816 Actions : constant List_Id := New_List;
7817 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
7825 Make_Object_Declaration (Loc,
7826 Defining_Identifier => Tnn,
7827 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
7829 New_Occurrence_Of (Boolean_Literals (Is_Universal), Loc));
7830 Append_To (Actions, Decl);
7832 Cond := Relocate_Node (Condition (N));
7834 -- Reset flag analyzed in the condition to force its analysis. Required
7835 -- since the previous analysis was done with expansion disabled (see
7836 -- Resolve_Quantified_Expression) and hence checks were not inserted
7837 -- and record comparisons have not been expanded.
7839 Reset_Analyzed_Flags (Cond);
7841 if Is_Universal then
7842 Cond := Make_Op_Not (Loc, Cond);
7846 Make_Implicit_If_Statement (N,
7848 Then_Statements => New_List (
7849 Make_Assignment_Statement (Loc,
7850 Name => New_Occurrence_Of (Tnn, Loc),
7852 New_Occurrence_Of (Boolean_Literals (not Is_Universal), Loc)),
7853 Make_Exit_Statement (Loc)));
7855 if Present (Loop_Parameter_Specification (N)) then
7857 Make_Iteration_Scheme (Loc,
7858 Loop_Parameter_Specification =>
7859 Loop_Parameter_Specification (N));
7862 Make_Iteration_Scheme (Loc,
7863 Iterator_Specification => Iterator_Specification (N));
7867 Make_Loop_Statement (Loc,
7868 Iteration_Scheme => I_Scheme,
7869 Statements => New_List (Test),
7870 End_Label => Empty));
7873 Make_Expression_With_Actions (Loc,
7874 Expression => New_Occurrence_Of (Tnn, Loc),
7875 Actions => Actions));
7877 Analyze_And_Resolve (N, Standard_Boolean);
7878 end Expand_N_Quantified_Expression;
7880 ---------------------------------
7881 -- Expand_N_Selected_Component --
7882 ---------------------------------
7884 -- If the selector is a discriminant of a concurrent object, rewrite the
7885 -- prefix to denote the corresponding record type.
7887 procedure Expand_N_Selected_Component (N : Node_Id) is
7888 Loc : constant Source_Ptr := Sloc (N);
7889 Par : constant Node_Id := Parent (N);
7890 P : constant Node_Id := Prefix (N);
7891 Ptyp : Entity_Id := Underlying_Type (Etype (P));
7897 function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
7898 -- Gigi needs a temporary for prefixes that depend on a discriminant,
7899 -- unless the context of an assignment can provide size information.
7900 -- Don't we have a general routine that does this???
7902 function Is_Subtype_Declaration return Boolean;
7903 -- The replacement of a discriminant reference by its value is required
7904 -- if this is part of the initialization of an temporary generated by a
7905 -- change of representation. This shows up as the construction of a
7906 -- discriminant constraint for a subtype declared at the same point as
7907 -- the entity in the prefix of the selected component. We recognize this
7908 -- case when the context of the reference is:
7909 -- subtype ST is T(Obj.D);
7910 -- where the entity for Obj comes from source, and ST has the same sloc.
7912 -----------------------
7913 -- In_Left_Hand_Side --
7914 -----------------------
7916 function In_Left_Hand_Side (Comp : Node_Id) return Boolean is
7918 return (Nkind (Parent (Comp)) = N_Assignment_Statement
7919 and then Comp = Name (Parent (Comp)))
7920 or else (Present (Parent (Comp))
7921 and then Nkind (Parent (Comp)) in N_Subexpr
7922 and then In_Left_Hand_Side (Parent (Comp)));
7923 end In_Left_Hand_Side;
7925 -----------------------------
7926 -- Is_Subtype_Declaration --
7927 -----------------------------
7929 function Is_Subtype_Declaration return Boolean is
7930 Par : constant Node_Id := Parent (N);
7933 Nkind (Par) = N_Index_Or_Discriminant_Constraint
7934 and then Nkind (Parent (Parent (Par))) = N_Subtype_Declaration
7935 and then Comes_From_Source (Entity (Prefix (N)))
7936 and then Sloc (Par) = Sloc (Entity (Prefix (N)));
7937 end Is_Subtype_Declaration;
7939 -- Start of processing for Expand_N_Selected_Component
7942 -- Insert explicit dereference if required
7944 if Is_Access_Type (Ptyp) then
7946 -- First set prefix type to proper access type, in case it currently
7947 -- has a private (non-access) view of this type.
7949 Set_Etype (P, Ptyp);
7951 Insert_Explicit_Dereference (P);
7952 Analyze_And_Resolve (P, Designated_Type (Ptyp));
7954 if Ekind (Etype (P)) = E_Private_Subtype
7955 and then Is_For_Access_Subtype (Etype (P))
7957 Set_Etype (P, Base_Type (Etype (P)));
7963 -- Deal with discriminant check required
7965 if Do_Discriminant_Check (N) then
7967 -- Present the discriminant checking function to the backend, so that
7968 -- it can inline the call to the function.
7971 (Discriminant_Checking_Func
7972 (Original_Record_Component (Entity (Selector_Name (N)))));
7974 -- Now reset the flag and generate the call
7976 Set_Do_Discriminant_Check (N, False);
7977 Generate_Discriminant_Check (N);
7980 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
7981 -- function, then additional actuals must be passed.
7983 if Ada_Version >= Ada_2005
7984 and then Is_Build_In_Place_Function_Call (P)
7986 Make_Build_In_Place_Call_In_Anonymous_Context (P);
7989 -- Gigi cannot handle unchecked conversions that are the prefix of a
7990 -- selected component with discriminants. This must be checked during
7991 -- expansion, because during analysis the type of the selector is not
7992 -- known at the point the prefix is analyzed. If the conversion is the
7993 -- target of an assignment, then we cannot force the evaluation.
7995 if Nkind (Prefix (N)) = N_Unchecked_Type_Conversion
7996 and then Has_Discriminants (Etype (N))
7997 and then not In_Left_Hand_Side (N)
7999 Force_Evaluation (Prefix (N));
8002 -- Remaining processing applies only if selector is a discriminant
8004 if Ekind (Entity (Selector_Name (N))) = E_Discriminant then
8006 -- If the selector is a discriminant of a constrained record type,
8007 -- we may be able to rewrite the expression with the actual value
8008 -- of the discriminant, a useful optimization in some cases.
8010 if Is_Record_Type (Ptyp)
8011 and then Has_Discriminants (Ptyp)
8012 and then Is_Constrained (Ptyp)
8014 -- Do this optimization for discrete types only, and not for
8015 -- access types (access discriminants get us into trouble!)
8017 if not Is_Discrete_Type (Etype (N)) then
8020 -- Don't do this on the left hand of an assignment statement.
8021 -- Normally one would think that references like this would not
8022 -- occur, but they do in generated code, and mean that we really
8023 -- do want to assign the discriminant!
8025 elsif Nkind (Par) = N_Assignment_Statement
8026 and then Name (Par) = N
8030 -- Don't do this optimization for the prefix of an attribute or
8031 -- the name of an object renaming declaration since these are
8032 -- contexts where we do not want the value anyway.
8034 elsif (Nkind (Par) = N_Attribute_Reference
8035 and then Prefix (Par) = N)
8036 or else Is_Renamed_Object (N)
8040 -- Don't do this optimization if we are within the code for a
8041 -- discriminant check, since the whole point of such a check may
8042 -- be to verify the condition on which the code below depends!
8044 elsif Is_In_Discriminant_Check (N) then
8047 -- Green light to see if we can do the optimization. There is
8048 -- still one condition that inhibits the optimization below but
8049 -- now is the time to check the particular discriminant.
8052 -- Loop through discriminants to find the matching discriminant
8053 -- constraint to see if we can copy it.
8055 Disc := First_Discriminant (Ptyp);
8056 Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
8057 Discr_Loop : while Present (Dcon) loop
8058 Dval := Node (Dcon);
8060 -- Check if this is the matching discriminant and if the
8061 -- discriminant value is simple enough to make sense to
8062 -- copy. We don't want to copy complex expressions, and
8063 -- indeed to do so can cause trouble (before we put in
8064 -- this guard, a discriminant expression containing an
8065 -- AND THEN was copied, causing problems for coverage
8068 -- However, if the reference is part of the initialization
8069 -- code generated for an object declaration, we must use
8070 -- the discriminant value from the subtype constraint,
8071 -- because the selected component may be a reference to the
8072 -- object being initialized, whose discriminant is not yet
8073 -- set. This only happens in complex cases involving changes
8074 -- or representation.
8076 if Disc = Entity (Selector_Name (N))
8077 and then (Is_Entity_Name (Dval)
8078 or else Compile_Time_Known_Value (Dval)
8079 or else Is_Subtype_Declaration)
8081 -- Here we have the matching discriminant. Check for
8082 -- the case of a discriminant of a component that is
8083 -- constrained by an outer discriminant, which cannot
8084 -- be optimized away.
8086 if Denotes_Discriminant
8087 (Dval, Check_Concurrent => True)
8091 elsif Nkind (Original_Node (Dval)) = N_Selected_Component
8093 Denotes_Discriminant
8094 (Selector_Name (Original_Node (Dval)), True)
8098 -- Do not retrieve value if constraint is not static. It
8099 -- is generally not useful, and the constraint may be a
8100 -- rewritten outer discriminant in which case it is in
8103 elsif Is_Entity_Name (Dval)
8104 and then Nkind (Parent (Entity (Dval))) =
8105 N_Object_Declaration
8106 and then Present (Expression (Parent (Entity (Dval))))
8108 not Is_Static_Expression
8109 (Expression (Parent (Entity (Dval))))
8113 -- In the context of a case statement, the expression may
8114 -- have the base type of the discriminant, and we need to
8115 -- preserve the constraint to avoid spurious errors on
8118 elsif Nkind (Parent (N)) = N_Case_Statement
8119 and then Etype (Dval) /= Etype (Disc)
8122 Make_Qualified_Expression (Loc,
8124 New_Occurrence_Of (Etype (Disc), Loc),
8126 New_Copy_Tree (Dval)));
8127 Analyze_And_Resolve (N, Etype (Disc));
8129 -- In case that comes out as a static expression,
8130 -- reset it (a selected component is never static).
8132 Set_Is_Static_Expression (N, False);
8135 -- Otherwise we can just copy the constraint, but the
8136 -- result is certainly not static! In some cases the
8137 -- discriminant constraint has been analyzed in the
8138 -- context of the original subtype indication, but for
8139 -- itypes the constraint might not have been analyzed
8140 -- yet, and this must be done now.
8143 Rewrite (N, New_Copy_Tree (Dval));
8144 Analyze_And_Resolve (N);
8145 Set_Is_Static_Expression (N, False);
8151 Next_Discriminant (Disc);
8152 end loop Discr_Loop;
8154 -- Note: the above loop should always find a matching
8155 -- discriminant, but if it does not, we just missed an
8156 -- optimization due to some glitch (perhaps a previous
8157 -- error), so ignore.
8162 -- The only remaining processing is in the case of a discriminant of
8163 -- a concurrent object, where we rewrite the prefix to denote the
8164 -- corresponding record type. If the type is derived and has renamed
8165 -- discriminants, use corresponding discriminant, which is the one
8166 -- that appears in the corresponding record.
8168 if not Is_Concurrent_Type (Ptyp) then
8172 Disc := Entity (Selector_Name (N));
8174 if Is_Derived_Type (Ptyp)
8175 and then Present (Corresponding_Discriminant (Disc))
8177 Disc := Corresponding_Discriminant (Disc);
8181 Make_Selected_Component (Loc,
8183 Unchecked_Convert_To (Corresponding_Record_Type (Ptyp),
8185 Selector_Name => Make_Identifier (Loc, Chars (Disc)));
8190 end Expand_N_Selected_Component;
8192 --------------------
8193 -- Expand_N_Slice --
8194 --------------------
8196 procedure Expand_N_Slice (N : Node_Id) is
8197 Loc : constant Source_Ptr := Sloc (N);
8198 Typ : constant Entity_Id := Etype (N);
8199 Pfx : constant Node_Id := Prefix (N);
8200 Ptp : Entity_Id := Etype (Pfx);
8202 function Is_Procedure_Actual (N : Node_Id) return Boolean;
8203 -- Check whether the argument is an actual for a procedure call, in
8204 -- which case the expansion of a bit-packed slice is deferred until the
8205 -- call itself is expanded. The reason this is required is that we might
8206 -- have an IN OUT or OUT parameter, and the copy out is essential, and
8207 -- that copy out would be missed if we created a temporary here in
8208 -- Expand_N_Slice. Note that we don't bother to test specifically for an
8209 -- IN OUT or OUT mode parameter, since it is a bit tricky to do, and it
8210 -- is harmless to defer expansion in the IN case, since the call
8211 -- processing will still generate the appropriate copy in operation,
8212 -- which will take care of the slice.
8214 procedure Make_Temporary_For_Slice;
8215 -- Create a named variable for the value of the slice, in cases where
8216 -- the back-end cannot handle it properly, e.g. when packed types or
8217 -- unaligned slices are involved.
8219 -------------------------
8220 -- Is_Procedure_Actual --
8221 -------------------------
8223 function Is_Procedure_Actual (N : Node_Id) return Boolean is
8224 Par : Node_Id := Parent (N);
8228 -- If our parent is a procedure call we can return
8230 if Nkind (Par) = N_Procedure_Call_Statement then
8233 -- If our parent is a type conversion, keep climbing the tree,
8234 -- since a type conversion can be a procedure actual. Also keep
8235 -- climbing if parameter association or a qualified expression,
8236 -- since these are additional cases that do can appear on
8237 -- procedure actuals.
8239 elsif Nkind_In (Par, N_Type_Conversion,
8240 N_Parameter_Association,
8241 N_Qualified_Expression)
8243 Par := Parent (Par);
8245 -- Any other case is not what we are looking for
8251 end Is_Procedure_Actual;
8253 ------------------------------
8254 -- Make_Temporary_For_Slice --
8255 ------------------------------
8257 procedure Make_Temporary_For_Slice is
8259 Ent : constant Entity_Id := Make_Temporary (Loc, 'T', N);
8263 Make_Object_Declaration (Loc,
8264 Defining_Identifier => Ent,
8265 Object_Definition => New_Occurrence_Of (Typ, Loc));
8267 Set_No_Initialization (Decl);
8269 Insert_Actions (N, New_List (
8271 Make_Assignment_Statement (Loc,
8272 Name => New_Occurrence_Of (Ent, Loc),
8273 Expression => Relocate_Node (N))));
8275 Rewrite (N, New_Occurrence_Of (Ent, Loc));
8276 Analyze_And_Resolve (N, Typ);
8277 end Make_Temporary_For_Slice;
8279 -- Start of processing for Expand_N_Slice
8282 -- Special handling for access types
8284 if Is_Access_Type (Ptp) then
8286 Ptp := Designated_Type (Ptp);
8289 Make_Explicit_Dereference (Sloc (N),
8290 Prefix => Relocate_Node (Pfx)));
8292 Analyze_And_Resolve (Pfx, Ptp);
8295 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
8296 -- function, then additional actuals must be passed.
8298 if Ada_Version >= Ada_2005
8299 and then Is_Build_In_Place_Function_Call (Pfx)
8301 Make_Build_In_Place_Call_In_Anonymous_Context (Pfx);
8304 -- The remaining case to be handled is packed slices. We can leave
8305 -- packed slices as they are in the following situations:
8307 -- 1. Right or left side of an assignment (we can handle this
8308 -- situation correctly in the assignment statement expansion).
8310 -- 2. Prefix of indexed component (the slide is optimized away in this
8311 -- case, see the start of Expand_N_Slice.)
8313 -- 3. Object renaming declaration, since we want the name of the
8314 -- slice, not the value.
8316 -- 4. Argument to procedure call, since copy-in/copy-out handling may
8317 -- be required, and this is handled in the expansion of call
8320 -- 5. Prefix of an address attribute (this is an error which is caught
8321 -- elsewhere, and the expansion would interfere with generating the
8324 if not Is_Packed (Typ) then
8326 -- Apply transformation for actuals of a function call, where
8327 -- Expand_Actuals is not used.
8329 if Nkind (Parent (N)) = N_Function_Call
8330 and then Is_Possibly_Unaligned_Slice (N)
8332 Make_Temporary_For_Slice;
8335 elsif Nkind (Parent (N)) = N_Assignment_Statement
8336 or else (Nkind (Parent (Parent (N))) = N_Assignment_Statement
8337 and then Parent (N) = Name (Parent (Parent (N))))
8341 elsif Nkind (Parent (N)) = N_Indexed_Component
8342 or else Is_Renamed_Object (N)
8343 or else Is_Procedure_Actual (N)
8347 elsif Nkind (Parent (N)) = N_Attribute_Reference
8348 and then Attribute_Name (Parent (N)) = Name_Address
8353 Make_Temporary_For_Slice;
8357 ------------------------------
8358 -- Expand_N_Type_Conversion --
8359 ------------------------------
8361 procedure Expand_N_Type_Conversion (N : Node_Id) is
8362 Loc : constant Source_Ptr := Sloc (N);
8363 Operand : constant Node_Id := Expression (N);
8364 Target_Type : constant Entity_Id := Etype (N);
8365 Operand_Type : Entity_Id := Etype (Operand);
8367 procedure Handle_Changed_Representation;
8368 -- This is called in the case of record and array type conversions to
8369 -- see if there is a change of representation to be handled. Change of
8370 -- representation is actually handled at the assignment statement level,
8371 -- and what this procedure does is rewrite node N conversion as an
8372 -- assignment to temporary. If there is no change of representation,
8373 -- then the conversion node is unchanged.
8375 procedure Raise_Accessibility_Error;
8376 -- Called when we know that an accessibility check will fail. Rewrites
8377 -- node N to an appropriate raise statement and outputs warning msgs.
8378 -- The Etype of the raise node is set to Target_Type.
8380 procedure Real_Range_Check;
8381 -- Handles generation of range check for real target value
8383 function Has_Extra_Accessibility (Id : Entity_Id) return Boolean;
8384 -- True iff Present (Effective_Extra_Accessibility (Id)) successfully
8385 -- evaluates to True.
8387 -----------------------------------
8388 -- Handle_Changed_Representation --
8389 -----------------------------------
8391 procedure Handle_Changed_Representation is
8400 -- Nothing else to do if no change of representation
8402 if Same_Representation (Operand_Type, Target_Type) then
8405 -- The real change of representation work is done by the assignment
8406 -- statement processing. So if this type conversion is appearing as
8407 -- the expression of an assignment statement, nothing needs to be
8408 -- done to the conversion.
8410 elsif Nkind (Parent (N)) = N_Assignment_Statement then
8413 -- Otherwise we need to generate a temporary variable, and do the
8414 -- change of representation assignment into that temporary variable.
8415 -- The conversion is then replaced by a reference to this variable.
8420 -- If type is unconstrained we have to add a constraint, copied
8421 -- from the actual value of the left hand side.
8423 if not Is_Constrained (Target_Type) then
8424 if Has_Discriminants (Operand_Type) then
8425 Disc := First_Discriminant (Operand_Type);
8427 if Disc /= First_Stored_Discriminant (Operand_Type) then
8428 Disc := First_Stored_Discriminant (Operand_Type);
8432 while Present (Disc) loop
8434 Make_Selected_Component (Loc,
8436 Duplicate_Subexpr_Move_Checks (Operand),
8438 Make_Identifier (Loc, Chars (Disc))));
8439 Next_Discriminant (Disc);
8442 elsif Is_Array_Type (Operand_Type) then
8443 N_Ix := First_Index (Target_Type);
8446 for J in 1 .. Number_Dimensions (Operand_Type) loop
8448 -- We convert the bounds explicitly. We use an unchecked
8449 -- conversion because bounds checks are done elsewhere.
8454 Unchecked_Convert_To (Etype (N_Ix),
8455 Make_Attribute_Reference (Loc,
8457 Duplicate_Subexpr_No_Checks
8458 (Operand, Name_Req => True),
8459 Attribute_Name => Name_First,
8460 Expressions => New_List (
8461 Make_Integer_Literal (Loc, J)))),
8464 Unchecked_Convert_To (Etype (N_Ix),
8465 Make_Attribute_Reference (Loc,
8467 Duplicate_Subexpr_No_Checks
8468 (Operand, Name_Req => True),
8469 Attribute_Name => Name_Last,
8470 Expressions => New_List (
8471 Make_Integer_Literal (Loc, J))))));
8478 Odef := New_Occurrence_Of (Target_Type, Loc);
8480 if Present (Cons) then
8482 Make_Subtype_Indication (Loc,
8483 Subtype_Mark => Odef,
8485 Make_Index_Or_Discriminant_Constraint (Loc,
8486 Constraints => Cons));
8489 Temp := Make_Temporary (Loc, 'C');
8491 Make_Object_Declaration (Loc,
8492 Defining_Identifier => Temp,
8493 Object_Definition => Odef);
8495 Set_No_Initialization (Decl, True);
8497 -- Insert required actions. It is essential to suppress checks
8498 -- since we have suppressed default initialization, which means
8499 -- that the variable we create may have no discriminants.
8504 Make_Assignment_Statement (Loc,
8505 Name => New_Occurrence_Of (Temp, Loc),
8506 Expression => Relocate_Node (N))),
8507 Suppress => All_Checks);
8509 Rewrite (N, New_Occurrence_Of (Temp, Loc));
8512 end Handle_Changed_Representation;
8514 -------------------------------
8515 -- Raise_Accessibility_Error --
8516 -------------------------------
8518 procedure Raise_Accessibility_Error is
8521 Make_Raise_Program_Error (Sloc (N),
8522 Reason => PE_Accessibility_Check_Failed));
8523 Set_Etype (N, Target_Type);
8525 Error_Msg_N ("?accessibility check failure", N);
8527 ("\?& will be raised at run time", N, Standard_Program_Error);
8528 end Raise_Accessibility_Error;
8530 ----------------------
8531 -- Real_Range_Check --
8532 ----------------------
8534 -- Case of conversions to floating-point or fixed-point. If range checks
8535 -- are enabled and the target type has a range constraint, we convert:
8541 -- Tnn : typ'Base := typ'Base (x);
8542 -- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
8545 -- This is necessary when there is a conversion of integer to float or
8546 -- to fixed-point to ensure that the correct checks are made. It is not
8547 -- necessary for float to float where it is enough to simply set the
8548 -- Do_Range_Check flag.
8550 procedure Real_Range_Check is
8551 Btyp : constant Entity_Id := Base_Type (Target_Type);
8552 Lo : constant Node_Id := Type_Low_Bound (Target_Type);
8553 Hi : constant Node_Id := Type_High_Bound (Target_Type);
8554 Xtyp : constant Entity_Id := Etype (Operand);
8559 -- Nothing to do if conversion was rewritten
8561 if Nkind (N) /= N_Type_Conversion then
8565 -- Nothing to do if range checks suppressed, or target has the same
8566 -- range as the base type (or is the base type).
8568 if Range_Checks_Suppressed (Target_Type)
8569 or else (Lo = Type_Low_Bound (Btyp)
8571 Hi = Type_High_Bound (Btyp))
8576 -- Nothing to do if expression is an entity on which checks have been
8579 if Is_Entity_Name (Operand)
8580 and then Range_Checks_Suppressed (Entity (Operand))
8585 -- Nothing to do if bounds are all static and we can tell that the
8586 -- expression is within the bounds of the target. Note that if the
8587 -- operand is of an unconstrained floating-point type, then we do
8588 -- not trust it to be in range (might be infinite)
8591 S_Lo : constant Node_Id := Type_Low_Bound (Xtyp);
8592 S_Hi : constant Node_Id := Type_High_Bound (Xtyp);
8595 if (not Is_Floating_Point_Type (Xtyp)
8596 or else Is_Constrained (Xtyp))
8597 and then Compile_Time_Known_Value (S_Lo)
8598 and then Compile_Time_Known_Value (S_Hi)
8599 and then Compile_Time_Known_Value (Hi)
8600 and then Compile_Time_Known_Value (Lo)
8603 D_Lov : constant Ureal := Expr_Value_R (Lo);
8604 D_Hiv : constant Ureal := Expr_Value_R (Hi);
8609 if Is_Real_Type (Xtyp) then
8610 S_Lov := Expr_Value_R (S_Lo);
8611 S_Hiv := Expr_Value_R (S_Hi);
8613 S_Lov := UR_From_Uint (Expr_Value (S_Lo));
8614 S_Hiv := UR_From_Uint (Expr_Value (S_Hi));
8618 and then S_Lov >= D_Lov
8619 and then S_Hiv <= D_Hiv
8621 Set_Do_Range_Check (Operand, False);
8628 -- For float to float conversions, we are done
8630 if Is_Floating_Point_Type (Xtyp)
8632 Is_Floating_Point_Type (Btyp)
8637 -- Otherwise rewrite the conversion as described above
8639 Conv := Relocate_Node (N);
8640 Rewrite (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc));
8641 Set_Etype (Conv, Btyp);
8643 -- Enable overflow except for case of integer to float conversions,
8644 -- where it is never required, since we can never have overflow in
8647 if not Is_Integer_Type (Etype (Operand)) then
8648 Enable_Overflow_Check (Conv);
8651 Tnn := Make_Temporary (Loc, 'T', Conv);
8653 Insert_Actions (N, New_List (
8654 Make_Object_Declaration (Loc,
8655 Defining_Identifier => Tnn,
8656 Object_Definition => New_Occurrence_Of (Btyp, Loc),
8657 Constant_Present => True,
8658 Expression => Conv),
8660 Make_Raise_Constraint_Error (Loc,
8665 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
8667 Make_Attribute_Reference (Loc,
8668 Attribute_Name => Name_First,
8670 New_Occurrence_Of (Target_Type, Loc))),
8674 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
8676 Make_Attribute_Reference (Loc,
8677 Attribute_Name => Name_Last,
8679 New_Occurrence_Of (Target_Type, Loc)))),
8680 Reason => CE_Range_Check_Failed)));
8682 Rewrite (N, New_Occurrence_Of (Tnn, Loc));
8683 Analyze_And_Resolve (N, Btyp);
8684 end Real_Range_Check;
8686 -----------------------------
8687 -- Has_Extra_Accessibility --
8688 -----------------------------
8690 -- Returns true for a formal of an anonymous access type or for
8691 -- an Ada 2012-style stand-alone object of an anonymous access type.
8693 function Has_Extra_Accessibility (Id : Entity_Id) return Boolean is
8695 if Is_Formal (Id) or else Ekind_In (Id, E_Constant, E_Variable) then
8696 return Present (Effective_Extra_Accessibility (Id));
8700 end Has_Extra_Accessibility;
8702 -- Start of processing for Expand_N_Type_Conversion
8705 -- Nothing at all to do if conversion is to the identical type so remove
8706 -- the conversion completely, it is useless, except that it may carry
8707 -- an Assignment_OK attribute, which must be propagated to the operand.
8709 if Operand_Type = Target_Type then
8710 if Assignment_OK (N) then
8711 Set_Assignment_OK (Operand);
8714 Rewrite (N, Relocate_Node (Operand));
8718 -- Nothing to do if this is the second argument of read. This is a
8719 -- "backwards" conversion that will be handled by the specialized code
8720 -- in attribute processing.
8722 if Nkind (Parent (N)) = N_Attribute_Reference
8723 and then Attribute_Name (Parent (N)) = Name_Read
8724 and then Next (First (Expressions (Parent (N)))) = N
8729 -- Check for case of converting to a type that has an invariant
8730 -- associated with it. This required an invariant check. We convert
8736 -- do invariant_check (typ (expr)) in typ (expr);
8738 -- using Duplicate_Subexpr to avoid multiple side effects
8740 -- Note: the Comes_From_Source check, and then the resetting of this
8741 -- flag prevents what would otherwise be an infinite recursion.
8743 if Has_Invariants (Target_Type)
8744 and then Present (Invariant_Procedure (Target_Type))
8745 and then Comes_From_Source (N)
8747 Set_Comes_From_Source (N, False);
8749 Make_Expression_With_Actions (Loc,
8750 Actions => New_List (
8751 Make_Invariant_Call (Duplicate_Subexpr (N))),
8752 Expression => Duplicate_Subexpr_No_Checks (N)));
8753 Analyze_And_Resolve (N, Target_Type);
8757 -- Here if we may need to expand conversion
8759 -- If the operand of the type conversion is an arithmetic operation on
8760 -- signed integers, and the based type of the signed integer type in
8761 -- question is smaller than Standard.Integer, we promote both of the
8762 -- operands to type Integer.
8764 -- For example, if we have
8766 -- target-type (opnd1 + opnd2)
8768 -- and opnd1 and opnd2 are of type short integer, then we rewrite
8771 -- target-type (integer(opnd1) + integer(opnd2))
8773 -- We do this because we are always allowed to compute in a larger type
8774 -- if we do the right thing with the result, and in this case we are
8775 -- going to do a conversion which will do an appropriate check to make
8776 -- sure that things are in range of the target type in any case. This
8777 -- avoids some unnecessary intermediate overflows.
8779 -- We might consider a similar transformation in the case where the
8780 -- target is a real type or a 64-bit integer type, and the operand
8781 -- is an arithmetic operation using a 32-bit integer type. However,
8782 -- we do not bother with this case, because it could cause significant
8783 -- inefficiencies on 32-bit machines. On a 64-bit machine it would be
8784 -- much cheaper, but we don't want different behavior on 32-bit and
8785 -- 64-bit machines. Note that the exclusion of the 64-bit case also
8786 -- handles the configurable run-time cases where 64-bit arithmetic
8787 -- may simply be unavailable.
8789 -- Note: this circuit is partially redundant with respect to the circuit
8790 -- in Checks.Apply_Arithmetic_Overflow_Check, but we catch more cases in
8791 -- the processing here. Also we still need the Checks circuit, since we
8792 -- have to be sure not to generate junk overflow checks in the first
8793 -- place, since it would be trick to remove them here!
8795 if Integer_Promotion_Possible (N) then
8797 -- All conditions met, go ahead with transformation
8805 Make_Type_Conversion (Loc,
8806 Subtype_Mark => New_Reference_To (Standard_Integer, Loc),
8807 Expression => Relocate_Node (Right_Opnd (Operand)));
8809 Opnd := New_Op_Node (Nkind (Operand), Loc);
8810 Set_Right_Opnd (Opnd, R);
8812 if Nkind (Operand) in N_Binary_Op then
8814 Make_Type_Conversion (Loc,
8815 Subtype_Mark => New_Reference_To (Standard_Integer, Loc),
8816 Expression => Relocate_Node (Left_Opnd (Operand)));
8818 Set_Left_Opnd (Opnd, L);
8822 Make_Type_Conversion (Loc,
8823 Subtype_Mark => Relocate_Node (Subtype_Mark (N)),
8824 Expression => Opnd));
8826 Analyze_And_Resolve (N, Target_Type);
8831 -- Do validity check if validity checking operands
8833 if Validity_Checks_On
8834 and then Validity_Check_Operands
8836 Ensure_Valid (Operand);
8839 -- Special case of converting from non-standard boolean type
8841 if Is_Boolean_Type (Operand_Type)
8842 and then (Nonzero_Is_True (Operand_Type))
8844 Adjust_Condition (Operand);
8845 Set_Etype (Operand, Standard_Boolean);
8846 Operand_Type := Standard_Boolean;
8849 -- Case of converting to an access type
8851 if Is_Access_Type (Target_Type) then
8853 -- Apply an accessibility check when the conversion operand is an
8854 -- access parameter (or a renaming thereof), unless conversion was
8855 -- expanded from an Unchecked_ or Unrestricted_Access attribute.
8856 -- Note that other checks may still need to be applied below (such
8857 -- as tagged type checks).
8859 if Is_Entity_Name (Operand)
8860 and then Has_Extra_Accessibility (Entity (Operand))
8861 and then Ekind (Etype (Operand)) = E_Anonymous_Access_Type
8862 and then (Nkind (Original_Node (N)) /= N_Attribute_Reference
8863 or else Attribute_Name (Original_Node (N)) = Name_Access)
8865 Apply_Accessibility_Check
8866 (Operand, Target_Type, Insert_Node => Operand);
8868 -- If the level of the operand type is statically deeper than the
8869 -- level of the target type, then force Program_Error. Note that this
8870 -- can only occur for cases where the attribute is within the body of
8871 -- an instantiation (otherwise the conversion will already have been
8872 -- rejected as illegal). Note: warnings are issued by the analyzer
8873 -- for the instance cases.
8875 elsif In_Instance_Body
8876 and then Type_Access_Level (Operand_Type) >
8877 Type_Access_Level (Target_Type)
8879 Raise_Accessibility_Error;
8881 -- When the operand is a selected access discriminant the check needs
8882 -- to be made against the level of the object denoted by the prefix
8883 -- of the selected name. Force Program_Error for this case as well
8884 -- (this accessibility violation can only happen if within the body
8885 -- of an instantiation).
8887 elsif In_Instance_Body
8888 and then Ekind (Operand_Type) = E_Anonymous_Access_Type
8889 and then Nkind (Operand) = N_Selected_Component
8890 and then Object_Access_Level (Operand) >
8891 Type_Access_Level (Target_Type)
8893 Raise_Accessibility_Error;
8898 -- Case of conversions of tagged types and access to tagged types
8900 -- When needed, that is to say when the expression is class-wide, Add
8901 -- runtime a tag check for (strict) downward conversion by using the
8902 -- membership test, generating:
8904 -- [constraint_error when Operand not in Target_Type'Class]
8906 -- or in the access type case
8908 -- [constraint_error
8909 -- when Operand /= null
8910 -- and then Operand.all not in
8911 -- Designated_Type (Target_Type)'Class]
8913 if (Is_Access_Type (Target_Type)
8914 and then Is_Tagged_Type (Designated_Type (Target_Type)))
8915 or else Is_Tagged_Type (Target_Type)
8917 -- Do not do any expansion in the access type case if the parent is a
8918 -- renaming, since this is an error situation which will be caught by
8919 -- Sem_Ch8, and the expansion can interfere with this error check.
8921 if Is_Access_Type (Target_Type) and then Is_Renamed_Object (N) then
8925 -- Otherwise, proceed with processing tagged conversion
8927 Tagged_Conversion : declare
8928 Actual_Op_Typ : Entity_Id;
8929 Actual_Targ_Typ : Entity_Id;
8930 Make_Conversion : Boolean := False;
8931 Root_Op_Typ : Entity_Id;
8933 procedure Make_Tag_Check (Targ_Typ : Entity_Id);
8934 -- Create a membership check to test whether Operand is a member
8935 -- of Targ_Typ. If the original Target_Type is an access, include
8936 -- a test for null value. The check is inserted at N.
8938 --------------------
8939 -- Make_Tag_Check --
8940 --------------------
8942 procedure Make_Tag_Check (Targ_Typ : Entity_Id) is
8947 -- [Constraint_Error
8948 -- when Operand /= null
8949 -- and then Operand.all not in Targ_Typ]
8951 if Is_Access_Type (Target_Type) then
8956 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
8957 Right_Opnd => Make_Null (Loc)),
8962 Make_Explicit_Dereference (Loc,
8963 Prefix => Duplicate_Subexpr_No_Checks (Operand)),
8964 Right_Opnd => New_Reference_To (Targ_Typ, Loc)));
8967 -- [Constraint_Error when Operand not in Targ_Typ]
8972 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
8973 Right_Opnd => New_Reference_To (Targ_Typ, Loc));
8977 Make_Raise_Constraint_Error (Loc,
8979 Reason => CE_Tag_Check_Failed));
8982 -- Start of processing for Tagged_Conversion
8985 -- Handle entities from the limited view
8987 if Is_Access_Type (Operand_Type) then
8989 Available_View (Designated_Type (Operand_Type));
8991 Actual_Op_Typ := Operand_Type;
8994 if Is_Access_Type (Target_Type) then
8996 Available_View (Designated_Type (Target_Type));
8998 Actual_Targ_Typ := Target_Type;
9001 Root_Op_Typ := Root_Type (Actual_Op_Typ);
9003 -- Ada 2005 (AI-251): Handle interface type conversion
9005 if Is_Interface (Actual_Op_Typ) then
9006 Expand_Interface_Conversion (N, Is_Static => False);
9010 if not Tag_Checks_Suppressed (Actual_Targ_Typ) then
9012 -- Create a runtime tag check for a downward class-wide type
9015 if Is_Class_Wide_Type (Actual_Op_Typ)
9016 and then Actual_Op_Typ /= Actual_Targ_Typ
9017 and then Root_Op_Typ /= Actual_Targ_Typ
9018 and then Is_Ancestor (Root_Op_Typ, Actual_Targ_Typ,
9019 Use_Full_View => True)
9021 Make_Tag_Check (Class_Wide_Type (Actual_Targ_Typ));
9022 Make_Conversion := True;
9025 -- AI05-0073: If the result subtype of the function is defined
9026 -- by an access_definition designating a specific tagged type
9027 -- T, a check is made that the result value is null or the tag
9028 -- of the object designated by the result value identifies T.
9029 -- Constraint_Error is raised if this check fails.
9031 if Nkind (Parent (N)) = Sinfo.N_Return_Statement then
9034 Func_Typ : Entity_Id;
9037 -- Climb scope stack looking for the enclosing function
9039 Func := Current_Scope;
9040 while Present (Func)
9041 and then Ekind (Func) /= E_Function
9043 Func := Scope (Func);
9046 -- The function's return subtype must be defined using
9047 -- an access definition.
9049 if Nkind (Result_Definition (Parent (Func))) =
9052 Func_Typ := Directly_Designated_Type (Etype (Func));
9054 -- The return subtype denotes a specific tagged type,
9055 -- in other words, a non class-wide type.
9057 if Is_Tagged_Type (Func_Typ)
9058 and then not Is_Class_Wide_Type (Func_Typ)
9060 Make_Tag_Check (Actual_Targ_Typ);
9061 Make_Conversion := True;
9067 -- We have generated a tag check for either a class-wide type
9068 -- conversion or for AI05-0073.
9070 if Make_Conversion then
9075 Make_Unchecked_Type_Conversion (Loc,
9076 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
9077 Expression => Relocate_Node (Expression (N)));
9079 Analyze_And_Resolve (N, Target_Type);
9083 end Tagged_Conversion;
9085 -- Case of other access type conversions
9087 elsif Is_Access_Type (Target_Type) then
9088 Apply_Constraint_Check (Operand, Target_Type);
9090 -- Case of conversions from a fixed-point type
9092 -- These conversions require special expansion and processing, found in
9093 -- the Exp_Fixd package. We ignore cases where Conversion_OK is set,
9094 -- since from a semantic point of view, these are simple integer
9095 -- conversions, which do not need further processing.
9097 elsif Is_Fixed_Point_Type (Operand_Type)
9098 and then not Conversion_OK (N)
9100 -- We should never see universal fixed at this case, since the
9101 -- expansion of the constituent divide or multiply should have
9102 -- eliminated the explicit mention of universal fixed.
9104 pragma Assert (Operand_Type /= Universal_Fixed);
9106 -- Check for special case of the conversion to universal real that
9107 -- occurs as a result of the use of a round attribute. In this case,
9108 -- the real type for the conversion is taken from the target type of
9109 -- the Round attribute and the result must be marked as rounded.
9111 if Target_Type = Universal_Real
9112 and then Nkind (Parent (N)) = N_Attribute_Reference
9113 and then Attribute_Name (Parent (N)) = Name_Round
9115 Set_Rounded_Result (N);
9116 Set_Etype (N, Etype (Parent (N)));
9119 -- Otherwise do correct fixed-conversion, but skip these if the
9120 -- Conversion_OK flag is set, because from a semantic point of view
9121 -- these are simple integer conversions needing no further processing
9122 -- (the backend will simply treat them as integers).
9124 if not Conversion_OK (N) then
9125 if Is_Fixed_Point_Type (Etype (N)) then
9126 Expand_Convert_Fixed_To_Fixed (N);
9129 elsif Is_Integer_Type (Etype (N)) then
9130 Expand_Convert_Fixed_To_Integer (N);
9133 pragma Assert (Is_Floating_Point_Type (Etype (N)));
9134 Expand_Convert_Fixed_To_Float (N);
9139 -- Case of conversions to a fixed-point type
9141 -- These conversions require special expansion and processing, found in
9142 -- the Exp_Fixd package. Again, ignore cases where Conversion_OK is set,
9143 -- since from a semantic point of view, these are simple integer
9144 -- conversions, which do not need further processing.
9146 elsif Is_Fixed_Point_Type (Target_Type)
9147 and then not Conversion_OK (N)
9149 if Is_Integer_Type (Operand_Type) then
9150 Expand_Convert_Integer_To_Fixed (N);
9153 pragma Assert (Is_Floating_Point_Type (Operand_Type));
9154 Expand_Convert_Float_To_Fixed (N);
9158 -- Case of float-to-integer conversions
9160 -- We also handle float-to-fixed conversions with Conversion_OK set
9161 -- since semantically the fixed-point target is treated as though it
9162 -- were an integer in such cases.
9164 elsif Is_Floating_Point_Type (Operand_Type)
9166 (Is_Integer_Type (Target_Type)
9168 (Is_Fixed_Point_Type (Target_Type) and then Conversion_OK (N)))
9170 -- One more check here, gcc is still not able to do conversions of
9171 -- this type with proper overflow checking, and so gigi is doing an
9172 -- approximation of what is required by doing floating-point compares
9173 -- with the end-point. But that can lose precision in some cases, and
9174 -- give a wrong result. Converting the operand to Universal_Real is
9175 -- helpful, but still does not catch all cases with 64-bit integers
9176 -- on targets with only 64-bit floats.
9178 -- The above comment seems obsoleted by Apply_Float_Conversion_Check
9179 -- Can this code be removed ???
9181 if Do_Range_Check (Operand) then
9183 Make_Type_Conversion (Loc,
9185 New_Occurrence_Of (Universal_Real, Loc),
9187 Relocate_Node (Operand)));
9189 Set_Etype (Operand, Universal_Real);
9190 Enable_Range_Check (Operand);
9191 Set_Do_Range_Check (Expression (Operand), False);
9194 -- Case of array conversions
9196 -- Expansion of array conversions, add required length/range checks but
9197 -- only do this if there is no change of representation. For handling of
9198 -- this case, see Handle_Changed_Representation.
9200 elsif Is_Array_Type (Target_Type) then
9201 if Is_Constrained (Target_Type) then
9202 Apply_Length_Check (Operand, Target_Type);
9204 Apply_Range_Check (Operand, Target_Type);
9207 Handle_Changed_Representation;
9209 -- Case of conversions of discriminated types
9211 -- Add required discriminant checks if target is constrained. Again this
9212 -- change is skipped if we have a change of representation.
9214 elsif Has_Discriminants (Target_Type)
9215 and then Is_Constrained (Target_Type)
9217 Apply_Discriminant_Check (Operand, Target_Type);
9218 Handle_Changed_Representation;
9220 -- Case of all other record conversions. The only processing required
9221 -- is to check for a change of representation requiring the special
9222 -- assignment processing.
9224 elsif Is_Record_Type (Target_Type) then
9226 -- Ada 2005 (AI-216): Program_Error is raised when converting from
9227 -- a derived Unchecked_Union type to an unconstrained type that is
9228 -- not Unchecked_Union if the operand lacks inferable discriminants.
9230 if Is_Derived_Type (Operand_Type)
9231 and then Is_Unchecked_Union (Base_Type (Operand_Type))
9232 and then not Is_Constrained (Target_Type)
9233 and then not Is_Unchecked_Union (Base_Type (Target_Type))
9234 and then not Has_Inferable_Discriminants (Operand)
9236 -- To prevent Gigi from generating illegal code, we generate a
9237 -- Program_Error node, but we give it the target type of the
9241 PE : constant Node_Id := Make_Raise_Program_Error (Loc,
9242 Reason => PE_Unchecked_Union_Restriction);
9245 Set_Etype (PE, Target_Type);
9250 Handle_Changed_Representation;
9253 -- Case of conversions of enumeration types
9255 elsif Is_Enumeration_Type (Target_Type) then
9257 -- Special processing is required if there is a change of
9258 -- representation (from enumeration representation clauses).
9260 if not Same_Representation (Target_Type, Operand_Type) then
9262 -- Convert: x(y) to x'val (ytyp'val (y))
9265 Make_Attribute_Reference (Loc,
9266 Prefix => New_Occurrence_Of (Target_Type, Loc),
9267 Attribute_Name => Name_Val,
9268 Expressions => New_List (
9269 Make_Attribute_Reference (Loc,
9270 Prefix => New_Occurrence_Of (Operand_Type, Loc),
9271 Attribute_Name => Name_Pos,
9272 Expressions => New_List (Operand)))));
9274 Analyze_And_Resolve (N, Target_Type);
9277 -- Case of conversions to floating-point
9279 elsif Is_Floating_Point_Type (Target_Type) then
9283 -- At this stage, either the conversion node has been transformed into
9284 -- some other equivalent expression, or left as a conversion that can be
9285 -- handled by Gigi, in the following cases:
9287 -- Conversions with no change of representation or type
9289 -- Numeric conversions involving integer, floating- and fixed-point
9290 -- values. Fixed-point values are allowed only if Conversion_OK is
9291 -- set, i.e. if the fixed-point values are to be treated as integers.
9293 -- No other conversions should be passed to Gigi
9295 -- Check: are these rules stated in sinfo??? if so, why restate here???
9297 -- The only remaining step is to generate a range check if we still have
9298 -- a type conversion at this stage and Do_Range_Check is set. For now we
9299 -- do this only for conversions of discrete types.
9301 if Nkind (N) = N_Type_Conversion
9302 and then Is_Discrete_Type (Etype (N))
9305 Expr : constant Node_Id := Expression (N);
9310 if Do_Range_Check (Expr)
9311 and then Is_Discrete_Type (Etype (Expr))
9313 Set_Do_Range_Check (Expr, False);
9315 -- Before we do a range check, we have to deal with treating a
9316 -- fixed-point operand as an integer. The way we do this is
9317 -- simply to do an unchecked conversion to an appropriate
9318 -- integer type large enough to hold the result.
9320 -- This code is not active yet, because we are only dealing
9321 -- with discrete types so far ???
9323 if Nkind (Expr) in N_Has_Treat_Fixed_As_Integer
9324 and then Treat_Fixed_As_Integer (Expr)
9326 Ftyp := Base_Type (Etype (Expr));
9328 if Esize (Ftyp) >= Esize (Standard_Integer) then
9329 Ityp := Standard_Long_Long_Integer;
9331 Ityp := Standard_Integer;
9334 Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
9337 -- Reset overflow flag, since the range check will include
9338 -- dealing with possible overflow, and generate the check. If
9339 -- Address is either a source type or target type, suppress
9340 -- range check to avoid typing anomalies when it is a visible
9343 Set_Do_Overflow_Check (N, False);
9344 if not Is_Descendent_Of_Address (Etype (Expr))
9345 and then not Is_Descendent_Of_Address (Target_Type)
9347 Generate_Range_Check
9348 (Expr, Target_Type, CE_Range_Check_Failed);
9354 -- Final step, if the result is a type conversion involving Vax_Float
9355 -- types, then it is subject for further special processing.
9357 if Nkind (N) = N_Type_Conversion
9358 and then (Vax_Float (Operand_Type) or else Vax_Float (Target_Type))
9360 Expand_Vax_Conversion (N);
9364 -- Here at end of processing
9367 -- Apply predicate check if required. Note that we can't just call
9368 -- Apply_Predicate_Check here, because the type looks right after
9369 -- the conversion and it would omit the check. The Comes_From_Source
9370 -- guard is necessary to prevent infinite recursions when we generate
9371 -- internal conversions for the purpose of checking predicates.
9373 if Present (Predicate_Function (Target_Type))
9374 and then Target_Type /= Operand_Type
9375 and then Comes_From_Source (N)
9378 New_Expr : constant Node_Id := Duplicate_Subexpr (N);
9381 -- Avoid infinite recursion on the subsequent expansion of
9382 -- of the copy of the original type conversion.
9384 Set_Comes_From_Source (New_Expr, False);
9385 Insert_Action (N, Make_Predicate_Check (Target_Type, New_Expr));
9388 end Expand_N_Type_Conversion;
9390 -----------------------------------
9391 -- Expand_N_Unchecked_Expression --
9392 -----------------------------------
9394 -- Remove the unchecked expression node from the tree. Its job was simply
9395 -- to make sure that its constituent expression was handled with checks
9396 -- off, and now that that is done, we can remove it from the tree, and
9397 -- indeed must, since Gigi does not expect to see these nodes.
9399 procedure Expand_N_Unchecked_Expression (N : Node_Id) is
9400 Exp : constant Node_Id := Expression (N);
9402 Set_Assignment_OK (Exp, Assignment_OK (N) or else Assignment_OK (Exp));
9404 end Expand_N_Unchecked_Expression;
9406 ----------------------------------------
9407 -- Expand_N_Unchecked_Type_Conversion --
9408 ----------------------------------------
9410 -- If this cannot be handled by Gigi and we haven't already made a
9411 -- temporary for it, do it now.
9413 procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id) is
9414 Target_Type : constant Entity_Id := Etype (N);
9415 Operand : constant Node_Id := Expression (N);
9416 Operand_Type : constant Entity_Id := Etype (Operand);
9419 -- Nothing at all to do if conversion is to the identical type so remove
9420 -- the conversion completely, it is useless, except that it may carry
9421 -- an Assignment_OK indication which must be propagated to the operand.
9423 if Operand_Type = Target_Type then
9425 -- Code duplicates Expand_N_Unchecked_Expression above, factor???
9427 if Assignment_OK (N) then
9428 Set_Assignment_OK (Operand);
9431 Rewrite (N, Relocate_Node (Operand));
9435 -- If we have a conversion of a compile time known value to a target
9436 -- type and the value is in range of the target type, then we can simply
9437 -- replace the construct by an integer literal of the correct type. We
9438 -- only apply this to integer types being converted. Possibly it may
9439 -- apply in other cases, but it is too much trouble to worry about.
9441 -- Note that we do not do this transformation if the Kill_Range_Check
9442 -- flag is set, since then the value may be outside the expected range.
9443 -- This happens in the Normalize_Scalars case.
9445 -- We also skip this if either the target or operand type is biased
9446 -- because in this case, the unchecked conversion is supposed to
9447 -- preserve the bit pattern, not the integer value.
9449 if Is_Integer_Type (Target_Type)
9450 and then not Has_Biased_Representation (Target_Type)
9451 and then Is_Integer_Type (Operand_Type)
9452 and then not Has_Biased_Representation (Operand_Type)
9453 and then Compile_Time_Known_Value (Operand)
9454 and then not Kill_Range_Check (N)
9457 Val : constant Uint := Expr_Value (Operand);
9460 if Compile_Time_Known_Value (Type_Low_Bound (Target_Type))
9462 Compile_Time_Known_Value (Type_High_Bound (Target_Type))
9464 Val >= Expr_Value (Type_Low_Bound (Target_Type))
9466 Val <= Expr_Value (Type_High_Bound (Target_Type))
9468 Rewrite (N, Make_Integer_Literal (Sloc (N), Val));
9470 -- If Address is the target type, just set the type to avoid a
9471 -- spurious type error on the literal when Address is a visible
9474 if Is_Descendent_Of_Address (Target_Type) then
9475 Set_Etype (N, Target_Type);
9477 Analyze_And_Resolve (N, Target_Type);
9485 -- Nothing to do if conversion is safe
9487 if Safe_Unchecked_Type_Conversion (N) then
9491 -- Otherwise force evaluation unless Assignment_OK flag is set (this
9492 -- flag indicates ??? -- more comments needed here)
9494 if Assignment_OK (N) then
9497 Force_Evaluation (N);
9499 end Expand_N_Unchecked_Type_Conversion;
9501 ----------------------------
9502 -- Expand_Record_Equality --
9503 ----------------------------
9505 -- For non-variant records, Equality is expanded when needed into:
9507 -- and then Lhs.Discr1 = Rhs.Discr1
9509 -- and then Lhs.Discrn = Rhs.Discrn
9510 -- and then Lhs.Cmp1 = Rhs.Cmp1
9512 -- and then Lhs.Cmpn = Rhs.Cmpn
9514 -- The expression is folded by the back-end for adjacent fields. This
9515 -- function is called for tagged record in only one occasion: for imple-
9516 -- menting predefined primitive equality (see Predefined_Primitives_Bodies)
9517 -- otherwise the primitive "=" is used directly.
9519 function Expand_Record_Equality
9524 Bodies : List_Id) return Node_Id
9526 Loc : constant Source_Ptr := Sloc (Nod);
9531 First_Time : Boolean := True;
9533 function Suitable_Element (C : Entity_Id) return Entity_Id;
9534 -- Return the first field to compare beginning with C, skipping the
9535 -- inherited components.
9537 ----------------------
9538 -- Suitable_Element --
9539 ----------------------
9541 function Suitable_Element (C : Entity_Id) return Entity_Id is
9546 elsif Ekind (C) /= E_Discriminant
9547 and then Ekind (C) /= E_Component
9549 return Suitable_Element (Next_Entity (C));
9551 elsif Is_Tagged_Type (Typ)
9552 and then C /= Original_Record_Component (C)
9554 return Suitable_Element (Next_Entity (C));
9556 elsif Chars (C) = Name_uTag then
9557 return Suitable_Element (Next_Entity (C));
9559 -- The .NET/JVM version of type Root_Controlled contains two fields
9560 -- which should not be considered part of the object. To achieve
9561 -- proper equiality between two controlled objects on .NET/JVM, skip
9562 -- field _parent whenever it is of type Root_Controlled.
9564 elsif Chars (C) = Name_uParent
9565 and then VM_Target /= No_VM
9566 and then Etype (C) = RTE (RE_Root_Controlled)
9568 return Suitable_Element (Next_Entity (C));
9570 elsif Is_Interface (Etype (C)) then
9571 return Suitable_Element (Next_Entity (C));
9576 end Suitable_Element;
9578 -- Start of processing for Expand_Record_Equality
9581 -- Generates the following code: (assuming that Typ has one Discr and
9582 -- component C2 is also a record)
9585 -- and then Lhs.Discr1 = Rhs.Discr1
9586 -- and then Lhs.C1 = Rhs.C1
9587 -- and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
9589 -- and then Lhs.Cmpn = Rhs.Cmpn
9591 Result := New_Reference_To (Standard_True, Loc);
9592 C := Suitable_Element (First_Entity (Typ));
9593 while Present (C) loop
9601 First_Time := False;
9605 New_Lhs := New_Copy_Tree (Lhs);
9606 New_Rhs := New_Copy_Tree (Rhs);
9610 Expand_Composite_Equality (Nod, Etype (C),
9612 Make_Selected_Component (Loc,
9614 Selector_Name => New_Reference_To (C, Loc)),
9616 Make_Selected_Component (Loc,
9618 Selector_Name => New_Reference_To (C, Loc)),
9621 -- If some (sub)component is an unchecked_union, the whole
9622 -- operation will raise program error.
9624 if Nkind (Check) = N_Raise_Program_Error then
9626 Set_Etype (Result, Standard_Boolean);
9631 Left_Opnd => Result,
9632 Right_Opnd => Check);
9636 C := Suitable_Element (Next_Entity (C));
9640 end Expand_Record_Equality;
9642 -----------------------------------
9643 -- Expand_Short_Circuit_Operator --
9644 -----------------------------------
9646 -- Deal with special expansion if actions are present for the right operand
9647 -- and deal with optimizing case of arguments being True or False. We also
9648 -- deal with the special case of non-standard boolean values.
9650 procedure Expand_Short_Circuit_Operator (N : Node_Id) is
9651 Loc : constant Source_Ptr := Sloc (N);
9652 Typ : constant Entity_Id := Etype (N);
9653 Left : constant Node_Id := Left_Opnd (N);
9654 Right : constant Node_Id := Right_Opnd (N);
9655 LocR : constant Source_Ptr := Sloc (Right);
9658 Shortcut_Value : constant Boolean := Nkind (N) = N_Or_Else;
9659 Shortcut_Ent : constant Entity_Id := Boolean_Literals (Shortcut_Value);
9660 -- If Left = Shortcut_Value then Right need not be evaluated
9662 function Make_Test_Expr (Opnd : Node_Id) return Node_Id;
9663 -- For Opnd a boolean expression, return a Boolean expression equivalent
9664 -- to Opnd /= Shortcut_Value.
9666 --------------------
9667 -- Make_Test_Expr --
9668 --------------------
9670 function Make_Test_Expr (Opnd : Node_Id) return Node_Id is
9672 if Shortcut_Value then
9673 return Make_Op_Not (Sloc (Opnd), Opnd);
9680 -- Entity for a temporary variable holding the value of the operator,
9681 -- used for expansion in the case where actions are present.
9683 -- Start of processing for Expand_Short_Circuit_Operator
9686 -- Deal with non-standard booleans
9688 if Is_Boolean_Type (Typ) then
9689 Adjust_Condition (Left);
9690 Adjust_Condition (Right);
9691 Set_Etype (N, Standard_Boolean);
9694 -- Check for cases where left argument is known to be True or False
9696 if Compile_Time_Known_Value (Left) then
9698 -- Mark SCO for left condition as compile time known
9700 if Generate_SCO and then Comes_From_Source (Left) then
9701 Set_SCO_Condition (Left, Expr_Value_E (Left) = Standard_True);
9704 -- Rewrite True AND THEN Right / False OR ELSE Right to Right.
9705 -- Any actions associated with Right will be executed unconditionally
9706 -- and can thus be inserted into the tree unconditionally.
9708 if Expr_Value_E (Left) /= Shortcut_Ent then
9709 if Present (Actions (N)) then
9710 Insert_Actions (N, Actions (N));
9715 -- Rewrite False AND THEN Right / True OR ELSE Right to Left.
9716 -- In this case we can forget the actions associated with Right,
9717 -- since they will never be executed.
9720 Kill_Dead_Code (Right);
9721 Kill_Dead_Code (Actions (N));
9722 Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
9725 Adjust_Result_Type (N, Typ);
9729 -- If Actions are present for the right operand, we have to do some
9730 -- special processing. We can't just let these actions filter back into
9731 -- code preceding the short circuit (which is what would have happened
9732 -- if we had not trapped them in the short-circuit form), since they
9733 -- must only be executed if the right operand of the short circuit is
9734 -- executed and not otherwise.
9736 -- the temporary variable C.
9738 if Present (Actions (N)) then
9739 Actlist := Actions (N);
9741 -- The old approach is to expand:
9743 -- left AND THEN right
9747 -- C : Boolean := False;
9755 -- and finally rewrite the operator into a reference to C. Similarly
9756 -- for left OR ELSE right, with negated values. Note that this
9757 -- rewrite causes some difficulties for coverage analysis because
9758 -- of the introduction of the new variable C, which obscures the
9759 -- structure of the test.
9761 -- We use this "old approach" if use of N_Expression_With_Actions
9762 -- is False (see description in Opt of when this is or is not set).
9764 if not Use_Expression_With_Actions then
9765 Op_Var := Make_Temporary (Loc, 'C', Related_Node => N);
9768 Make_Object_Declaration (Loc,
9769 Defining_Identifier =>
9771 Object_Definition =>
9772 New_Occurrence_Of (Standard_Boolean, Loc),
9774 New_Occurrence_Of (Shortcut_Ent, Loc)));
9777 Make_Implicit_If_Statement (Right,
9778 Condition => Make_Test_Expr (Right),
9779 Then_Statements => New_List (
9780 Make_Assignment_Statement (LocR,
9781 Name => New_Occurrence_Of (Op_Var, LocR),
9784 (Boolean_Literals (not Shortcut_Value), LocR)))));
9787 Make_Implicit_If_Statement (Left,
9788 Condition => Make_Test_Expr (Left),
9789 Then_Statements => Actlist));
9791 Rewrite (N, New_Occurrence_Of (Op_Var, Loc));
9792 Analyze_And_Resolve (N, Standard_Boolean);
9794 -- The new approach, activated for now by the use of debug flag
9795 -- -gnatd.X is to use the new Expression_With_Actions node for the
9796 -- right operand of the short-circuit form. This should solve the
9797 -- traceability problems for coverage analysis.
9801 Make_Expression_With_Actions (LocR,
9802 Expression => Relocate_Node (Right),
9803 Actions => Actlist));
9804 Set_Actions (N, No_List);
9805 Analyze_And_Resolve (Right, Standard_Boolean);
9808 Adjust_Result_Type (N, Typ);
9812 -- No actions present, check for cases of right argument True/False
9814 if Compile_Time_Known_Value (Right) then
9816 -- Mark SCO for left condition as compile time known
9818 if Generate_SCO and then Comes_From_Source (Right) then
9819 Set_SCO_Condition (Right, Expr_Value_E (Right) = Standard_True);
9822 -- Change (Left and then True), (Left or else False) to Left.
9823 -- Note that we know there are no actions associated with the right
9824 -- operand, since we just checked for this case above.
9826 if Expr_Value_E (Right) /= Shortcut_Ent then
9829 -- Change (Left and then False), (Left or else True) to Right,
9830 -- making sure to preserve any side effects associated with the Left
9834 Remove_Side_Effects (Left);
9835 Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
9839 Adjust_Result_Type (N, Typ);
9840 end Expand_Short_Circuit_Operator;
9842 -------------------------------------
9843 -- Fixup_Universal_Fixed_Operation --
9844 -------------------------------------
9846 procedure Fixup_Universal_Fixed_Operation (N : Node_Id) is
9847 Conv : constant Node_Id := Parent (N);
9850 -- We must have a type conversion immediately above us
9852 pragma Assert (Nkind (Conv) = N_Type_Conversion);
9854 -- Normally the type conversion gives our target type. The exception
9855 -- occurs in the case of the Round attribute, where the conversion
9856 -- will be to universal real, and our real type comes from the Round
9857 -- attribute (as well as an indication that we must round the result)
9859 if Nkind (Parent (Conv)) = N_Attribute_Reference
9860 and then Attribute_Name (Parent (Conv)) = Name_Round
9862 Set_Etype (N, Etype (Parent (Conv)));
9863 Set_Rounded_Result (N);
9865 -- Normal case where type comes from conversion above us
9868 Set_Etype (N, Etype (Conv));
9870 end Fixup_Universal_Fixed_Operation;
9872 ---------------------------------
9873 -- Has_Inferable_Discriminants --
9874 ---------------------------------
9876 function Has_Inferable_Discriminants (N : Node_Id) return Boolean is
9878 function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean;
9879 -- Determines whether the left-most prefix of a selected component is a
9880 -- formal parameter in a subprogram. Assumes N is a selected component.
9882 --------------------------------
9883 -- Prefix_Is_Formal_Parameter --
9884 --------------------------------
9886 function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean is
9887 Sel_Comp : Node_Id := N;
9890 -- Move to the left-most prefix by climbing up the tree
9892 while Present (Parent (Sel_Comp))
9893 and then Nkind (Parent (Sel_Comp)) = N_Selected_Component
9895 Sel_Comp := Parent (Sel_Comp);
9898 return Ekind (Entity (Prefix (Sel_Comp))) in Formal_Kind;
9899 end Prefix_Is_Formal_Parameter;
9901 -- Start of processing for Has_Inferable_Discriminants
9904 -- For identifiers and indexed components, it is sufficient to have a
9905 -- constrained Unchecked_Union nominal subtype.
9907 if Nkind_In (N, N_Identifier, N_Indexed_Component) then
9908 return Is_Unchecked_Union (Base_Type (Etype (N)))
9910 Is_Constrained (Etype (N));
9912 -- For selected components, the subtype of the selector must be a
9913 -- constrained Unchecked_Union. If the component is subject to a
9914 -- per-object constraint, then the enclosing object must have inferable
9917 elsif Nkind (N) = N_Selected_Component then
9918 if Has_Per_Object_Constraint (Entity (Selector_Name (N))) then
9920 -- A small hack. If we have a per-object constrained selected
9921 -- component of a formal parameter, return True since we do not
9922 -- know the actual parameter association yet.
9924 if Prefix_Is_Formal_Parameter (N) then
9928 -- Otherwise, check the enclosing object and the selector
9930 return Has_Inferable_Discriminants (Prefix (N))
9932 Has_Inferable_Discriminants (Selector_Name (N));
9935 -- The call to Has_Inferable_Discriminants will determine whether
9936 -- the selector has a constrained Unchecked_Union nominal type.
9938 return Has_Inferable_Discriminants (Selector_Name (N));
9940 -- A qualified expression has inferable discriminants if its subtype
9941 -- mark is a constrained Unchecked_Union subtype.
9943 elsif Nkind (N) = N_Qualified_Expression then
9944 return Is_Unchecked_Union (Subtype_Mark (N))
9946 Is_Constrained (Subtype_Mark (N));
9951 end Has_Inferable_Discriminants;
9953 -------------------------------
9954 -- Insert_Dereference_Action --
9955 -------------------------------
9957 procedure Insert_Dereference_Action (N : Node_Id) is
9958 Loc : constant Source_Ptr := Sloc (N);
9959 Typ : constant Entity_Id := Etype (N);
9960 Pool : constant Entity_Id := Associated_Storage_Pool (Typ);
9961 Pnod : constant Node_Id := Parent (N);
9963 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
9964 -- Return true if type of P is derived from Checked_Pool;
9966 -----------------------------
9967 -- Is_Checked_Storage_Pool --
9968 -----------------------------
9970 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean is
9979 while T /= Etype (T) loop
9980 if Is_RTE (T, RE_Checked_Pool) then
9988 end Is_Checked_Storage_Pool;
9990 -- Start of processing for Insert_Dereference_Action
9993 pragma Assert (Nkind (Pnod) = N_Explicit_Dereference);
9995 if not (Is_Checked_Storage_Pool (Pool)
9996 and then Comes_From_Source (Original_Node (Pnod)))
10002 Make_Procedure_Call_Statement (Loc,
10003 Name => New_Reference_To (
10004 Find_Prim_Op (Etype (Pool), Name_Dereference), Loc),
10006 Parameter_Associations => New_List (
10010 New_Reference_To (Pool, Loc),
10012 -- Storage_Address. We use the attribute Pool_Address, which uses
10013 -- the pointer itself to find the address of the object, and which
10014 -- handles unconstrained arrays properly by computing the address
10015 -- of the template. i.e. the correct address of the corresponding
10018 Make_Attribute_Reference (Loc,
10019 Prefix => Duplicate_Subexpr_Move_Checks (N),
10020 Attribute_Name => Name_Pool_Address),
10022 -- Size_In_Storage_Elements
10024 Make_Op_Divide (Loc,
10026 Make_Attribute_Reference (Loc,
10028 Make_Explicit_Dereference (Loc,
10029 Duplicate_Subexpr_Move_Checks (N)),
10030 Attribute_Name => Name_Size),
10032 Make_Integer_Literal (Loc, System_Storage_Unit)),
10036 Make_Attribute_Reference (Loc,
10038 Make_Explicit_Dereference (Loc,
10039 Duplicate_Subexpr_Move_Checks (N)),
10040 Attribute_Name => Name_Alignment))));
10043 when RE_Not_Available =>
10045 end Insert_Dereference_Action;
10047 --------------------------------
10048 -- Integer_Promotion_Possible --
10049 --------------------------------
10051 function Integer_Promotion_Possible (N : Node_Id) return Boolean is
10052 Operand : constant Node_Id := Expression (N);
10053 Operand_Type : constant Entity_Id := Etype (Operand);
10054 Root_Operand_Type : constant Entity_Id := Root_Type (Operand_Type);
10057 pragma Assert (Nkind (N) = N_Type_Conversion);
10061 -- We only do the transformation for source constructs. We assume
10062 -- that the expander knows what it is doing when it generates code.
10064 Comes_From_Source (N)
10066 -- If the operand type is Short_Integer or Short_Short_Integer,
10067 -- then we will promote to Integer, which is available on all
10068 -- targets, and is sufficient to ensure no intermediate overflow.
10069 -- Furthermore it is likely to be as efficient or more efficient
10070 -- than using the smaller type for the computation so we do this
10071 -- unconditionally.
10074 (Root_Operand_Type = Base_Type (Standard_Short_Integer)
10076 Root_Operand_Type = Base_Type (Standard_Short_Short_Integer))
10078 -- Test for interesting operation, which includes addition,
10079 -- division, exponentiation, multiplication, subtraction, absolute
10080 -- value and unary negation. Unary "+" is omitted since it is a
10081 -- no-op and thus can't overflow.
10083 and then Nkind_In (Operand, N_Op_Abs,
10090 end Integer_Promotion_Possible;
10092 ------------------------------
10093 -- Make_Array_Comparison_Op --
10094 ------------------------------
10096 -- This is a hand-coded expansion of the following generic function:
10099 -- type elem is (<>);
10100 -- type index is (<>);
10101 -- type a is array (index range <>) of elem;
10103 -- function Gnnn (X : a; Y: a) return boolean is
10104 -- J : index := Y'first;
10107 -- if X'length = 0 then
10110 -- elsif Y'length = 0 then
10114 -- for I in X'range loop
10115 -- if X (I) = Y (J) then
10116 -- if J = Y'last then
10119 -- J := index'succ (J);
10123 -- return X (I) > Y (J);
10127 -- return X'length > Y'length;
10131 -- Note that since we are essentially doing this expansion by hand, we
10132 -- do not need to generate an actual or formal generic part, just the
10133 -- instantiated function itself.
10135 function Make_Array_Comparison_Op
10137 Nod : Node_Id) return Node_Id
10139 Loc : constant Source_Ptr := Sloc (Nod);
10141 X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uX);
10142 Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uY);
10143 I : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uI);
10144 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
10146 Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ)));
10148 Loop_Statement : Node_Id;
10149 Loop_Body : Node_Id;
10151 Inner_If : Node_Id;
10152 Final_Expr : Node_Id;
10153 Func_Body : Node_Id;
10154 Func_Name : Entity_Id;
10160 -- if J = Y'last then
10163 -- J := index'succ (J);
10167 Make_Implicit_If_Statement (Nod,
10170 Left_Opnd => New_Reference_To (J, Loc),
10172 Make_Attribute_Reference (Loc,
10173 Prefix => New_Reference_To (Y, Loc),
10174 Attribute_Name => Name_Last)),
10176 Then_Statements => New_List (
10177 Make_Exit_Statement (Loc)),
10181 Make_Assignment_Statement (Loc,
10182 Name => New_Reference_To (J, Loc),
10184 Make_Attribute_Reference (Loc,
10185 Prefix => New_Reference_To (Index, Loc),
10186 Attribute_Name => Name_Succ,
10187 Expressions => New_List (New_Reference_To (J, Loc))))));
10189 -- if X (I) = Y (J) then
10192 -- return X (I) > Y (J);
10196 Make_Implicit_If_Statement (Nod,
10200 Make_Indexed_Component (Loc,
10201 Prefix => New_Reference_To (X, Loc),
10202 Expressions => New_List (New_Reference_To (I, Loc))),
10205 Make_Indexed_Component (Loc,
10206 Prefix => New_Reference_To (Y, Loc),
10207 Expressions => New_List (New_Reference_To (J, Loc)))),
10209 Then_Statements => New_List (Inner_If),
10211 Else_Statements => New_List (
10212 Make_Simple_Return_Statement (Loc,
10216 Make_Indexed_Component (Loc,
10217 Prefix => New_Reference_To (X, Loc),
10218 Expressions => New_List (New_Reference_To (I, Loc))),
10221 Make_Indexed_Component (Loc,
10222 Prefix => New_Reference_To (Y, Loc),
10223 Expressions => New_List (
10224 New_Reference_To (J, Loc)))))));
10226 -- for I in X'range loop
10231 Make_Implicit_Loop_Statement (Nod,
10232 Identifier => Empty,
10234 Iteration_Scheme =>
10235 Make_Iteration_Scheme (Loc,
10236 Loop_Parameter_Specification =>
10237 Make_Loop_Parameter_Specification (Loc,
10238 Defining_Identifier => I,
10239 Discrete_Subtype_Definition =>
10240 Make_Attribute_Reference (Loc,
10241 Prefix => New_Reference_To (X, Loc),
10242 Attribute_Name => Name_Range))),
10244 Statements => New_List (Loop_Body));
10246 -- if X'length = 0 then
10248 -- elsif Y'length = 0 then
10251 -- for ... loop ... end loop;
10252 -- return X'length > Y'length;
10256 Make_Attribute_Reference (Loc,
10257 Prefix => New_Reference_To (X, Loc),
10258 Attribute_Name => Name_Length);
10261 Make_Attribute_Reference (Loc,
10262 Prefix => New_Reference_To (Y, Loc),
10263 Attribute_Name => Name_Length);
10267 Left_Opnd => Length1,
10268 Right_Opnd => Length2);
10271 Make_Implicit_If_Statement (Nod,
10275 Make_Attribute_Reference (Loc,
10276 Prefix => New_Reference_To (X, Loc),
10277 Attribute_Name => Name_Length),
10279 Make_Integer_Literal (Loc, 0)),
10283 Make_Simple_Return_Statement (Loc,
10284 Expression => New_Reference_To (Standard_False, Loc))),
10286 Elsif_Parts => New_List (
10287 Make_Elsif_Part (Loc,
10291 Make_Attribute_Reference (Loc,
10292 Prefix => New_Reference_To (Y, Loc),
10293 Attribute_Name => Name_Length),
10295 Make_Integer_Literal (Loc, 0)),
10299 Make_Simple_Return_Statement (Loc,
10300 Expression => New_Reference_To (Standard_True, Loc))))),
10302 Else_Statements => New_List (
10304 Make_Simple_Return_Statement (Loc,
10305 Expression => Final_Expr)));
10309 Formals := New_List (
10310 Make_Parameter_Specification (Loc,
10311 Defining_Identifier => X,
10312 Parameter_Type => New_Reference_To (Typ, Loc)),
10314 Make_Parameter_Specification (Loc,
10315 Defining_Identifier => Y,
10316 Parameter_Type => New_Reference_To (Typ, Loc)));
10318 -- function Gnnn (...) return boolean is
10319 -- J : index := Y'first;
10324 Func_Name := Make_Temporary (Loc, 'G');
10327 Make_Subprogram_Body (Loc,
10329 Make_Function_Specification (Loc,
10330 Defining_Unit_Name => Func_Name,
10331 Parameter_Specifications => Formals,
10332 Result_Definition => New_Reference_To (Standard_Boolean, Loc)),
10334 Declarations => New_List (
10335 Make_Object_Declaration (Loc,
10336 Defining_Identifier => J,
10337 Object_Definition => New_Reference_To (Index, Loc),
10339 Make_Attribute_Reference (Loc,
10340 Prefix => New_Reference_To (Y, Loc),
10341 Attribute_Name => Name_First))),
10343 Handled_Statement_Sequence =>
10344 Make_Handled_Sequence_Of_Statements (Loc,
10345 Statements => New_List (If_Stat)));
10348 end Make_Array_Comparison_Op;
10350 ---------------------------
10351 -- Make_Boolean_Array_Op --
10352 ---------------------------
10354 -- For logical operations on boolean arrays, expand in line the following,
10355 -- replacing 'and' with 'or' or 'xor' where needed:
10357 -- function Annn (A : typ; B: typ) return typ is
10360 -- for J in A'range loop
10361 -- C (J) := A (J) op B (J);
10366 -- Here typ is the boolean array type
10368 function Make_Boolean_Array_Op
10370 N : Node_Id) return Node_Id
10372 Loc : constant Source_Ptr := Sloc (N);
10374 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
10375 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
10376 C : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uC);
10377 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
10385 Func_Name : Entity_Id;
10386 Func_Body : Node_Id;
10387 Loop_Statement : Node_Id;
10391 Make_Indexed_Component (Loc,
10392 Prefix => New_Reference_To (A, Loc),
10393 Expressions => New_List (New_Reference_To (J, Loc)));
10396 Make_Indexed_Component (Loc,
10397 Prefix => New_Reference_To (B, Loc),
10398 Expressions => New_List (New_Reference_To (J, Loc)));
10401 Make_Indexed_Component (Loc,
10402 Prefix => New_Reference_To (C, Loc),
10403 Expressions => New_List (New_Reference_To (J, Loc)));
10405 if Nkind (N) = N_Op_And then
10409 Right_Opnd => B_J);
10411 elsif Nkind (N) = N_Op_Or then
10415 Right_Opnd => B_J);
10421 Right_Opnd => B_J);
10425 Make_Implicit_Loop_Statement (N,
10426 Identifier => Empty,
10428 Iteration_Scheme =>
10429 Make_Iteration_Scheme (Loc,
10430 Loop_Parameter_Specification =>
10431 Make_Loop_Parameter_Specification (Loc,
10432 Defining_Identifier => J,
10433 Discrete_Subtype_Definition =>
10434 Make_Attribute_Reference (Loc,
10435 Prefix => New_Reference_To (A, Loc),
10436 Attribute_Name => Name_Range))),
10438 Statements => New_List (
10439 Make_Assignment_Statement (Loc,
10441 Expression => Op)));
10443 Formals := New_List (
10444 Make_Parameter_Specification (Loc,
10445 Defining_Identifier => A,
10446 Parameter_Type => New_Reference_To (Typ, Loc)),
10448 Make_Parameter_Specification (Loc,
10449 Defining_Identifier => B,
10450 Parameter_Type => New_Reference_To (Typ, Loc)));
10452 Func_Name := Make_Temporary (Loc, 'A');
10453 Set_Is_Inlined (Func_Name);
10456 Make_Subprogram_Body (Loc,
10458 Make_Function_Specification (Loc,
10459 Defining_Unit_Name => Func_Name,
10460 Parameter_Specifications => Formals,
10461 Result_Definition => New_Reference_To (Typ, Loc)),
10463 Declarations => New_List (
10464 Make_Object_Declaration (Loc,
10465 Defining_Identifier => C,
10466 Object_Definition => New_Reference_To (Typ, Loc))),
10468 Handled_Statement_Sequence =>
10469 Make_Handled_Sequence_Of_Statements (Loc,
10470 Statements => New_List (
10472 Make_Simple_Return_Statement (Loc,
10473 Expression => New_Reference_To (C, Loc)))));
10476 end Make_Boolean_Array_Op;
10478 --------------------------------
10479 -- Optimize_Length_Comparison --
10480 --------------------------------
10482 procedure Optimize_Length_Comparison (N : Node_Id) is
10483 Loc : constant Source_Ptr := Sloc (N);
10484 Typ : constant Entity_Id := Etype (N);
10489 -- First and Last attribute reference nodes, which end up as left and
10490 -- right operands of the optimized result.
10493 -- True for comparison operand of zero
10496 -- Comparison operand, set only if Is_Zero is false
10499 -- Entity whose length is being compared
10502 -- Integer_Literal node for length attribute expression, or Empty
10503 -- if there is no such expression present.
10506 -- Type of array index to which 'Length is applied
10508 Op : Node_Kind := Nkind (N);
10509 -- Kind of comparison operator, gets flipped if operands backwards
10511 function Is_Optimizable (N : Node_Id) return Boolean;
10512 -- Tests N to see if it is an optimizable comparison value (defined as
10513 -- constant zero or one, or something else where the value is known to
10514 -- be positive and in the range of 32-bits, and where the corresponding
10515 -- Length value is also known to be 32-bits. If result is true, sets
10516 -- Is_Zero, Ityp, and Comp accordingly.
10518 function Is_Entity_Length (N : Node_Id) return Boolean;
10519 -- Tests if N is a length attribute applied to a simple entity. If so,
10520 -- returns True, and sets Ent to the entity, and Index to the integer
10521 -- literal provided as an attribute expression, or to Empty if none.
10522 -- Also returns True if the expression is a generated type conversion
10523 -- whose expression is of the desired form. This latter case arises
10524 -- when Apply_Universal_Integer_Attribute_Check installs a conversion
10525 -- to check for being in range, which is not needed in this context.
10526 -- Returns False if neither condition holds.
10528 function Prepare_64 (N : Node_Id) return Node_Id;
10529 -- Given a discrete expression, returns a Long_Long_Integer typed
10530 -- expression representing the underlying value of the expression.
10531 -- This is done with an unchecked conversion to the result type. We
10532 -- use unchecked conversion to handle the enumeration type case.
10534 ----------------------
10535 -- Is_Entity_Length --
10536 ----------------------
10538 function Is_Entity_Length (N : Node_Id) return Boolean is
10540 if Nkind (N) = N_Attribute_Reference
10541 and then Attribute_Name (N) = Name_Length
10542 and then Is_Entity_Name (Prefix (N))
10544 Ent := Entity (Prefix (N));
10546 if Present (Expressions (N)) then
10547 Index := First (Expressions (N));
10554 elsif Nkind (N) = N_Type_Conversion
10555 and then not Comes_From_Source (N)
10557 return Is_Entity_Length (Expression (N));
10562 end Is_Entity_Length;
10564 --------------------
10565 -- Is_Optimizable --
10566 --------------------
10568 function Is_Optimizable (N : Node_Id) return Boolean is
10576 if Compile_Time_Known_Value (N) then
10577 Val := Expr_Value (N);
10579 if Val = Uint_0 then
10584 elsif Val = Uint_1 then
10591 -- Here we have to make sure of being within 32-bits
10593 Determine_Range (N, OK, Lo, Hi, Assume_Valid => True);
10596 or else Lo < Uint_1
10597 or else Hi > UI_From_Int (Int'Last)
10602 -- Comparison value was within range, so now we must check the index
10603 -- value to make sure it is also within 32-bits.
10605 Indx := First_Index (Etype (Ent));
10607 if Present (Index) then
10608 for J in 2 .. UI_To_Int (Intval (Index)) loop
10613 Ityp := Etype (Indx);
10615 if Esize (Ityp) > 32 then
10622 end Is_Optimizable;
10628 function Prepare_64 (N : Node_Id) return Node_Id is
10630 return Unchecked_Convert_To (Standard_Long_Long_Integer, N);
10633 -- Start of processing for Optimize_Length_Comparison
10636 -- Nothing to do if not a comparison
10638 if Op not in N_Op_Compare then
10642 -- Nothing to do if special -gnatd.P debug flag set
10644 if Debug_Flag_Dot_PP then
10648 -- Ent'Length op 0/1
10650 if Is_Entity_Length (Left_Opnd (N))
10651 and then Is_Optimizable (Right_Opnd (N))
10655 -- 0/1 op Ent'Length
10657 elsif Is_Entity_Length (Right_Opnd (N))
10658 and then Is_Optimizable (Left_Opnd (N))
10660 -- Flip comparison to opposite sense
10663 when N_Op_Lt => Op := N_Op_Gt;
10664 when N_Op_Le => Op := N_Op_Ge;
10665 when N_Op_Gt => Op := N_Op_Lt;
10666 when N_Op_Ge => Op := N_Op_Le;
10667 when others => null;
10670 -- Else optimization not possible
10676 -- Fall through if we will do the optimization
10678 -- Cases to handle:
10680 -- X'Length = 0 => X'First > X'Last
10681 -- X'Length = 1 => X'First = X'Last
10682 -- X'Length = n => X'First + (n - 1) = X'Last
10684 -- X'Length /= 0 => X'First <= X'Last
10685 -- X'Length /= 1 => X'First /= X'Last
10686 -- X'Length /= n => X'First + (n - 1) /= X'Last
10688 -- X'Length >= 0 => always true, warn
10689 -- X'Length >= 1 => X'First <= X'Last
10690 -- X'Length >= n => X'First + (n - 1) <= X'Last
10692 -- X'Length > 0 => X'First <= X'Last
10693 -- X'Length > 1 => X'First < X'Last
10694 -- X'Length > n => X'First + (n - 1) < X'Last
10696 -- X'Length <= 0 => X'First > X'Last (warn, could be =)
10697 -- X'Length <= 1 => X'First >= X'Last
10698 -- X'Length <= n => X'First + (n - 1) >= X'Last
10700 -- X'Length < 0 => always false (warn)
10701 -- X'Length < 1 => X'First > X'Last
10702 -- X'Length < n => X'First + (n - 1) > X'Last
10704 -- Note: for the cases of n (not constant 0,1), we require that the
10705 -- corresponding index type be integer or shorter (i.e. not 64-bit),
10706 -- and the same for the comparison value. Then we do the comparison
10707 -- using 64-bit arithmetic (actually long long integer), so that we
10708 -- cannot have overflow intefering with the result.
10710 -- First deal with warning cases
10719 Convert_To (Typ, New_Occurrence_Of (Standard_True, Loc)));
10720 Analyze_And_Resolve (N, Typ);
10721 Warn_On_Known_Condition (N);
10728 Convert_To (Typ, New_Occurrence_Of (Standard_False, Loc)));
10729 Analyze_And_Resolve (N, Typ);
10730 Warn_On_Known_Condition (N);
10734 if Constant_Condition_Warnings
10735 and then Comes_From_Source (Original_Node (N))
10737 Error_Msg_N ("could replace by ""'=""?", N);
10747 -- Build the First reference we will use
10750 Make_Attribute_Reference (Loc,
10751 Prefix => New_Occurrence_Of (Ent, Loc),
10752 Attribute_Name => Name_First);
10754 if Present (Index) then
10755 Set_Expressions (Left, New_List (New_Copy (Index)));
10758 -- If general value case, then do the addition of (n - 1), and
10759 -- also add the needed conversions to type Long_Long_Integer.
10761 if Present (Comp) then
10764 Left_Opnd => Prepare_64 (Left),
10766 Make_Op_Subtract (Loc,
10767 Left_Opnd => Prepare_64 (Comp),
10768 Right_Opnd => Make_Integer_Literal (Loc, 1)));
10771 -- Build the Last reference we will use
10774 Make_Attribute_Reference (Loc,
10775 Prefix => New_Occurrence_Of (Ent, Loc),
10776 Attribute_Name => Name_Last);
10778 if Present (Index) then
10779 Set_Expressions (Right, New_List (New_Copy (Index)));
10782 -- If general operand, convert Last reference to Long_Long_Integer
10784 if Present (Comp) then
10785 Right := Prepare_64 (Right);
10788 -- Check for cases to optimize
10790 -- X'Length = 0 => X'First > X'Last
10791 -- X'Length < 1 => X'First > X'Last
10792 -- X'Length < n => X'First + (n - 1) > X'Last
10794 if (Is_Zero and then Op = N_Op_Eq)
10795 or else (not Is_Zero and then Op = N_Op_Lt)
10800 Right_Opnd => Right);
10802 -- X'Length = 1 => X'First = X'Last
10803 -- X'Length = n => X'First + (n - 1) = X'Last
10805 elsif not Is_Zero and then Op = N_Op_Eq then
10809 Right_Opnd => Right);
10811 -- X'Length /= 0 => X'First <= X'Last
10812 -- X'Length > 0 => X'First <= X'Last
10814 elsif Is_Zero and (Op = N_Op_Ne or else Op = N_Op_Gt) then
10818 Right_Opnd => Right);
10820 -- X'Length /= 1 => X'First /= X'Last
10821 -- X'Length /= n => X'First + (n - 1) /= X'Last
10823 elsif not Is_Zero and then Op = N_Op_Ne then
10827 Right_Opnd => Right);
10829 -- X'Length >= 1 => X'First <= X'Last
10830 -- X'Length >= n => X'First + (n - 1) <= X'Last
10832 elsif not Is_Zero and then Op = N_Op_Ge then
10836 Right_Opnd => Right);
10838 -- X'Length > 1 => X'First < X'Last
10839 -- X'Length > n => X'First + (n = 1) < X'Last
10841 elsif not Is_Zero and then Op = N_Op_Gt then
10845 Right_Opnd => Right);
10847 -- X'Length <= 1 => X'First >= X'Last
10848 -- X'Length <= n => X'First + (n - 1) >= X'Last
10850 elsif not Is_Zero and then Op = N_Op_Le then
10854 Right_Opnd => Right);
10856 -- Should not happen at this stage
10859 raise Program_Error;
10862 -- Rewrite and finish up
10864 Rewrite (N, Result);
10865 Analyze_And_Resolve (N, Typ);
10867 end Optimize_Length_Comparison;
10869 ------------------------
10870 -- Rewrite_Comparison --
10871 ------------------------
10873 procedure Rewrite_Comparison (N : Node_Id) is
10874 Warning_Generated : Boolean := False;
10875 -- Set to True if first pass with Assume_Valid generates a warning in
10876 -- which case we skip the second pass to avoid warning overloaded.
10879 -- Set to Standard_True or Standard_False
10882 if Nkind (N) = N_Type_Conversion then
10883 Rewrite_Comparison (Expression (N));
10886 elsif Nkind (N) not in N_Op_Compare then
10890 -- Now start looking at the comparison in detail. We potentially go
10891 -- through this loop twice. The first time, Assume_Valid is set False
10892 -- in the call to Compile_Time_Compare. If this call results in a
10893 -- clear result of always True or Always False, that's decisive and
10894 -- we are done. Otherwise we repeat the processing with Assume_Valid
10895 -- set to True to generate additional warnings. We can skip that step
10896 -- if Constant_Condition_Warnings is False.
10898 for AV in False .. True loop
10900 Typ : constant Entity_Id := Etype (N);
10901 Op1 : constant Node_Id := Left_Opnd (N);
10902 Op2 : constant Node_Id := Right_Opnd (N);
10904 Res : constant Compare_Result :=
10905 Compile_Time_Compare (Op1, Op2, Assume_Valid => AV);
10906 -- Res indicates if compare outcome can be compile time determined
10908 True_Result : Boolean;
10909 False_Result : Boolean;
10912 case N_Op_Compare (Nkind (N)) is
10914 True_Result := Res = EQ;
10915 False_Result := Res = LT or else Res = GT or else Res = NE;
10918 True_Result := Res in Compare_GE;
10919 False_Result := Res = LT;
10922 and then Constant_Condition_Warnings
10923 and then Comes_From_Source (Original_Node (N))
10924 and then Nkind (Original_Node (N)) = N_Op_Ge
10925 and then not In_Instance
10926 and then Is_Integer_Type (Etype (Left_Opnd (N)))
10927 and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
10930 ("can never be greater than, could replace by ""'=""?", N);
10931 Warning_Generated := True;
10935 True_Result := Res = GT;
10936 False_Result := Res in Compare_LE;
10939 True_Result := Res = LT;
10940 False_Result := Res in Compare_GE;
10943 True_Result := Res in Compare_LE;
10944 False_Result := Res = GT;
10947 and then Constant_Condition_Warnings
10948 and then Comes_From_Source (Original_Node (N))
10949 and then Nkind (Original_Node (N)) = N_Op_Le
10950 and then not In_Instance
10951 and then Is_Integer_Type (Etype (Left_Opnd (N)))
10952 and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
10955 ("can never be less than, could replace by ""'=""?", N);
10956 Warning_Generated := True;
10960 True_Result := Res = NE or else Res = GT or else Res = LT;
10961 False_Result := Res = EQ;
10964 -- If this is the first iteration, then we actually convert the
10965 -- comparison into True or False, if the result is certain.
10968 if True_Result or False_Result then
10969 if True_Result then
10970 Result := Standard_True;
10972 Result := Standard_False;
10977 New_Occurrence_Of (Result, Sloc (N))));
10978 Analyze_And_Resolve (N, Typ);
10979 Warn_On_Known_Condition (N);
10983 -- If this is the second iteration (AV = True), and the original
10984 -- node comes from source and we are not in an instance, then give
10985 -- a warning if we know result would be True or False. Note: we
10986 -- know Constant_Condition_Warnings is set if we get here.
10988 elsif Comes_From_Source (Original_Node (N))
10989 and then not In_Instance
10991 if True_Result then
10993 ("condition can only be False if invalid values present?",
10995 elsif False_Result then
10997 ("condition can only be True if invalid values present?",
11003 -- Skip second iteration if not warning on constant conditions or
11004 -- if the first iteration already generated a warning of some kind or
11005 -- if we are in any case assuming all values are valid (so that the
11006 -- first iteration took care of the valid case).
11008 exit when not Constant_Condition_Warnings;
11009 exit when Warning_Generated;
11010 exit when Assume_No_Invalid_Values;
11012 end Rewrite_Comparison;
11014 ----------------------------
11015 -- Safe_In_Place_Array_Op --
11016 ----------------------------
11018 function Safe_In_Place_Array_Op
11021 Op2 : Node_Id) return Boolean
11023 Target : Entity_Id;
11025 function Is_Safe_Operand (Op : Node_Id) return Boolean;
11026 -- Operand is safe if it cannot overlap part of the target of the
11027 -- operation. If the operand and the target are identical, the operand
11028 -- is safe. The operand can be empty in the case of negation.
11030 function Is_Unaliased (N : Node_Id) return Boolean;
11031 -- Check that N is a stand-alone entity
11037 function Is_Unaliased (N : Node_Id) return Boolean is
11041 and then No (Address_Clause (Entity (N)))
11042 and then No (Renamed_Object (Entity (N)));
11045 ---------------------
11046 -- Is_Safe_Operand --
11047 ---------------------
11049 function Is_Safe_Operand (Op : Node_Id) return Boolean is
11054 elsif Is_Entity_Name (Op) then
11055 return Is_Unaliased (Op);
11057 elsif Nkind_In (Op, N_Indexed_Component, N_Selected_Component) then
11058 return Is_Unaliased (Prefix (Op));
11060 elsif Nkind (Op) = N_Slice then
11062 Is_Unaliased (Prefix (Op))
11063 and then Entity (Prefix (Op)) /= Target;
11065 elsif Nkind (Op) = N_Op_Not then
11066 return Is_Safe_Operand (Right_Opnd (Op));
11071 end Is_Safe_Operand;
11073 -- Start of processing for Is_Safe_In_Place_Array_Op
11076 -- Skip this processing if the component size is different from system
11077 -- storage unit (since at least for NOT this would cause problems).
11079 if Component_Size (Etype (Lhs)) /= System_Storage_Unit then
11082 -- Cannot do in place stuff on VM_Target since cannot pass addresses
11084 elsif VM_Target /= No_VM then
11087 -- Cannot do in place stuff if non-standard Boolean representation
11089 elsif Has_Non_Standard_Rep (Component_Type (Etype (Lhs))) then
11092 elsif not Is_Unaliased (Lhs) then
11096 Target := Entity (Lhs);
11097 return Is_Safe_Operand (Op1) and then Is_Safe_Operand (Op2);
11099 end Safe_In_Place_Array_Op;
11101 -----------------------
11102 -- Tagged_Membership --
11103 -----------------------
11105 -- There are two different cases to consider depending on whether the right
11106 -- operand is a class-wide type or not. If not we just compare the actual
11107 -- tag of the left expr to the target type tag:
11109 -- Left_Expr.Tag = Right_Type'Tag;
11111 -- If it is a class-wide type we use the RT function CW_Membership which is
11112 -- usually implemented by looking in the ancestor tables contained in the
11113 -- dispatch table pointed by Left_Expr.Tag for Typ'Tag
11115 -- Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
11116 -- function IW_Membership which is usually implemented by looking in the
11117 -- table of abstract interface types plus the ancestor table contained in
11118 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
11120 procedure Tagged_Membership
11122 SCIL_Node : out Node_Id;
11123 Result : out Node_Id)
11125 Left : constant Node_Id := Left_Opnd (N);
11126 Right : constant Node_Id := Right_Opnd (N);
11127 Loc : constant Source_Ptr := Sloc (N);
11129 Full_R_Typ : Entity_Id;
11130 Left_Type : Entity_Id;
11131 New_Node : Node_Id;
11132 Right_Type : Entity_Id;
11136 SCIL_Node := Empty;
11138 -- Handle entities from the limited view
11140 Left_Type := Available_View (Etype (Left));
11141 Right_Type := Available_View (Etype (Right));
11143 -- In the case where the type is an access type, the test is applied
11144 -- using the designated types (needed in Ada 2012 for implicit anonymous
11145 -- access conversions, for AI05-0149).
11147 if Is_Access_Type (Right_Type) then
11148 Left_Type := Designated_Type (Left_Type);
11149 Right_Type := Designated_Type (Right_Type);
11152 if Is_Class_Wide_Type (Left_Type) then
11153 Left_Type := Root_Type (Left_Type);
11156 if Is_Class_Wide_Type (Right_Type) then
11157 Full_R_Typ := Underlying_Type (Root_Type (Right_Type));
11159 Full_R_Typ := Underlying_Type (Right_Type);
11163 Make_Selected_Component (Loc,
11164 Prefix => Relocate_Node (Left),
11166 New_Reference_To (First_Tag_Component (Left_Type), Loc));
11168 if Is_Class_Wide_Type (Right_Type) then
11170 -- No need to issue a run-time check if we statically know that the
11171 -- result of this membership test is always true. For example,
11172 -- considering the following declarations:
11174 -- type Iface is interface;
11175 -- type T is tagged null record;
11176 -- type DT is new T and Iface with null record;
11181 -- These membership tests are always true:
11184 -- Obj2 in T'Class;
11185 -- Obj2 in Iface'Class;
11187 -- We do not need to handle cases where the membership is illegal.
11190 -- Obj1 in DT'Class; -- Compile time error
11191 -- Obj1 in Iface'Class; -- Compile time error
11193 if not Is_Class_Wide_Type (Left_Type)
11194 and then (Is_Ancestor (Etype (Right_Type), Left_Type,
11195 Use_Full_View => True)
11196 or else (Is_Interface (Etype (Right_Type))
11197 and then Interface_Present_In_Ancestor
11199 Iface => Etype (Right_Type))))
11201 Result := New_Reference_To (Standard_True, Loc);
11205 -- Ada 2005 (AI-251): Class-wide applied to interfaces
11207 if Is_Interface (Etype (Class_Wide_Type (Right_Type)))
11209 -- Support to: "Iface_CW_Typ in Typ'Class"
11211 or else Is_Interface (Left_Type)
11213 -- Issue error if IW_Membership operation not available in a
11214 -- configurable run time setting.
11216 if not RTE_Available (RE_IW_Membership) then
11218 ("dynamic membership test on interface types", N);
11224 Make_Function_Call (Loc,
11225 Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
11226 Parameter_Associations => New_List (
11227 Make_Attribute_Reference (Loc,
11229 Attribute_Name => Name_Address),
11231 Node (First_Elmt (Access_Disp_Table (Full_R_Typ))),
11234 -- Ada 95: Normal case
11237 Build_CW_Membership (Loc,
11238 Obj_Tag_Node => Obj_Tag,
11241 Node (First_Elmt (Access_Disp_Table (Full_R_Typ))), Loc),
11243 New_Node => New_Node);
11245 -- Generate the SCIL node for this class-wide membership test.
11246 -- Done here because the previous call to Build_CW_Membership
11247 -- relocates Obj_Tag.
11249 if Generate_SCIL then
11250 SCIL_Node := Make_SCIL_Membership_Test (Sloc (N));
11251 Set_SCIL_Entity (SCIL_Node, Etype (Right_Type));
11252 Set_SCIL_Tag_Value (SCIL_Node, Obj_Tag);
11255 Result := New_Node;
11258 -- Right_Type is not a class-wide type
11261 -- No need to check the tag of the object if Right_Typ is abstract
11263 if Is_Abstract_Type (Right_Type) then
11264 Result := New_Reference_To (Standard_False, Loc);
11269 Left_Opnd => Obj_Tag,
11272 (Node (First_Elmt (Access_Disp_Table (Full_R_Typ))), Loc));
11275 end Tagged_Membership;
11277 ------------------------------
11278 -- Unary_Op_Validity_Checks --
11279 ------------------------------
11281 procedure Unary_Op_Validity_Checks (N : Node_Id) is
11283 if Validity_Checks_On and Validity_Check_Operands then
11284 Ensure_Valid (Right_Opnd (N));
11286 end Unary_Op_Validity_Checks;