1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2012, 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 -- It 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 objects 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
390 Unit_Id
:= Cunit_Entity
(Current_Sem_Unit
);
392 -- Find the entity of the current unit
394 if Ekind
(Unit_Id
) = E_Subprogram_Body
then
396 -- When processing subprogram bodies, the proper scope is always that
399 Subp_Body
:= Unit_Id
;
400 while Present
(Subp_Body
)
401 and then Nkind
(Subp_Body
) /= N_Subprogram_Body
403 Subp_Body
:= Parent
(Subp_Body
);
406 Unit_Id
:= Corresponding_Spec
(Subp_Body
);
409 Loc
:= Sloc
(Unit_Id
);
410 Unit_Decl
:= Unit
(Cunit
(Current_Sem_Unit
));
412 -- Find the declarations list of the current unit
414 if Nkind
(Unit_Decl
) = N_Package_Declaration
then
415 Unit_Decl
:= Specification
(Unit_Decl
);
416 Decls
:= Visible_Declarations
(Unit_Decl
);
419 Decls
:= New_List
(Make_Null_Statement
(Loc
));
420 Set_Visible_Declarations
(Unit_Decl
, Decls
);
422 elsif Is_Empty_List
(Decls
) then
423 Append_To
(Decls
, Make_Null_Statement
(Loc
));
427 Decls
:= Declarations
(Unit_Decl
);
430 Decls
:= New_List
(Make_Null_Statement
(Loc
));
431 Set_Declarations
(Unit_Decl
, Decls
);
433 elsif Is_Empty_List
(Decls
) then
434 Append_To
(Decls
, Make_Null_Statement
(Loc
));
438 -- The current unit has an existing anonymous master, traverse its
439 -- declarations and locate the entity.
441 if Has_Anonymous_Master
(Unit_Id
) then
444 Fin_Mas_Id
: Entity_Id
;
447 Decl
:= First
(Decls
);
448 while Present
(Decl
) loop
450 -- Look for the first variable in the declarations whole type
451 -- is Finalization_Master.
453 if Nkind
(Decl
) = N_Object_Declaration
then
454 Fin_Mas_Id
:= Defining_Identifier
(Decl
);
456 if Ekind
(Fin_Mas_Id
) = E_Variable
457 and then Etype
(Fin_Mas_Id
) = RTE
(RE_Finalization_Master
)
466 -- The master was not found even though the unit was labeled as
472 -- Create a new anonymous master
476 First_Decl
: constant Node_Id
:= First
(Decls
);
478 Fin_Mas_Id
: Entity_Id
;
481 -- Since the master and its associated initialization is inserted
482 -- at top level, use the scope of the unit when analyzing.
484 Push_Scope
(Unit_Id
);
486 -- Create the finalization master
489 Make_Defining_Identifier
(Loc
,
490 Chars
=> New_External_Name
(Chars
(Unit_Id
), "AM"));
493 -- <Fin_Mas_Id> : Finalization_Master;
496 Make_Object_Declaration
(Loc
,
497 Defining_Identifier
=> Fin_Mas_Id
,
499 New_Reference_To
(RTE
(RE_Finalization_Master
), Loc
));
501 Insert_Before_And_Analyze
(First_Decl
, Action
);
503 -- Mark the unit to prevent the generation of multiple masters
505 Set_Has_Anonymous_Master
(Unit_Id
);
507 -- Do not set the base pool and mode of operation on .NET/JVM
508 -- since those targets do not support pools and all VM masters
509 -- are heterogeneous by default.
511 if VM_Target
= No_VM
then
515 -- (<Fin_Mas_Id>, Global_Pool_Object'Unrestricted_Access);
518 Make_Procedure_Call_Statement
(Loc
,
520 New_Reference_To
(RTE
(RE_Set_Base_Pool
), Loc
),
522 Parameter_Associations
=> New_List
(
523 New_Reference_To
(Fin_Mas_Id
, Loc
),
524 Make_Attribute_Reference
(Loc
,
526 New_Reference_To
(RTE
(RE_Global_Pool_Object
), Loc
),
527 Attribute_Name
=> Name_Unrestricted_Access
)));
529 Insert_Before_And_Analyze
(First_Decl
, Action
);
532 -- Set_Is_Heterogeneous (<Fin_Mas_Id>);
535 Make_Procedure_Call_Statement
(Loc
,
537 New_Reference_To
(RTE
(RE_Set_Is_Heterogeneous
), Loc
),
538 Parameter_Associations
=> New_List
(
539 New_Reference_To
(Fin_Mas_Id
, Loc
)));
541 Insert_Before_And_Analyze
(First_Decl
, Action
);
544 -- Restore the original state of the scope stack
551 end Current_Anonymous_Master
;
553 --------------------------------
554 -- Displace_Allocator_Pointer --
555 --------------------------------
557 procedure Displace_Allocator_Pointer
(N
: Node_Id
) is
558 Loc
: constant Source_Ptr
:= Sloc
(N
);
559 Orig_Node
: constant Node_Id
:= Original_Node
(N
);
565 -- Do nothing in case of VM targets: the virtual machine will handle
566 -- interfaces directly.
568 if not Tagged_Type_Expansion
then
572 pragma Assert
(Nkind
(N
) = N_Identifier
573 and then Nkind
(Orig_Node
) = N_Allocator
);
575 PtrT
:= Etype
(Orig_Node
);
576 Dtyp
:= Available_View
(Designated_Type
(PtrT
));
577 Etyp
:= Etype
(Expression
(Orig_Node
));
579 if Is_Class_Wide_Type
(Dtyp
)
580 and then Is_Interface
(Dtyp
)
582 -- If the type of the allocator expression is not an interface type
583 -- we can generate code to reference the record component containing
584 -- the pointer to the secondary dispatch table.
586 if not Is_Interface
(Etyp
) then
588 Saved_Typ
: constant Entity_Id
:= Etype
(Orig_Node
);
591 -- 1) Get access to the allocated object
594 Make_Explicit_Dereference
(Loc
, Relocate_Node
(N
)));
598 -- 2) Add the conversion to displace the pointer to reference
599 -- the secondary dispatch table.
601 Rewrite
(N
, Convert_To
(Dtyp
, Relocate_Node
(N
)));
602 Analyze_And_Resolve
(N
, Dtyp
);
604 -- 3) The 'access to the secondary dispatch table will be used
605 -- as the value returned by the allocator.
608 Make_Attribute_Reference
(Loc
,
609 Prefix
=> Relocate_Node
(N
),
610 Attribute_Name
=> Name_Access
));
611 Set_Etype
(N
, Saved_Typ
);
615 -- If the type of the allocator expression is an interface type we
616 -- generate a run-time call to displace "this" to reference the
617 -- component containing the pointer to the secondary dispatch table
618 -- or else raise Constraint_Error if the actual object does not
619 -- implement the target interface. This case corresponds with the
620 -- following example:
622 -- function Op (Obj : Iface_1'Class) return access Iface_2'Class is
624 -- return new Iface_2'Class'(Obj);
629 Unchecked_Convert_To
(PtrT
,
630 Make_Function_Call
(Loc
,
631 Name
=> New_Reference_To
(RTE
(RE_Displace
), Loc
),
632 Parameter_Associations
=> New_List
(
633 Unchecked_Convert_To
(RTE
(RE_Address
),
639 (Access_Disp_Table
(Etype
(Base_Type
(Dtyp
))))),
641 Analyze_And_Resolve
(N
, PtrT
);
644 end Displace_Allocator_Pointer
;
646 ---------------------------------
647 -- Expand_Allocator_Expression --
648 ---------------------------------
650 procedure Expand_Allocator_Expression
(N
: Node_Id
) is
651 Loc
: constant Source_Ptr
:= Sloc
(N
);
652 Exp
: constant Node_Id
:= Expression
(Expression
(N
));
653 PtrT
: constant Entity_Id
:= Etype
(N
);
654 DesigT
: constant Entity_Id
:= Designated_Type
(PtrT
);
656 procedure Apply_Accessibility_Check
658 Built_In_Place
: Boolean := False);
659 -- Ada 2005 (AI-344): For an allocator with a class-wide designated
660 -- type, generate an accessibility check to verify that the level of the
661 -- type of the created object is not deeper than the level of the access
662 -- type. If the type of the qualified expression is class-wide, then
663 -- always generate the check (except in the case where it is known to be
664 -- unnecessary, see comment below). Otherwise, only generate the check
665 -- if the level of the qualified expression type is statically deeper
666 -- than the access type.
668 -- Although the static accessibility will generally have been performed
669 -- as a legality check, it won't have been done in cases where the
670 -- allocator appears in generic body, so a run-time check is needed in
671 -- general. One special case is when the access type is declared in the
672 -- same scope as the class-wide allocator, in which case the check can
673 -- never fail, so it need not be generated.
675 -- As an open issue, there seem to be cases where the static level
676 -- associated with the class-wide object's underlying type is not
677 -- sufficient to perform the proper accessibility check, such as for
678 -- allocators in nested subprograms or accept statements initialized by
679 -- class-wide formals when the actual originates outside at a deeper
680 -- static level. The nested subprogram case might require passing
681 -- accessibility levels along with class-wide parameters, and the task
682 -- case seems to be an actual gap in the language rules that needs to
683 -- be fixed by the ARG. ???
685 -------------------------------
686 -- Apply_Accessibility_Check --
687 -------------------------------
689 procedure Apply_Accessibility_Check
691 Built_In_Place
: Boolean := False)
693 Pool_Id
: constant Entity_Id
:= Associated_Storage_Pool
(PtrT
);
700 if Ada_Version
>= Ada_2005
701 and then Is_Class_Wide_Type
(DesigT
)
702 and then not Scope_Suppress
.Suppress
(Accessibility_Check
)
704 (Type_Access_Level
(Etype
(Exp
)) > Type_Access_Level
(PtrT
)
706 (Is_Class_Wide_Type
(Etype
(Exp
))
707 and then Scope
(PtrT
) /= Current_Scope
))
708 and then (Tagged_Type_Expansion
or else VM_Target
/= No_VM
)
710 -- If the allocator was built in place, Ref is already a reference
711 -- to the access object initialized to the result of the allocator
712 -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). We call
713 -- Remove_Side_Effects for cases where the build-in-place call may
714 -- still be the prefix of the reference (to avoid generating
715 -- duplicate calls). Otherwise, it is the entity associated with
716 -- the object containing the address of the allocated object.
718 if Built_In_Place
then
719 Remove_Side_Effects
(Ref
);
720 Obj_Ref
:= New_Copy
(Ref
);
722 Obj_Ref
:= New_Reference_To
(Ref
, Loc
);
725 -- Step 1: Create the object clean up code
729 -- Create an explicit free statement to clean up the allocated
730 -- object in case the accessibility check fails. Generate:
734 Free_Stmt
:= Make_Free_Statement
(Loc
, New_Copy
(Obj_Ref
));
735 Set_Storage_Pool
(Free_Stmt
, Pool_Id
);
737 Append_To
(Stmts
, Free_Stmt
);
739 -- Finalize the object (if applicable), but wrap the call inside
740 -- a block to ensure that the object would still be deallocated in
741 -- case the finalization fails. Generate:
744 -- [Deep_]Finalize (Obj_Ref.all);
751 if Needs_Finalization
(DesigT
) then
753 Make_Block_Statement
(Loc
,
754 Handled_Statement_Sequence
=>
755 Make_Handled_Sequence_Of_Statements
(Loc
,
756 Statements
=> New_List
(
759 Make_Explicit_Dereference
(Loc
,
760 Prefix
=> New_Copy
(Obj_Ref
)),
763 Exception_Handlers
=> New_List
(
764 Make_Exception_Handler
(Loc
,
765 Exception_Choices
=> New_List
(
766 Make_Others_Choice
(Loc
)),
767 Statements
=> New_List
(
768 New_Copy_Tree
(Free_Stmt
),
769 Make_Raise_Statement
(Loc
)))))));
772 -- Signal the accessibility failure through a Program_Error
775 Make_Raise_Program_Error
(Loc
,
776 Condition
=> New_Reference_To
(Standard_True
, Loc
),
777 Reason
=> PE_Accessibility_Check_Failed
));
779 -- Step 2: Create the accessibility comparison
785 Make_Attribute_Reference
(Loc
,
787 Attribute_Name
=> Name_Tag
);
789 -- For tagged types, determine the accessibility level by looking
790 -- at the type specific data of the dispatch table. Generate:
792 -- Type_Specific_Data (Address (Ref'Tag)).Access_Level
794 if Tagged_Type_Expansion
then
795 Cond
:= Build_Get_Access_Level
(Loc
, Obj_Ref
);
797 -- Use a runtime call to determine the accessibility level when
798 -- compiling on virtual machine targets. Generate:
800 -- Get_Access_Level (Ref'Tag)
804 Make_Function_Call
(Loc
,
806 New_Reference_To
(RTE
(RE_Get_Access_Level
), Loc
),
807 Parameter_Associations
=> New_List
(Obj_Ref
));
814 Make_Integer_Literal
(Loc
, Type_Access_Level
(PtrT
)));
816 -- Due to the complexity and side effects of the check, utilize an
817 -- if statement instead of the regular Program_Error circuitry.
820 Make_If_Statement
(Loc
,
822 Then_Statements
=> Stmts
));
824 end Apply_Accessibility_Check
;
828 Aggr_In_Place
: constant Boolean := Is_Delayed_Aggregate
(Exp
);
829 Indic
: constant Node_Id
:= Subtype_Mark
(Expression
(N
));
830 T
: constant Entity_Id
:= Entity
(Indic
);
832 Tag_Assign
: Node_Id
;
836 TagT
: Entity_Id
:= Empty
;
837 -- Type used as source for tag assignment
839 TagR
: Node_Id
:= Empty
;
840 -- Target reference for tag assignment
842 -- Start of processing for Expand_Allocator_Expression
845 -- In the case of an Ada 2012 allocator whose initial value comes from a
846 -- function call, pass "the accessibility level determined by the point
847 -- of call" (AI05-0234) to the function. Conceptually, this belongs in
848 -- Expand_Call but it couldn't be done there (because the Etype of the
849 -- allocator wasn't set then) so we generate the parameter here. See
850 -- the Boolean variable Defer in (a block within) Expand_Call.
852 if Ada_Version
>= Ada_2012
and then Nkind
(Exp
) = N_Function_Call
then
857 if Nkind
(Name
(Exp
)) = N_Explicit_Dereference
then
858 Subp
:= Designated_Type
(Etype
(Prefix
(Name
(Exp
))));
860 Subp
:= Entity
(Name
(Exp
));
863 Subp
:= Ultimate_Alias
(Subp
);
865 if Present
(Extra_Accessibility_Of_Result
(Subp
)) then
866 Add_Extra_Actual_To_Call
867 (Subprogram_Call
=> Exp
,
868 Extra_Formal
=> Extra_Accessibility_Of_Result
(Subp
),
869 Extra_Actual
=> Dynamic_Accessibility_Level
(PtrT
));
874 -- Would be nice to comment the branches of this very long if ???
876 if Is_Tagged_Type
(T
) or else Needs_Finalization
(T
) then
877 if Is_CPP_Constructor_Call
(Exp
) then
880 -- Pnnn : constant ptr_T := new (T);
881 -- Init (Pnnn.all,...);
883 -- Allocate the object without an expression
885 Node
:= Relocate_Node
(N
);
886 Set_Expression
(Node
, New_Reference_To
(Etype
(Exp
), Loc
));
888 -- Avoid its expansion to avoid generating a call to the default
893 Temp
:= Make_Temporary
(Loc
, 'P', N
);
896 Make_Object_Declaration
(Loc
,
897 Defining_Identifier
=> Temp
,
898 Constant_Present
=> True,
899 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
901 Insert_Action
(N
, Temp_Decl
);
903 Apply_Accessibility_Check
(Temp
);
905 -- Locate the enclosing list and insert the C++ constructor call
912 while not Is_List_Member
(P
) loop
916 Insert_List_After_And_Analyze
(P
,
917 Build_Initialization_Call
(Loc
,
919 Make_Explicit_Dereference
(Loc
,
920 Prefix
=> New_Reference_To
(Temp
, Loc
)),
922 Constructor_Ref
=> Exp
));
925 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
926 Analyze_And_Resolve
(N
, PtrT
);
930 -- Ada 2005 (AI-318-02): If the initialization expression is a call
931 -- to a build-in-place function, then access to the allocated object
932 -- must be passed to the function. Currently we limit such functions
933 -- to those with constrained limited result subtypes, but eventually
934 -- we plan to expand the allowed forms of functions that are treated
935 -- as build-in-place.
937 if Ada_Version
>= Ada_2005
938 and then Is_Build_In_Place_Function_Call
(Exp
)
940 Make_Build_In_Place_Call_In_Allocator
(N
, Exp
);
941 Apply_Accessibility_Check
(N
, Built_In_Place
=> True);
945 -- Actions inserted before:
946 -- Temp : constant ptr_T := new T'(Expression);
947 -- Temp._tag = T'tag; -- when not class-wide
948 -- [Deep_]Adjust (Temp.all);
950 -- We analyze by hand the new internal allocator to avoid any
951 -- recursion and inappropriate call to Initialize
953 -- We don't want to remove side effects when the expression must be
954 -- built in place. In the case of a build-in-place function call,
955 -- that could lead to a duplication of the call, which was already
956 -- substituted for the allocator.
958 if not Aggr_In_Place
then
959 Remove_Side_Effects
(Exp
);
962 Temp
:= Make_Temporary
(Loc
, 'P', N
);
964 -- For a class wide allocation generate the following code:
966 -- type Equiv_Record is record ... end record;
967 -- implicit subtype CW is <Class_Wide_Subytpe>;
968 -- temp : PtrT := new CW'(CW!(expr));
970 if Is_Class_Wide_Type
(T
) then
971 Expand_Subtype_From_Expr
(Empty
, T
, Indic
, Exp
);
973 -- Ada 2005 (AI-251): If the expression is a class-wide interface
974 -- object we generate code to move up "this" to reference the
975 -- base of the object before allocating the new object.
977 -- Note that Exp'Address is recursively expanded into a call
978 -- to Base_Address (Exp.Tag)
980 if Is_Class_Wide_Type
(Etype
(Exp
))
981 and then Is_Interface
(Etype
(Exp
))
982 and then Tagged_Type_Expansion
986 Unchecked_Convert_To
(Entity
(Indic
),
987 Make_Explicit_Dereference
(Loc
,
988 Unchecked_Convert_To
(RTE
(RE_Tag_Ptr
),
989 Make_Attribute_Reference
(Loc
,
991 Attribute_Name
=> Name_Address
)))));
995 Unchecked_Convert_To
(Entity
(Indic
), Exp
));
998 Analyze_And_Resolve
(Expression
(N
), Entity
(Indic
));
1001 -- Processing for allocators returning non-interface types
1003 if not Is_Interface
(Directly_Designated_Type
(PtrT
)) then
1004 if Aggr_In_Place
then
1006 Make_Object_Declaration
(Loc
,
1007 Defining_Identifier
=> Temp
,
1008 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
1010 Make_Allocator
(Loc
,
1012 New_Reference_To
(Etype
(Exp
), Loc
)));
1014 -- Copy the Comes_From_Source flag for the allocator we just
1015 -- built, since logically this allocator is a replacement of
1016 -- the original allocator node. This is for proper handling of
1017 -- restriction No_Implicit_Heap_Allocations.
1019 Set_Comes_From_Source
1020 (Expression
(Temp_Decl
), Comes_From_Source
(N
));
1022 Set_No_Initialization
(Expression
(Temp_Decl
));
1023 Insert_Action
(N
, Temp_Decl
);
1025 Build_Allocate_Deallocate_Proc
(Temp_Decl
, True);
1026 Convert_Aggr_In_Allocator
(N
, Temp_Decl
, Exp
);
1028 -- Attach the object to the associated finalization master.
1029 -- This is done manually on .NET/JVM since those compilers do
1030 -- no support pools and can't benefit from internally generated
1031 -- Allocate / Deallocate procedures.
1033 if VM_Target
/= No_VM
1034 and then Is_Controlled
(DesigT
)
1035 and then Present
(Finalization_Master
(PtrT
))
1040 New_Reference_To
(Temp
, Loc
),
1045 Node
:= Relocate_Node
(N
);
1046 Set_Analyzed
(Node
);
1049 Make_Object_Declaration
(Loc
,
1050 Defining_Identifier
=> Temp
,
1051 Constant_Present
=> True,
1052 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
1053 Expression
=> Node
);
1055 Insert_Action
(N
, Temp_Decl
);
1056 Build_Allocate_Deallocate_Proc
(Temp_Decl
, True);
1058 -- Attach the object to the associated finalization master.
1059 -- This is done manually on .NET/JVM since those compilers do
1060 -- no support pools and can't benefit from internally generated
1061 -- Allocate / Deallocate procedures.
1063 if VM_Target
/= No_VM
1064 and then Is_Controlled
(DesigT
)
1065 and then Present
(Finalization_Master
(PtrT
))
1070 New_Reference_To
(Temp
, Loc
),
1075 -- Ada 2005 (AI-251): Handle allocators whose designated type is an
1076 -- interface type. In this case we use the type of the qualified
1077 -- expression to allocate the object.
1081 Def_Id
: constant Entity_Id
:= Make_Temporary
(Loc
, 'T');
1086 Make_Full_Type_Declaration
(Loc
,
1087 Defining_Identifier
=> Def_Id
,
1089 Make_Access_To_Object_Definition
(Loc
,
1090 All_Present
=> True,
1091 Null_Exclusion_Present
=> False,
1092 Constant_Present
=> False,
1093 Subtype_Indication
=>
1094 New_Reference_To
(Etype
(Exp
), Loc
)));
1096 Insert_Action
(N
, New_Decl
);
1098 -- Inherit the allocation-related attributes from the original
1101 Set_Finalization_Master
(Def_Id
, Finalization_Master
(PtrT
));
1103 Set_Associated_Storage_Pool
(Def_Id
,
1104 Associated_Storage_Pool
(PtrT
));
1106 -- Declare the object using the previous type declaration
1108 if Aggr_In_Place
then
1110 Make_Object_Declaration
(Loc
,
1111 Defining_Identifier
=> Temp
,
1112 Object_Definition
=> New_Reference_To
(Def_Id
, Loc
),
1114 Make_Allocator
(Loc
,
1115 New_Reference_To
(Etype
(Exp
), Loc
)));
1117 -- Copy the Comes_From_Source flag for the allocator we just
1118 -- built, since logically this allocator is a replacement of
1119 -- the original allocator node. This is for proper handling
1120 -- of restriction No_Implicit_Heap_Allocations.
1122 Set_Comes_From_Source
1123 (Expression
(Temp_Decl
), Comes_From_Source
(N
));
1125 Set_No_Initialization
(Expression
(Temp_Decl
));
1126 Insert_Action
(N
, Temp_Decl
);
1128 Build_Allocate_Deallocate_Proc
(Temp_Decl
, True);
1129 Convert_Aggr_In_Allocator
(N
, Temp_Decl
, Exp
);
1132 Node
:= Relocate_Node
(N
);
1133 Set_Analyzed
(Node
);
1136 Make_Object_Declaration
(Loc
,
1137 Defining_Identifier
=> Temp
,
1138 Constant_Present
=> True,
1139 Object_Definition
=> New_Reference_To
(Def_Id
, Loc
),
1140 Expression
=> Node
);
1142 Insert_Action
(N
, Temp_Decl
);
1143 Build_Allocate_Deallocate_Proc
(Temp_Decl
, True);
1146 -- Generate an additional object containing the address of the
1147 -- returned object. The type of this second object declaration
1148 -- is the correct type required for the common processing that
1149 -- is still performed by this subprogram. The displacement of
1150 -- this pointer to reference the component associated with the
1151 -- interface type will be done at the end of common processing.
1154 Make_Object_Declaration
(Loc
,
1155 Defining_Identifier
=> Make_Temporary
(Loc
, 'P'),
1156 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
1158 Unchecked_Convert_To
(PtrT
,
1159 New_Reference_To
(Temp
, Loc
)));
1161 Insert_Action
(N
, New_Decl
);
1163 Temp_Decl
:= New_Decl
;
1164 Temp
:= Defining_Identifier
(New_Decl
);
1168 Apply_Accessibility_Check
(Temp
);
1170 -- Generate the tag assignment
1172 -- Suppress the tag assignment when VM_Target because VM tags are
1173 -- represented implicitly in objects.
1175 if not Tagged_Type_Expansion
then
1178 -- Ada 2005 (AI-251): Suppress the tag assignment with class-wide
1179 -- interface objects because in this case the tag does not change.
1181 elsif Is_Interface
(Directly_Designated_Type
(Etype
(N
))) then
1182 pragma Assert
(Is_Class_Wide_Type
1183 (Directly_Designated_Type
(Etype
(N
))));
1186 elsif Is_Tagged_Type
(T
) and then not Is_Class_Wide_Type
(T
) then
1188 TagR
:= New_Reference_To
(Temp
, Loc
);
1190 elsif Is_Private_Type
(T
)
1191 and then Is_Tagged_Type
(Underlying_Type
(T
))
1193 TagT
:= Underlying_Type
(T
);
1195 Unchecked_Convert_To
(Underlying_Type
(T
),
1196 Make_Explicit_Dereference
(Loc
,
1197 Prefix
=> New_Reference_To
(Temp
, Loc
)));
1200 if Present
(TagT
) then
1202 Full_T
: constant Entity_Id
:= Underlying_Type
(TagT
);
1205 Make_Assignment_Statement
(Loc
,
1207 Make_Selected_Component
(Loc
,
1210 New_Reference_To
(First_Tag_Component
(Full_T
), Loc
)),
1212 Unchecked_Convert_To
(RTE
(RE_Tag
),
1215 (First_Elmt
(Access_Disp_Table
(Full_T
))), Loc
)));
1218 -- The previous assignment has to be done in any case
1220 Set_Assignment_OK
(Name
(Tag_Assign
));
1221 Insert_Action
(N
, Tag_Assign
);
1224 if Needs_Finalization
(DesigT
)
1225 and then Needs_Finalization
(T
)
1227 -- Generate an Adjust call if the object will be moved. In Ada
1228 -- 2005, the object may be inherently limited, in which case
1229 -- there is no Adjust procedure, and the object is built in
1230 -- place. In Ada 95, the object can be limited but not
1231 -- inherently limited if this allocator came from a return
1232 -- statement (we're allocating the result on the secondary
1233 -- stack). In that case, the object will be moved, so we _do_
1236 if not Aggr_In_Place
1237 and then not Is_Immutably_Limited_Type
(T
)
1243 -- An unchecked conversion is needed in the classwide
1244 -- case because the designated type can be an ancestor
1245 -- of the subtype mark of the allocator.
1247 Unchecked_Convert_To
(T
,
1248 Make_Explicit_Dereference
(Loc
,
1249 Prefix
=> New_Reference_To
(Temp
, Loc
))),
1254 -- Set_Finalize_Address (<PtrT>FM, <T>FD'Unrestricted_Access);
1256 -- Do not generate this call in the following cases:
1258 -- * .NET/JVM - these targets do not support address arithmetic
1259 -- and unchecked conversion, key elements of Finalize_Address.
1261 -- * Alfa mode - the call is useless and results in unwanted
1264 -- * CodePeer mode - TSS primitive Finalize_Address is not
1265 -- created in this mode.
1267 if VM_Target
= No_VM
1268 and then not Alfa_Mode
1269 and then not CodePeer_Mode
1270 and then Present
(Finalization_Master
(PtrT
))
1271 and then Present
(Temp_Decl
)
1272 and then Nkind
(Expression
(Temp_Decl
)) = N_Allocator
1275 Make_Set_Finalize_Address_Call
1282 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
1283 Analyze_And_Resolve
(N
, PtrT
);
1285 -- Ada 2005 (AI-251): Displace the pointer to reference the record
1286 -- component containing the secondary dispatch table of the interface
1289 if Is_Interface
(Directly_Designated_Type
(PtrT
)) then
1290 Displace_Allocator_Pointer
(N
);
1293 elsif Aggr_In_Place
then
1294 Temp
:= Make_Temporary
(Loc
, 'P', N
);
1296 Make_Object_Declaration
(Loc
,
1297 Defining_Identifier
=> Temp
,
1298 Object_Definition
=> New_Reference_To
(PtrT
, Loc
),
1300 Make_Allocator
(Loc
,
1301 Expression
=> New_Reference_To
(Etype
(Exp
), Loc
)));
1303 -- Copy the Comes_From_Source flag for the allocator we just built,
1304 -- since logically this allocator is a replacement of the original
1305 -- allocator node. This is for proper handling of restriction
1306 -- No_Implicit_Heap_Allocations.
1308 Set_Comes_From_Source
1309 (Expression
(Temp_Decl
), Comes_From_Source
(N
));
1311 Set_No_Initialization
(Expression
(Temp_Decl
));
1312 Insert_Action
(N
, Temp_Decl
);
1314 Build_Allocate_Deallocate_Proc
(Temp_Decl
, True);
1315 Convert_Aggr_In_Allocator
(N
, Temp_Decl
, Exp
);
1317 -- Attach the object to the associated finalization master. Thisis
1318 -- done manually on .NET/JVM since those compilers do no support
1319 -- pools and cannot benefit from internally generated Allocate and
1320 -- Deallocate procedures.
1322 if VM_Target
/= No_VM
1323 and then Is_Controlled
(DesigT
)
1324 and then Present
(Finalization_Master
(PtrT
))
1328 (Obj_Ref
=> New_Reference_To
(Temp
, Loc
),
1332 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
1333 Analyze_And_Resolve
(N
, PtrT
);
1335 elsif Is_Access_Type
(T
)
1336 and then Can_Never_Be_Null
(T
)
1338 Install_Null_Excluding_Check
(Exp
);
1340 elsif Is_Access_Type
(DesigT
)
1341 and then Nkind
(Exp
) = N_Allocator
1342 and then Nkind
(Expression
(Exp
)) /= N_Qualified_Expression
1344 -- Apply constraint to designated subtype indication
1346 Apply_Constraint_Check
(Expression
(Exp
),
1347 Designated_Type
(DesigT
),
1348 No_Sliding
=> True);
1350 if Nkind
(Expression
(Exp
)) = N_Raise_Constraint_Error
then
1352 -- Propagate constraint_error to enclosing allocator
1354 Rewrite
(Exp
, New_Copy
(Expression
(Exp
)));
1358 Build_Allocate_Deallocate_Proc
(N
, True);
1361 -- type A is access T1;
1362 -- X : A := new T2'(...);
1363 -- T1 and T2 can be different subtypes, and we might need to check
1364 -- both constraints. First check against the type of the qualified
1367 Apply_Constraint_Check
(Exp
, T
, No_Sliding
=> True);
1369 if Do_Range_Check
(Exp
) then
1370 Set_Do_Range_Check
(Exp
, False);
1371 Generate_Range_Check
(Exp
, DesigT
, CE_Range_Check_Failed
);
1374 -- A check is also needed in cases where the designated subtype is
1375 -- constrained and differs from the subtype given in the qualified
1376 -- expression. Note that the check on the qualified expression does
1377 -- not allow sliding, but this check does (a relaxation from Ada 83).
1379 if Is_Constrained
(DesigT
)
1380 and then not Subtypes_Statically_Match
(T
, DesigT
)
1382 Apply_Constraint_Check
1383 (Exp
, DesigT
, No_Sliding
=> False);
1385 if Do_Range_Check
(Exp
) then
1386 Set_Do_Range_Check
(Exp
, False);
1387 Generate_Range_Check
(Exp
, DesigT
, CE_Range_Check_Failed
);
1391 -- For an access to unconstrained packed array, GIGI needs to see an
1392 -- expression with a constrained subtype in order to compute the
1393 -- proper size for the allocator.
1395 if Is_Array_Type
(T
)
1396 and then not Is_Constrained
(T
)
1397 and then Is_Packed
(T
)
1400 ConstrT
: constant Entity_Id
:= Make_Temporary
(Loc
, 'A');
1401 Internal_Exp
: constant Node_Id
:= Relocate_Node
(Exp
);
1404 Make_Subtype_Declaration
(Loc
,
1405 Defining_Identifier
=> ConstrT
,
1406 Subtype_Indication
=>
1407 Make_Subtype_From_Expr
(Internal_Exp
, T
)));
1408 Freeze_Itype
(ConstrT
, Exp
);
1409 Rewrite
(Exp
, OK_Convert_To
(ConstrT
, Internal_Exp
));
1413 -- Ada 2005 (AI-318-02): If the initialization expression is a call
1414 -- to a build-in-place function, then access to the allocated object
1415 -- must be passed to the function. Currently we limit such functions
1416 -- to those with constrained limited result subtypes, but eventually
1417 -- we plan to expand the allowed forms of functions that are treated
1418 -- as build-in-place.
1420 if Ada_Version
>= Ada_2005
1421 and then Is_Build_In_Place_Function_Call
(Exp
)
1423 Make_Build_In_Place_Call_In_Allocator
(N
, Exp
);
1428 when RE_Not_Available
=>
1430 end Expand_Allocator_Expression
;
1432 -----------------------------
1433 -- Expand_Array_Comparison --
1434 -----------------------------
1436 -- Expansion is only required in the case of array types. For the unpacked
1437 -- case, an appropriate runtime routine is called. For packed cases, and
1438 -- also in some other cases where a runtime routine cannot be called, the
1439 -- form of the expansion is:
1441 -- [body for greater_nn; boolean_expression]
1443 -- The body is built by Make_Array_Comparison_Op, and the form of the
1444 -- Boolean expression depends on the operator involved.
1446 procedure Expand_Array_Comparison
(N
: Node_Id
) is
1447 Loc
: constant Source_Ptr
:= Sloc
(N
);
1448 Op1
: Node_Id
:= Left_Opnd
(N
);
1449 Op2
: Node_Id
:= Right_Opnd
(N
);
1450 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
1451 Ctyp
: constant Entity_Id
:= Component_Type
(Typ1
);
1454 Func_Body
: Node_Id
;
1455 Func_Name
: Entity_Id
;
1459 Byte_Addressable
: constant Boolean := System_Storage_Unit
= Byte
'Size;
1460 -- True for byte addressable target
1462 function Length_Less_Than_4
(Opnd
: Node_Id
) return Boolean;
1463 -- Returns True if the length of the given operand is known to be less
1464 -- than 4. Returns False if this length is known to be four or greater
1465 -- or is not known at compile time.
1467 ------------------------
1468 -- Length_Less_Than_4 --
1469 ------------------------
1471 function Length_Less_Than_4
(Opnd
: Node_Id
) return Boolean is
1472 Otyp
: constant Entity_Id
:= Etype
(Opnd
);
1475 if Ekind
(Otyp
) = E_String_Literal_Subtype
then
1476 return String_Literal_Length
(Otyp
) < 4;
1480 Ityp
: constant Entity_Id
:= Etype
(First_Index
(Otyp
));
1481 Lo
: constant Node_Id
:= Type_Low_Bound
(Ityp
);
1482 Hi
: constant Node_Id
:= Type_High_Bound
(Ityp
);
1487 if Compile_Time_Known_Value
(Lo
) then
1488 Lov
:= Expr_Value
(Lo
);
1493 if Compile_Time_Known_Value
(Hi
) then
1494 Hiv
:= Expr_Value
(Hi
);
1499 return Hiv
< Lov
+ 3;
1502 end Length_Less_Than_4
;
1504 -- Start of processing for Expand_Array_Comparison
1507 -- Deal first with unpacked case, where we can call a runtime routine
1508 -- except that we avoid this for targets for which are not addressable
1509 -- by bytes, and for the JVM/CIL, since they do not support direct
1510 -- addressing of array components.
1512 if not Is_Bit_Packed_Array
(Typ1
)
1513 and then Byte_Addressable
1514 and then VM_Target
= No_VM
1516 -- The call we generate is:
1518 -- Compare_Array_xn[_Unaligned]
1519 -- (left'address, right'address, left'length, right'length) <op> 0
1521 -- x = U for unsigned, S for signed
1522 -- n = 8,16,32,64 for component size
1523 -- Add _Unaligned if length < 4 and component size is 8.
1524 -- <op> is the standard comparison operator
1526 if Component_Size
(Typ1
) = 8 then
1527 if Length_Less_Than_4
(Op1
)
1529 Length_Less_Than_4
(Op2
)
1531 if Is_Unsigned_Type
(Ctyp
) then
1532 Comp
:= RE_Compare_Array_U8_Unaligned
;
1534 Comp
:= RE_Compare_Array_S8_Unaligned
;
1538 if Is_Unsigned_Type
(Ctyp
) then
1539 Comp
:= RE_Compare_Array_U8
;
1541 Comp
:= RE_Compare_Array_S8
;
1545 elsif Component_Size
(Typ1
) = 16 then
1546 if Is_Unsigned_Type
(Ctyp
) then
1547 Comp
:= RE_Compare_Array_U16
;
1549 Comp
:= RE_Compare_Array_S16
;
1552 elsif Component_Size
(Typ1
) = 32 then
1553 if Is_Unsigned_Type
(Ctyp
) then
1554 Comp
:= RE_Compare_Array_U32
;
1556 Comp
:= RE_Compare_Array_S32
;
1559 else pragma Assert
(Component_Size
(Typ1
) = 64);
1560 if Is_Unsigned_Type
(Ctyp
) then
1561 Comp
:= RE_Compare_Array_U64
;
1563 Comp
:= RE_Compare_Array_S64
;
1567 Remove_Side_Effects
(Op1
, Name_Req
=> True);
1568 Remove_Side_Effects
(Op2
, Name_Req
=> True);
1571 Make_Function_Call
(Sloc
(Op1
),
1572 Name
=> New_Occurrence_Of
(RTE
(Comp
), Loc
),
1574 Parameter_Associations
=> New_List
(
1575 Make_Attribute_Reference
(Loc
,
1576 Prefix
=> Relocate_Node
(Op1
),
1577 Attribute_Name
=> Name_Address
),
1579 Make_Attribute_Reference
(Loc
,
1580 Prefix
=> Relocate_Node
(Op2
),
1581 Attribute_Name
=> Name_Address
),
1583 Make_Attribute_Reference
(Loc
,
1584 Prefix
=> Relocate_Node
(Op1
),
1585 Attribute_Name
=> Name_Length
),
1587 Make_Attribute_Reference
(Loc
,
1588 Prefix
=> Relocate_Node
(Op2
),
1589 Attribute_Name
=> Name_Length
))));
1592 Make_Integer_Literal
(Sloc
(Op2
),
1595 Analyze_And_Resolve
(Op1
, Standard_Integer
);
1596 Analyze_And_Resolve
(Op2
, Standard_Integer
);
1600 -- Cases where we cannot make runtime call
1602 -- For (a <= b) we convert to not (a > b)
1604 if Chars
(N
) = Name_Op_Le
then
1610 Right_Opnd
=> Op2
)));
1611 Analyze_And_Resolve
(N
, Standard_Boolean
);
1614 -- For < the Boolean expression is
1615 -- greater__nn (op2, op1)
1617 elsif Chars
(N
) = Name_Op_Lt
then
1618 Func_Body
:= Make_Array_Comparison_Op
(Typ1
, N
);
1622 Op1
:= Right_Opnd
(N
);
1623 Op2
:= Left_Opnd
(N
);
1625 -- For (a >= b) we convert to not (a < b)
1627 elsif Chars
(N
) = Name_Op_Ge
then
1633 Right_Opnd
=> Op2
)));
1634 Analyze_And_Resolve
(N
, Standard_Boolean
);
1637 -- For > the Boolean expression is
1638 -- greater__nn (op1, op2)
1641 pragma Assert
(Chars
(N
) = Name_Op_Gt
);
1642 Func_Body
:= Make_Array_Comparison_Op
(Typ1
, N
);
1645 Func_Name
:= Defining_Unit_Name
(Specification
(Func_Body
));
1647 Make_Function_Call
(Loc
,
1648 Name
=> New_Reference_To
(Func_Name
, Loc
),
1649 Parameter_Associations
=> New_List
(Op1
, Op2
));
1651 Insert_Action
(N
, Func_Body
);
1653 Analyze_And_Resolve
(N
, Standard_Boolean
);
1656 when RE_Not_Available
=>
1658 end Expand_Array_Comparison
;
1660 ---------------------------
1661 -- Expand_Array_Equality --
1662 ---------------------------
1664 -- Expand an equality function for multi-dimensional arrays. Here is an
1665 -- example of such a function for Nb_Dimension = 2
1667 -- function Enn (A : atyp; B : btyp) return boolean is
1669 -- if (A'length (1) = 0 or else A'length (2) = 0)
1671 -- (B'length (1) = 0 or else B'length (2) = 0)
1673 -- return True; -- RM 4.5.2(22)
1676 -- if A'length (1) /= B'length (1)
1678 -- A'length (2) /= B'length (2)
1680 -- return False; -- RM 4.5.2(23)
1684 -- A1 : Index_T1 := A'first (1);
1685 -- B1 : Index_T1 := B'first (1);
1689 -- A2 : Index_T2 := A'first (2);
1690 -- B2 : Index_T2 := B'first (2);
1693 -- if A (A1, A2) /= B (B1, B2) then
1697 -- exit when A2 = A'last (2);
1698 -- A2 := Index_T2'succ (A2);
1699 -- B2 := Index_T2'succ (B2);
1703 -- exit when A1 = A'last (1);
1704 -- A1 := Index_T1'succ (A1);
1705 -- B1 := Index_T1'succ (B1);
1712 -- Note on the formal types used (atyp and btyp). If either of the arrays
1713 -- is of a private type, we use the underlying type, and do an unchecked
1714 -- conversion of the actual. If either of the arrays has a bound depending
1715 -- on a discriminant, then we use the base type since otherwise we have an
1716 -- escaped discriminant in the function.
1718 -- If both arrays are constrained and have the same bounds, we can generate
1719 -- a loop with an explicit iteration scheme using a 'Range attribute over
1722 function Expand_Array_Equality
1727 Typ
: Entity_Id
) return Node_Id
1729 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
1730 Decls
: constant List_Id
:= New_List
;
1731 Index_List1
: constant List_Id
:= New_List
;
1732 Index_List2
: constant List_Id
:= New_List
;
1736 Func_Name
: Entity_Id
;
1737 Func_Body
: Node_Id
;
1739 A
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uA
);
1740 B
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uB
);
1744 -- The parameter types to be used for the formals
1749 Num
: Int
) return Node_Id
;
1750 -- This builds the attribute reference Arr'Nam (Expr)
1752 function Component_Equality
(Typ
: Entity_Id
) return Node_Id
;
1753 -- Create one statement to compare corresponding components, designated
1754 -- by a full set of indexes.
1756 function Get_Arg_Type
(N
: Node_Id
) return Entity_Id
;
1757 -- Given one of the arguments, computes the appropriate type to be used
1758 -- for that argument in the corresponding function formal
1760 function Handle_One_Dimension
1762 Index
: Node_Id
) return Node_Id
;
1763 -- This procedure returns the following code
1766 -- Bn : Index_T := B'First (N);
1770 -- exit when An = A'Last (N);
1771 -- An := Index_T'Succ (An)
1772 -- Bn := Index_T'Succ (Bn)
1776 -- If both indexes are constrained and identical, the procedure
1777 -- returns a simpler loop:
1779 -- for An in A'Range (N) loop
1783 -- N is the dimension for which we are generating a loop. Index is the
1784 -- N'th index node, whose Etype is Index_Type_n in the above code. The
1785 -- xxx statement is either the loop or declare for the next dimension
1786 -- or if this is the last dimension the comparison of corresponding
1787 -- components of the arrays.
1789 -- The actual way the code works is to return the comparison of
1790 -- corresponding components for the N+1 call. That's neater!
1792 function Test_Empty_Arrays
return Node_Id
;
1793 -- This function constructs the test for both arrays being empty
1794 -- (A'length (1) = 0 or else A'length (2) = 0 or else ...)
1796 -- (B'length (1) = 0 or else B'length (2) = 0 or else ...)
1798 function Test_Lengths_Correspond
return Node_Id
;
1799 -- This function constructs the test for arrays having different lengths
1800 -- in at least one index position, in which case the resulting code is:
1802 -- A'length (1) /= B'length (1)
1804 -- A'length (2) /= B'length (2)
1815 Num
: Int
) return Node_Id
1819 Make_Attribute_Reference
(Loc
,
1820 Attribute_Name
=> Nam
,
1821 Prefix
=> New_Reference_To
(Arr
, Loc
),
1822 Expressions
=> New_List
(Make_Integer_Literal
(Loc
, Num
)));
1825 ------------------------
1826 -- Component_Equality --
1827 ------------------------
1829 function Component_Equality
(Typ
: Entity_Id
) return Node_Id
is
1834 -- if a(i1...) /= b(j1...) then return false; end if;
1837 Make_Indexed_Component
(Loc
,
1838 Prefix
=> Make_Identifier
(Loc
, Chars
(A
)),
1839 Expressions
=> Index_List1
);
1842 Make_Indexed_Component
(Loc
,
1843 Prefix
=> Make_Identifier
(Loc
, Chars
(B
)),
1844 Expressions
=> Index_List2
);
1846 Test
:= Expand_Composite_Equality
1847 (Nod
, Component_Type
(Typ
), L
, R
, Decls
);
1849 -- If some (sub)component is an unchecked_union, the whole operation
1850 -- will raise program error.
1852 if Nkind
(Test
) = N_Raise_Program_Error
then
1854 -- This node is going to be inserted at a location where a
1855 -- statement is expected: clear its Etype so analysis will set
1856 -- it to the expected Standard_Void_Type.
1858 Set_Etype
(Test
, Empty
);
1863 Make_Implicit_If_Statement
(Nod
,
1864 Condition
=> Make_Op_Not
(Loc
, Right_Opnd
=> Test
),
1865 Then_Statements
=> New_List
(
1866 Make_Simple_Return_Statement
(Loc
,
1867 Expression
=> New_Occurrence_Of
(Standard_False
, Loc
))));
1869 end Component_Equality
;
1875 function Get_Arg_Type
(N
: Node_Id
) return Entity_Id
is
1886 T
:= Underlying_Type
(T
);
1888 X
:= First_Index
(T
);
1889 while Present
(X
) loop
1890 if Denotes_Discriminant
(Type_Low_Bound
(Etype
(X
)))
1892 Denotes_Discriminant
(Type_High_Bound
(Etype
(X
)))
1905 --------------------------
1906 -- Handle_One_Dimension --
1907 ---------------------------
1909 function Handle_One_Dimension
1911 Index
: Node_Id
) return Node_Id
1913 Need_Separate_Indexes
: constant Boolean :=
1915 or else not Is_Constrained
(Ltyp
);
1916 -- If the index types are identical, and we are working with
1917 -- constrained types, then we can use the same index for both
1920 An
: constant Entity_Id
:= Make_Temporary
(Loc
, 'A');
1923 Index_T
: Entity_Id
;
1928 if N
> Number_Dimensions
(Ltyp
) then
1929 return Component_Equality
(Ltyp
);
1932 -- Case where we generate a loop
1934 Index_T
:= Base_Type
(Etype
(Index
));
1936 if Need_Separate_Indexes
then
1937 Bn
:= Make_Temporary
(Loc
, 'B');
1942 Append
(New_Reference_To
(An
, Loc
), Index_List1
);
1943 Append
(New_Reference_To
(Bn
, Loc
), Index_List2
);
1945 Stm_List
:= New_List
(
1946 Handle_One_Dimension
(N
+ 1, Next_Index
(Index
)));
1948 if Need_Separate_Indexes
then
1950 -- Generate guard for loop, followed by increments of indexes
1952 Append_To
(Stm_List
,
1953 Make_Exit_Statement
(Loc
,
1956 Left_Opnd
=> New_Reference_To
(An
, Loc
),
1957 Right_Opnd
=> Arr_Attr
(A
, Name_Last
, N
))));
1959 Append_To
(Stm_List
,
1960 Make_Assignment_Statement
(Loc
,
1961 Name
=> New_Reference_To
(An
, Loc
),
1963 Make_Attribute_Reference
(Loc
,
1964 Prefix
=> New_Reference_To
(Index_T
, Loc
),
1965 Attribute_Name
=> Name_Succ
,
1966 Expressions
=> New_List
(New_Reference_To
(An
, Loc
)))));
1968 Append_To
(Stm_List
,
1969 Make_Assignment_Statement
(Loc
,
1970 Name
=> New_Reference_To
(Bn
, Loc
),
1972 Make_Attribute_Reference
(Loc
,
1973 Prefix
=> New_Reference_To
(Index_T
, Loc
),
1974 Attribute_Name
=> Name_Succ
,
1975 Expressions
=> New_List
(New_Reference_To
(Bn
, Loc
)))));
1978 -- If separate indexes, we need a declare block for An and Bn, and a
1979 -- loop without an iteration scheme.
1981 if Need_Separate_Indexes
then
1983 Make_Implicit_Loop_Statement
(Nod
, Statements
=> Stm_List
);
1986 Make_Block_Statement
(Loc
,
1987 Declarations
=> New_List
(
1988 Make_Object_Declaration
(Loc
,
1989 Defining_Identifier
=> An
,
1990 Object_Definition
=> New_Reference_To
(Index_T
, Loc
),
1991 Expression
=> Arr_Attr
(A
, Name_First
, N
)),
1993 Make_Object_Declaration
(Loc
,
1994 Defining_Identifier
=> Bn
,
1995 Object_Definition
=> New_Reference_To
(Index_T
, Loc
),
1996 Expression
=> Arr_Attr
(B
, Name_First
, N
))),
1998 Handled_Statement_Sequence
=>
1999 Make_Handled_Sequence_Of_Statements
(Loc
,
2000 Statements
=> New_List
(Loop_Stm
)));
2002 -- If no separate indexes, return loop statement with explicit
2003 -- iteration scheme on its own
2007 Make_Implicit_Loop_Statement
(Nod
,
2008 Statements
=> Stm_List
,
2010 Make_Iteration_Scheme
(Loc
,
2011 Loop_Parameter_Specification
=>
2012 Make_Loop_Parameter_Specification
(Loc
,
2013 Defining_Identifier
=> An
,
2014 Discrete_Subtype_Definition
=>
2015 Arr_Attr
(A
, Name_Range
, N
))));
2018 end Handle_One_Dimension
;
2020 -----------------------
2021 -- Test_Empty_Arrays --
2022 -----------------------
2024 function Test_Empty_Arrays
return Node_Id
is
2034 for J
in 1 .. Number_Dimensions
(Ltyp
) loop
2037 Left_Opnd
=> Arr_Attr
(A
, Name_Length
, J
),
2038 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0));
2042 Left_Opnd
=> Arr_Attr
(B
, Name_Length
, J
),
2043 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0));
2052 Left_Opnd
=> Relocate_Node
(Alist
),
2053 Right_Opnd
=> Atest
);
2057 Left_Opnd
=> Relocate_Node
(Blist
),
2058 Right_Opnd
=> Btest
);
2065 Right_Opnd
=> Blist
);
2066 end Test_Empty_Arrays
;
2068 -----------------------------
2069 -- Test_Lengths_Correspond --
2070 -----------------------------
2072 function Test_Lengths_Correspond
return Node_Id
is
2078 for J
in 1 .. Number_Dimensions
(Ltyp
) loop
2081 Left_Opnd
=> Arr_Attr
(A
, Name_Length
, J
),
2082 Right_Opnd
=> Arr_Attr
(B
, Name_Length
, J
));
2089 Left_Opnd
=> Relocate_Node
(Result
),
2090 Right_Opnd
=> Rtest
);
2095 end Test_Lengths_Correspond
;
2097 -- Start of processing for Expand_Array_Equality
2100 Ltyp
:= Get_Arg_Type
(Lhs
);
2101 Rtyp
:= Get_Arg_Type
(Rhs
);
2103 -- For now, if the argument types are not the same, go to the base type,
2104 -- since the code assumes that the formals have the same type. This is
2105 -- fixable in future ???
2107 if Ltyp
/= Rtyp
then
2108 Ltyp
:= Base_Type
(Ltyp
);
2109 Rtyp
:= Base_Type
(Rtyp
);
2110 pragma Assert
(Ltyp
= Rtyp
);
2113 -- Build list of formals for function
2115 Formals
:= New_List
(
2116 Make_Parameter_Specification
(Loc
,
2117 Defining_Identifier
=> A
,
2118 Parameter_Type
=> New_Reference_To
(Ltyp
, Loc
)),
2120 Make_Parameter_Specification
(Loc
,
2121 Defining_Identifier
=> B
,
2122 Parameter_Type
=> New_Reference_To
(Rtyp
, Loc
)));
2124 Func_Name
:= Make_Temporary
(Loc
, 'E');
2126 -- Build statement sequence for function
2129 Make_Subprogram_Body
(Loc
,
2131 Make_Function_Specification
(Loc
,
2132 Defining_Unit_Name
=> Func_Name
,
2133 Parameter_Specifications
=> Formals
,
2134 Result_Definition
=> New_Reference_To
(Standard_Boolean
, Loc
)),
2136 Declarations
=> Decls
,
2138 Handled_Statement_Sequence
=>
2139 Make_Handled_Sequence_Of_Statements
(Loc
,
2140 Statements
=> New_List
(
2142 Make_Implicit_If_Statement
(Nod
,
2143 Condition
=> Test_Empty_Arrays
,
2144 Then_Statements
=> New_List
(
2145 Make_Simple_Return_Statement
(Loc
,
2147 New_Occurrence_Of
(Standard_True
, Loc
)))),
2149 Make_Implicit_If_Statement
(Nod
,
2150 Condition
=> Test_Lengths_Correspond
,
2151 Then_Statements
=> New_List
(
2152 Make_Simple_Return_Statement
(Loc
,
2154 New_Occurrence_Of
(Standard_False
, Loc
)))),
2156 Handle_One_Dimension
(1, First_Index
(Ltyp
)),
2158 Make_Simple_Return_Statement
(Loc
,
2159 Expression
=> New_Occurrence_Of
(Standard_True
, Loc
)))));
2161 Set_Has_Completion
(Func_Name
, True);
2162 Set_Is_Inlined
(Func_Name
);
2164 -- If the array type is distinct from the type of the arguments, it
2165 -- is the full view of a private type. Apply an unchecked conversion
2166 -- to insure that analysis of the call succeeds.
2176 or else Base_Type
(Etype
(Lhs
)) /= Base_Type
(Ltyp
)
2178 L
:= OK_Convert_To
(Ltyp
, Lhs
);
2182 or else Base_Type
(Etype
(Rhs
)) /= Base_Type
(Rtyp
)
2184 R
:= OK_Convert_To
(Rtyp
, Rhs
);
2187 Actuals
:= New_List
(L
, R
);
2190 Append_To
(Bodies
, Func_Body
);
2193 Make_Function_Call
(Loc
,
2194 Name
=> New_Reference_To
(Func_Name
, Loc
),
2195 Parameter_Associations
=> Actuals
);
2196 end Expand_Array_Equality
;
2198 -----------------------------
2199 -- Expand_Boolean_Operator --
2200 -----------------------------
2202 -- Note that we first get the actual subtypes of the operands, since we
2203 -- always want to deal with types that have bounds.
2205 procedure Expand_Boolean_Operator
(N
: Node_Id
) is
2206 Typ
: constant Entity_Id
:= Etype
(N
);
2209 -- Special case of bit packed array where both operands are known to be
2210 -- properly aligned. In this case we use an efficient run time routine
2211 -- to carry out the operation (see System.Bit_Ops).
2213 if Is_Bit_Packed_Array
(Typ
)
2214 and then not Is_Possibly_Unaligned_Object
(Left_Opnd
(N
))
2215 and then not Is_Possibly_Unaligned_Object
(Right_Opnd
(N
))
2217 Expand_Packed_Boolean_Operator
(N
);
2221 -- For the normal non-packed case, the general expansion is to build
2222 -- function for carrying out the comparison (use Make_Boolean_Array_Op)
2223 -- and then inserting it into the tree. The original operator node is
2224 -- then rewritten as a call to this function. We also use this in the
2225 -- packed case if either operand is a possibly unaligned object.
2228 Loc
: constant Source_Ptr
:= Sloc
(N
);
2229 L
: constant Node_Id
:= Relocate_Node
(Left_Opnd
(N
));
2230 R
: constant Node_Id
:= Relocate_Node
(Right_Opnd
(N
));
2231 Func_Body
: Node_Id
;
2232 Func_Name
: Entity_Id
;
2235 Convert_To_Actual_Subtype
(L
);
2236 Convert_To_Actual_Subtype
(R
);
2237 Ensure_Defined
(Etype
(L
), N
);
2238 Ensure_Defined
(Etype
(R
), N
);
2239 Apply_Length_Check
(R
, Etype
(L
));
2241 if Nkind
(N
) = N_Op_Xor
then
2242 Silly_Boolean_Array_Xor_Test
(N
, Etype
(L
));
2245 if Nkind
(Parent
(N
)) = N_Assignment_Statement
2246 and then Safe_In_Place_Array_Op
(Name
(Parent
(N
)), L
, R
)
2248 Build_Boolean_Array_Proc_Call
(Parent
(N
), L
, R
);
2250 elsif Nkind
(Parent
(N
)) = N_Op_Not
2251 and then Nkind
(N
) = N_Op_And
2253 Safe_In_Place_Array_Op
(Name
(Parent
(Parent
(N
))), L
, R
)
2258 Func_Body
:= Make_Boolean_Array_Op
(Etype
(L
), N
);
2259 Func_Name
:= Defining_Unit_Name
(Specification
(Func_Body
));
2260 Insert_Action
(N
, Func_Body
);
2262 -- Now rewrite the expression with a call
2265 Make_Function_Call
(Loc
,
2266 Name
=> New_Reference_To
(Func_Name
, Loc
),
2267 Parameter_Associations
=>
2270 Make_Type_Conversion
2271 (Loc
, New_Reference_To
(Etype
(L
), Loc
), R
))));
2273 Analyze_And_Resolve
(N
, Typ
);
2276 end Expand_Boolean_Operator
;
2278 -------------------------------
2279 -- Expand_Composite_Equality --
2280 -------------------------------
2282 -- This function is only called for comparing internal fields of composite
2283 -- types when these fields are themselves composites. This is a special
2284 -- case because it is not possible to respect normal Ada visibility rules.
2286 function Expand_Composite_Equality
2291 Bodies
: List_Id
) return Node_Id
2293 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
2294 Full_Type
: Entity_Id
;
2298 function Find_Primitive_Eq
return Node_Id
;
2299 -- AI05-0123: Locate primitive equality for type if it exists, and
2300 -- build the corresponding call. If operation is abstract, replace
2301 -- call with an explicit raise. Return Empty if there is no primitive.
2303 -----------------------
2304 -- Find_Primitive_Eq --
2305 -----------------------
2307 function Find_Primitive_Eq
return Node_Id
is
2312 Prim_E
:= First_Elmt
(Collect_Primitive_Operations
(Typ
));
2313 while Present
(Prim_E
) loop
2314 Prim
:= Node
(Prim_E
);
2316 -- Locate primitive equality with the right signature
2318 if Chars
(Prim
) = Name_Op_Eq
2319 and then Etype
(First_Formal
(Prim
)) =
2320 Etype
(Next_Formal
(First_Formal
(Prim
)))
2321 and then Etype
(Prim
) = Standard_Boolean
2323 if Is_Abstract_Subprogram
(Prim
) then
2325 Make_Raise_Program_Error
(Loc
,
2326 Reason
=> PE_Explicit_Raise
);
2330 Make_Function_Call
(Loc
,
2331 Name
=> New_Reference_To
(Prim
, Loc
),
2332 Parameter_Associations
=> New_List
(Lhs
, Rhs
));
2339 -- If not found, predefined operation will be used
2342 end Find_Primitive_Eq
;
2344 -- Start of processing for Expand_Composite_Equality
2347 if Is_Private_Type
(Typ
) then
2348 Full_Type
:= Underlying_Type
(Typ
);
2353 -- Defense against malformed private types with no completion the error
2354 -- will be diagnosed later by check_completion
2356 if No
(Full_Type
) then
2357 return New_Reference_To
(Standard_False
, Loc
);
2360 Full_Type
:= Base_Type
(Full_Type
);
2362 if Is_Array_Type
(Full_Type
) then
2364 -- If the operand is an elementary type other than a floating-point
2365 -- type, then we can simply use the built-in block bitwise equality,
2366 -- since the predefined equality operators always apply and bitwise
2367 -- equality is fine for all these cases.
2369 if Is_Elementary_Type
(Component_Type
(Full_Type
))
2370 and then not Is_Floating_Point_Type
(Component_Type
(Full_Type
))
2372 return Make_Op_Eq
(Loc
, Left_Opnd
=> Lhs
, Right_Opnd
=> Rhs
);
2374 -- For composite component types, and floating-point types, use the
2375 -- expansion. This deals with tagged component types (where we use
2376 -- the applicable equality routine) and floating-point, (where we
2377 -- need to worry about negative zeroes), and also the case of any
2378 -- composite type recursively containing such fields.
2381 return Expand_Array_Equality
(Nod
, Lhs
, Rhs
, Bodies
, Full_Type
);
2384 elsif Is_Tagged_Type
(Full_Type
) then
2386 -- Call the primitive operation "=" of this type
2388 if Is_Class_Wide_Type
(Full_Type
) then
2389 Full_Type
:= Root_Type
(Full_Type
);
2392 -- If this is derived from an untagged private type completed with a
2393 -- tagged type, it does not have a full view, so we use the primitive
2394 -- operations of the private type. This check should no longer be
2395 -- necessary when these types receive their full views ???
2397 if Is_Private_Type
(Typ
)
2398 and then not Is_Tagged_Type
(Typ
)
2399 and then not Is_Controlled
(Typ
)
2400 and then Is_Derived_Type
(Typ
)
2401 and then No
(Full_View
(Typ
))
2403 Prim
:= First_Elmt
(Collect_Primitive_Operations
(Typ
));
2405 Prim
:= First_Elmt
(Primitive_Operations
(Full_Type
));
2409 Eq_Op
:= Node
(Prim
);
2410 exit when Chars
(Eq_Op
) = Name_Op_Eq
2411 and then Etype
(First_Formal
(Eq_Op
)) =
2412 Etype
(Next_Formal
(First_Formal
(Eq_Op
)))
2413 and then Base_Type
(Etype
(Eq_Op
)) = Standard_Boolean
;
2415 pragma Assert
(Present
(Prim
));
2418 Eq_Op
:= Node
(Prim
);
2421 Make_Function_Call
(Loc
,
2422 Name
=> New_Reference_To
(Eq_Op
, Loc
),
2423 Parameter_Associations
=>
2425 (Unchecked_Convert_To
(Etype
(First_Formal
(Eq_Op
)), Lhs
),
2426 Unchecked_Convert_To
(Etype
(First_Formal
(Eq_Op
)), Rhs
)));
2428 elsif Is_Record_Type
(Full_Type
) then
2429 Eq_Op
:= TSS
(Full_Type
, TSS_Composite_Equality
);
2431 if Present
(Eq_Op
) then
2432 if Etype
(First_Formal
(Eq_Op
)) /= Full_Type
then
2434 -- Inherited equality from parent type. Convert the actuals to
2435 -- match signature of operation.
2438 T
: constant Entity_Id
:= Etype
(First_Formal
(Eq_Op
));
2442 Make_Function_Call
(Loc
,
2443 Name
=> New_Reference_To
(Eq_Op
, Loc
),
2444 Parameter_Associations
=> New_List
(
2445 OK_Convert_To
(T
, Lhs
),
2446 OK_Convert_To
(T
, Rhs
)));
2450 -- Comparison between Unchecked_Union components
2452 if Is_Unchecked_Union
(Full_Type
) then
2454 Lhs_Type
: Node_Id
:= Full_Type
;
2455 Rhs_Type
: Node_Id
:= Full_Type
;
2456 Lhs_Discr_Val
: Node_Id
;
2457 Rhs_Discr_Val
: Node_Id
;
2462 if Nkind
(Lhs
) = N_Selected_Component
then
2463 Lhs_Type
:= Etype
(Entity
(Selector_Name
(Lhs
)));
2468 if Nkind
(Rhs
) = N_Selected_Component
then
2469 Rhs_Type
:= Etype
(Entity
(Selector_Name
(Rhs
)));
2472 -- Lhs of the composite equality
2474 if Is_Constrained
(Lhs_Type
) then
2476 -- Since the enclosing record type can never be an
2477 -- Unchecked_Union (this code is executed for records
2478 -- that do not have variants), we may reference its
2481 if Nkind
(Lhs
) = N_Selected_Component
2482 and then Has_Per_Object_Constraint
(
2483 Entity
(Selector_Name
(Lhs
)))
2486 Make_Selected_Component
(Loc
,
2487 Prefix
=> Prefix
(Lhs
),
2490 (Get_Discriminant_Value
2491 (First_Discriminant
(Lhs_Type
),
2493 Stored_Constraint
(Lhs_Type
))));
2498 (Get_Discriminant_Value
2499 (First_Discriminant
(Lhs_Type
),
2501 Stored_Constraint
(Lhs_Type
)));
2505 -- It is not possible to infer the discriminant since
2506 -- the subtype is not constrained.
2509 Make_Raise_Program_Error
(Loc
,
2510 Reason
=> PE_Unchecked_Union_Restriction
);
2513 -- Rhs of the composite equality
2515 if Is_Constrained
(Rhs_Type
) then
2516 if Nkind
(Rhs
) = N_Selected_Component
2517 and then Has_Per_Object_Constraint
2518 (Entity
(Selector_Name
(Rhs
)))
2521 Make_Selected_Component
(Loc
,
2522 Prefix
=> Prefix
(Rhs
),
2525 (Get_Discriminant_Value
2526 (First_Discriminant
(Rhs_Type
),
2528 Stored_Constraint
(Rhs_Type
))));
2533 (Get_Discriminant_Value
2534 (First_Discriminant
(Rhs_Type
),
2536 Stored_Constraint
(Rhs_Type
)));
2541 Make_Raise_Program_Error
(Loc
,
2542 Reason
=> PE_Unchecked_Union_Restriction
);
2545 -- Call the TSS equality function with the inferred
2546 -- discriminant values.
2549 Make_Function_Call
(Loc
,
2550 Name
=> New_Reference_To
(Eq_Op
, Loc
),
2551 Parameter_Associations
=> New_List
(
2560 Make_Function_Call
(Loc
,
2561 Name
=> New_Reference_To
(Eq_Op
, Loc
),
2562 Parameter_Associations
=> New_List
(Lhs
, Rhs
));
2566 -- Equality composes in Ada 2012 for untagged record types. It also
2567 -- composes for bounded strings, because they are part of the
2568 -- predefined environment. We could make it compose for bounded
2569 -- strings by making them tagged, or by making sure all subcomponents
2570 -- are set to the same value, even when not used. Instead, we have
2571 -- this special case in the compiler, because it's more efficient.
2573 elsif Ada_Version
>= Ada_2012
or else Is_Bounded_String
(Typ
) then
2575 -- if no TSS has been created for the type, check whether there is
2576 -- a primitive equality declared for it.
2579 Op
: constant Node_Id
:= Find_Primitive_Eq
;
2582 -- Use user-defined primitive if it exists, otherwise use
2583 -- predefined equality.
2585 if Present
(Op
) then
2588 return Make_Op_Eq
(Loc
, Lhs
, Rhs
);
2593 return Expand_Record_Equality
(Nod
, Full_Type
, Lhs
, Rhs
, Bodies
);
2597 -- If not array or record type, it is predefined equality.
2599 return Make_Op_Eq
(Loc
, Left_Opnd
=> Lhs
, Right_Opnd
=> Rhs
);
2601 end Expand_Composite_Equality
;
2603 ------------------------
2604 -- Expand_Concatenate --
2605 ------------------------
2607 procedure Expand_Concatenate
(Cnode
: Node_Id
; Opnds
: List_Id
) is
2608 Loc
: constant Source_Ptr
:= Sloc
(Cnode
);
2610 Atyp
: constant Entity_Id
:= Base_Type
(Etype
(Cnode
));
2611 -- Result type of concatenation
2613 Ctyp
: constant Entity_Id
:= Base_Type
(Component_Type
(Etype
(Cnode
)));
2614 -- Component type. Elements of this component type can appear as one
2615 -- of the operands of concatenation as well as arrays.
2617 Istyp
: constant Entity_Id
:= Etype
(First_Index
(Atyp
));
2620 Ityp
: constant Entity_Id
:= Base_Type
(Istyp
);
2621 -- Index type. This is the base type of the index subtype, and is used
2622 -- for all computed bounds (which may be out of range of Istyp in the
2623 -- case of null ranges).
2626 -- This is the type we use to do arithmetic to compute the bounds and
2627 -- lengths of operands. The choice of this type is a little subtle and
2628 -- is discussed in a separate section at the start of the body code.
2630 Concatenation_Error
: exception;
2631 -- Raised if concatenation is sure to raise a CE
2633 Result_May_Be_Null
: Boolean := True;
2634 -- Reset to False if at least one operand is encountered which is known
2635 -- at compile time to be non-null. Used for handling the special case
2636 -- of setting the high bound to the last operand high bound for a null
2637 -- result, thus ensuring a proper high bound in the super-flat case.
2639 N
: constant Nat
:= List_Length
(Opnds
);
2640 -- Number of concatenation operands including possibly null operands
2643 -- Number of operands excluding any known to be null, except that the
2644 -- last operand is always retained, in case it provides the bounds for
2648 -- Current operand being processed in the loop through operands. After
2649 -- this loop is complete, always contains the last operand (which is not
2650 -- the same as Operands (NN), since null operands are skipped).
2652 -- Arrays describing the operands, only the first NN entries of each
2653 -- array are set (NN < N when we exclude known null operands).
2655 Is_Fixed_Length
: array (1 .. N
) of Boolean;
2656 -- True if length of corresponding operand known at compile time
2658 Operands
: array (1 .. N
) of Node_Id
;
2659 -- Set to the corresponding entry in the Opnds list (but note that null
2660 -- operands are excluded, so not all entries in the list are stored).
2662 Fixed_Length
: array (1 .. N
) of Uint
;
2663 -- Set to length of operand. Entries in this array are set only if the
2664 -- corresponding entry in Is_Fixed_Length is True.
2666 Opnd_Low_Bound
: array (1 .. N
) of Node_Id
;
2667 -- Set to lower bound of operand. Either an integer literal in the case
2668 -- where the bound is known at compile time, else actual lower bound.
2669 -- The operand low bound is of type Ityp.
2671 Var_Length
: array (1 .. N
) of Entity_Id
;
2672 -- Set to an entity of type Natural that contains the length of an
2673 -- operand whose length is not known at compile time. Entries in this
2674 -- array are set only if the corresponding entry in Is_Fixed_Length
2675 -- is False. The entity is of type Artyp.
2677 Aggr_Length
: array (0 .. N
) of Node_Id
;
2678 -- The J'th entry in an expression node that represents the total length
2679 -- of operands 1 through J. It is either an integer literal node, or a
2680 -- reference to a constant entity with the right value, so it is fine
2681 -- to just do a Copy_Node to get an appropriate copy. The extra zero'th
2682 -- entry always is set to zero. The length is of type Artyp.
2684 Low_Bound
: Node_Id
;
2685 -- A tree node representing the low bound of the result (of type Ityp).
2686 -- This is either an integer literal node, or an identifier reference to
2687 -- a constant entity initialized to the appropriate value.
2689 Last_Opnd_Low_Bound
: Node_Id
;
2690 -- A tree node representing the low bound of the last operand. This
2691 -- need only be set if the result could be null. It is used for the
2692 -- special case of setting the right low bound for a null result.
2693 -- This is of type Ityp.
2695 Last_Opnd_High_Bound
: Node_Id
;
2696 -- A tree node representing the high bound of the last operand. This
2697 -- need only be set if the result could be null. It is used for the
2698 -- special case of setting the right high bound for a null result.
2699 -- This is of type Ityp.
2701 High_Bound
: Node_Id
;
2702 -- A tree node representing the high bound of the result (of type Ityp)
2705 -- Result of the concatenation (of type Ityp)
2707 Actions
: constant List_Id
:= New_List
;
2708 -- Collect actions to be inserted
2710 Known_Non_Null_Operand_Seen
: Boolean;
2711 -- Set True during generation of the assignments of operands into
2712 -- result once an operand known to be non-null has been seen.
2714 function Make_Artyp_Literal
(Val
: Nat
) return Node_Id
;
2715 -- This function makes an N_Integer_Literal node that is returned in
2716 -- analyzed form with the type set to Artyp. Importantly this literal
2717 -- is not flagged as static, so that if we do computations with it that
2718 -- result in statically detected out of range conditions, we will not
2719 -- generate error messages but instead warning messages.
2721 function To_Artyp
(X
: Node_Id
) return Node_Id
;
2722 -- Given a node of type Ityp, returns the corresponding value of type
2723 -- Artyp. For non-enumeration types, this is a plain integer conversion.
2724 -- For enum types, the Pos of the value is returned.
2726 function To_Ityp
(X
: Node_Id
) return Node_Id
;
2727 -- The inverse function (uses Val in the case of enumeration types)
2729 ------------------------
2730 -- Make_Artyp_Literal --
2731 ------------------------
2733 function Make_Artyp_Literal
(Val
: Nat
) return Node_Id
is
2734 Result
: constant Node_Id
:= Make_Integer_Literal
(Loc
, Val
);
2736 Set_Etype
(Result
, Artyp
);
2737 Set_Analyzed
(Result
, True);
2738 Set_Is_Static_Expression
(Result
, False);
2740 end Make_Artyp_Literal
;
2746 function To_Artyp
(X
: Node_Id
) return Node_Id
is
2748 if Ityp
= Base_Type
(Artyp
) then
2751 elsif Is_Enumeration_Type
(Ityp
) then
2753 Make_Attribute_Reference
(Loc
,
2754 Prefix
=> New_Occurrence_Of
(Ityp
, Loc
),
2755 Attribute_Name
=> Name_Pos
,
2756 Expressions
=> New_List
(X
));
2759 return Convert_To
(Artyp
, X
);
2767 function To_Ityp
(X
: Node_Id
) return Node_Id
is
2769 if Is_Enumeration_Type
(Ityp
) then
2771 Make_Attribute_Reference
(Loc
,
2772 Prefix
=> New_Occurrence_Of
(Ityp
, Loc
),
2773 Attribute_Name
=> Name_Val
,
2774 Expressions
=> New_List
(X
));
2776 -- Case where we will do a type conversion
2779 if Ityp
= Base_Type
(Artyp
) then
2782 return Convert_To
(Ityp
, X
);
2787 -- Local Declarations
2789 Opnd_Typ
: Entity_Id
;
2796 -- Start of processing for Expand_Concatenate
2799 -- Choose an appropriate computational type
2801 -- We will be doing calculations of lengths and bounds in this routine
2802 -- and computing one from the other in some cases, e.g. getting the high
2803 -- bound by adding the length-1 to the low bound.
2805 -- We can't just use the index type, or even its base type for this
2806 -- purpose for two reasons. First it might be an enumeration type which
2807 -- is not suitable for computations of any kind, and second it may
2808 -- simply not have enough range. For example if the index type is
2809 -- -128..+127 then lengths can be up to 256, which is out of range of
2812 -- For enumeration types, we can simply use Standard_Integer, this is
2813 -- sufficient since the actual number of enumeration literals cannot
2814 -- possibly exceed the range of integer (remember we will be doing the
2815 -- arithmetic with POS values, not representation values).
2817 if Is_Enumeration_Type
(Ityp
) then
2818 Artyp
:= Standard_Integer
;
2820 -- If index type is Positive, we use the standard unsigned type, to give
2821 -- more room on the top of the range, obviating the need for an overflow
2822 -- check when creating the upper bound. This is needed to avoid junk
2823 -- overflow checks in the common case of String types.
2825 -- ??? Disabled for now
2827 -- elsif Istyp = Standard_Positive then
2828 -- Artyp := Standard_Unsigned;
2830 -- For modular types, we use a 32-bit modular type for types whose size
2831 -- is in the range 1-31 bits. For 32-bit unsigned types, we use the
2832 -- identity type, and for larger unsigned types we use 64-bits.
2834 elsif Is_Modular_Integer_Type
(Ityp
) then
2835 if RM_Size
(Ityp
) < RM_Size
(Standard_Unsigned
) then
2836 Artyp
:= Standard_Unsigned
;
2837 elsif RM_Size
(Ityp
) = RM_Size
(Standard_Unsigned
) then
2840 Artyp
:= RTE
(RE_Long_Long_Unsigned
);
2843 -- Similar treatment for signed types
2846 if RM_Size
(Ityp
) < RM_Size
(Standard_Integer
) then
2847 Artyp
:= Standard_Integer
;
2848 elsif RM_Size
(Ityp
) = RM_Size
(Standard_Integer
) then
2851 Artyp
:= Standard_Long_Long_Integer
;
2855 -- Supply dummy entry at start of length array
2857 Aggr_Length
(0) := Make_Artyp_Literal
(0);
2859 -- Go through operands setting up the above arrays
2863 Opnd
:= Remove_Head
(Opnds
);
2864 Opnd_Typ
:= Etype
(Opnd
);
2866 -- The parent got messed up when we put the operands in a list,
2867 -- so now put back the proper parent for the saved operand, that
2868 -- is to say the concatenation node, to make sure that each operand
2869 -- is seen as a subexpression, e.g. if actions must be inserted.
2871 Set_Parent
(Opnd
, Cnode
);
2873 -- Set will be True when we have setup one entry in the array
2877 -- Singleton element (or character literal) case
2879 if Base_Type
(Opnd_Typ
) = Ctyp
then
2881 Operands
(NN
) := Opnd
;
2882 Is_Fixed_Length
(NN
) := True;
2883 Fixed_Length
(NN
) := Uint_1
;
2884 Result_May_Be_Null
:= False;
2886 -- Set low bound of operand (no need to set Last_Opnd_High_Bound
2887 -- since we know that the result cannot be null).
2889 Opnd_Low_Bound
(NN
) :=
2890 Make_Attribute_Reference
(Loc
,
2891 Prefix
=> New_Reference_To
(Istyp
, Loc
),
2892 Attribute_Name
=> Name_First
);
2896 -- String literal case (can only occur for strings of course)
2898 elsif Nkind
(Opnd
) = N_String_Literal
then
2899 Len
:= String_Literal_Length
(Opnd_Typ
);
2902 Result_May_Be_Null
:= False;
2905 -- Capture last operand low and high bound if result could be null
2907 if J
= N
and then Result_May_Be_Null
then
2908 Last_Opnd_Low_Bound
:=
2909 New_Copy_Tree
(String_Literal_Low_Bound
(Opnd_Typ
));
2911 Last_Opnd_High_Bound
:=
2912 Make_Op_Subtract
(Loc
,
2914 New_Copy_Tree
(String_Literal_Low_Bound
(Opnd_Typ
)),
2915 Right_Opnd
=> Make_Integer_Literal
(Loc
, 1));
2918 -- Skip null string literal
2920 if J
< N
and then Len
= 0 then
2925 Operands
(NN
) := Opnd
;
2926 Is_Fixed_Length
(NN
) := True;
2928 -- Set length and bounds
2930 Fixed_Length
(NN
) := Len
;
2932 Opnd_Low_Bound
(NN
) :=
2933 New_Copy_Tree
(String_Literal_Low_Bound
(Opnd_Typ
));
2940 -- Check constrained case with known bounds
2942 if Is_Constrained
(Opnd_Typ
) then
2944 Index
: constant Node_Id
:= First_Index
(Opnd_Typ
);
2945 Indx_Typ
: constant Entity_Id
:= Etype
(Index
);
2946 Lo
: constant Node_Id
:= Type_Low_Bound
(Indx_Typ
);
2947 Hi
: constant Node_Id
:= Type_High_Bound
(Indx_Typ
);
2950 -- Fixed length constrained array type with known at compile
2951 -- time bounds is last case of fixed length operand.
2953 if Compile_Time_Known_Value
(Lo
)
2955 Compile_Time_Known_Value
(Hi
)
2958 Loval
: constant Uint
:= Expr_Value
(Lo
);
2959 Hival
: constant Uint
:= Expr_Value
(Hi
);
2960 Len
: constant Uint
:=
2961 UI_Max
(Hival
- Loval
+ 1, Uint_0
);
2965 Result_May_Be_Null
:= False;
2968 -- Capture last operand bounds if result could be null
2970 if J
= N
and then Result_May_Be_Null
then
2971 Last_Opnd_Low_Bound
:=
2973 Make_Integer_Literal
(Loc
, Expr_Value
(Lo
)));
2975 Last_Opnd_High_Bound
:=
2977 Make_Integer_Literal
(Loc
, Expr_Value
(Hi
)));
2980 -- Exclude null length case unless last operand
2982 if J
< N
and then Len
= 0 then
2987 Operands
(NN
) := Opnd
;
2988 Is_Fixed_Length
(NN
) := True;
2989 Fixed_Length
(NN
) := Len
;
2991 Opnd_Low_Bound
(NN
) :=
2993 (Make_Integer_Literal
(Loc
, Expr_Value
(Lo
)));
3000 -- All cases where the length is not known at compile time, or the
3001 -- special case of an operand which is known to be null but has a
3002 -- lower bound other than 1 or is other than a string type.
3007 -- Capture operand bounds
3009 Opnd_Low_Bound
(NN
) :=
3010 Make_Attribute_Reference
(Loc
,
3012 Duplicate_Subexpr
(Opnd
, Name_Req
=> True),
3013 Attribute_Name
=> Name_First
);
3015 -- Capture last operand bounds if result could be null
3017 if J
= N
and Result_May_Be_Null
then
3018 Last_Opnd_Low_Bound
:=
3020 Make_Attribute_Reference
(Loc
,
3022 Duplicate_Subexpr
(Opnd
, Name_Req
=> True),
3023 Attribute_Name
=> Name_First
));
3025 Last_Opnd_High_Bound
:=
3027 Make_Attribute_Reference
(Loc
,
3029 Duplicate_Subexpr
(Opnd
, Name_Req
=> True),
3030 Attribute_Name
=> Name_Last
));
3033 -- Capture length of operand in entity
3035 Operands
(NN
) := Opnd
;
3036 Is_Fixed_Length
(NN
) := False;
3038 Var_Length
(NN
) := Make_Temporary
(Loc
, 'L');
3041 Make_Object_Declaration
(Loc
,
3042 Defining_Identifier
=> Var_Length
(NN
),
3043 Constant_Present
=> True,
3044 Object_Definition
=> New_Occurrence_Of
(Artyp
, Loc
),
3046 Make_Attribute_Reference
(Loc
,
3048 Duplicate_Subexpr
(Opnd
, Name_Req
=> True),
3049 Attribute_Name
=> Name_Length
)));
3053 -- Set next entry in aggregate length array
3055 -- For first entry, make either integer literal for fixed length
3056 -- or a reference to the saved length for variable length.
3059 if Is_Fixed_Length
(1) then
3060 Aggr_Length
(1) := Make_Integer_Literal
(Loc
, Fixed_Length
(1));
3062 Aggr_Length
(1) := New_Reference_To
(Var_Length
(1), Loc
);
3065 -- If entry is fixed length and only fixed lengths so far, make
3066 -- appropriate new integer literal adding new length.
3068 elsif Is_Fixed_Length
(NN
)
3069 and then Nkind
(Aggr_Length
(NN
- 1)) = N_Integer_Literal
3072 Make_Integer_Literal
(Loc
,
3073 Intval
=> Fixed_Length
(NN
) + Intval
(Aggr_Length
(NN
- 1)));
3075 -- All other cases, construct an addition node for the length and
3076 -- create an entity initialized to this length.
3079 Ent
:= Make_Temporary
(Loc
, 'L');
3081 if Is_Fixed_Length
(NN
) then
3082 Clen
:= Make_Integer_Literal
(Loc
, Fixed_Length
(NN
));
3084 Clen
:= New_Reference_To
(Var_Length
(NN
), Loc
);
3088 Make_Object_Declaration
(Loc
,
3089 Defining_Identifier
=> Ent
,
3090 Constant_Present
=> True,
3091 Object_Definition
=> New_Occurrence_Of
(Artyp
, Loc
),
3094 Left_Opnd
=> New_Copy
(Aggr_Length
(NN
- 1)),
3095 Right_Opnd
=> Clen
)));
3097 Aggr_Length
(NN
) := Make_Identifier
(Loc
, Chars
=> Chars
(Ent
));
3104 -- If we have only skipped null operands, return the last operand
3111 -- If we have only one non-null operand, return it and we are done.
3112 -- There is one case in which this cannot be done, and that is when
3113 -- the sole operand is of the element type, in which case it must be
3114 -- converted to an array, and the easiest way of doing that is to go
3115 -- through the normal general circuit.
3118 and then Base_Type
(Etype
(Operands
(1))) /= Ctyp
3120 Result
:= Operands
(1);
3124 -- Cases where we have a real concatenation
3126 -- Next step is to find the low bound for the result array that we
3127 -- will allocate. The rules for this are in (RM 4.5.6(5-7)).
3129 -- If the ultimate ancestor of the index subtype is a constrained array
3130 -- definition, then the lower bound is that of the index subtype as
3131 -- specified by (RM 4.5.3(6)).
3133 -- The right test here is to go to the root type, and then the ultimate
3134 -- ancestor is the first subtype of this root type.
3136 if Is_Constrained
(First_Subtype
(Root_Type
(Atyp
))) then
3138 Make_Attribute_Reference
(Loc
,
3140 New_Occurrence_Of
(First_Subtype
(Root_Type
(Atyp
)), Loc
),
3141 Attribute_Name
=> Name_First
);
3143 -- If the first operand in the list has known length we know that
3144 -- the lower bound of the result is the lower bound of this operand.
3146 elsif Is_Fixed_Length
(1) then
3147 Low_Bound
:= Opnd_Low_Bound
(1);
3149 -- OK, we don't know the lower bound, we have to build a horrible
3150 -- conditional expression node of the form
3152 -- if Cond1'Length /= 0 then
3155 -- if Opnd2'Length /= 0 then
3160 -- The nesting ends either when we hit an operand whose length is known
3161 -- at compile time, or on reaching the last operand, whose low bound we
3162 -- take unconditionally whether or not it is null. It's easiest to do
3163 -- this with a recursive procedure:
3167 function Get_Known_Bound
(J
: Nat
) return Node_Id
;
3168 -- Returns the lower bound determined by operands J .. NN
3170 ---------------------
3171 -- Get_Known_Bound --
3172 ---------------------
3174 function Get_Known_Bound
(J
: Nat
) return Node_Id
is
3176 if Is_Fixed_Length
(J
) or else J
= NN
then
3177 return New_Copy
(Opnd_Low_Bound
(J
));
3181 Make_Conditional_Expression
(Loc
,
3182 Expressions
=> New_List
(
3185 Left_Opnd
=> New_Reference_To
(Var_Length
(J
), Loc
),
3186 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0)),
3188 New_Copy
(Opnd_Low_Bound
(J
)),
3189 Get_Known_Bound
(J
+ 1)));
3191 end Get_Known_Bound
;
3194 Ent
:= Make_Temporary
(Loc
, 'L');
3197 Make_Object_Declaration
(Loc
,
3198 Defining_Identifier
=> Ent
,
3199 Constant_Present
=> True,
3200 Object_Definition
=> New_Occurrence_Of
(Ityp
, Loc
),
3201 Expression
=> Get_Known_Bound
(1)));
3203 Low_Bound
:= New_Reference_To
(Ent
, Loc
);
3207 -- Now we can safely compute the upper bound, normally
3208 -- Low_Bound + Length - 1.
3213 Left_Opnd
=> To_Artyp
(New_Copy
(Low_Bound
)),
3215 Make_Op_Subtract
(Loc
,
3216 Left_Opnd
=> New_Copy
(Aggr_Length
(NN
)),
3217 Right_Opnd
=> Make_Artyp_Literal
(1))));
3219 -- Note that calculation of the high bound may cause overflow in some
3220 -- very weird cases, so in the general case we need an overflow check on
3221 -- the high bound. We can avoid this for the common case of string types
3222 -- and other types whose index is Positive, since we chose a wider range
3223 -- for the arithmetic type.
3225 if Istyp
/= Standard_Positive
then
3226 Activate_Overflow_Check
(High_Bound
);
3229 -- Handle the exceptional case where the result is null, in which case
3230 -- case the bounds come from the last operand (so that we get the proper
3231 -- bounds if the last operand is super-flat).
3233 if Result_May_Be_Null
then
3235 Make_Conditional_Expression
(Loc
,
3236 Expressions
=> New_List
(
3238 Left_Opnd
=> New_Copy
(Aggr_Length
(NN
)),
3239 Right_Opnd
=> Make_Artyp_Literal
(0)),
3240 Last_Opnd_Low_Bound
,
3244 Make_Conditional_Expression
(Loc
,
3245 Expressions
=> New_List
(
3247 Left_Opnd
=> New_Copy
(Aggr_Length
(NN
)),
3248 Right_Opnd
=> Make_Artyp_Literal
(0)),
3249 Last_Opnd_High_Bound
,
3253 -- Here is where we insert the saved up actions
3255 Insert_Actions
(Cnode
, Actions
, Suppress
=> All_Checks
);
3257 -- Now we construct an array object with appropriate bounds. We mark
3258 -- the target as internal to prevent useless initialization when
3259 -- Initialize_Scalars is enabled. Also since this is the actual result
3260 -- entity, we make sure we have debug information for the result.
3262 Ent
:= Make_Temporary
(Loc
, 'S');
3263 Set_Is_Internal
(Ent
);
3264 Set_Needs_Debug_Info
(Ent
);
3266 -- If the bound is statically known to be out of range, we do not want
3267 -- to abort, we want a warning and a runtime constraint error. Note that
3268 -- we have arranged that the result will not be treated as a static
3269 -- constant, so we won't get an illegality during this insertion.
3271 Insert_Action
(Cnode
,
3272 Make_Object_Declaration
(Loc
,
3273 Defining_Identifier
=> Ent
,
3274 Object_Definition
=>
3275 Make_Subtype_Indication
(Loc
,
3276 Subtype_Mark
=> New_Occurrence_Of
(Atyp
, Loc
),
3278 Make_Index_Or_Discriminant_Constraint
(Loc
,
3279 Constraints
=> New_List
(
3281 Low_Bound
=> Low_Bound
,
3282 High_Bound
=> High_Bound
))))),
3283 Suppress
=> All_Checks
);
3285 -- If the result of the concatenation appears as the initializing
3286 -- expression of an object declaration, we can just rename the
3287 -- result, rather than copying it.
3289 Set_OK_To_Rename
(Ent
);
3291 -- Catch the static out of range case now
3293 if Raises_Constraint_Error
(High_Bound
) then
3294 raise Concatenation_Error
;
3297 -- Now we will generate the assignments to do the actual concatenation
3299 -- There is one case in which we will not do this, namely when all the
3300 -- following conditions are met:
3302 -- The result type is Standard.String
3304 -- There are nine or fewer retained (non-null) operands
3306 -- The optimization level is -O0
3308 -- The corresponding System.Concat_n.Str_Concat_n routine is
3309 -- available in the run time.
3311 -- The debug flag gnatd.c is not set
3313 -- If all these conditions are met then we generate a call to the
3314 -- relevant concatenation routine. The purpose of this is to avoid
3315 -- undesirable code bloat at -O0.
3317 if Atyp
= Standard_String
3318 and then NN
in 2 .. 9
3319 and then (Opt
.Optimization_Level
= 0 or else Debug_Flag_Dot_CC
)
3320 and then not Debug_Flag_Dot_C
3323 RR
: constant array (Nat
range 2 .. 9) of RE_Id
:=
3334 if RTE_Available
(RR
(NN
)) then
3336 Opnds
: constant List_Id
:=
3337 New_List
(New_Occurrence_Of
(Ent
, Loc
));
3340 for J
in 1 .. NN
loop
3341 if Is_List_Member
(Operands
(J
)) then
3342 Remove
(Operands
(J
));
3345 if Base_Type
(Etype
(Operands
(J
))) = Ctyp
then
3347 Make_Aggregate
(Loc
,
3348 Component_Associations
=> New_List
(
3349 Make_Component_Association
(Loc
,
3350 Choices
=> New_List
(
3351 Make_Integer_Literal
(Loc
, 1)),
3352 Expression
=> Operands
(J
)))));
3355 Append_To
(Opnds
, Operands
(J
));
3359 Insert_Action
(Cnode
,
3360 Make_Procedure_Call_Statement
(Loc
,
3361 Name
=> New_Reference_To
(RTE
(RR
(NN
)), Loc
),
3362 Parameter_Associations
=> Opnds
));
3364 Result
:= New_Reference_To
(Ent
, Loc
);
3371 -- Not special case so generate the assignments
3373 Known_Non_Null_Operand_Seen
:= False;
3375 for J
in 1 .. NN
loop
3377 Lo
: constant Node_Id
:=
3379 Left_Opnd
=> To_Artyp
(New_Copy
(Low_Bound
)),
3380 Right_Opnd
=> Aggr_Length
(J
- 1));
3382 Hi
: constant Node_Id
:=
3384 Left_Opnd
=> To_Artyp
(New_Copy
(Low_Bound
)),
3386 Make_Op_Subtract
(Loc
,
3387 Left_Opnd
=> Aggr_Length
(J
),
3388 Right_Opnd
=> Make_Artyp_Literal
(1)));
3391 -- Singleton case, simple assignment
3393 if Base_Type
(Etype
(Operands
(J
))) = Ctyp
then
3394 Known_Non_Null_Operand_Seen
:= True;
3395 Insert_Action
(Cnode
,
3396 Make_Assignment_Statement
(Loc
,
3398 Make_Indexed_Component
(Loc
,
3399 Prefix
=> New_Occurrence_Of
(Ent
, Loc
),
3400 Expressions
=> New_List
(To_Ityp
(Lo
))),
3401 Expression
=> Operands
(J
)),
3402 Suppress
=> All_Checks
);
3404 -- Array case, slice assignment, skipped when argument is fixed
3405 -- length and known to be null.
3407 elsif (not Is_Fixed_Length
(J
)) or else (Fixed_Length
(J
) > 0) then
3410 Make_Assignment_Statement
(Loc
,
3414 New_Occurrence_Of
(Ent
, Loc
),
3417 Low_Bound
=> To_Ityp
(Lo
),
3418 High_Bound
=> To_Ityp
(Hi
))),
3419 Expression
=> Operands
(J
));
3421 if Is_Fixed_Length
(J
) then
3422 Known_Non_Null_Operand_Seen
:= True;
3424 elsif not Known_Non_Null_Operand_Seen
then
3426 -- Here if operand length is not statically known and no
3427 -- operand known to be non-null has been processed yet.
3428 -- If operand length is 0, we do not need to perform the
3429 -- assignment, and we must avoid the evaluation of the
3430 -- high bound of the slice, since it may underflow if the
3431 -- low bound is Ityp'First.
3434 Make_Implicit_If_Statement
(Cnode
,
3438 New_Occurrence_Of
(Var_Length
(J
), Loc
),
3439 Right_Opnd
=> Make_Integer_Literal
(Loc
, 0)),
3440 Then_Statements
=> New_List
(Assign
));
3443 Insert_Action
(Cnode
, Assign
, Suppress
=> All_Checks
);
3449 -- Finally we build the result, which is a reference to the array object
3451 Result
:= New_Reference_To
(Ent
, Loc
);
3454 Rewrite
(Cnode
, Result
);
3455 Analyze_And_Resolve
(Cnode
, Atyp
);
3458 when Concatenation_Error
=>
3460 -- Kill warning generated for the declaration of the static out of
3461 -- range high bound, and instead generate a Constraint_Error with
3462 -- an appropriate specific message.
3464 Kill_Dead_Code
(Declaration_Node
(Entity
(High_Bound
)));
3465 Apply_Compile_Time_Constraint_Error
3467 Msg
=> "concatenation result upper bound out of range?",
3468 Reason
=> CE_Range_Check_Failed
);
3469 -- Set_Etype (Cnode, Atyp);
3470 end Expand_Concatenate
;
3472 ------------------------
3473 -- Expand_N_Allocator --
3474 ------------------------
3476 procedure Expand_N_Allocator
(N
: Node_Id
) is
3477 PtrT
: constant Entity_Id
:= Etype
(N
);
3478 Dtyp
: constant Entity_Id
:= Available_View
(Designated_Type
(PtrT
));
3479 Etyp
: constant Entity_Id
:= Etype
(Expression
(N
));
3480 Loc
: constant Source_Ptr
:= Sloc
(N
);
3486 procedure Rewrite_Coextension
(N
: Node_Id
);
3487 -- Static coextensions have the same lifetime as the entity they
3488 -- constrain. Such occurrences can be rewritten as aliased objects
3489 -- and their unrestricted access used instead of the coextension.
3491 function Size_In_Storage_Elements
(E
: Entity_Id
) return Node_Id
;
3492 -- Given a constrained array type E, returns a node representing the
3493 -- code to compute the size in storage elements for the given type.
3494 -- This is done without using the attribute (which malfunctions for
3497 -------------------------
3498 -- Rewrite_Coextension --
3499 -------------------------
3501 procedure Rewrite_Coextension
(N
: Node_Id
) is
3502 Temp_Id
: constant Node_Id
:= Make_Temporary
(Loc
, 'C');
3503 Temp_Decl
: Node_Id
;
3507 -- Cnn : aliased Etyp;
3510 Make_Object_Declaration
(Loc
,
3511 Defining_Identifier
=> Temp_Id
,
3512 Aliased_Present
=> True,
3513 Object_Definition
=> New_Occurrence_Of
(Etyp
, Loc
));
3515 if Nkind
(Expression
(N
)) = N_Qualified_Expression
then
3516 Set_Expression
(Temp_Decl
, Expression
(Expression
(N
)));
3519 Insert_Action
(N
, Temp_Decl
);
3521 Make_Attribute_Reference
(Loc
,
3522 Prefix
=> New_Occurrence_Of
(Temp_Id
, Loc
),
3523 Attribute_Name
=> Name_Unrestricted_Access
));
3525 Analyze_And_Resolve
(N
, PtrT
);
3526 end Rewrite_Coextension
;
3528 ------------------------------
3529 -- Size_In_Storage_Elements --
3530 ------------------------------
3532 function Size_In_Storage_Elements
(E
: Entity_Id
) return Node_Id
is
3534 -- Logically this just returns E'Max_Size_In_Storage_Elements.
3535 -- However, the reason for the existence of this function is
3536 -- to construct a test for sizes too large, which means near the
3537 -- 32-bit limit on a 32-bit machine, and precisely the trouble
3538 -- is that we get overflows when sizes are greater than 2**31.
3540 -- So what we end up doing for array types is to use the expression:
3542 -- number-of-elements * component_type'Max_Size_In_Storage_Elements
3544 -- which avoids this problem. All this is a bit bogus, but it does
3545 -- mean we catch common cases of trying to allocate arrays that
3546 -- are too large, and which in the absence of a check results in
3547 -- undetected chaos ???
3554 for J
in 1 .. Number_Dimensions
(E
) loop
3556 Make_Attribute_Reference
(Loc
,
3557 Prefix
=> New_Occurrence_Of
(E
, Loc
),
3558 Attribute_Name
=> Name_Length
,
3559 Expressions
=> New_List
(Make_Integer_Literal
(Loc
, J
)));
3566 Make_Op_Multiply
(Loc
,
3573 Make_Op_Multiply
(Loc
,
3576 Make_Attribute_Reference
(Loc
,
3577 Prefix
=> New_Occurrence_Of
(Component_Type
(E
), Loc
),
3578 Attribute_Name
=> Name_Max_Size_In_Storage_Elements
));
3580 end Size_In_Storage_Elements
;
3582 -- Start of processing for Expand_N_Allocator
3585 -- RM E.2.3(22). We enforce that the expected type of an allocator
3586 -- shall not be a remote access-to-class-wide-limited-private type
3588 -- Why is this being done at expansion time, seems clearly wrong ???
3590 Validate_Remote_Access_To_Class_Wide_Type
(N
);
3592 -- Processing for anonymous access-to-controlled types. These access
3593 -- types receive a special finalization master which appears in the
3594 -- declarations of the enclosing semantic unit. This expansion is done
3595 -- now to ensure that any additional types generated by this routine or
3596 -- Expand_Allocator_Expression inherit the proper type attributes.
3598 if (Ekind
(PtrT
) = E_Anonymous_Access_Type
3600 (Is_Itype
(PtrT
) and then No
(Finalization_Master
(PtrT
))))
3601 and then Needs_Finalization
(Dtyp
)
3603 -- Anonymous access-to-controlled types allocate on the global pool.
3604 -- Do not set this attribute on .NET/JVM since those targets do not
3607 if No
(Associated_Storage_Pool
(PtrT
)) and then VM_Target
= No_VM
then
3608 Set_Associated_Storage_Pool
3609 (PtrT
, Get_Global_Pool_For_Access_Type
(PtrT
));
3612 -- The finalization master must be inserted and analyzed as part of
3613 -- the current semantic unit. This form of expansion is not carried
3614 -- out in Alfa mode because it is useless. Note that the master is
3615 -- updated when analysis changes current units.
3617 if not Alfa_Mode
then
3618 Set_Finalization_Master
(PtrT
, Current_Anonymous_Master
);
3622 -- Set the storage pool and find the appropriate version of Allocate to
3623 -- call. Do not overwrite the storage pool if it is already set, which
3624 -- can happen for build-in-place function returns (see
3625 -- Exp_Ch4.Expand_N_Extended_Return_Statement).
3627 if No
(Storage_Pool
(N
)) then
3628 Pool
:= Associated_Storage_Pool
(Root_Type
(PtrT
));
3630 if Present
(Pool
) then
3631 Set_Storage_Pool
(N
, Pool
);
3633 if Is_RTE
(Pool
, RE_SS_Pool
) then
3634 if VM_Target
= No_VM
then
3635 Set_Procedure_To_Call
(N
, RTE
(RE_SS_Allocate
));
3638 -- In the case of an allocator for a simple storage pool, locate
3639 -- and save a reference to the pool type's Allocate routine.
3641 elsif Present
(Get_Rep_Pragma
3642 (Etype
(Pool
), Name_Simple_Storage_Pool_Type
))
3645 Pool_Type
: constant Entity_Id
:= Base_Type
(Etype
(Pool
));
3646 Alloc_Op
: Entity_Id
;
3648 Alloc_Op
:= Get_Name_Entity_Id
(Name_Allocate
);
3649 while Present
(Alloc_Op
) loop
3650 if Scope
(Alloc_Op
) = Scope
(Pool_Type
)
3651 and then Present
(First_Formal
(Alloc_Op
))
3652 and then Etype
(First_Formal
(Alloc_Op
)) = Pool_Type
3654 Set_Procedure_To_Call
(N
, Alloc_Op
);
3657 Alloc_Op
:= Homonym
(Alloc_Op
);
3662 elsif Is_Class_Wide_Type
(Etype
(Pool
)) then
3663 Set_Procedure_To_Call
(N
, RTE
(RE_Allocate_Any
));
3666 Set_Procedure_To_Call
(N
,
3667 Find_Prim_Op
(Etype
(Pool
), Name_Allocate
));
3672 -- Under certain circumstances we can replace an allocator by an access
3673 -- to statically allocated storage. The conditions, as noted in AARM
3674 -- 3.10 (10c) are as follows:
3676 -- Size and initial value is known at compile time
3677 -- Access type is access-to-constant
3679 -- The allocator is not part of a constraint on a record component,
3680 -- because in that case the inserted actions are delayed until the
3681 -- record declaration is fully analyzed, which is too late for the
3682 -- analysis of the rewritten allocator.
3684 if Is_Access_Constant
(PtrT
)
3685 and then Nkind
(Expression
(N
)) = N_Qualified_Expression
3686 and then Compile_Time_Known_Value
(Expression
(Expression
(N
)))
3687 and then Size_Known_At_Compile_Time
3688 (Etype
(Expression
(Expression
(N
))))
3689 and then not Is_Record_Type
(Current_Scope
)
3691 -- Here we can do the optimization. For the allocator
3695 -- We insert an object declaration
3697 -- Tnn : aliased x := y;
3699 -- and replace the allocator by Tnn'Unrestricted_Access. Tnn is
3700 -- marked as requiring static allocation.
3702 Temp
:= Make_Temporary
(Loc
, 'T', Expression
(Expression
(N
)));
3703 Desig
:= Subtype_Mark
(Expression
(N
));
3705 -- If context is constrained, use constrained subtype directly,
3706 -- so that the constant is not labelled as having a nominally
3707 -- unconstrained subtype.
3709 if Entity
(Desig
) = Base_Type
(Dtyp
) then
3710 Desig
:= New_Occurrence_Of
(Dtyp
, Loc
);
3714 Make_Object_Declaration
(Loc
,
3715 Defining_Identifier
=> Temp
,
3716 Aliased_Present
=> True,
3717 Constant_Present
=> Is_Access_Constant
(PtrT
),
3718 Object_Definition
=> Desig
,
3719 Expression
=> Expression
(Expression
(N
))));
3722 Make_Attribute_Reference
(Loc
,
3723 Prefix
=> New_Occurrence_Of
(Temp
, Loc
),
3724 Attribute_Name
=> Name_Unrestricted_Access
));
3726 Analyze_And_Resolve
(N
, PtrT
);
3728 -- We set the variable as statically allocated, since we don't want
3729 -- it going on the stack of the current procedure!
3731 Set_Is_Statically_Allocated
(Temp
);
3735 -- Same if the allocator is an access discriminant for a local object:
3736 -- instead of an allocator we create a local value and constrain the
3737 -- enclosing object with the corresponding access attribute.
3739 if Is_Static_Coextension
(N
) then
3740 Rewrite_Coextension
(N
);
3744 -- Check for size too large, we do this because the back end misses
3745 -- proper checks here and can generate rubbish allocation calls when
3746 -- we are near the limit. We only do this for the 32-bit address case
3747 -- since that is from a practical point of view where we see a problem.
3749 if System_Address_Size
= 32
3750 and then not Storage_Checks_Suppressed
(PtrT
)
3751 and then not Storage_Checks_Suppressed
(Dtyp
)
3752 and then not Storage_Checks_Suppressed
(Etyp
)
3754 -- The check we want to generate should look like
3756 -- if Etyp'Max_Size_In_Storage_Elements > 3.5 gigabytes then
3757 -- raise Storage_Error;
3760 -- where 3.5 gigabytes is a constant large enough to accommodate any
3761 -- reasonable request for. But we can't do it this way because at
3762 -- least at the moment we don't compute this attribute right, and
3763 -- can silently give wrong results when the result gets large. Since
3764 -- this is all about large results, that's bad, so instead we only
3765 -- apply the check for constrained arrays, and manually compute the
3766 -- value of the attribute ???
3768 if Is_Array_Type
(Etyp
) and then Is_Constrained
(Etyp
) then
3770 Make_Raise_Storage_Error
(Loc
,
3773 Left_Opnd
=> Size_In_Storage_Elements
(Etyp
),
3775 Make_Integer_Literal
(Loc
, Uint_7
* (Uint_2
** 29))),
3776 Reason
=> SE_Object_Too_Large
));
3780 -- Handle case of qualified expression (other than optimization above)
3781 -- First apply constraint checks, because the bounds or discriminants
3782 -- in the aggregate might not match the subtype mark in the allocator.
3784 if Nkind
(Expression
(N
)) = N_Qualified_Expression
then
3785 Apply_Constraint_Check
3786 (Expression
(Expression
(N
)), Etype
(Expression
(N
)));
3788 Expand_Allocator_Expression
(N
);
3792 -- If the allocator is for a type which requires initialization, and
3793 -- there is no initial value (i.e. operand is a subtype indication
3794 -- rather than a qualified expression), then we must generate a call to
3795 -- the initialization routine using an expressions action node:
3797 -- [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
3799 -- Here ptr_T is the pointer type for the allocator, and T is the
3800 -- subtype of the allocator. A special case arises if the designated
3801 -- type of the access type is a task or contains tasks. In this case
3802 -- the call to Init (Temp.all ...) is replaced by code that ensures
3803 -- that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
3804 -- for details). In addition, if the type T is a task T, then the
3805 -- first argument to Init must be converted to the task record type.
3808 T
: constant Entity_Id
:= Entity
(Expression
(N
));
3814 Init_Arg1
: Node_Id
;
3815 Temp_Decl
: Node_Id
;
3816 Temp_Type
: Entity_Id
;
3819 if No_Initialization
(N
) then
3821 -- Even though this might be a simple allocation, create a custom
3822 -- Allocate if the context requires it. Since .NET/JVM compilers
3823 -- do not support pools, this step is skipped.
3825 if VM_Target
= No_VM
3826 and then Present
(Finalization_Master
(PtrT
))
3828 Build_Allocate_Deallocate_Proc
3830 Is_Allocate
=> True);
3833 -- Case of no initialization procedure present
3835 elsif not Has_Non_Null_Base_Init_Proc
(T
) then
3837 -- Case of simple initialization required
3839 if Needs_Simple_Initialization
(T
) then
3840 Check_Restriction
(No_Default_Initialization
, N
);
3841 Rewrite
(Expression
(N
),
3842 Make_Qualified_Expression
(Loc
,
3843 Subtype_Mark
=> New_Occurrence_Of
(T
, Loc
),
3844 Expression
=> Get_Simple_Init_Val
(T
, N
)));
3846 Analyze_And_Resolve
(Expression
(Expression
(N
)), T
);
3847 Analyze_And_Resolve
(Expression
(N
), T
);
3848 Set_Paren_Count
(Expression
(Expression
(N
)), 1);
3849 Expand_N_Allocator
(N
);
3851 -- No initialization required
3857 -- Case of initialization procedure present, must be called
3860 Check_Restriction
(No_Default_Initialization
, N
);
3862 if not Restriction_Active
(No_Default_Initialization
) then
3863 Init
:= Base_Init_Proc
(T
);
3865 Temp
:= Make_Temporary
(Loc
, 'P');
3867 -- Construct argument list for the initialization routine call
3870 Make_Explicit_Dereference
(Loc
,
3872 New_Reference_To
(Temp
, Loc
));
3874 Set_Assignment_OK
(Init_Arg1
);
3877 -- The initialization procedure expects a specific type. if the
3878 -- context is access to class wide, indicate that the object
3879 -- being allocated has the right specific type.
3881 if Is_Class_Wide_Type
(Dtyp
) then
3882 Init_Arg1
:= Unchecked_Convert_To
(T
, Init_Arg1
);
3885 -- If designated type is a concurrent type or if it is private
3886 -- type whose definition is a concurrent type, the first
3887 -- argument in the Init routine has to be unchecked conversion
3888 -- to the corresponding record type. If the designated type is
3889 -- a derived type, also convert the argument to its root type.
3891 if Is_Concurrent_Type
(T
) then
3893 Unchecked_Convert_To
(
3894 Corresponding_Record_Type
(T
), Init_Arg1
);
3896 elsif Is_Private_Type
(T
)
3897 and then Present
(Full_View
(T
))
3898 and then Is_Concurrent_Type
(Full_View
(T
))
3901 Unchecked_Convert_To
3902 (Corresponding_Record_Type
(Full_View
(T
)), Init_Arg1
);
3904 elsif Etype
(First_Formal
(Init
)) /= Base_Type
(T
) then
3906 Ftyp
: constant Entity_Id
:= Etype
(First_Formal
(Init
));
3909 Init_Arg1
:= OK_Convert_To
(Etype
(Ftyp
), Init_Arg1
);
3910 Set_Etype
(Init_Arg1
, Ftyp
);
3914 Args
:= New_List
(Init_Arg1
);
3916 -- For the task case, pass the Master_Id of the access type as
3917 -- the value of the _Master parameter, and _Chain as the value
3918 -- of the _Chain parameter (_Chain will be defined as part of
3919 -- the generated code for the allocator).
3921 -- In Ada 2005, the context may be a function that returns an
3922 -- anonymous access type. In that case the Master_Id has been
3923 -- created when expanding the function declaration.
3925 if Has_Task
(T
) then
3926 if No
(Master_Id
(Base_Type
(PtrT
))) then
3928 -- The designated type was an incomplete type, and the
3929 -- access type did not get expanded. Salvage it now.
3931 if not Restriction_Active
(No_Task_Hierarchy
) then
3932 pragma Assert
(Present
(Parent
(Base_Type
(PtrT
))));
3933 Expand_N_Full_Type_Declaration
3934 (Parent
(Base_Type
(PtrT
)));
3938 -- If the context of the allocator is a declaration or an
3939 -- assignment, we can generate a meaningful image for it,
3940 -- even though subsequent assignments might remove the
3941 -- connection between task and entity. We build this image
3942 -- when the left-hand side is a simple variable, a simple
3943 -- indexed assignment or a simple selected component.
3945 if Nkind
(Parent
(N
)) = N_Assignment_Statement
then
3947 Nam
: constant Node_Id
:= Name
(Parent
(N
));
3950 if Is_Entity_Name
(Nam
) then
3952 Build_Task_Image_Decls
3955 (Entity
(Nam
), Sloc
(Nam
)), T
);
3957 elsif Nkind_In
(Nam
, N_Indexed_Component
,
3958 N_Selected_Component
)
3959 and then Is_Entity_Name
(Prefix
(Nam
))
3962 Build_Task_Image_Decls
3963 (Loc
, Nam
, Etype
(Prefix
(Nam
)));
3965 Decls
:= Build_Task_Image_Decls
(Loc
, T
, T
);
3969 elsif Nkind
(Parent
(N
)) = N_Object_Declaration
then
3971 Build_Task_Image_Decls
3972 (Loc
, Defining_Identifier
(Parent
(N
)), T
);
3975 Decls
:= Build_Task_Image_Decls
(Loc
, T
, T
);
3978 if Restriction_Active
(No_Task_Hierarchy
) then
3980 New_Occurrence_Of
(RTE
(RE_Library_Task_Level
), Loc
));
3984 (Master_Id
(Base_Type
(Root_Type
(PtrT
))), Loc
));
3987 Append_To
(Args
, Make_Identifier
(Loc
, Name_uChain
));
3989 Decl
:= Last
(Decls
);
3991 New_Occurrence_Of
(Defining_Identifier
(Decl
), Loc
));
3993 -- Has_Task is false, Decls not used
3999 -- Add discriminants if discriminated type
4002 Dis
: Boolean := False;
4006 if Has_Discriminants
(T
) then
4010 elsif Is_Private_Type
(T
)
4011 and then Present
(Full_View
(T
))
4012 and then Has_Discriminants
(Full_View
(T
))
4015 Typ
:= Full_View
(T
);
4020 -- If the allocated object will be constrained by the
4021 -- default values for discriminants, then build a subtype
4022 -- with those defaults, and change the allocated subtype
4023 -- to that. Note that this happens in fewer cases in Ada
4026 if not Is_Constrained
(Typ
)
4027 and then Present
(Discriminant_Default_Value
4028 (First_Discriminant
(Typ
)))
4029 and then (Ada_Version
< Ada_2005
4031 Effectively_Has_Constrained_Partial_View
4033 Scop
=> Current_Scope
))
4035 Typ
:= Build_Default_Subtype
(Typ
, N
);
4036 Set_Expression
(N
, New_Reference_To
(Typ
, Loc
));
4039 Discr
:= First_Elmt
(Discriminant_Constraint
(Typ
));
4040 while Present
(Discr
) loop
4041 Nod
:= Node
(Discr
);
4042 Append
(New_Copy_Tree
(Node
(Discr
)), Args
);
4044 -- AI-416: when the discriminant constraint is an
4045 -- anonymous access type make sure an accessibility
4046 -- check is inserted if necessary (3.10.2(22.q/2))
4048 if Ada_Version
>= Ada_2005
4050 Ekind
(Etype
(Nod
)) = E_Anonymous_Access_Type
4052 Apply_Accessibility_Check
4053 (Nod
, Typ
, Insert_Node
=> Nod
);
4061 -- We set the allocator as analyzed so that when we analyze
4062 -- the conditional expression node, we do not get an unwanted
4063 -- recursive expansion of the allocator expression.
4065 Set_Analyzed
(N
, True);
4066 Nod
:= Relocate_Node
(N
);
4068 -- Here is the transformation:
4069 -- input: new Ctrl_Typ
4070 -- output: Temp : constant Ctrl_Typ_Ptr := new Ctrl_Typ;
4071 -- Ctrl_TypIP (Temp.all, ...);
4072 -- [Deep_]Initialize (Temp.all);
4074 -- Here Ctrl_Typ_Ptr is the pointer type for the allocator, and
4075 -- is the subtype of the allocator.
4078 Make_Object_Declaration
(Loc
,
4079 Defining_Identifier
=> Temp
,
4080 Constant_Present
=> True,
4081 Object_Definition
=> New_Reference_To
(Temp_Type
, Loc
),
4084 Set_Assignment_OK
(Temp_Decl
);
4085 Insert_Action
(N
, Temp_Decl
, Suppress
=> All_Checks
);
4087 Build_Allocate_Deallocate_Proc
(Temp_Decl
, True);
4089 -- If the designated type is a task type or contains tasks,
4090 -- create block to activate created tasks, and insert
4091 -- declaration for Task_Image variable ahead of call.
4093 if Has_Task
(T
) then
4095 L
: constant List_Id
:= New_List
;
4098 Build_Task_Allocate_Block
(L
, Nod
, Args
);
4100 Insert_List_Before
(First
(Declarations
(Blk
)), Decls
);
4101 Insert_Actions
(N
, L
);
4106 Make_Procedure_Call_Statement
(Loc
,
4107 Name
=> New_Reference_To
(Init
, Loc
),
4108 Parameter_Associations
=> Args
));
4111 if Needs_Finalization
(T
) then
4114 -- [Deep_]Initialize (Init_Arg1);
4118 (Obj_Ref
=> New_Copy_Tree
(Init_Arg1
),
4121 if Present
(Finalization_Master
(PtrT
)) then
4123 -- Special processing for .NET/JVM, the allocated object
4124 -- is attached to the finalization master. Generate:
4126 -- Attach (<PtrT>FM, Root_Controlled_Ptr (Init_Arg1));
4128 -- Types derived from [Limited_]Controlled are the only
4129 -- ones considered since they have fields Prev and Next.
4131 if VM_Target
/= No_VM
then
4132 if Is_Controlled
(T
) then
4135 (Obj_Ref
=> New_Copy_Tree
(Init_Arg1
),
4139 -- Default case, generate:
4141 -- Set_Finalize_Address
4142 -- (<PtrT>FM, <T>FD'Unrestricted_Access);
4144 -- Do not generate this call in the following cases:
4146 -- * Alfa mode - the call is useless and results in
4147 -- unwanted expansion.
4149 -- * CodePeer mode - TSS primitive Finalize_Address is
4150 -- not created in this mode.
4153 and then not CodePeer_Mode
4156 Make_Set_Finalize_Address_Call
4164 Rewrite
(N
, New_Reference_To
(Temp
, Loc
));
4165 Analyze_And_Resolve
(N
, PtrT
);
4170 -- Ada 2005 (AI-251): If the allocator is for a class-wide interface
4171 -- object that has been rewritten as a reference, we displace "this"
4172 -- to reference properly its secondary dispatch table.
4174 if Nkind
(N
) = N_Identifier
4175 and then Is_Interface
(Dtyp
)
4177 Displace_Allocator_Pointer
(N
);
4181 when RE_Not_Available
=>
4183 end Expand_N_Allocator
;
4185 -----------------------
4186 -- Expand_N_And_Then --
4187 -----------------------
4189 procedure Expand_N_And_Then
(N
: Node_Id
)
4190 renames Expand_Short_Circuit_Operator
;
4192 ------------------------------
4193 -- Expand_N_Case_Expression --
4194 ------------------------------
4196 procedure Expand_N_Case_Expression
(N
: Node_Id
) is
4197 Loc
: constant Source_Ptr
:= Sloc
(N
);
4198 Typ
: constant Entity_Id
:= Etype
(N
);
4210 -- case X is when A => AX, when B => BX ...
4225 -- However, this expansion is wrong for limited types, and also
4226 -- wrong for unconstrained types (since the bounds may not be the
4227 -- same in all branches). Furthermore it involves an extra copy
4228 -- for large objects. So we take care of this by using the following
4229 -- modified expansion for non-scalar types:
4232 -- type Pnn is access all typ;
4236 -- T := AX'Unrestricted_Access;
4238 -- T := BX'Unrestricted_Access;
4244 Make_Case_Statement
(Loc
,
4245 Expression
=> Expression
(N
),
4246 Alternatives
=> New_List
);
4248 Actions
:= New_List
;
4252 if Is_Scalar_Type
(Typ
) then
4256 Pnn
:= Make_Temporary
(Loc
, 'P');
4258 Make_Full_Type_Declaration
(Loc
,
4259 Defining_Identifier
=> Pnn
,
4261 Make_Access_To_Object_Definition
(Loc
,
4262 All_Present
=> True,
4263 Subtype_Indication
=>
4264 New_Reference_To
(Typ
, Loc
))));
4268 Tnn
:= Make_Temporary
(Loc
, 'T');
4270 Make_Object_Declaration
(Loc
,
4271 Defining_Identifier
=> Tnn
,
4272 Object_Definition
=> New_Occurrence_Of
(Ttyp
, Loc
)));
4274 -- Now process the alternatives
4276 Alt
:= First
(Alternatives
(N
));
4277 while Present
(Alt
) loop
4279 Aexp
: Node_Id
:= Expression
(Alt
);
4280 Aloc
: constant Source_Ptr
:= Sloc
(Aexp
);
4284 -- As described above, take Unrestricted_Access for case of non-
4285 -- scalar types, to avoid big copies, and special cases.
4287 if not Is_Scalar_Type
(Typ
) then
4289 Make_Attribute_Reference
(Aloc
,
4290 Prefix
=> Relocate_Node
(Aexp
),
4291 Attribute_Name
=> Name_Unrestricted_Access
);
4295 Make_Assignment_Statement
(Aloc
,
4296 Name
=> New_Occurrence_Of
(Tnn
, Loc
),
4297 Expression
=> Aexp
));
4299 -- Propagate declarations inserted in the node by Insert_Actions
4300 -- (for example, temporaries generated to remove side effects).
4301 -- These actions must remain attached to the alternative, given
4302 -- that they are generated by the corresponding expression.
4304 if Present
(Sinfo
.Actions
(Alt
)) then
4305 Prepend_List
(Sinfo
.Actions
(Alt
), Stats
);
4309 (Alternatives
(Cstmt
),
4310 Make_Case_Statement_Alternative
(Sloc
(Alt
),
4311 Discrete_Choices
=> Discrete_Choices
(Alt
),
4312 Statements
=> Stats
));
4318 Append_To
(Actions
, Cstmt
);
4320 -- Construct and return final expression with actions
4322 if Is_Scalar_Type
(Typ
) then
4323 Fexp
:= New_Occurrence_Of
(Tnn
, Loc
);
4326 Make_Explicit_Dereference
(Loc
,
4327 Prefix
=> New_Occurrence_Of
(Tnn
, Loc
));
4331 Make_Expression_With_Actions
(Loc
,
4333 Actions
=> Actions
));
4335 Analyze_And_Resolve
(N
, Typ
);
4336 end Expand_N_Case_Expression
;
4338 -------------------------------------
4339 -- Expand_N_Conditional_Expression --
4340 -------------------------------------
4342 -- Deal with limited types and condition actions
4344 procedure Expand_N_Conditional_Expression
(N
: Node_Id
) is
4345 function Create_Alternative
4347 Temp_Id
: Entity_Id
;
4348 Flag_Id
: Entity_Id
;
4349 Expr
: Node_Id
) return List_Id
;
4350 -- Build the statements of a "then" or "else" conditional expression
4351 -- alternative. Temp_Id is the conditional expression result, Flag_Id
4352 -- is a finalization flag created to service expression Expr.
4354 function Is_Controlled_Function_Call
(Expr
: Node_Id
) return Boolean;
4355 -- Determine if expression Expr is a rewritten controlled function call
4357 ------------------------
4358 -- Create_Alternative --
4359 ------------------------
4361 function Create_Alternative
4363 Temp_Id
: Entity_Id
;
4364 Flag_Id
: Entity_Id
;
4365 Expr
: Node_Id
) return List_Id
4367 Result
: constant List_Id
:= New_List
;
4373 if Present
(Flag_Id
)
4374 and then not Is_Controlled_Function_Call
(Expr
)
4377 Make_Assignment_Statement
(Loc
,
4378 Name
=> New_Reference_To
(Flag_Id
, Loc
),
4379 Expression
=> New_Reference_To
(Standard_True
, Loc
)));
4383 -- Cnn := <expr>'Unrestricted_Access;
4386 Make_Assignment_Statement
(Loc
,
4387 Name
=> New_Reference_To
(Temp_Id
, Loc
),
4389 Make_Attribute_Reference
(Loc
,
4390 Prefix
=> Relocate_Node
(Expr
),
4391 Attribute_Name
=> Name_Unrestricted_Access
)));
4394 end Create_Alternative
;
4396 ---------------------------------
4397 -- Is_Controlled_Function_Call --
4398 ---------------------------------
4400 function Is_Controlled_Function_Call
(Expr
: Node_Id
) return Boolean is
4403 Nkind
(Original_Node
(Expr
)) = N_Function_Call
4404 and then Needs_Finalization
(Etype
(Expr
));
4405 end Is_Controlled_Function_Call
;
4409 Loc
: constant Source_Ptr
:= Sloc
(N
);
4410 Cond
: constant Node_Id
:= First
(Expressions
(N
));
4411 Thenx
: constant Node_Id
:= Next
(Cond
);
4412 Elsex
: constant Node_Id
:= Next
(Thenx
);
4413 Typ
: constant Entity_Id
:= Etype
(N
);
4423 -- Fold at compile time if condition known. We have already folded
4424 -- static conditional expressions, but it is possible to fold any
4425 -- case in which the condition is known at compile time, even though
4426 -- the result is non-static.
4428 -- Note that we don't do the fold of such cases in Sem_Elab because
4429 -- it can cause infinite loops with the expander adding a conditional
4430 -- expression, and Sem_Elab circuitry removing it repeatedly.
4432 if Compile_Time_Known_Value
(Cond
) then
4433 if Is_True
(Expr_Value
(Cond
)) then
4435 Actions
:= Then_Actions
(N
);
4438 Actions
:= Else_Actions
(N
);
4443 if Present
(Actions
) then
4445 -- If we are not allowed to use Expression_With_Actions, just skip
4446 -- the optimization, it is not critical for correctness.
4448 if not Use_Expression_With_Actions
then
4449 goto Skip_Optimization
;
4453 Make_Expression_With_Actions
(Loc
,
4454 Expression
=> Relocate_Node
(Expr
),
4455 Actions
=> Actions
));
4456 Analyze_And_Resolve
(N
, Typ
);
4459 Rewrite
(N
, Relocate_Node
(Expr
));
4462 -- Note that the result is never static (legitimate cases of static
4463 -- conditional expressions were folded in Sem_Eval).
4465 Set_Is_Static_Expression
(N
, False);
4469 <<Skip_Optimization
>>
4471 -- If the type is limited or unconstrained, we expand as follows to
4472 -- avoid any possibility of improper copies.
4474 -- Note: it may be possible to avoid this special processing if the
4475 -- back end uses its own mechanisms for handling by-reference types ???
4477 -- type Ptr is access all Typ;
4481 -- Cnn := then-expr'Unrestricted_Access;
4484 -- Cnn := else-expr'Unrestricted_Access;
4487 -- and replace the conditional expression by a reference to Cnn.all.
4489 -- This special case can be skipped if the back end handles limited
4490 -- types properly and ensures that no incorrect copies are made.
4492 if Is_By_Reference_Type
(Typ
)
4493 and then not Back_End_Handles_Limited_Types
4496 Flag_Id
: Entity_Id
;
4497 Ptr_Typ
: Entity_Id
;
4502 -- At least one of the conditional expression alternatives uses a
4503 -- controlled function to provide the result. Create a status flag
4504 -- to signal the finalization machinery that Cnn needs special
4507 if Is_Controlled_Function_Call
(Thenx
)
4509 Is_Controlled_Function_Call
(Elsex
)
4511 Flag_Id
:= Make_Temporary
(Loc
, 'F');
4514 Make_Object_Declaration
(Loc
,
4515 Defining_Identifier
=> Flag_Id
,
4516 Object_Definition
=>
4517 New_Reference_To
(Standard_Boolean
, Loc
),
4519 New_Reference_To
(Standard_False
, Loc
)));
4523 -- type Ann is access all Typ;
4525 Ptr_Typ
:= Make_Temporary
(Loc
, 'A');
4528 Make_Full_Type_Declaration
(Loc
,
4529 Defining_Identifier
=> Ptr_Typ
,
4531 Make_Access_To_Object_Definition
(Loc
,
4532 All_Present
=> True,
4533 Subtype_Indication
=> New_Reference_To
(Typ
, Loc
))));
4538 Cnn
:= Make_Temporary
(Loc
, 'C', N
);
4539 Set_Ekind
(Cnn
, E_Variable
);
4540 Set_Status_Flag_Or_Transient_Decl
(Cnn
, Flag_Id
);
4543 Make_Object_Declaration
(Loc
,
4544 Defining_Identifier
=> Cnn
,
4545 Object_Definition
=> New_Occurrence_Of
(Ptr_Typ
, Loc
));
4548 Make_Implicit_If_Statement
(N
,
4549 Condition
=> Relocate_Node
(Cond
),
4551 Create_Alternative
(Sloc
(Thenx
), Cnn
, Flag_Id
, Thenx
),
4553 Create_Alternative
(Sloc
(Elsex
), Cnn
, Flag_Id
, Elsex
));
4556 Make_Explicit_Dereference
(Loc
,
4557 Prefix
=> New_Occurrence_Of
(Cnn
, Loc
));
4560 -- For other types, we only need to expand if there are other actions
4561 -- associated with either branch.
4563 elsif Present
(Then_Actions
(N
)) or else Present
(Else_Actions
(N
)) then
4565 -- We have two approaches to handling this. If we are allowed to use
4566 -- N_Expression_With_Actions, then we can just wrap the actions into
4567 -- the appropriate expression.
4569 if Use_Expression_With_Actions
then
4570 if Present
(Then_Actions
(N
)) then
4572 Make_Expression_With_Actions
(Sloc
(Thenx
),
4573 Actions
=> Then_Actions
(N
),
4574 Expression
=> Relocate_Node
(Thenx
)));
4575 Set_Then_Actions
(N
, No_List
);
4576 Analyze_And_Resolve
(Thenx
, Typ
);
4579 if Present
(Else_Actions
(N
)) then
4581 Make_Expression_With_Actions
(Sloc
(Elsex
),
4582 Actions
=> Else_Actions
(N
),
4583 Expression
=> Relocate_Node
(Elsex
)));
4584 Set_Else_Actions
(N
, No_List
);
4585 Analyze_And_Resolve
(Elsex
, Typ
);
4590 -- if we can't use N_Expression_With_Actions nodes, then we insert
4591 -- the following sequence of actions (using Insert_Actions):
4596 -- Cnn := then-expr;
4602 -- and replace the conditional expression by a reference to Cnn
4605 Cnn
:= Make_Temporary
(Loc
, 'C', N
);
4608 Make_Object_Declaration
(Loc
,
4609 Defining_Identifier
=> Cnn
,
4610 Object_Definition
=> New_Occurrence_Of
(Typ
, Loc
));
4613 Make_Implicit_If_Statement
(N
,
4614 Condition
=> Relocate_Node
(Cond
),
4616 Then_Statements
=> New_List
(
4617 Make_Assignment_Statement
(Sloc
(Thenx
),
4618 Name
=> New_Occurrence_Of
(Cnn
, Sloc
(Thenx
)),
4619 Expression
=> Relocate_Node
(Thenx
))),
4621 Else_Statements
=> New_List
(
4622 Make_Assignment_Statement
(Sloc
(Elsex
),
4623 Name
=> New_Occurrence_Of
(Cnn
, Sloc
(Elsex
)),
4624 Expression
=> Relocate_Node
(Elsex
))));
4626 Set_Assignment_OK
(Name
(First
(Then_Statements
(New_If
))));
4627 Set_Assignment_OK
(Name
(First
(Else_Statements
(New_If
))));
4629 New_N
:= New_Occurrence_Of
(Cnn
, Loc
);
4632 -- If no actions then no expansion needed, gigi will handle it using
4633 -- the same approach as a C conditional expression.
4639 -- Fall through here for either the limited expansion, or the case of
4640 -- inserting actions for non-limited types. In both these cases, we must
4641 -- move the SLOC of the parent If statement to the newly created one and
4642 -- change it to the SLOC of the expression which, after expansion, will
4643 -- correspond to what is being evaluated.
4645 if Present
(Parent
(N
))
4646 and then Nkind
(Parent
(N
)) = N_If_Statement
4648 Set_Sloc
(New_If
, Sloc
(Parent
(N
)));
4649 Set_Sloc
(Parent
(N
), Loc
);
4652 -- Make sure Then_Actions and Else_Actions are appropriately moved
4653 -- to the new if statement.
4655 if Present
(Then_Actions
(N
)) then
4657 (First
(Then_Statements
(New_If
)), Then_Actions
(N
));
4660 if Present
(Else_Actions
(N
)) then
4662 (First
(Else_Statements
(New_If
)), Else_Actions
(N
));
4665 Insert_Action
(N
, Decl
);
4666 Insert_Action
(N
, New_If
);
4668 Analyze_And_Resolve
(N
, Typ
);
4669 end Expand_N_Conditional_Expression
;
4671 -----------------------------------
4672 -- Expand_N_Explicit_Dereference --
4673 -----------------------------------
4675 procedure Expand_N_Explicit_Dereference
(N
: Node_Id
) is
4677 -- Insert explicit dereference call for the checked storage pool case
4679 Insert_Dereference_Action
(Prefix
(N
));
4681 -- If the type is an Atomic type for which Atomic_Sync is enabled, then
4682 -- we set the atomic sync flag.
4684 if Is_Atomic
(Etype
(N
))
4685 and then not Atomic_Synchronization_Disabled
(Etype
(N
))
4687 Activate_Atomic_Synchronization
(N
);
4689 end Expand_N_Explicit_Dereference
;
4691 --------------------------------------
4692 -- Expand_N_Expression_With_Actions --
4693 --------------------------------------
4695 procedure Expand_N_Expression_With_Actions
(N
: Node_Id
) is
4697 procedure Process_Transient_Object
(Decl
: Node_Id
);
4698 -- Given the declaration of a controlled transient declared inside the
4699 -- Actions list of an Expression_With_Actions, generate all necessary
4700 -- types and hooks in order to properly finalize the transient. This
4701 -- mechanism works in conjunction with Build_Finalizer.
4703 ------------------------------
4704 -- Process_Transient_Object --
4705 ------------------------------
4707 procedure Process_Transient_Object
(Decl
: Node_Id
) is
4709 function Find_Insertion_Node
return Node_Id
;
4710 -- Complex conditions in if statements may be converted into nested
4711 -- EWAs. In this case, any generated code must be inserted before the
4712 -- if statement to ensure proper visibility of the hook objects. This
4713 -- routine returns the top most short circuit operator or the parent
4714 -- of the EWA if no nesting was detected.
4716 -------------------------
4717 -- Find_Insertion_Node --
4718 -------------------------
4720 function Find_Insertion_Node
return Node_Id
is
4724 -- Climb up the branches of a complex condition
4727 while Nkind_In
(Parent
(Par
), N_And_Then
, N_Op_Not
, N_Or_Else
) loop
4728 Par
:= Parent
(Par
);
4732 end Find_Insertion_Node
;
4736 Ins_Node
: constant Node_Id
:= Find_Insertion_Node
;
4737 Loc
: constant Source_Ptr
:= Sloc
(Decl
);
4738 Obj_Id
: constant Entity_Id
:= Defining_Identifier
(Decl
);
4739 Obj_Typ
: constant Entity_Id
:= Etype
(Obj_Id
);
4740 Desig_Typ
: Entity_Id
;
4744 Temp_Decl
: Node_Id
;
4747 -- Start of processing for Process_Transient_Object
4750 -- Step 1: Create the access type which provides a reference to the
4751 -- transient object.
4753 if Is_Access_Type
(Obj_Typ
) then
4754 Desig_Typ
:= Directly_Designated_Type
(Obj_Typ
);
4756 Desig_Typ
:= Obj_Typ
;
4760 -- Ann : access [all] <Desig_Typ>;
4762 Ptr_Id
:= Make_Temporary
(Loc
, 'A');
4765 Make_Full_Type_Declaration
(Loc
,
4766 Defining_Identifier
=> Ptr_Id
,
4768 Make_Access_To_Object_Definition
(Loc
,
4770 Ekind
(Obj_Typ
) = E_General_Access_Type
,
4771 Subtype_Indication
=> New_Reference_To
(Desig_Typ
, Loc
)));
4773 Insert_Action
(Ins_Node
, Ptr_Decl
);
4776 -- Step 2: Create a temporary which acts as a hook to the transient
4777 -- object. Generate:
4779 -- Temp : Ptr_Id := null;
4781 Temp_Id
:= Make_Temporary
(Loc
, 'T');
4784 Make_Object_Declaration
(Loc
,
4785 Defining_Identifier
=> Temp_Id
,
4786 Object_Definition
=> New_Reference_To
(Ptr_Id
, Loc
));
4788 Insert_Action
(Ins_Node
, Temp_Decl
);
4789 Analyze
(Temp_Decl
);
4791 -- Mark this temporary as created for the purposes of exporting the
4792 -- transient declaration out of the Actions list. This signals the
4793 -- machinery in Build_Finalizer to recognize this special case.
4795 Set_Status_Flag_Or_Transient_Decl
(Temp_Id
, Decl
);
4797 -- Step 3: Hook the transient object to the temporary
4799 if Is_Access_Type
(Obj_Typ
) then
4800 Expr
:= Convert_To
(Ptr_Id
, New_Reference_To
(Obj_Id
, Loc
));
4803 Make_Attribute_Reference
(Loc
,
4804 Prefix
=> New_Reference_To
(Obj_Id
, Loc
),
4805 Attribute_Name
=> Name_Unrestricted_Access
);
4809 -- Temp := Ptr_Id (Obj_Id);
4811 -- Temp := Obj_Id'Unrestricted_Access;
4813 Insert_After_And_Analyze
(Decl
,
4814 Make_Assignment_Statement
(Loc
,
4815 Name
=> New_Reference_To
(Temp_Id
, Loc
),
4816 Expression
=> Expr
));
4817 end Process_Transient_Object
;
4823 -- Start of processing for Expand_N_Expression_With_Actions
4826 Decl
:= First
(Actions
(N
));
4827 while Present
(Decl
) loop
4828 if Nkind
(Decl
) = N_Object_Declaration
4829 and then Is_Finalizable_Transient
(Decl
, N
)
4831 Process_Transient_Object
(Decl
);
4836 end Expand_N_Expression_With_Actions
;
4842 procedure Expand_N_In
(N
: Node_Id
) is
4843 Loc
: constant Source_Ptr
:= Sloc
(N
);
4844 Restyp
: constant Entity_Id
:= Etype
(N
);
4845 Lop
: constant Node_Id
:= Left_Opnd
(N
);
4846 Rop
: constant Node_Id
:= Right_Opnd
(N
);
4847 Static
: constant Boolean := Is_OK_Static_Expression
(N
);
4852 procedure Substitute_Valid_Check
;
4853 -- Replaces node N by Lop'Valid. This is done when we have an explicit
4854 -- test for the left operand being in range of its subtype.
4856 ----------------------------
4857 -- Substitute_Valid_Check --
4858 ----------------------------
4860 procedure Substitute_Valid_Check
is
4863 Make_Attribute_Reference
(Loc
,
4864 Prefix
=> Relocate_Node
(Lop
),
4865 Attribute_Name
=> Name_Valid
));
4867 Analyze_And_Resolve
(N
, Restyp
);
4869 Error_Msg_N
("?explicit membership test may be optimized away", N
);
4870 Error_Msg_N
-- CODEFIX
4871 ("\?use ''Valid attribute instead", N
);
4873 end Substitute_Valid_Check
;
4875 -- Start of processing for Expand_N_In
4878 -- If set membership case, expand with separate procedure
4880 if Present
(Alternatives
(N
)) then
4881 Expand_Set_Membership
(N
);
4885 -- Not set membership, proceed with expansion
4887 Ltyp
:= Etype
(Left_Opnd
(N
));
4888 Rtyp
:= Etype
(Right_Opnd
(N
));
4890 -- Check case of explicit test for an expression in range of its
4891 -- subtype. This is suspicious usage and we replace it with a 'Valid
4892 -- test and give a warning. For floating point types however, this is a
4893 -- standard way to check for finite numbers, and using 'Valid would
4894 -- typically be a pessimization. Also skip this test for predicated
4895 -- types, since it is perfectly reasonable to check if a value meets
4898 if Is_Scalar_Type
(Ltyp
)
4899 and then not Is_Floating_Point_Type
(Ltyp
)
4900 and then Nkind
(Rop
) in N_Has_Entity
4901 and then Ltyp
= Entity
(Rop
)
4902 and then Comes_From_Source
(N
)
4903 and then VM_Target
= No_VM
4904 and then not (Is_Discrete_Type
(Ltyp
)
4905 and then Present
(Predicate_Function
(Ltyp
)))
4907 Substitute_Valid_Check
;
4911 -- Do validity check on operands
4913 if Validity_Checks_On
and Validity_Check_Operands
then
4914 Ensure_Valid
(Left_Opnd
(N
));
4915 Validity_Check_Range
(Right_Opnd
(N
));
4918 -- Case of explicit range
4920 if Nkind
(Rop
) = N_Range
then
4922 Lo
: constant Node_Id
:= Low_Bound
(Rop
);
4923 Hi
: constant Node_Id
:= High_Bound
(Rop
);
4925 Lo_Orig
: constant Node_Id
:= Original_Node
(Lo
);
4926 Hi_Orig
: constant Node_Id
:= Original_Node
(Hi
);
4928 Lcheck
: Compare_Result
;
4929 Ucheck
: Compare_Result
;
4931 Warn1
: constant Boolean :=
4932 Constant_Condition_Warnings
4933 and then Comes_From_Source
(N
)
4934 and then not In_Instance
;
4935 -- This must be true for any of the optimization warnings, we
4936 -- clearly want to give them only for source with the flag on. We
4937 -- also skip these warnings in an instance since it may be the
4938 -- case that different instantiations have different ranges.
4940 Warn2
: constant Boolean :=
4942 and then Nkind
(Original_Node
(Rop
)) = N_Range
4943 and then Is_Integer_Type
(Etype
(Lo
));
4944 -- For the case where only one bound warning is elided, we also
4945 -- insist on an explicit range and an integer type. The reason is
4946 -- that the use of enumeration ranges including an end point is
4947 -- common, as is the use of a subtype name, one of whose bounds is
4948 -- the same as the type of the expression.
4951 -- If test is explicit x'First .. x'Last, replace by valid check
4953 -- Could use some individual comments for this complex test ???
4955 if Is_Scalar_Type
(Ltyp
)
4956 and then Nkind
(Lo_Orig
) = N_Attribute_Reference
4957 and then Attribute_Name
(Lo_Orig
) = Name_First
4958 and then Nkind
(Prefix
(Lo_Orig
)) in N_Has_Entity
4959 and then Entity
(Prefix
(Lo_Orig
)) = Ltyp
4960 and then Nkind
(Hi_Orig
) = N_Attribute_Reference
4961 and then Attribute_Name
(Hi_Orig
) = Name_Last
4962 and then Nkind
(Prefix
(Hi_Orig
)) in N_Has_Entity
4963 and then Entity
(Prefix
(Hi_Orig
)) = Ltyp
4964 and then Comes_From_Source
(N
)
4965 and then VM_Target
= No_VM
4967 Substitute_Valid_Check
;
4971 -- If bounds of type are known at compile time, and the end points
4972 -- are known at compile time and identical, this is another case
4973 -- for substituting a valid test. We only do this for discrete
4974 -- types, since it won't arise in practice for float types.
4976 if Comes_From_Source
(N
)
4977 and then Is_Discrete_Type
(Ltyp
)
4978 and then Compile_Time_Known_Value
(Type_High_Bound
(Ltyp
))
4979 and then Compile_Time_Known_Value
(Type_Low_Bound
(Ltyp
))
4980 and then Compile_Time_Known_Value
(Lo
)
4981 and then Compile_Time_Known_Value
(Hi
)
4982 and then Expr_Value
(Type_High_Bound
(Ltyp
)) = Expr_Value
(Hi
)
4983 and then Expr_Value
(Type_Low_Bound
(Ltyp
)) = Expr_Value
(Lo
)
4985 -- Kill warnings in instances, since they may be cases where we
4986 -- have a test in the generic that makes sense with some types
4987 -- and not with other types.
4989 and then not In_Instance
4991 Substitute_Valid_Check
;
4995 -- If we have an explicit range, do a bit of optimization based on
4996 -- range analysis (we may be able to kill one or both checks).
4998 Lcheck
:= Compile_Time_Compare
(Lop
, Lo
, Assume_Valid
=> False);
4999 Ucheck
:= Compile_Time_Compare
(Lop
, Hi
, Assume_Valid
=> False);
5001 -- If either check is known to fail, replace result by False since
5002 -- the other check does not matter. Preserve the static flag for
5003 -- legality checks, because we are constant-folding beyond RM 4.9.
5005 if Lcheck
= LT
or else Ucheck
= GT
then
5007 Error_Msg_N
("?range test optimized away", N
);
5008 Error_Msg_N
("\?value is known to be out of range", N
);
5011 Rewrite
(N
, New_Reference_To
(Standard_False
, Loc
));
5012 Analyze_And_Resolve
(N
, Restyp
);
5013 Set_Is_Static_Expression
(N
, Static
);
5016 -- If both checks are known to succeed, replace result by True,
5017 -- since we know we are in range.
5019 elsif Lcheck
in Compare_GE
and then Ucheck
in Compare_LE
then
5021 Error_Msg_N
("?range test optimized away", N
);
5022 Error_Msg_N
("\?value is known to be in range", N
);
5025 Rewrite
(N
, New_Reference_To
(Standard_True
, Loc
));
5026 Analyze_And_Resolve
(N
, Restyp
);
5027 Set_Is_Static_Expression
(N
, Static
);
5030 -- If lower bound check succeeds and upper bound check is not
5031 -- known to succeed or fail, then replace the range check with
5032 -- a comparison against the upper bound.
5034 elsif Lcheck
in Compare_GE
then
5035 if Warn2
and then not In_Instance
then
5036 Error_Msg_N
("?lower bound test optimized away", Lo
);
5037 Error_Msg_N
("\?value is known to be in range", Lo
);
5043 Right_Opnd
=> High_Bound
(Rop
)));
5044 Analyze_And_Resolve
(N
, Restyp
);
5047 -- If upper bound check succeeds and lower bound check is not
5048 -- known to succeed or fail, then replace the range check with
5049 -- a comparison against the lower bound.
5051 elsif Ucheck
in Compare_LE
then
5052 if Warn2
and then not In_Instance
then
5053 Error_Msg_N
("?upper bound test optimized away", Hi
);
5054 Error_Msg_N
("\?value is known to be in range", Hi
);
5060 Right_Opnd
=> Low_Bound
(Rop
)));
5061 Analyze_And_Resolve
(N
, Restyp
);
5065 -- We couldn't optimize away the range check, but there is one
5066 -- more issue. If we are checking constant conditionals, then we
5067 -- see if we can determine the outcome assuming everything is
5068 -- valid, and if so give an appropriate warning.
5070 if Warn1
and then not Assume_No_Invalid_Values
then
5071 Lcheck
:= Compile_Time_Compare
(Lop
, Lo
, Assume_Valid
=> True);
5072 Ucheck
:= Compile_Time_Compare
(Lop
, Hi
, Assume_Valid
=> True);
5074 -- Result is out of range for valid value
5076 if Lcheck
= LT
or else Ucheck
= GT
then
5078 ("?value can only be in range if it is invalid", N
);
5080 -- Result is in range for valid value
5082 elsif Lcheck
in Compare_GE
and then Ucheck
in Compare_LE
then
5084 ("?value can only be out of range if it is invalid", N
);
5086 -- Lower bound check succeeds if value is valid
5088 elsif Warn2
and then Lcheck
in Compare_GE
then
5090 ("?lower bound check only fails if it is invalid", Lo
);
5092 -- Upper bound check succeeds if value is valid
5094 elsif Warn2
and then Ucheck
in Compare_LE
then
5096 ("?upper bound check only fails for invalid values", Hi
);
5101 -- For all other cases of an explicit range, nothing to be done
5105 -- Here right operand is a subtype mark
5109 Typ
: Entity_Id
:= Etype
(Rop
);
5110 Is_Acc
: constant Boolean := Is_Access_Type
(Typ
);
5111 Cond
: Node_Id
:= Empty
;
5113 Obj
: Node_Id
:= Lop
;
5114 SCIL_Node
: Node_Id
;
5117 Remove_Side_Effects
(Obj
);
5119 -- For tagged type, do tagged membership operation
5121 if Is_Tagged_Type
(Typ
) then
5123 -- No expansion will be performed when VM_Target, as the VM
5124 -- back-ends will handle the membership tests directly (tags
5125 -- are not explicitly represented in Java objects, so the
5126 -- normal tagged membership expansion is not what we want).
5128 if Tagged_Type_Expansion
then
5129 Tagged_Membership
(N
, SCIL_Node
, New_N
);
5131 Analyze_And_Resolve
(N
, Restyp
);
5133 -- Update decoration of relocated node referenced by the
5136 if Generate_SCIL
and then Present
(SCIL_Node
) then
5137 Set_SCIL_Node
(N
, SCIL_Node
);
5143 -- If type is scalar type, rewrite as x in t'First .. t'Last.
5144 -- This reason we do this is that the bounds may have the wrong
5145 -- type if they come from the original type definition. Also this
5146 -- way we get all the processing above for an explicit range.
5148 -- Don't do this for predicated types, since in this case we
5149 -- want to check the predicate!
5151 elsif Is_Scalar_Type
(Typ
) then
5152 if No
(Predicate_Function
(Typ
)) then
5156 Make_Attribute_Reference
(Loc
,
5157 Attribute_Name
=> Name_First
,
5158 Prefix
=> New_Reference_To
(Typ
, Loc
)),
5161 Make_Attribute_Reference
(Loc
,
5162 Attribute_Name
=> Name_Last
,
5163 Prefix
=> New_Reference_To
(Typ
, Loc
))));
5164 Analyze_And_Resolve
(N
, Restyp
);
5169 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
5170 -- a membership test if the subtype mark denotes a constrained
5171 -- Unchecked_Union subtype and the expression lacks inferable
5174 elsif Is_Unchecked_Union
(Base_Type
(Typ
))
5175 and then Is_Constrained
(Typ
)
5176 and then not Has_Inferable_Discriminants
(Lop
)
5179 Make_Raise_Program_Error
(Loc
,
5180 Reason
=> PE_Unchecked_Union_Restriction
));
5182 -- Prevent Gigi from generating incorrect code by rewriting the
5185 Rewrite
(N
, New_Occurrence_Of
(Standard_False
, Loc
));
5189 -- Here we have a non-scalar type
5192 Typ
:= Designated_Type
(Typ
);
5195 if not Is_Constrained
(Typ
) then
5196 Rewrite
(N
, New_Reference_To
(Standard_True
, Loc
));
5197 Analyze_And_Resolve
(N
, Restyp
);
5199 -- For the constrained array case, we have to check the subscripts
5200 -- for an exact match if the lengths are non-zero (the lengths
5201 -- must match in any case).
5203 elsif Is_Array_Type
(Typ
) then
5204 Check_Subscripts
: declare
5205 function Build_Attribute_Reference
5208 Dim
: Nat
) return Node_Id
;
5209 -- Build attribute reference E'Nam (Dim)
5211 -------------------------------
5212 -- Build_Attribute_Reference --
5213 -------------------------------
5215 function Build_Attribute_Reference
5218 Dim
: Nat
) return Node_Id
5222 Make_Attribute_Reference
(Loc
,
5224 Attribute_Name
=> Nam
,
5225 Expressions
=> New_List
(
5226 Make_Integer_Literal
(Loc
, Dim
)));
5227 end Build_Attribute_Reference
;
5229 -- Start of processing for Check_Subscripts
5232 for J
in 1 .. Number_Dimensions
(Typ
) loop
5233 Evolve_And_Then
(Cond
,
5236 Build_Attribute_Reference
5237 (Duplicate_Subexpr_No_Checks
(Obj
),
5240 Build_Attribute_Reference
5241 (New_Occurrence_Of
(Typ
, Loc
), Name_First
, J
)));
5243 Evolve_And_Then
(Cond
,
5246 Build_Attribute_Reference
5247 (Duplicate_Subexpr_No_Checks
(Obj
),
5250 Build_Attribute_Reference
5251 (New_Occurrence_Of
(Typ
, Loc
), Name_Last
, J
)));
5260 Right_Opnd
=> Make_Null
(Loc
)),
5261 Right_Opnd
=> Cond
);
5265 Analyze_And_Resolve
(N
, Restyp
);
5266 end Check_Subscripts
;
5268 -- These are the cases where constraint checks may be required,
5269 -- e.g. records with possible discriminants
5272 -- Expand the test into a series of discriminant comparisons.
5273 -- The expression that is built is the negation of the one that
5274 -- is used for checking discriminant constraints.
5276 Obj
:= Relocate_Node
(Left_Opnd
(N
));
5278 if Has_Discriminants
(Typ
) then
5279 Cond
:= Make_Op_Not
(Loc
,
5280 Right_Opnd
=> Build_Discriminant_Checks
(Obj
, Typ
));
5283 Cond
:= Make_Or_Else
(Loc
,
5287 Right_Opnd
=> Make_Null
(Loc
)),
5288 Right_Opnd
=> Cond
);
5292 Cond
:= New_Occurrence_Of
(Standard_True
, Loc
);
5296 Analyze_And_Resolve
(N
, Restyp
);
5299 -- Ada 2012 (AI05-0149): Handle membership tests applied to an
5300 -- expression of an anonymous access type. This can involve an
5301 -- accessibility test and a tagged type membership test in the
5302 -- case of tagged designated types.
5304 if Ada_Version
>= Ada_2012
5306 and then Ekind
(Ltyp
) = E_Anonymous_Access_Type
5309 Expr_Entity
: Entity_Id
:= Empty
;
5311 Param_Level
: Node_Id
;
5312 Type_Level
: Node_Id
;
5315 if Is_Entity_Name
(Lop
) then
5316 Expr_Entity
:= Param_Entity
(Lop
);
5318 if not Present
(Expr_Entity
) then
5319 Expr_Entity
:= Entity
(Lop
);
5323 -- If a conversion of the anonymous access value to the
5324 -- tested type would be illegal, then the result is False.
5326 if not Valid_Conversion
5327 (Lop
, Rtyp
, Lop
, Report_Errs
=> False)
5329 Rewrite
(N
, New_Occurrence_Of
(Standard_False
, Loc
));
5330 Analyze_And_Resolve
(N
, Restyp
);
5332 -- Apply an accessibility check if the access object has an
5333 -- associated access level and when the level of the type is
5334 -- less deep than the level of the access parameter. This
5335 -- only occur for access parameters and stand-alone objects
5336 -- of an anonymous access type.
5339 if Present
(Expr_Entity
)
5342 (Effective_Extra_Accessibility
(Expr_Entity
))
5343 and then UI_Gt
(Object_Access_Level
(Lop
),
5344 Type_Access_Level
(Rtyp
))
5348 (Effective_Extra_Accessibility
(Expr_Entity
), Loc
);
5351 Make_Integer_Literal
(Loc
, Type_Access_Level
(Rtyp
));
5353 -- Return True only if the accessibility level of the
5354 -- expression entity is not deeper than the level of
5355 -- the tested access type.
5359 Left_Opnd
=> Relocate_Node
(N
),
5360 Right_Opnd
=> Make_Op_Le
(Loc
,
5361 Left_Opnd
=> Param_Level
,
5362 Right_Opnd
=> Type_Level
)));
5364 Analyze_And_Resolve
(N
);
5367 -- If the designated type is tagged, do tagged membership
5370 -- *** NOTE: we have to check not null before doing the
5371 -- tagged membership test (but maybe that can be done
5372 -- inside Tagged_Membership?).
5374 if Is_Tagged_Type
(Typ
) then
5377 Left_Opnd
=> Relocate_Node
(N
),
5381 Right_Opnd
=> Make_Null
(Loc
))));
5383 -- No expansion will be performed when VM_Target, as
5384 -- the VM back-ends will handle the membership tests
5385 -- directly (tags are not explicitly represented in
5386 -- Java objects, so the normal tagged membership
5387 -- expansion is not what we want).
5389 if Tagged_Type_Expansion
then
5391 -- Note that we have to pass Original_Node, because
5392 -- the membership test might already have been
5393 -- rewritten by earlier parts of membership test.
5396 (Original_Node
(N
), SCIL_Node
, New_N
);
5398 -- Update decoration of relocated node referenced
5399 -- by the SCIL node.
5401 if Generate_SCIL
and then Present
(SCIL_Node
) then
5402 Set_SCIL_Node
(New_N
, SCIL_Node
);
5407 Left_Opnd
=> Relocate_Node
(N
),
5408 Right_Opnd
=> New_N
));
5410 Analyze_And_Resolve
(N
, Restyp
);
5419 -- At this point, we have done the processing required for the basic
5420 -- membership test, but not yet dealt with the predicate.
5424 -- If a predicate is present, then we do the predicate test, but we
5425 -- most certainly want to omit this if we are within the predicate
5426 -- function itself, since otherwise we have an infinite recursion!
5429 PFunc
: constant Entity_Id
:= Predicate_Function
(Rtyp
);
5433 and then Current_Scope
/= PFunc
5437 Left_Opnd
=> Relocate_Node
(N
),
5438 Right_Opnd
=> Make_Predicate_Call
(Rtyp
, Lop
)));
5440 -- Analyze new expression, mark left operand as analyzed to
5441 -- avoid infinite recursion adding predicate calls. Similarly,
5442 -- suppress further range checks on the call.
5444 Set_Analyzed
(Left_Opnd
(N
));
5445 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
5447 -- All done, skip attempt at compile time determination of result
5454 --------------------------------
5455 -- Expand_N_Indexed_Component --
5456 --------------------------------
5458 procedure Expand_N_Indexed_Component
(N
: Node_Id
) is
5459 Loc
: constant Source_Ptr
:= Sloc
(N
);
5460 Typ
: constant Entity_Id
:= Etype
(N
);
5461 P
: constant Node_Id
:= Prefix
(N
);
5462 T
: constant Entity_Id
:= Etype
(P
);
5466 -- A special optimization, if we have an indexed component that is
5467 -- selecting from a slice, then we can eliminate the slice, since, for
5468 -- example, x (i .. j)(k) is identical to x(k). The only difference is
5469 -- the range check required by the slice. The range check for the slice
5470 -- itself has already been generated. The range check for the
5471 -- subscripting operation is ensured by converting the subject to
5472 -- the subtype of the slice.
5474 -- This optimization not only generates better code, avoiding slice
5475 -- messing especially in the packed case, but more importantly bypasses
5476 -- some problems in handling this peculiar case, for example, the issue
5477 -- of dealing specially with object renamings.
5479 if Nkind
(P
) = N_Slice
then
5481 Make_Indexed_Component
(Loc
,
5482 Prefix
=> Prefix
(P
),
5483 Expressions
=> New_List
(
5485 (Etype
(First_Index
(Etype
(P
))),
5486 First
(Expressions
(N
))))));
5487 Analyze_And_Resolve
(N
, Typ
);
5491 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
5492 -- function, then additional actuals must be passed.
5494 if Ada_Version
>= Ada_2005
5495 and then Is_Build_In_Place_Function_Call
(P
)
5497 Make_Build_In_Place_Call_In_Anonymous_Context
(P
);
5500 -- If the prefix is an access type, then we unconditionally rewrite if
5501 -- as an explicit dereference. This simplifies processing for several
5502 -- cases, including packed array cases and certain cases in which checks
5503 -- must be generated. We used to try to do this only when it was
5504 -- necessary, but it cleans up the code to do it all the time.
5506 if Is_Access_Type
(T
) then
5507 Insert_Explicit_Dereference
(P
);
5508 Analyze_And_Resolve
(P
, Designated_Type
(T
));
5509 Atp
:= Designated_Type
(T
);
5514 -- Generate index and validity checks
5516 Generate_Index_Checks
(N
);
5518 if Validity_Checks_On
and then Validity_Check_Subscripts
then
5519 Apply_Subscript_Validity_Checks
(N
);
5522 -- If selecting from an array with atomic components, and atomic sync
5523 -- is not suppressed for this array type, set atomic sync flag.
5525 if (Has_Atomic_Components
(Atp
)
5526 and then not Atomic_Synchronization_Disabled
(Atp
))
5527 or else (Is_Atomic
(Typ
)
5528 and then not Atomic_Synchronization_Disabled
(Typ
))
5530 Activate_Atomic_Synchronization
(N
);
5533 -- All done for the non-packed case
5535 if not Is_Packed
(Etype
(Prefix
(N
))) then
5539 -- For packed arrays that are not bit-packed (i.e. the case of an array
5540 -- with one or more index types with a non-contiguous enumeration type),
5541 -- we can always use the normal packed element get circuit.
5543 if not Is_Bit_Packed_Array
(Etype
(Prefix
(N
))) then
5544 Expand_Packed_Element_Reference
(N
);
5548 -- For a reference to a component of a bit packed array, we have to
5549 -- convert it to a reference to the corresponding Packed_Array_Type.
5550 -- We only want to do this for simple references, and not for:
5552 -- Left side of assignment, or prefix of left side of assignment, or
5553 -- prefix of the prefix, to handle packed arrays of packed arrays,
5554 -- This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
5556 -- Renaming objects in renaming associations
5557 -- This case is handled when a use of the renamed variable occurs
5559 -- Actual parameters for a procedure call
5560 -- This case is handled in Exp_Ch6.Expand_Actuals
5562 -- The second expression in a 'Read attribute reference
5564 -- The prefix of an address or bit or size attribute reference
5566 -- The following circuit detects these exceptions
5569 Child
: Node_Id
:= N
;
5570 Parnt
: Node_Id
:= Parent
(N
);
5574 if Nkind
(Parnt
) = N_Unchecked_Expression
then
5577 elsif Nkind_In
(Parnt
, N_Object_Renaming_Declaration
,
5578 N_Procedure_Call_Statement
)
5579 or else (Nkind
(Parnt
) = N_Parameter_Association
5581 Nkind
(Parent
(Parnt
)) = N_Procedure_Call_Statement
)
5585 elsif Nkind
(Parnt
) = N_Attribute_Reference
5586 and then (Attribute_Name
(Parnt
) = Name_Address
5588 Attribute_Name
(Parnt
) = Name_Bit
5590 Attribute_Name
(Parnt
) = Name_Size
)
5591 and then Prefix
(Parnt
) = Child
5595 elsif Nkind
(Parnt
) = N_Assignment_Statement
5596 and then Name
(Parnt
) = Child
5600 -- If the expression is an index of an indexed component, it must
5601 -- be expanded regardless of context.
5603 elsif Nkind
(Parnt
) = N_Indexed_Component
5604 and then Child
/= Prefix
(Parnt
)
5606 Expand_Packed_Element_Reference
(N
);
5609 elsif Nkind
(Parent
(Parnt
)) = N_Assignment_Statement
5610 and then Name
(Parent
(Parnt
)) = Parnt
5614 elsif Nkind
(Parnt
) = N_Attribute_Reference
5615 and then Attribute_Name
(Parnt
) = Name_Read
5616 and then Next
(First
(Expressions
(Parnt
))) = Child
5620 elsif Nkind_In
(Parnt
, N_Indexed_Component
, N_Selected_Component
)
5621 and then Prefix
(Parnt
) = Child
5626 Expand_Packed_Element_Reference
(N
);
5630 -- Keep looking up tree for unchecked expression, or if we are the
5631 -- prefix of a possible assignment left side.
5634 Parnt
:= Parent
(Child
);
5637 end Expand_N_Indexed_Component
;
5639 ---------------------
5640 -- Expand_N_Not_In --
5641 ---------------------
5643 -- Replace a not in b by not (a in b) so that the expansions for (a in b)
5644 -- can be done. This avoids needing to duplicate this expansion code.
5646 procedure Expand_N_Not_In
(N
: Node_Id
) is
5647 Loc
: constant Source_Ptr
:= Sloc
(N
);
5648 Typ
: constant Entity_Id
:= Etype
(N
);
5649 Cfs
: constant Boolean := Comes_From_Source
(N
);
5656 Left_Opnd
=> Left_Opnd
(N
),
5657 Right_Opnd
=> Right_Opnd
(N
))));
5659 -- If this is a set membership, preserve list of alternatives
5661 Set_Alternatives
(Right_Opnd
(N
), Alternatives
(Original_Node
(N
)));
5663 -- We want this to appear as coming from source if original does (see
5664 -- transformations in Expand_N_In).
5666 Set_Comes_From_Source
(N
, Cfs
);
5667 Set_Comes_From_Source
(Right_Opnd
(N
), Cfs
);
5669 -- Now analyze transformed node
5671 Analyze_And_Resolve
(N
, Typ
);
5672 end Expand_N_Not_In
;
5678 -- The only replacement required is for the case of a null of a type that
5679 -- is an access to protected subprogram, or a subtype thereof. We represent
5680 -- such access values as a record, and so we must replace the occurrence of
5681 -- null by the equivalent record (with a null address and a null pointer in
5682 -- it), so that the backend creates the proper value.
5684 procedure Expand_N_Null
(N
: Node_Id
) is
5685 Loc
: constant Source_Ptr
:= Sloc
(N
);
5686 Typ
: constant Entity_Id
:= Base_Type
(Etype
(N
));
5690 if Is_Access_Protected_Subprogram_Type
(Typ
) then
5692 Make_Aggregate
(Loc
,
5693 Expressions
=> New_List
(
5694 New_Occurrence_Of
(RTE
(RE_Null_Address
), Loc
),
5698 Analyze_And_Resolve
(N
, Equivalent_Type
(Typ
));
5700 -- For subsequent semantic analysis, the node must retain its type.
5701 -- Gigi in any case replaces this type by the corresponding record
5702 -- type before processing the node.
5708 when RE_Not_Available
=>
5712 ---------------------
5713 -- Expand_N_Op_Abs --
5714 ---------------------
5716 procedure Expand_N_Op_Abs
(N
: Node_Id
) is
5717 Loc
: constant Source_Ptr
:= Sloc
(N
);
5718 Expr
: constant Node_Id
:= Right_Opnd
(N
);
5721 Unary_Op_Validity_Checks
(N
);
5723 -- Deal with software overflow checking
5725 if not Backend_Overflow_Checks_On_Target
5726 and then Is_Signed_Integer_Type
(Etype
(N
))
5727 and then Do_Overflow_Check
(N
)
5729 -- The only case to worry about is when the argument is equal to the
5730 -- largest negative number, so what we do is to insert the check:
5732 -- [constraint_error when Expr = typ'Base'First]
5734 -- with the usual Duplicate_Subexpr use coding for expr
5737 Make_Raise_Constraint_Error
(Loc
,
5740 Left_Opnd
=> Duplicate_Subexpr
(Expr
),
5742 Make_Attribute_Reference
(Loc
,
5744 New_Occurrence_Of
(Base_Type
(Etype
(Expr
)), Loc
),
5745 Attribute_Name
=> Name_First
)),
5746 Reason
=> CE_Overflow_Check_Failed
));
5749 -- Vax floating-point types case
5751 if Vax_Float
(Etype
(N
)) then
5752 Expand_Vax_Arith
(N
);
5754 end Expand_N_Op_Abs
;
5756 ---------------------
5757 -- Expand_N_Op_Add --
5758 ---------------------
5760 procedure Expand_N_Op_Add
(N
: Node_Id
) is
5761 Typ
: constant Entity_Id
:= Etype
(N
);
5764 Binary_Op_Validity_Checks
(N
);
5766 -- N + 0 = 0 + N = N for integer types
5768 if Is_Integer_Type
(Typ
) then
5769 if Compile_Time_Known_Value
(Right_Opnd
(N
))
5770 and then Expr_Value
(Right_Opnd
(N
)) = Uint_0
5772 Rewrite
(N
, Left_Opnd
(N
));
5775 elsif Compile_Time_Known_Value
(Left_Opnd
(N
))
5776 and then Expr_Value
(Left_Opnd
(N
)) = Uint_0
5778 Rewrite
(N
, Right_Opnd
(N
));
5783 -- Arithmetic overflow checks for signed integer/fixed point types
5785 if Is_Signed_Integer_Type
(Typ
)
5786 or else Is_Fixed_Point_Type
(Typ
)
5788 Apply_Arithmetic_Overflow_Check
(N
);
5791 -- Vax floating-point types case
5793 elsif Vax_Float
(Typ
) then
5794 Expand_Vax_Arith
(N
);
5796 end Expand_N_Op_Add
;
5798 ---------------------
5799 -- Expand_N_Op_And --
5800 ---------------------
5802 procedure Expand_N_Op_And
(N
: Node_Id
) is
5803 Typ
: constant Entity_Id
:= Etype
(N
);
5806 Binary_Op_Validity_Checks
(N
);
5808 if Is_Array_Type
(Etype
(N
)) then
5809 Expand_Boolean_Operator
(N
);
5811 elsif Is_Boolean_Type
(Etype
(N
)) then
5812 Adjust_Condition
(Left_Opnd
(N
));
5813 Adjust_Condition
(Right_Opnd
(N
));
5814 Set_Etype
(N
, Standard_Boolean
);
5815 Adjust_Result_Type
(N
, Typ
);
5817 elsif Is_Intrinsic_Subprogram
(Entity
(N
)) then
5818 Expand_Intrinsic_Call
(N
, Entity
(N
));
5821 end Expand_N_Op_And
;
5823 ------------------------
5824 -- Expand_N_Op_Concat --
5825 ------------------------
5827 procedure Expand_N_Op_Concat
(N
: Node_Id
) is
5829 -- List of operands to be concatenated
5832 -- Node which is to be replaced by the result of concatenating the nodes
5833 -- in the list Opnds.
5836 -- Ensure validity of both operands
5838 Binary_Op_Validity_Checks
(N
);
5840 -- If we are the left operand of a concatenation higher up the tree,
5841 -- then do nothing for now, since we want to deal with a series of
5842 -- concatenations as a unit.
5844 if Nkind
(Parent
(N
)) = N_Op_Concat
5845 and then N
= Left_Opnd
(Parent
(N
))
5850 -- We get here with a concatenation whose left operand may be a
5851 -- concatenation itself with a consistent type. We need to process
5852 -- these concatenation operands from left to right, which means
5853 -- from the deepest node in the tree to the highest node.
5856 while Nkind
(Left_Opnd
(Cnode
)) = N_Op_Concat
loop
5857 Cnode
:= Left_Opnd
(Cnode
);
5860 -- Now Cnode is the deepest concatenation, and its parents are the
5861 -- concatenation nodes above, so now we process bottom up, doing the
5862 -- operations. We gather a string that is as long as possible up to five
5865 -- The outer loop runs more than once if more than one concatenation
5866 -- type is involved.
5869 Opnds
:= New_List
(Left_Opnd
(Cnode
), Right_Opnd
(Cnode
));
5870 Set_Parent
(Opnds
, N
);
5872 -- The inner loop gathers concatenation operands
5874 Inner
: while Cnode
/= N
5875 and then Base_Type
(Etype
(Cnode
)) =
5876 Base_Type
(Etype
(Parent
(Cnode
)))
5878 Cnode
:= Parent
(Cnode
);
5879 Append
(Right_Opnd
(Cnode
), Opnds
);
5882 Expand_Concatenate
(Cnode
, Opnds
);
5884 exit Outer
when Cnode
= N
;
5885 Cnode
:= Parent
(Cnode
);
5887 end Expand_N_Op_Concat
;
5889 ------------------------
5890 -- Expand_N_Op_Divide --
5891 ------------------------
5893 procedure Expand_N_Op_Divide
(N
: Node_Id
) is
5894 Loc
: constant Source_Ptr
:= Sloc
(N
);
5895 Lopnd
: constant Node_Id
:= Left_Opnd
(N
);
5896 Ropnd
: constant Node_Id
:= Right_Opnd
(N
);
5897 Ltyp
: constant Entity_Id
:= Etype
(Lopnd
);
5898 Rtyp
: constant Entity_Id
:= Etype
(Ropnd
);
5899 Typ
: Entity_Id
:= Etype
(N
);
5900 Rknow
: constant Boolean := Is_Integer_Type
(Typ
)
5902 Compile_Time_Known_Value
(Ropnd
);
5906 Binary_Op_Validity_Checks
(N
);
5909 Rval
:= Expr_Value
(Ropnd
);
5912 -- N / 1 = N for integer types
5914 if Rknow
and then Rval
= Uint_1
then
5919 -- Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
5920 -- Is_Power_Of_2_For_Shift is set means that we know that our left
5921 -- operand is an unsigned integer, as required for this to work.
5923 if Nkind
(Ropnd
) = N_Op_Expon
5924 and then Is_Power_Of_2_For_Shift
(Ropnd
)
5926 -- We cannot do this transformation in configurable run time mode if we
5927 -- have 64-bit integers and long shifts are not available.
5931 or else Support_Long_Shifts_On_Target
)
5934 Make_Op_Shift_Right
(Loc
,
5937 Convert_To
(Standard_Natural
, Right_Opnd
(Ropnd
))));
5938 Analyze_And_Resolve
(N
, Typ
);
5942 -- Do required fixup of universal fixed operation
5944 if Typ
= Universal_Fixed
then
5945 Fixup_Universal_Fixed_Operation
(N
);
5949 -- Divisions with fixed-point results
5951 if Is_Fixed_Point_Type
(Typ
) then
5953 -- No special processing if Treat_Fixed_As_Integer is set, since
5954 -- from a semantic point of view such operations are simply integer
5955 -- operations and will be treated that way.
5957 if not Treat_Fixed_As_Integer
(N
) then
5958 if Is_Integer_Type
(Rtyp
) then
5959 Expand_Divide_Fixed_By_Integer_Giving_Fixed
(N
);
5961 Expand_Divide_Fixed_By_Fixed_Giving_Fixed
(N
);
5965 -- Other cases of division of fixed-point operands. Again we exclude the
5966 -- case where Treat_Fixed_As_Integer is set.
5968 elsif (Is_Fixed_Point_Type
(Ltyp
) or else
5969 Is_Fixed_Point_Type
(Rtyp
))
5970 and then not Treat_Fixed_As_Integer
(N
)
5972 if Is_Integer_Type
(Typ
) then
5973 Expand_Divide_Fixed_By_Fixed_Giving_Integer
(N
);
5975 pragma Assert
(Is_Floating_Point_Type
(Typ
));
5976 Expand_Divide_Fixed_By_Fixed_Giving_Float
(N
);
5979 -- Mixed-mode operations can appear in a non-static universal context,
5980 -- in which case the integer argument must be converted explicitly.
5982 elsif Typ
= Universal_Real
5983 and then Is_Integer_Type
(Rtyp
)
5986 Convert_To
(Universal_Real
, Relocate_Node
(Ropnd
)));
5988 Analyze_And_Resolve
(Ropnd
, Universal_Real
);
5990 elsif Typ
= Universal_Real
5991 and then Is_Integer_Type
(Ltyp
)
5994 Convert_To
(Universal_Real
, Relocate_Node
(Lopnd
)));
5996 Analyze_And_Resolve
(Lopnd
, Universal_Real
);
5998 -- Non-fixed point cases, do integer zero divide and overflow checks
6000 elsif Is_Integer_Type
(Typ
) then
6001 Apply_Divide_Check
(N
);
6003 -- Deal with Vax_Float
6005 elsif Vax_Float
(Typ
) then
6006 Expand_Vax_Arith
(N
);
6009 end Expand_N_Op_Divide
;
6011 --------------------
6012 -- Expand_N_Op_Eq --
6013 --------------------
6015 procedure Expand_N_Op_Eq
(N
: Node_Id
) is
6016 Loc
: constant Source_Ptr
:= Sloc
(N
);
6017 Typ
: constant Entity_Id
:= Etype
(N
);
6018 Lhs
: constant Node_Id
:= Left_Opnd
(N
);
6019 Rhs
: constant Node_Id
:= Right_Opnd
(N
);
6020 Bodies
: constant List_Id
:= New_List
;
6021 A_Typ
: constant Entity_Id
:= Etype
(Lhs
);
6023 Typl
: Entity_Id
:= A_Typ
;
6024 Op_Name
: Entity_Id
;
6027 procedure Build_Equality_Call
(Eq
: Entity_Id
);
6028 -- If a constructed equality exists for the type or for its parent,
6029 -- build and analyze call, adding conversions if the operation is
6032 function Has_Unconstrained_UU_Component
(Typ
: Node_Id
) return Boolean;
6033 -- Determines whether a type has a subcomponent of an unconstrained
6034 -- Unchecked_Union subtype. Typ is a record type.
6036 -------------------------
6037 -- Build_Equality_Call --
6038 -------------------------
6040 procedure Build_Equality_Call
(Eq
: Entity_Id
) is
6041 Op_Type
: constant Entity_Id
:= Etype
(First_Formal
(Eq
));
6042 L_Exp
: Node_Id
:= Relocate_Node
(Lhs
);
6043 R_Exp
: Node_Id
:= Relocate_Node
(Rhs
);
6046 if Base_Type
(Op_Type
) /= Base_Type
(A_Typ
)
6047 and then not Is_Class_Wide_Type
(A_Typ
)
6049 L_Exp
:= OK_Convert_To
(Op_Type
, L_Exp
);
6050 R_Exp
:= OK_Convert_To
(Op_Type
, R_Exp
);
6053 -- If we have an Unchecked_Union, we need to add the inferred
6054 -- discriminant values as actuals in the function call. At this
6055 -- point, the expansion has determined that both operands have
6056 -- inferable discriminants.
6058 if Is_Unchecked_Union
(Op_Type
) then
6060 Lhs_Type
: constant Node_Id
:= Etype
(L_Exp
);
6061 Rhs_Type
: constant Node_Id
:= Etype
(R_Exp
);
6062 Lhs_Discr_Val
: Node_Id
;
6063 Rhs_Discr_Val
: Node_Id
;
6066 -- Per-object constrained selected components require special
6067 -- attention. If the enclosing scope of the component is an
6068 -- Unchecked_Union, we cannot reference its discriminants
6069 -- directly. This is why we use the two extra parameters of
6070 -- the equality function of the enclosing Unchecked_Union.
6072 -- type UU_Type (Discr : Integer := 0) is
6075 -- pragma Unchecked_Union (UU_Type);
6077 -- 1. Unchecked_Union enclosing record:
6079 -- type Enclosing_UU_Type (Discr : Integer := 0) is record
6081 -- Comp : UU_Type (Discr);
6083 -- end Enclosing_UU_Type;
6084 -- pragma Unchecked_Union (Enclosing_UU_Type);
6086 -- Obj1 : Enclosing_UU_Type;
6087 -- Obj2 : Enclosing_UU_Type (1);
6089 -- [. . .] Obj1 = Obj2 [. . .]
6093 -- if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
6095 -- A and B are the formal parameters of the equality function
6096 -- of Enclosing_UU_Type. The function always has two extra
6097 -- formals to capture the inferred discriminant values.
6099 -- 2. Non-Unchecked_Union enclosing record:
6102 -- Enclosing_Non_UU_Type (Discr : Integer := 0)
6105 -- Comp : UU_Type (Discr);
6107 -- end Enclosing_Non_UU_Type;
6109 -- Obj1 : Enclosing_Non_UU_Type;
6110 -- Obj2 : Enclosing_Non_UU_Type (1);
6112 -- ... Obj1 = Obj2 ...
6116 -- if not (uu_typeEQ (obj1.comp, obj2.comp,
6117 -- obj1.discr, obj2.discr)) then
6119 -- In this case we can directly reference the discriminants of
6120 -- the enclosing record.
6124 if Nkind
(Lhs
) = N_Selected_Component
6125 and then Has_Per_Object_Constraint
6126 (Entity
(Selector_Name
(Lhs
)))
6128 -- Enclosing record is an Unchecked_Union, use formal A
6130 if Is_Unchecked_Union
6131 (Scope
(Entity
(Selector_Name
(Lhs
))))
6133 Lhs_Discr_Val
:= Make_Identifier
(Loc
, Name_A
);
6135 -- Enclosing record is of a non-Unchecked_Union type, it is
6136 -- possible to reference the discriminant.
6140 Make_Selected_Component
(Loc
,
6141 Prefix
=> Prefix
(Lhs
),
6144 (Get_Discriminant_Value
6145 (First_Discriminant
(Lhs_Type
),
6147 Stored_Constraint
(Lhs_Type
))));
6150 -- Comment needed here ???
6153 -- Infer the discriminant value
6157 (Get_Discriminant_Value
6158 (First_Discriminant
(Lhs_Type
),
6160 Stored_Constraint
(Lhs_Type
)));
6165 if Nkind
(Rhs
) = N_Selected_Component
6166 and then Has_Per_Object_Constraint
6167 (Entity
(Selector_Name
(Rhs
)))
6169 if Is_Unchecked_Union
6170 (Scope
(Entity
(Selector_Name
(Rhs
))))
6172 Rhs_Discr_Val
:= Make_Identifier
(Loc
, Name_B
);
6176 Make_Selected_Component
(Loc
,
6177 Prefix
=> Prefix
(Rhs
),
6179 New_Copy
(Get_Discriminant_Value
(
6180 First_Discriminant
(Rhs_Type
),
6182 Stored_Constraint
(Rhs_Type
))));
6187 New_Copy
(Get_Discriminant_Value
(
6188 First_Discriminant
(Rhs_Type
),
6190 Stored_Constraint
(Rhs_Type
)));
6195 Make_Function_Call
(Loc
,
6196 Name
=> New_Reference_To
(Eq
, Loc
),
6197 Parameter_Associations
=> New_List
(
6204 -- Normal case, not an unchecked union
6208 Make_Function_Call
(Loc
,
6209 Name
=> New_Reference_To
(Eq
, Loc
),
6210 Parameter_Associations
=> New_List
(L_Exp
, R_Exp
)));
6213 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
6214 end Build_Equality_Call
;
6216 ------------------------------------
6217 -- Has_Unconstrained_UU_Component --
6218 ------------------------------------
6220 function Has_Unconstrained_UU_Component
6221 (Typ
: Node_Id
) return Boolean
6223 Tdef
: constant Node_Id
:=
6224 Type_Definition
(Declaration_Node
(Base_Type
(Typ
)));
6228 function Component_Is_Unconstrained_UU
6229 (Comp
: Node_Id
) return Boolean;
6230 -- Determines whether the subtype of the component is an
6231 -- unconstrained Unchecked_Union.
6233 function Variant_Is_Unconstrained_UU
6234 (Variant
: Node_Id
) return Boolean;
6235 -- Determines whether a component of the variant has an unconstrained
6236 -- Unchecked_Union subtype.
6238 -----------------------------------
6239 -- Component_Is_Unconstrained_UU --
6240 -----------------------------------
6242 function Component_Is_Unconstrained_UU
6243 (Comp
: Node_Id
) return Boolean
6246 if Nkind
(Comp
) /= N_Component_Declaration
then
6251 Sindic
: constant Node_Id
:=
6252 Subtype_Indication
(Component_Definition
(Comp
));
6255 -- Unconstrained nominal type. In the case of a constraint
6256 -- present, the node kind would have been N_Subtype_Indication.
6258 if Nkind
(Sindic
) = N_Identifier
then
6259 return Is_Unchecked_Union
(Base_Type
(Etype
(Sindic
)));
6264 end Component_Is_Unconstrained_UU
;
6266 ---------------------------------
6267 -- Variant_Is_Unconstrained_UU --
6268 ---------------------------------
6270 function Variant_Is_Unconstrained_UU
6271 (Variant
: Node_Id
) return Boolean
6273 Clist
: constant Node_Id
:= Component_List
(Variant
);
6276 if Is_Empty_List
(Component_Items
(Clist
)) then
6280 -- We only need to test one component
6283 Comp
: Node_Id
:= First
(Component_Items
(Clist
));
6286 while Present
(Comp
) loop
6287 if Component_Is_Unconstrained_UU
(Comp
) then
6295 -- None of the components withing the variant were of
6296 -- unconstrained Unchecked_Union type.
6299 end Variant_Is_Unconstrained_UU
;
6301 -- Start of processing for Has_Unconstrained_UU_Component
6304 if Null_Present
(Tdef
) then
6308 Clist
:= Component_List
(Tdef
);
6309 Vpart
:= Variant_Part
(Clist
);
6311 -- Inspect available components
6313 if Present
(Component_Items
(Clist
)) then
6315 Comp
: Node_Id
:= First
(Component_Items
(Clist
));
6318 while Present
(Comp
) loop
6320 -- One component is sufficient
6322 if Component_Is_Unconstrained_UU
(Comp
) then
6331 -- Inspect available components withing variants
6333 if Present
(Vpart
) then
6335 Variant
: Node_Id
:= First
(Variants
(Vpart
));
6338 while Present
(Variant
) loop
6340 -- One component within a variant is sufficient
6342 if Variant_Is_Unconstrained_UU
(Variant
) then
6351 -- Neither the available components, nor the components inside the
6352 -- variant parts were of an unconstrained Unchecked_Union subtype.
6355 end Has_Unconstrained_UU_Component
;
6357 -- Start of processing for Expand_N_Op_Eq
6360 Binary_Op_Validity_Checks
(N
);
6362 if Ekind
(Typl
) = E_Private_Type
then
6363 Typl
:= Underlying_Type
(Typl
);
6364 elsif Ekind
(Typl
) = E_Private_Subtype
then
6365 Typl
:= Underlying_Type
(Base_Type
(Typl
));
6370 -- It may happen in error situations that the underlying type is not
6371 -- set. The error will be detected later, here we just defend the
6378 Typl
:= Base_Type
(Typl
);
6380 -- Boolean types (requiring handling of non-standard case)
6382 if Is_Boolean_Type
(Typl
) then
6383 Adjust_Condition
(Left_Opnd
(N
));
6384 Adjust_Condition
(Right_Opnd
(N
));
6385 Set_Etype
(N
, Standard_Boolean
);
6386 Adjust_Result_Type
(N
, Typ
);
6390 elsif Is_Array_Type
(Typl
) then
6392 -- If we are doing full validity checking, and it is possible for the
6393 -- array elements to be invalid then expand out array comparisons to
6394 -- make sure that we check the array elements.
6396 if Validity_Check_Operands
6397 and then not Is_Known_Valid
(Component_Type
(Typl
))
6400 Save_Force_Validity_Checks
: constant Boolean :=
6401 Force_Validity_Checks
;
6403 Force_Validity_Checks
:= True;
6405 Expand_Array_Equality
6407 Relocate_Node
(Lhs
),
6408 Relocate_Node
(Rhs
),
6411 Insert_Actions
(N
, Bodies
);
6412 Analyze_And_Resolve
(N
, Standard_Boolean
);
6413 Force_Validity_Checks
:= Save_Force_Validity_Checks
;
6416 -- Packed case where both operands are known aligned
6418 elsif Is_Bit_Packed_Array
(Typl
)
6419 and then not Is_Possibly_Unaligned_Object
(Lhs
)
6420 and then not Is_Possibly_Unaligned_Object
(Rhs
)
6422 Expand_Packed_Eq
(N
);
6424 -- Where the component type is elementary we can use a block bit
6425 -- comparison (if supported on the target) exception in the case
6426 -- of floating-point (negative zero issues require element by
6427 -- element comparison), and atomic types (where we must be sure
6428 -- to load elements independently) and possibly unaligned arrays.
6430 elsif Is_Elementary_Type
(Component_Type
(Typl
))
6431 and then not Is_Floating_Point_Type
(Component_Type
(Typl
))
6432 and then not Is_Atomic
(Component_Type
(Typl
))
6433 and then not Is_Possibly_Unaligned_Object
(Lhs
)
6434 and then not Is_Possibly_Unaligned_Object
(Rhs
)
6435 and then Support_Composite_Compare_On_Target
6439 -- For composite and floating-point cases, expand equality loop to
6440 -- make sure of using proper comparisons for tagged types, and
6441 -- correctly handling the floating-point case.
6445 Expand_Array_Equality
6447 Relocate_Node
(Lhs
),
6448 Relocate_Node
(Rhs
),
6451 Insert_Actions
(N
, Bodies
, Suppress
=> All_Checks
);
6452 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
6457 elsif Is_Record_Type
(Typl
) then
6459 -- For tagged types, use the primitive "="
6461 if Is_Tagged_Type
(Typl
) then
6463 -- No need to do anything else compiling under restriction
6464 -- No_Dispatching_Calls. During the semantic analysis we
6465 -- already notified such violation.
6467 if Restriction_Active
(No_Dispatching_Calls
) then
6471 -- If this is derived from an untagged private type completed with
6472 -- a tagged type, it does not have a full view, so we use the
6473 -- primitive operations of the private type. This check should no
6474 -- longer be necessary when these types get their full views???
6476 if Is_Private_Type
(A_Typ
)
6477 and then not Is_Tagged_Type
(A_Typ
)
6478 and then Is_Derived_Type
(A_Typ
)
6479 and then No
(Full_View
(A_Typ
))
6481 -- Search for equality operation, checking that the operands
6482 -- have the same type. Note that we must find a matching entry,
6483 -- or something is very wrong!
6485 Prim
:= First_Elmt
(Collect_Primitive_Operations
(A_Typ
));
6487 while Present
(Prim
) loop
6488 exit when Chars
(Node
(Prim
)) = Name_Op_Eq
6489 and then Etype
(First_Formal
(Node
(Prim
))) =
6490 Etype
(Next_Formal
(First_Formal
(Node
(Prim
))))
6492 Base_Type
(Etype
(Node
(Prim
))) = Standard_Boolean
;
6497 pragma Assert
(Present
(Prim
));
6498 Op_Name
:= Node
(Prim
);
6500 -- Find the type's predefined equality or an overriding
6501 -- user- defined equality. The reason for not simply calling
6502 -- Find_Prim_Op here is that there may be a user-defined
6503 -- overloaded equality op that precedes the equality that we want,
6504 -- so we have to explicitly search (e.g., there could be an
6505 -- equality with two different parameter types).
6508 if Is_Class_Wide_Type
(Typl
) then
6509 Typl
:= Root_Type
(Typl
);
6512 Prim
:= First_Elmt
(Primitive_Operations
(Typl
));
6513 while Present
(Prim
) loop
6514 exit when Chars
(Node
(Prim
)) = Name_Op_Eq
6515 and then Etype
(First_Formal
(Node
(Prim
))) =
6516 Etype
(Next_Formal
(First_Formal
(Node
(Prim
))))
6518 Base_Type
(Etype
(Node
(Prim
))) = Standard_Boolean
;
6523 pragma Assert
(Present
(Prim
));
6524 Op_Name
:= Node
(Prim
);
6527 Build_Equality_Call
(Op_Name
);
6529 -- Ada 2005 (AI-216): Program_Error is raised when evaluating the
6530 -- predefined equality operator for a type which has a subcomponent
6531 -- of an Unchecked_Union type whose nominal subtype is unconstrained.
6533 elsif Has_Unconstrained_UU_Component
(Typl
) then
6535 Make_Raise_Program_Error
(Loc
,
6536 Reason
=> PE_Unchecked_Union_Restriction
));
6538 -- Prevent Gigi from generating incorrect code by rewriting the
6539 -- equality as a standard False.
6542 New_Occurrence_Of
(Standard_False
, Loc
));
6544 elsif Is_Unchecked_Union
(Typl
) then
6546 -- If we can infer the discriminants of the operands, we make a
6547 -- call to the TSS equality function.
6549 if Has_Inferable_Discriminants
(Lhs
)
6551 Has_Inferable_Discriminants
(Rhs
)
6554 (TSS
(Root_Type
(Typl
), TSS_Composite_Equality
));
6557 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
6558 -- the predefined equality operator for an Unchecked_Union type
6559 -- if either of the operands lack inferable discriminants.
6562 Make_Raise_Program_Error
(Loc
,
6563 Reason
=> PE_Unchecked_Union_Restriction
));
6565 -- Prevent Gigi from generating incorrect code by rewriting
6566 -- the equality as a standard False.
6569 New_Occurrence_Of
(Standard_False
, Loc
));
6573 -- If a type support function is present (for complex cases), use it
6575 elsif Present
(TSS
(Root_Type
(Typl
), TSS_Composite_Equality
)) then
6577 (TSS
(Root_Type
(Typl
), TSS_Composite_Equality
));
6579 -- Otherwise expand the component by component equality. Note that
6580 -- we never use block-bit comparisons for records, because of the
6581 -- problems with gaps. The backend will often be able to recombine
6582 -- the separate comparisons that we generate here.
6585 Remove_Side_Effects
(Lhs
);
6586 Remove_Side_Effects
(Rhs
);
6588 Expand_Record_Equality
(N
, Typl
, Lhs
, Rhs
, Bodies
));
6590 Insert_Actions
(N
, Bodies
, Suppress
=> All_Checks
);
6591 Analyze_And_Resolve
(N
, Standard_Boolean
, Suppress
=> All_Checks
);
6595 -- Test if result is known at compile time
6597 Rewrite_Comparison
(N
);
6599 -- If we still have comparison for Vax_Float, process it
6601 if Vax_Float
(Typl
) and then Nkind
(N
) in N_Op_Compare
then
6602 Expand_Vax_Comparison
(N
);
6606 Optimize_Length_Comparison
(N
);
6609 -----------------------
6610 -- Expand_N_Op_Expon --
6611 -----------------------
6613 procedure Expand_N_Op_Expon
(N
: Node_Id
) is
6614 Loc
: constant Source_Ptr
:= Sloc
(N
);
6615 Typ
: constant Entity_Id
:= Etype
(N
);
6616 Rtyp
: constant Entity_Id
:= Root_Type
(Typ
);
6617 Base
: constant Node_Id
:= Relocate_Node
(Left_Opnd
(N
));
6618 Bastyp
: constant Node_Id
:= Etype
(Base
);
6619 Exp
: constant Node_Id
:= Relocate_Node
(Right_Opnd
(N
));
6620 Exptyp
: constant Entity_Id
:= Etype
(Exp
);
6621 Ovflo
: constant Boolean := Do_Overflow_Check
(N
);
6630 Binary_Op_Validity_Checks
(N
);
6632 -- CodePeer and GNATprove want to see the unexpanded N_Op_Expon node
6634 if CodePeer_Mode
or Alfa_Mode
then
6638 -- If either operand is of a private type, then we have the use of an
6639 -- intrinsic operator, and we get rid of the privateness, by using root
6640 -- types of underlying types for the actual operation. Otherwise the
6641 -- private types will cause trouble if we expand multiplications or
6642 -- shifts etc. We also do this transformation if the result type is
6643 -- different from the base type.
6645 if Is_Private_Type
(Etype
(Base
))
6646 or else Is_Private_Type
(Typ
)
6647 or else Is_Private_Type
(Exptyp
)
6648 or else Rtyp
/= Root_Type
(Bastyp
)
6651 Bt
: constant Entity_Id
:= Root_Type
(Underlying_Type
(Bastyp
));
6652 Et
: constant Entity_Id
:= Root_Type
(Underlying_Type
(Exptyp
));
6656 Unchecked_Convert_To
(Typ
,
6658 Left_Opnd
=> Unchecked_Convert_To
(Bt
, Base
),
6659 Right_Opnd
=> Unchecked_Convert_To
(Et
, Exp
))));
6660 Analyze_And_Resolve
(N
, Typ
);
6665 -- Test for case of known right argument
6667 if Compile_Time_Known_Value
(Exp
) then
6668 Expv
:= Expr_Value
(Exp
);
6670 -- We only fold small non-negative exponents. You might think we
6671 -- could fold small negative exponents for the real case, but we
6672 -- can't because we are required to raise Constraint_Error for
6673 -- the case of 0.0 ** (negative) even if Machine_Overflows = False.
6674 -- See ACVC test C4A012B.
6676 if Expv
>= 0 and then Expv
<= 4 then
6678 -- X ** 0 = 1 (or 1.0)
6682 -- Call Remove_Side_Effects to ensure that any side effects
6683 -- in the ignored left operand (in particular function calls
6684 -- to user defined functions) are properly executed.
6686 Remove_Side_Effects
(Base
);
6688 if Ekind
(Typ
) in Integer_Kind
then
6689 Xnode
:= Make_Integer_Literal
(Loc
, Intval
=> 1);
6691 Xnode
:= Make_Real_Literal
(Loc
, Ureal_1
);
6703 Make_Op_Multiply
(Loc
,
6704 Left_Opnd
=> Duplicate_Subexpr
(Base
),
6705 Right_Opnd
=> Duplicate_Subexpr_No_Checks
(Base
));
6707 -- X ** 3 = X * X * X
6711 Make_Op_Multiply
(Loc
,
6713 Make_Op_Multiply
(Loc
,
6714 Left_Opnd
=> Duplicate_Subexpr
(Base
),
6715 Right_Opnd
=> Duplicate_Subexpr_No_Checks
(Base
)),
6716 Right_Opnd
=> Duplicate_Subexpr_No_Checks
(Base
));
6719 -- En : constant base'type := base * base;
6724 Temp
:= Make_Temporary
(Loc
, 'E', Base
);
6726 Insert_Actions
(N
, New_List
(
6727 Make_Object_Declaration
(Loc
,
6728 Defining_Identifier
=> Temp
,
6729 Constant_Present
=> True,
6730 Object_Definition
=> New_Reference_To
(Typ
, Loc
),
6732 Make_Op_Multiply
(Loc
,
6733 Left_Opnd
=> Duplicate_Subexpr
(Base
),
6734 Right_Opnd
=> Duplicate_Subexpr_No_Checks
(Base
)))));
6737 Make_Op_Multiply
(Loc
,
6738 Left_Opnd
=> New_Reference_To
(Temp
, Loc
),
6739 Right_Opnd
=> New_Reference_To
(Temp
, Loc
));
6743 Analyze_And_Resolve
(N
, Typ
);
6748 -- Case of (2 ** expression) appearing as an argument of an integer
6749 -- multiplication, or as the right argument of a division of a non-
6750 -- negative integer. In such cases we leave the node untouched, setting
6751 -- the flag Is_Natural_Power_Of_2_for_Shift set, then the expansion
6752 -- of the higher level node converts it into a shift.
6754 -- Another case is 2 ** N in any other context. We simply convert
6755 -- this to 1 * 2 ** N, and then the above transformation applies.
6757 -- Note: this transformation is not applicable for a modular type with
6758 -- a non-binary modulus in the multiplication case, since we get a wrong
6759 -- result if the shift causes an overflow before the modular reduction.
6761 if Nkind
(Base
) = N_Integer_Literal
6762 and then Intval
(Base
) = 2
6763 and then Is_Integer_Type
(Root_Type
(Exptyp
))
6764 and then Esize
(Root_Type
(Exptyp
)) <= Esize
(Standard_Integer
)
6765 and then Is_Unsigned_Type
(Exptyp
)
6768 -- First the multiply and divide cases
6770 if Nkind_In
(Parent
(N
), N_Op_Divide
, N_Op_Multiply
) then
6772 P
: constant Node_Id
:= Parent
(N
);
6773 L
: constant Node_Id
:= Left_Opnd
(P
);
6774 R
: constant Node_Id
:= Right_Opnd
(P
);
6777 if (Nkind
(P
) = N_Op_Multiply
6778 and then not Non_Binary_Modulus
(Typ
)
6780 ((Is_Integer_Type
(Etype
(L
)) and then R
= N
)
6782 (Is_Integer_Type
(Etype
(R
)) and then L
= N
))
6783 and then not Do_Overflow_Check
(P
))
6785 (Nkind
(P
) = N_Op_Divide
6786 and then Is_Integer_Type
(Etype
(L
))
6787 and then Is_Unsigned_Type
(Etype
(L
))
6789 and then not Do_Overflow_Check
(P
))
6791 Set_Is_Power_Of_2_For_Shift
(N
);
6796 -- Now the other cases
6798 elsif not Non_Binary_Modulus
(Typ
) then
6800 Make_Op_Multiply
(Loc
,
6801 Left_Opnd
=> Make_Integer_Literal
(Loc
, 1),
6802 Right_Opnd
=> Relocate_Node
(N
)));
6803 Analyze_And_Resolve
(N
, Typ
);
6808 -- Fall through if exponentiation must be done using a runtime routine
6810 -- First deal with modular case
6812 if Is_Modular_Integer_Type
(Rtyp
) then
6814 -- Non-binary case, we call the special exponentiation routine for
6815 -- the non-binary case, converting the argument to Long_Long_Integer
6816 -- and passing the modulus value. Then the result is converted back
6817 -- to the base type.
6819 if Non_Binary_Modulus
(Rtyp
) then
6822 Make_Function_Call
(Loc
,
6823 Name
=> New_Reference_To
(RTE
(RE_Exp_Modular
), Loc
),
6824 Parameter_Associations
=> New_List
(
6825 Convert_To
(Standard_Integer
, Base
),
6826 Make_Integer_Literal
(Loc
, Modulus
(Rtyp
)),
6829 -- Binary case, in this case, we call one of two routines, either the
6830 -- unsigned integer case, or the unsigned long long integer case,
6831 -- with a final "and" operation to do the required mod.
6834 if UI_To_Int
(Esize
(Rtyp
)) <= Standard_Integer_Size
then
6835 Ent
:= RTE
(RE_Exp_Unsigned
);
6837 Ent
:= RTE
(RE_Exp_Long_Long_Unsigned
);
6844 Make_Function_Call
(Loc
,
6845 Name
=> New_Reference_To
(Ent
, Loc
),
6846 Parameter_Associations
=> New_List
(
6847 Convert_To
(Etype
(First_Formal
(Ent
)), Base
),
6850 Make_Integer_Literal
(Loc
, Modulus
(Rtyp
) - 1))));
6854 -- Common exit point for modular type case
6856 Analyze_And_Resolve
(N
, Typ
);
6859 -- Signed integer cases, done using either Integer or Long_Long_Integer.
6860 -- It is not worth having routines for Short_[Short_]Integer, since for
6861 -- most machines it would not help, and it would generate more code that
6862 -- might need certification when a certified run time is required.
6864 -- In the integer cases, we have two routines, one for when overflow
6865 -- checks are required, and one when they are not required, since there
6866 -- is a real gain in omitting checks on many machines.
6868 elsif Rtyp
= Base_Type
(Standard_Long_Long_Integer
)
6869 or else (Rtyp
= Base_Type
(Standard_Long_Integer
)
6871 Esize
(Standard_Long_Integer
) > Esize
(Standard_Integer
))
6872 or else (Rtyp
= Universal_Integer
)
6874 Etyp
:= Standard_Long_Long_Integer
;
6877 Rent
:= RE_Exp_Long_Long_Integer
;
6879 Rent
:= RE_Exn_Long_Long_Integer
;
6882 elsif Is_Signed_Integer_Type
(Rtyp
) then
6883 Etyp
:= Standard_Integer
;
6886 Rent
:= RE_Exp_Integer
;
6888 Rent
:= RE_Exn_Integer
;
6891 -- Floating-point cases, always done using Long_Long_Float. We do not
6892 -- need separate routines for the overflow case here, since in the case
6893 -- of floating-point, we generate infinities anyway as a rule (either
6894 -- that or we automatically trap overflow), and if there is an infinity
6895 -- generated and a range check is required, the check will fail anyway.
6898 pragma Assert
(Is_Floating_Point_Type
(Rtyp
));
6899 Etyp
:= Standard_Long_Long_Float
;
6900 Rent
:= RE_Exn_Long_Long_Float
;
6903 -- Common processing for integer cases and floating-point cases.
6904 -- If we are in the right type, we can call runtime routine directly
6907 and then Rtyp
/= Universal_Integer
6908 and then Rtyp
/= Universal_Real
6911 Make_Function_Call
(Loc
,
6912 Name
=> New_Reference_To
(RTE
(Rent
), Loc
),
6913 Parameter_Associations
=> New_List
(Base
, Exp
)));
6915 -- Otherwise we have to introduce conversions (conversions are also
6916 -- required in the universal cases, since the runtime routine is
6917 -- typed using one of the standard types).
6922 Make_Function_Call
(Loc
,
6923 Name
=> New_Reference_To
(RTE
(Rent
), Loc
),
6924 Parameter_Associations
=> New_List
(
6925 Convert_To
(Etyp
, Base
),
6929 Analyze_And_Resolve
(N
, Typ
);
6933 when RE_Not_Available
=>
6935 end Expand_N_Op_Expon
;
6937 --------------------
6938 -- Expand_N_Op_Ge --
6939 --------------------
6941 procedure Expand_N_Op_Ge
(N
: Node_Id
) is
6942 Typ
: constant Entity_Id
:= Etype
(N
);
6943 Op1
: constant Node_Id
:= Left_Opnd
(N
);
6944 Op2
: constant Node_Id
:= Right_Opnd
(N
);
6945 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
6948 Binary_Op_Validity_Checks
(N
);
6950 if Is_Array_Type
(Typ1
) then
6951 Expand_Array_Comparison
(N
);
6955 if Is_Boolean_Type
(Typ1
) then
6956 Adjust_Condition
(Op1
);
6957 Adjust_Condition
(Op2
);
6958 Set_Etype
(N
, Standard_Boolean
);
6959 Adjust_Result_Type
(N
, Typ
);
6962 Rewrite_Comparison
(N
);
6964 -- If we still have comparison, and Vax_Float type, process it
6966 if Vax_Float
(Typ1
) and then Nkind
(N
) in N_Op_Compare
then
6967 Expand_Vax_Comparison
(N
);
6971 Optimize_Length_Comparison
(N
);
6974 --------------------
6975 -- Expand_N_Op_Gt --
6976 --------------------
6978 procedure Expand_N_Op_Gt
(N
: Node_Id
) is
6979 Typ
: constant Entity_Id
:= Etype
(N
);
6980 Op1
: constant Node_Id
:= Left_Opnd
(N
);
6981 Op2
: constant Node_Id
:= Right_Opnd
(N
);
6982 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
6985 Binary_Op_Validity_Checks
(N
);
6987 if Is_Array_Type
(Typ1
) then
6988 Expand_Array_Comparison
(N
);
6992 if Is_Boolean_Type
(Typ1
) then
6993 Adjust_Condition
(Op1
);
6994 Adjust_Condition
(Op2
);
6995 Set_Etype
(N
, Standard_Boolean
);
6996 Adjust_Result_Type
(N
, Typ
);
6999 Rewrite_Comparison
(N
);
7001 -- If we still have comparison, and Vax_Float type, process it
7003 if Vax_Float
(Typ1
) and then Nkind
(N
) in N_Op_Compare
then
7004 Expand_Vax_Comparison
(N
);
7008 Optimize_Length_Comparison
(N
);
7011 --------------------
7012 -- Expand_N_Op_Le --
7013 --------------------
7015 procedure Expand_N_Op_Le
(N
: Node_Id
) is
7016 Typ
: constant Entity_Id
:= Etype
(N
);
7017 Op1
: constant Node_Id
:= Left_Opnd
(N
);
7018 Op2
: constant Node_Id
:= Right_Opnd
(N
);
7019 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
7022 Binary_Op_Validity_Checks
(N
);
7024 if Is_Array_Type
(Typ1
) then
7025 Expand_Array_Comparison
(N
);
7029 if Is_Boolean_Type
(Typ1
) then
7030 Adjust_Condition
(Op1
);
7031 Adjust_Condition
(Op2
);
7032 Set_Etype
(N
, Standard_Boolean
);
7033 Adjust_Result_Type
(N
, Typ
);
7036 Rewrite_Comparison
(N
);
7038 -- If we still have comparison, and Vax_Float type, process it
7040 if Vax_Float
(Typ1
) and then Nkind
(N
) in N_Op_Compare
then
7041 Expand_Vax_Comparison
(N
);
7045 Optimize_Length_Comparison
(N
);
7048 --------------------
7049 -- Expand_N_Op_Lt --
7050 --------------------
7052 procedure Expand_N_Op_Lt
(N
: Node_Id
) is
7053 Typ
: constant Entity_Id
:= Etype
(N
);
7054 Op1
: constant Node_Id
:= Left_Opnd
(N
);
7055 Op2
: constant Node_Id
:= Right_Opnd
(N
);
7056 Typ1
: constant Entity_Id
:= Base_Type
(Etype
(Op1
));
7059 Binary_Op_Validity_Checks
(N
);
7061 if Is_Array_Type
(Typ1
) then
7062 Expand_Array_Comparison
(N
);
7066 if Is_Boolean_Type
(Typ1
) then
7067 Adjust_Condition
(Op1
);
7068 Adjust_Condition
(Op2
);
7069 Set_Etype
(N
, Standard_Boolean
);
7070 Adjust_Result_Type
(N
, Typ
);
7073 Rewrite_Comparison
(N
);
7075 -- If we still have comparison, and Vax_Float type, process it
7077 if Vax_Float
(Typ1
) and then Nkind
(N
) in N_Op_Compare
then
7078 Expand_Vax_Comparison
(N
);
7082 Optimize_Length_Comparison
(N
);
7085 -----------------------
7086 -- Expand_N_Op_Minus --
7087 -----------------------
7089 procedure Expand_N_Op_Minus
(N
: Node_Id
) is
7090 Loc
: constant Source_Ptr
:= Sloc
(N
);
7091 Typ
: constant Entity_Id
:= Etype
(N
);
7094 Unary_Op_Validity_Checks
(N
);
7096 if not Backend_Overflow_Checks_On_Target
7097 and then Is_Signed_Integer_Type
(Etype
(N
))
7098 and then Do_Overflow_Check
(N
)
7100 -- Software overflow checking expands -expr into (0 - expr)
7103 Make_Op_Subtract
(Loc
,
7104 Left_Opnd
=> Make_Integer_Literal
(Loc
, 0),
7105 Right_Opnd
=> Right_Opnd
(N
)));
7107 Analyze_And_Resolve
(N
, Typ
);
7109 -- Vax floating-point types case
7111 elsif Vax_Float
(Etype
(N
)) then
7112 Expand_Vax_Arith
(N
);
7114 end Expand_N_Op_Minus
;
7116 ---------------------
7117 -- Expand_N_Op_Mod --
7118 ---------------------
7120 procedure Expand_N_Op_Mod
(N
: Node_Id
) is
7121 Loc
: constant Source_Ptr
:= Sloc
(N
);
7122 Typ
: constant Entity_Id
:= Etype
(N
);
7123 Left
: constant Node_Id
:= Left_Opnd
(N
);
7124 Right
: constant Node_Id
:= Right_Opnd
(N
);
7125 DOC
: constant Boolean := Do_Overflow_Check
(N
);
7126 DDC
: constant Boolean := Do_Division_Check
(N
);
7136 pragma Warnings
(Off
, Lhi
);
7139 Binary_Op_Validity_Checks
(N
);
7141 Determine_Range
(Right
, ROK
, Rlo
, Rhi
, Assume_Valid
=> True);
7142 Determine_Range
(Left
, LOK
, Llo
, Lhi
, Assume_Valid
=> True);
7144 -- Convert mod to rem if operands are known non-negative. We do this
7145 -- since it is quite likely that this will improve the quality of code,
7146 -- (the operation now corresponds to the hardware remainder), and it
7147 -- does not seem likely that it could be harmful.
7149 if LOK
and then Llo
>= 0
7151 ROK
and then Rlo
>= 0
7154 Make_Op_Rem
(Sloc
(N
),
7155 Left_Opnd
=> Left_Opnd
(N
),
7156 Right_Opnd
=> Right_Opnd
(N
)));
7158 -- Instead of reanalyzing the node we do the analysis manually. This
7159 -- avoids anomalies when the replacement is done in an instance and
7160 -- is epsilon more efficient.
7162 Set_Entity
(N
, Standard_Entity
(S_Op_Rem
));
7164 Set_Do_Overflow_Check
(N
, DOC
);
7165 Set_Do_Division_Check
(N
, DDC
);
7166 Expand_N_Op_Rem
(N
);
7169 -- Otherwise, normal mod processing
7172 if Is_Integer_Type
(Etype
(N
)) then
7173 Apply_Divide_Check
(N
);
7176 -- Apply optimization x mod 1 = 0. We don't really need that with
7177 -- gcc, but it is useful with other back ends (e.g. AAMP), and is
7178 -- certainly harmless.
7180 if Is_Integer_Type
(Etype
(N
))
7181 and then Compile_Time_Known_Value
(Right
)
7182 and then Expr_Value
(Right
) = Uint_1
7184 -- Call Remove_Side_Effects to ensure that any side effects in
7185 -- the ignored left operand (in particular function calls to
7186 -- user defined functions) are properly executed.
7188 Remove_Side_Effects
(Left
);
7190 Rewrite
(N
, Make_Integer_Literal
(Loc
, 0));
7191 Analyze_And_Resolve
(N
, Typ
);
7195 -- Deal with annoying case of largest negative number remainder
7196 -- minus one. Gigi does not handle this case correctly, because
7197 -- it generates a divide instruction which may trap in this case.
7199 -- In fact the check is quite easy, if the right operand is -1, then
7200 -- the mod value is always 0, and we can just ignore the left operand
7201 -- completely in this case.
7203 -- The operand type may be private (e.g. in the expansion of an
7204 -- intrinsic operation) so we must use the underlying type to get the
7205 -- bounds, and convert the literals explicitly.
7209 (Type_Low_Bound
(Base_Type
(Underlying_Type
(Etype
(Left
)))));
7211 if ((not ROK
) or else (Rlo
<= (-1) and then (-1) <= Rhi
))
7213 ((not LOK
) or else (Llo
= LLB
))
7216 Make_Conditional_Expression
(Loc
,
7217 Expressions
=> New_List
(
7219 Left_Opnd
=> Duplicate_Subexpr
(Right
),
7221 Unchecked_Convert_To
(Typ
,
7222 Make_Integer_Literal
(Loc
, -1))),
7223 Unchecked_Convert_To
(Typ
,
7224 Make_Integer_Literal
(Loc
, Uint_0
)),
7225 Relocate_Node
(N
))));
7227 Set_Analyzed
(Next
(Next
(First
(Expressions
(N
)))));
7228 Analyze_And_Resolve
(N
, Typ
);
7231 end Expand_N_Op_Mod
;
7233 --------------------------
7234 -- Expand_N_Op_Multiply --
7235 --------------------------
7237 procedure Expand_N_Op_Multiply
(N
: Node_Id
) is
7238 Loc
: constant Source_Ptr
:= Sloc
(N
);
7239 Lop
: constant Node_Id
:= Left_Opnd
(N
);
7240 Rop
: constant Node_Id
:= Right_Opnd
(N
);
7242 Lp2
: constant Boolean :=
7243 Nkind
(Lop
) = N_Op_Expon
7244 and then Is_Power_Of_2_For_Shift
(Lop
);
7246 Rp2
: constant Boolean :=
7247 Nkind
(Rop
) = N_Op_Expon
7248 and then Is_Power_Of_2_For_Shift
(Rop
);
7250 Ltyp
: constant Entity_Id
:= Etype
(Lop
);
7251 Rtyp
: constant Entity_Id
:= Etype
(Rop
);
7252 Typ
: Entity_Id
:= Etype
(N
);
7255 Binary_Op_Validity_Checks
(N
);
7257 -- Special optimizations for integer types
7259 if Is_Integer_Type
(Typ
) then
7261 -- N * 0 = 0 for integer types
7263 if Compile_Time_Known_Value
(Rop
)
7264 and then Expr_Value
(Rop
) = Uint_0
7266 -- Call Remove_Side_Effects to ensure that any side effects in
7267 -- the ignored left operand (in particular function calls to
7268 -- user defined functions) are properly executed.
7270 Remove_Side_Effects
(Lop
);
7272 Rewrite
(N
, Make_Integer_Literal
(Loc
, Uint_0
));
7273 Analyze_And_Resolve
(N
, Typ
);
7277 -- Similar handling for 0 * N = 0
7279 if Compile_Time_Known_Value
(Lop
)
7280 and then Expr_Value
(Lop
) = Uint_0
7282 Remove_Side_Effects
(Rop
);
7283 Rewrite
(N
, Make_Integer_Literal
(Loc
, Uint_0
));
7284 Analyze_And_Resolve
(N
, Typ
);
7288 -- N * 1 = 1 * N = N for integer types
7290 -- This optimisation is not done if we are going to
7291 -- rewrite the product 1 * 2 ** N to a shift.
7293 if Compile_Time_Known_Value
(Rop
)
7294 and then Expr_Value
(Rop
) = Uint_1
7300 elsif Compile_Time_Known_Value
(Lop
)
7301 and then Expr_Value
(Lop
) = Uint_1
7309 -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
7310 -- Is_Power_Of_2_For_Shift is set means that we know that our left
7311 -- operand is an integer, as required for this to work.
7316 -- Convert 2 ** A * 2 ** B into 2 ** (A + B)
7320 Left_Opnd
=> Make_Integer_Literal
(Loc
, 2),
7323 Left_Opnd
=> Right_Opnd
(Lop
),
7324 Right_Opnd
=> Right_Opnd
(Rop
))));
7325 Analyze_And_Resolve
(N
, Typ
);
7330 Make_Op_Shift_Left
(Loc
,
7333 Convert_To
(Standard_Natural
, Right_Opnd
(Rop
))));
7334 Analyze_And_Resolve
(N
, Typ
);
7338 -- Same processing for the operands the other way round
7342 Make_Op_Shift_Left
(Loc
,
7345 Convert_To
(Standard_Natural
, Right_Opnd
(Lop
))));
7346 Analyze_And_Resolve
(N
, Typ
);
7350 -- Do required fixup of universal fixed operation
7352 if Typ
= Universal_Fixed
then
7353 Fixup_Universal_Fixed_Operation
(N
);
7357 -- Multiplications with fixed-point results
7359 if Is_Fixed_Point_Type
(Typ
) then
7361 -- No special processing if Treat_Fixed_As_Integer is set, since from
7362 -- a semantic point of view such operations are simply integer
7363 -- operations and will be treated that way.
7365 if not Treat_Fixed_As_Integer
(N
) then
7367 -- Case of fixed * integer => fixed
7369 if Is_Integer_Type
(Rtyp
) then
7370 Expand_Multiply_Fixed_By_Integer_Giving_Fixed
(N
);
7372 -- Case of integer * fixed => fixed
7374 elsif Is_Integer_Type
(Ltyp
) then
7375 Expand_Multiply_Integer_By_Fixed_Giving_Fixed
(N
);
7377 -- Case of fixed * fixed => fixed
7380 Expand_Multiply_Fixed_By_Fixed_Giving_Fixed
(N
);
7384 -- Other cases of multiplication of fixed-point operands. Again we
7385 -- exclude the cases where Treat_Fixed_As_Integer flag is set.
7387 elsif (Is_Fixed_Point_Type
(Ltyp
) or else Is_Fixed_Point_Type
(Rtyp
))
7388 and then not Treat_Fixed_As_Integer
(N
)
7390 if Is_Integer_Type
(Typ
) then
7391 Expand_Multiply_Fixed_By_Fixed_Giving_Integer
(N
);
7393 pragma Assert
(Is_Floating_Point_Type
(Typ
));
7394 Expand_Multiply_Fixed_By_Fixed_Giving_Float
(N
);
7397 -- Mixed-mode operations can appear in a non-static universal context,
7398 -- in which case the integer argument must be converted explicitly.
7400 elsif Typ
= Universal_Real
7401 and then Is_Integer_Type
(Rtyp
)
7403 Rewrite
(Rop
, Convert_To
(Universal_Real
, Relocate_Node
(Rop
)));
7405 Analyze_And_Resolve
(Rop
, Universal_Real
);
7407 elsif Typ
= Universal_Real
7408 and then Is_Integer_Type
(Ltyp
)
7410 Rewrite
(Lop
, Convert_To
(Universal_Real
, Relocate_Node
(Lop
)));
7412 Analyze_And_Resolve
(Lop
, Universal_Real
);
7414 -- Non-fixed point cases, check software overflow checking required
7416 elsif Is_Signed_Integer_Type
(Etype
(N
)) then
7417 Apply_Arithmetic_Overflow_Check
(N
);
7419 -- Deal with VAX float case
7421 elsif Vax_Float
(Typ
) then
7422 Expand_Vax_Arith
(N
);
7425 end Expand_N_Op_Multiply
;
7427 --------------------
7428 -- Expand_N_Op_Ne --
7429 --------------------
7431 procedure Expand_N_Op_Ne
(N
: Node_Id
) is
7432 Typ
: constant Entity_Id
:= Etype
(Left_Opnd
(N
));
7435 -- Case of elementary type with standard operator
7437 if Is_Elementary_Type
(Typ
)
7438 and then Sloc
(Entity
(N
)) = Standard_Location
7440 Binary_Op_Validity_Checks
(N
);
7442 -- Boolean types (requiring handling of non-standard case)
7444 if Is_Boolean_Type
(Typ
) then
7445 Adjust_Condition
(Left_Opnd
(N
));
7446 Adjust_Condition
(Right_Opnd
(N
));
7447 Set_Etype
(N
, Standard_Boolean
);
7448 Adjust_Result_Type
(N
, Typ
);
7451 Rewrite_Comparison
(N
);
7453 -- If we still have comparison for Vax_Float, process it
7455 if Vax_Float
(Typ
) and then Nkind
(N
) in N_Op_Compare
then
7456 Expand_Vax_Comparison
(N
);
7460 -- For all cases other than elementary types, we rewrite node as the
7461 -- negation of an equality operation, and reanalyze. The equality to be
7462 -- used is defined in the same scope and has the same signature. This
7463 -- signature must be set explicitly since in an instance it may not have
7464 -- the same visibility as in the generic unit. This avoids duplicating
7465 -- or factoring the complex code for record/array equality tests etc.
7469 Loc
: constant Source_Ptr
:= Sloc
(N
);
7471 Ne
: constant Entity_Id
:= Entity
(N
);
7474 Binary_Op_Validity_Checks
(N
);
7480 Left_Opnd
=> Left_Opnd
(N
),
7481 Right_Opnd
=> Right_Opnd
(N
)));
7482 Set_Paren_Count
(Right_Opnd
(Neg
), 1);
7484 if Scope
(Ne
) /= Standard_Standard
then
7485 Set_Entity
(Right_Opnd
(Neg
), Corresponding_Equality
(Ne
));
7488 -- For navigation purposes, we want to treat the inequality as an
7489 -- implicit reference to the corresponding equality. Preserve the
7490 -- Comes_From_ source flag to generate proper Xref entries.
7492 Preserve_Comes_From_Source
(Neg
, N
);
7493 Preserve_Comes_From_Source
(Right_Opnd
(Neg
), N
);
7495 Analyze_And_Resolve
(N
, Standard_Boolean
);
7499 Optimize_Length_Comparison
(N
);
7502 ---------------------
7503 -- Expand_N_Op_Not --
7504 ---------------------
7506 -- If the argument is other than a Boolean array type, there is no special
7507 -- expansion required, except for VMS operations on signed integers.
7509 -- For the packed case, we call the special routine in Exp_Pakd, except
7510 -- that if the component size is greater than one, we use the standard
7511 -- routine generating a gruesome loop (it is so peculiar to have packed
7512 -- arrays with non-standard Boolean representations anyway, so it does not
7513 -- matter that we do not handle this case efficiently).
7515 -- For the unpacked case (and for the special packed case where we have non
7516 -- standard Booleans, as discussed above), we generate and insert into the
7517 -- tree the following function definition:
7519 -- function Nnnn (A : arr) is
7522 -- for J in a'range loop
7523 -- B (J) := not A (J);
7528 -- Here arr is the actual subtype of the parameter (and hence always
7529 -- constrained). Then we replace the not with a call to this function.
7531 procedure Expand_N_Op_Not
(N
: Node_Id
) is
7532 Loc
: constant Source_Ptr
:= Sloc
(N
);
7533 Typ
: constant Entity_Id
:= Etype
(N
);
7542 Func_Name
: Entity_Id
;
7543 Loop_Statement
: Node_Id
;
7546 Unary_Op_Validity_Checks
(N
);
7548 -- For boolean operand, deal with non-standard booleans
7550 if Is_Boolean_Type
(Typ
) then
7551 Adjust_Condition
(Right_Opnd
(N
));
7552 Set_Etype
(N
, Standard_Boolean
);
7553 Adjust_Result_Type
(N
, Typ
);
7557 -- For the VMS "not" on signed integer types, use conversion to and from
7558 -- a predefined modular type.
7560 if Is_VMS_Operator
(Entity
(N
)) then
7566 -- If this is a derived type, retrieve original VMS type so that
7567 -- the proper sized type is used for intermediate values.
7569 if Is_Derived_Type
(Typ
) then
7570 Rtyp
:= First_Subtype
(Etype
(Typ
));
7575 -- The proper unsigned type must have a size compatible with the
7576 -- operand, to prevent misalignment.
7578 if RM_Size
(Rtyp
) <= 8 then
7579 Utyp
:= RTE
(RE_Unsigned_8
);
7581 elsif RM_Size
(Rtyp
) <= 16 then
7582 Utyp
:= RTE
(RE_Unsigned_16
);
7584 elsif RM_Size
(Rtyp
) = RM_Size
(Standard_Unsigned
) then
7585 Utyp
:= RTE
(RE_Unsigned_32
);
7588 Utyp
:= RTE
(RE_Long_Long_Unsigned
);
7592 Unchecked_Convert_To
(Typ
,
7594 Unchecked_Convert_To
(Utyp
, Right_Opnd
(N
)))));
7595 Analyze_And_Resolve
(N
, Typ
);
7600 -- Only array types need any other processing
7602 if not Is_Array_Type
(Typ
) then
7606 -- Case of array operand. If bit packed with a component size of 1,
7607 -- handle it in Exp_Pakd if the operand is known to be aligned.
7609 if Is_Bit_Packed_Array
(Typ
)
7610 and then Component_Size
(Typ
) = 1
7611 and then not Is_Possibly_Unaligned_Object
(Right_Opnd
(N
))
7613 Expand_Packed_Not
(N
);
7617 -- Case of array operand which is not bit-packed. If the context is
7618 -- a safe assignment, call in-place operation, If context is a larger
7619 -- boolean expression in the context of a safe assignment, expansion is
7620 -- done by enclosing operation.
7622 Opnd
:= Relocate_Node
(Right_Opnd
(N
));
7623 Convert_To_Actual_Subtype
(Opnd
);
7624 Arr
:= Etype
(Opnd
);
7625 Ensure_Defined
(Arr
, N
);
7626 Silly_Boolean_Array_Not_Test
(N
, Arr
);
7628 if Nkind
(Parent
(N
)) = N_Assignment_Statement
then
7629 if Safe_In_Place_Array_Op
(Name
(Parent
(N
)), N
, Empty
) then
7630 Build_Boolean_Array_Proc_Call
(Parent
(N
), Opnd
, Empty
);
7633 -- Special case the negation of a binary operation
7635 elsif Nkind_In
(Opnd
, N_Op_And
, N_Op_Or
, N_Op_Xor
)
7636 and then Safe_In_Place_Array_Op
7637 (Name
(Parent
(N
)), Left_Opnd
(Opnd
), Right_Opnd
(Opnd
))
7639 Build_Boolean_Array_Proc_Call
(Parent
(N
), Opnd
, Empty
);
7643 elsif Nkind
(Parent
(N
)) in N_Binary_Op
7644 and then Nkind
(Parent
(Parent
(N
))) = N_Assignment_Statement
7647 Op1
: constant Node_Id
:= Left_Opnd
(Parent
(N
));
7648 Op2
: constant Node_Id
:= Right_Opnd
(Parent
(N
));
7649 Lhs
: constant Node_Id
:= Name
(Parent
(Parent
(N
)));
7652 if Safe_In_Place_Array_Op
(Lhs
, Op1
, Op2
) then
7654 -- (not A) op (not B) can be reduced to a single call
7656 if N
= Op1
and then Nkind
(Op2
) = N_Op_Not
then
7659 elsif N
= Op2
and then Nkind
(Op1
) = N_Op_Not
then
7662 -- A xor (not B) can also be special-cased
7664 elsif N
= Op2
and then Nkind
(Parent
(N
)) = N_Op_Xor
then
7671 A
:= Make_Defining_Identifier
(Loc
, Name_uA
);
7672 B
:= Make_Defining_Identifier
(Loc
, Name_uB
);
7673 J
:= Make_Defining_Identifier
(Loc
, Name_uJ
);
7676 Make_Indexed_Component
(Loc
,
7677 Prefix
=> New_Reference_To
(A
, Loc
),
7678 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
7681 Make_Indexed_Component
(Loc
,
7682 Prefix
=> New_Reference_To
(B
, Loc
),
7683 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
7686 Make_Implicit_Loop_Statement
(N
,
7687 Identifier
=> Empty
,
7690 Make_Iteration_Scheme
(Loc
,
7691 Loop_Parameter_Specification
=>
7692 Make_Loop_Parameter_Specification
(Loc
,
7693 Defining_Identifier
=> J
,
7694 Discrete_Subtype_Definition
=>
7695 Make_Attribute_Reference
(Loc
,
7696 Prefix
=> Make_Identifier
(Loc
, Chars
(A
)),
7697 Attribute_Name
=> Name_Range
))),
7699 Statements
=> New_List
(
7700 Make_Assignment_Statement
(Loc
,
7702 Expression
=> Make_Op_Not
(Loc
, A_J
))));
7704 Func_Name
:= Make_Temporary
(Loc
, 'N');
7705 Set_Is_Inlined
(Func_Name
);
7708 Make_Subprogram_Body
(Loc
,
7710 Make_Function_Specification
(Loc
,
7711 Defining_Unit_Name
=> Func_Name
,
7712 Parameter_Specifications
=> New_List
(
7713 Make_Parameter_Specification
(Loc
,
7714 Defining_Identifier
=> A
,
7715 Parameter_Type
=> New_Reference_To
(Typ
, Loc
))),
7716 Result_Definition
=> New_Reference_To
(Typ
, Loc
)),
7718 Declarations
=> New_List
(
7719 Make_Object_Declaration
(Loc
,
7720 Defining_Identifier
=> B
,
7721 Object_Definition
=> New_Reference_To
(Arr
, Loc
))),
7723 Handled_Statement_Sequence
=>
7724 Make_Handled_Sequence_Of_Statements
(Loc
,
7725 Statements
=> New_List
(
7727 Make_Simple_Return_Statement
(Loc
,
7728 Expression
=> Make_Identifier
(Loc
, Chars
(B
)))))));
7731 Make_Function_Call
(Loc
,
7732 Name
=> New_Reference_To
(Func_Name
, Loc
),
7733 Parameter_Associations
=> New_List
(Opnd
)));
7735 Analyze_And_Resolve
(N
, Typ
);
7736 end Expand_N_Op_Not
;
7738 --------------------
7739 -- Expand_N_Op_Or --
7740 --------------------
7742 procedure Expand_N_Op_Or
(N
: Node_Id
) is
7743 Typ
: constant Entity_Id
:= Etype
(N
);
7746 Binary_Op_Validity_Checks
(N
);
7748 if Is_Array_Type
(Etype
(N
)) then
7749 Expand_Boolean_Operator
(N
);
7751 elsif Is_Boolean_Type
(Etype
(N
)) then
7752 Adjust_Condition
(Left_Opnd
(N
));
7753 Adjust_Condition
(Right_Opnd
(N
));
7754 Set_Etype
(N
, Standard_Boolean
);
7755 Adjust_Result_Type
(N
, Typ
);
7757 elsif Is_Intrinsic_Subprogram
(Entity
(N
)) then
7758 Expand_Intrinsic_Call
(N
, Entity
(N
));
7763 ----------------------
7764 -- Expand_N_Op_Plus --
7765 ----------------------
7767 procedure Expand_N_Op_Plus
(N
: Node_Id
) is
7769 Unary_Op_Validity_Checks
(N
);
7770 end Expand_N_Op_Plus
;
7772 ---------------------
7773 -- Expand_N_Op_Rem --
7774 ---------------------
7776 procedure Expand_N_Op_Rem
(N
: Node_Id
) is
7777 Loc
: constant Source_Ptr
:= Sloc
(N
);
7778 Typ
: constant Entity_Id
:= Etype
(N
);
7780 Left
: constant Node_Id
:= Left_Opnd
(N
);
7781 Right
: constant Node_Id
:= Right_Opnd
(N
);
7789 -- Set if corresponding operand can be negative
7791 pragma Unreferenced
(Hi
);
7794 Binary_Op_Validity_Checks
(N
);
7796 if Is_Integer_Type
(Etype
(N
)) then
7797 Apply_Divide_Check
(N
);
7800 -- Apply optimization x rem 1 = 0. We don't really need that with gcc,
7801 -- but it is useful with other back ends (e.g. AAMP), and is certainly
7804 if Is_Integer_Type
(Etype
(N
))
7805 and then Compile_Time_Known_Value
(Right
)
7806 and then Expr_Value
(Right
) = Uint_1
7808 -- Call Remove_Side_Effects to ensure that any side effects in the
7809 -- ignored left operand (in particular function calls to user defined
7810 -- functions) are properly executed.
7812 Remove_Side_Effects
(Left
);
7814 Rewrite
(N
, Make_Integer_Literal
(Loc
, 0));
7815 Analyze_And_Resolve
(N
, Typ
);
7819 -- Deal with annoying case of largest negative number remainder minus
7820 -- one. Gigi does not handle this case correctly, because it generates
7821 -- a divide instruction which may trap in this case.
7823 -- In fact the check is quite easy, if the right operand is -1, then
7824 -- the remainder is always 0, and we can just ignore the left operand
7825 -- completely in this case.
7827 Determine_Range
(Right
, OK
, Lo
, Hi
, Assume_Valid
=> True);
7828 Lneg
:= (not OK
) or else Lo
< 0;
7830 Determine_Range
(Left
, OK
, Lo
, Hi
, Assume_Valid
=> True);
7831 Rneg
:= (not OK
) or else Lo
< 0;
7833 -- We won't mess with trying to find out if the left operand can really
7834 -- be the largest negative number (that's a pain in the case of private
7835 -- types and this is really marginal). We will just assume that we need
7836 -- the test if the left operand can be negative at all.
7838 if Lneg
and Rneg
then
7840 Make_Conditional_Expression
(Loc
,
7841 Expressions
=> New_List
(
7843 Left_Opnd
=> Duplicate_Subexpr
(Right
),
7845 Unchecked_Convert_To
(Typ
, Make_Integer_Literal
(Loc
, -1))),
7847 Unchecked_Convert_To
(Typ
,
7848 Make_Integer_Literal
(Loc
, Uint_0
)),
7850 Relocate_Node
(N
))));
7852 Set_Analyzed
(Next
(Next
(First
(Expressions
(N
)))));
7853 Analyze_And_Resolve
(N
, Typ
);
7855 end Expand_N_Op_Rem
;
7857 -----------------------------
7858 -- Expand_N_Op_Rotate_Left --
7859 -----------------------------
7861 procedure Expand_N_Op_Rotate_Left
(N
: Node_Id
) is
7863 Binary_Op_Validity_Checks
(N
);
7864 end Expand_N_Op_Rotate_Left
;
7866 ------------------------------
7867 -- Expand_N_Op_Rotate_Right --
7868 ------------------------------
7870 procedure Expand_N_Op_Rotate_Right
(N
: Node_Id
) is
7872 Binary_Op_Validity_Checks
(N
);
7873 end Expand_N_Op_Rotate_Right
;
7875 ----------------------------
7876 -- Expand_N_Op_Shift_Left --
7877 ----------------------------
7879 procedure Expand_N_Op_Shift_Left
(N
: Node_Id
) is
7881 Binary_Op_Validity_Checks
(N
);
7882 end Expand_N_Op_Shift_Left
;
7884 -----------------------------
7885 -- Expand_N_Op_Shift_Right --
7886 -----------------------------
7888 procedure Expand_N_Op_Shift_Right
(N
: Node_Id
) is
7890 Binary_Op_Validity_Checks
(N
);
7891 end Expand_N_Op_Shift_Right
;
7893 ----------------------------------------
7894 -- Expand_N_Op_Shift_Right_Arithmetic --
7895 ----------------------------------------
7897 procedure Expand_N_Op_Shift_Right_Arithmetic
(N
: Node_Id
) is
7899 Binary_Op_Validity_Checks
(N
);
7900 end Expand_N_Op_Shift_Right_Arithmetic
;
7902 --------------------------
7903 -- Expand_N_Op_Subtract --
7904 --------------------------
7906 procedure Expand_N_Op_Subtract
(N
: Node_Id
) is
7907 Typ
: constant Entity_Id
:= Etype
(N
);
7910 Binary_Op_Validity_Checks
(N
);
7912 -- N - 0 = N for integer types
7914 if Is_Integer_Type
(Typ
)
7915 and then Compile_Time_Known_Value
(Right_Opnd
(N
))
7916 and then Expr_Value
(Right_Opnd
(N
)) = 0
7918 Rewrite
(N
, Left_Opnd
(N
));
7922 -- Arithmetic overflow checks for signed integer/fixed point types
7924 if Is_Signed_Integer_Type
(Typ
)
7926 Is_Fixed_Point_Type
(Typ
)
7928 Apply_Arithmetic_Overflow_Check
(N
);
7930 -- VAX floating-point types case
7932 elsif Vax_Float
(Typ
) then
7933 Expand_Vax_Arith
(N
);
7935 end Expand_N_Op_Subtract
;
7937 ---------------------
7938 -- Expand_N_Op_Xor --
7939 ---------------------
7941 procedure Expand_N_Op_Xor
(N
: Node_Id
) is
7942 Typ
: constant Entity_Id
:= Etype
(N
);
7945 Binary_Op_Validity_Checks
(N
);
7947 if Is_Array_Type
(Etype
(N
)) then
7948 Expand_Boolean_Operator
(N
);
7950 elsif Is_Boolean_Type
(Etype
(N
)) then
7951 Adjust_Condition
(Left_Opnd
(N
));
7952 Adjust_Condition
(Right_Opnd
(N
));
7953 Set_Etype
(N
, Standard_Boolean
);
7954 Adjust_Result_Type
(N
, Typ
);
7956 elsif Is_Intrinsic_Subprogram
(Entity
(N
)) then
7957 Expand_Intrinsic_Call
(N
, Entity
(N
));
7960 end Expand_N_Op_Xor
;
7962 ----------------------
7963 -- Expand_N_Or_Else --
7964 ----------------------
7966 procedure Expand_N_Or_Else
(N
: Node_Id
)
7967 renames Expand_Short_Circuit_Operator
;
7969 -----------------------------------
7970 -- Expand_N_Qualified_Expression --
7971 -----------------------------------
7973 procedure Expand_N_Qualified_Expression
(N
: Node_Id
) is
7974 Operand
: constant Node_Id
:= Expression
(N
);
7975 Target_Type
: constant Entity_Id
:= Entity
(Subtype_Mark
(N
));
7978 -- Do validity check if validity checking operands
7980 if Validity_Checks_On
and then Validity_Check_Operands
then
7981 Ensure_Valid
(Operand
);
7984 -- Apply possible constraint check
7986 Apply_Constraint_Check
(Operand
, Target_Type
, No_Sliding
=> True);
7988 if Do_Range_Check
(Operand
) then
7989 Set_Do_Range_Check
(Operand
, False);
7990 Generate_Range_Check
(Operand
, Target_Type
, CE_Range_Check_Failed
);
7992 end Expand_N_Qualified_Expression
;
7994 ------------------------------------
7995 -- Expand_N_Quantified_Expression --
7996 ------------------------------------
8000 -- for all X in range => Cond
8005 -- for X in range loop
8012 -- Similarly, an existentially quantified expression:
8014 -- for some X in range => Cond
8019 -- for X in range loop
8026 -- In both cases, the iteration may be over a container in which case it is
8027 -- given by an iterator specification, not a loop parameter specification.
8029 procedure Expand_N_Quantified_Expression
(N
: Node_Id
) is
8030 Actions
: constant List_Id
:= New_List
;
8031 For_All
: constant Boolean := All_Present
(N
);
8032 Iter_Spec
: constant Node_Id
:= Iterator_Specification
(N
);
8033 Loc
: constant Source_Ptr
:= Sloc
(N
);
8034 Loop_Spec
: constant Node_Id
:= Loop_Parameter_Specification
(N
);
8041 -- Create the declaration of the flag which tracks the status of the
8042 -- quantified expression. Generate:
8044 -- Flag : Boolean := (True | False);
8046 Flag
:= Make_Temporary
(Loc
, 'T', N
);
8049 Make_Object_Declaration
(Loc
,
8050 Defining_Identifier
=> Flag
,
8051 Object_Definition
=> New_Occurrence_Of
(Standard_Boolean
, Loc
),
8053 New_Occurrence_Of
(Boolean_Literals
(For_All
), Loc
)));
8055 -- Construct the circuitry which tracks the status of the quantified
8056 -- expression. Generate:
8058 -- if [not] Cond then
8059 -- Flag := (False | True);
8063 Cond
:= Relocate_Node
(Condition
(N
));
8066 Cond
:= Make_Op_Not
(Loc
, Cond
);
8070 Make_Implicit_If_Statement
(N
,
8072 Then_Statements
=> New_List
(
8073 Make_Assignment_Statement
(Loc
,
8074 Name
=> New_Occurrence_Of
(Flag
, Loc
),
8076 New_Occurrence_Of
(Boolean_Literals
(not For_All
), Loc
)),
8077 Make_Exit_Statement
(Loc
))));
8079 -- Build the loop equivalent of the quantified expression
8081 if Present
(Iter_Spec
) then
8083 Make_Iteration_Scheme
(Loc
,
8084 Iterator_Specification
=> Iter_Spec
);
8087 Make_Iteration_Scheme
(Loc
,
8088 Loop_Parameter_Specification
=> Loop_Spec
);
8092 Make_Loop_Statement
(Loc
,
8093 Iteration_Scheme
=> Scheme
,
8094 Statements
=> Stmts
,
8095 End_Label
=> Empty
));
8097 -- Transform the quantified expression
8100 Make_Expression_With_Actions
(Loc
,
8101 Expression
=> New_Occurrence_Of
(Flag
, Loc
),
8102 Actions
=> Actions
));
8103 Analyze_And_Resolve
(N
, Standard_Boolean
);
8104 end Expand_N_Quantified_Expression
;
8106 ---------------------------------
8107 -- Expand_N_Selected_Component --
8108 ---------------------------------
8110 procedure Expand_N_Selected_Component
(N
: Node_Id
) is
8111 Loc
: constant Source_Ptr
:= Sloc
(N
);
8112 Par
: constant Node_Id
:= Parent
(N
);
8113 P
: constant Node_Id
:= Prefix
(N
);
8114 Ptyp
: Entity_Id
:= Underlying_Type
(Etype
(P
));
8120 function In_Left_Hand_Side
(Comp
: Node_Id
) return Boolean;
8121 -- Gigi needs a temporary for prefixes that depend on a discriminant,
8122 -- unless the context of an assignment can provide size information.
8123 -- Don't we have a general routine that does this???
8125 function Is_Subtype_Declaration
return Boolean;
8126 -- The replacement of a discriminant reference by its value is required
8127 -- if this is part of the initialization of an temporary generated by a
8128 -- change of representation. This shows up as the construction of a
8129 -- discriminant constraint for a subtype declared at the same point as
8130 -- the entity in the prefix of the selected component. We recognize this
8131 -- case when the context of the reference is:
8132 -- subtype ST is T(Obj.D);
8133 -- where the entity for Obj comes from source, and ST has the same sloc.
8135 -----------------------
8136 -- In_Left_Hand_Side --
8137 -----------------------
8139 function In_Left_Hand_Side
(Comp
: Node_Id
) return Boolean is
8141 return (Nkind
(Parent
(Comp
)) = N_Assignment_Statement
8142 and then Comp
= Name
(Parent
(Comp
)))
8143 or else (Present
(Parent
(Comp
))
8144 and then Nkind
(Parent
(Comp
)) in N_Subexpr
8145 and then In_Left_Hand_Side
(Parent
(Comp
)));
8146 end In_Left_Hand_Side
;
8148 -----------------------------
8149 -- Is_Subtype_Declaration --
8150 -----------------------------
8152 function Is_Subtype_Declaration
return Boolean is
8153 Par
: constant Node_Id
:= Parent
(N
);
8156 Nkind
(Par
) = N_Index_Or_Discriminant_Constraint
8157 and then Nkind
(Parent
(Parent
(Par
))) = N_Subtype_Declaration
8158 and then Comes_From_Source
(Entity
(Prefix
(N
)))
8159 and then Sloc
(Par
) = Sloc
(Entity
(Prefix
(N
)));
8160 end Is_Subtype_Declaration
;
8162 -- Start of processing for Expand_N_Selected_Component
8165 -- Insert explicit dereference if required
8167 if Is_Access_Type
(Ptyp
) then
8169 -- First set prefix type to proper access type, in case it currently
8170 -- has a private (non-access) view of this type.
8172 Set_Etype
(P
, Ptyp
);
8174 Insert_Explicit_Dereference
(P
);
8175 Analyze_And_Resolve
(P
, Designated_Type
(Ptyp
));
8177 if Ekind
(Etype
(P
)) = E_Private_Subtype
8178 and then Is_For_Access_Subtype
(Etype
(P
))
8180 Set_Etype
(P
, Base_Type
(Etype
(P
)));
8186 -- Deal with discriminant check required
8188 if Do_Discriminant_Check
(N
) then
8190 -- Present the discriminant checking function to the backend, so that
8191 -- it can inline the call to the function.
8194 (Discriminant_Checking_Func
8195 (Original_Record_Component
(Entity
(Selector_Name
(N
)))));
8197 -- Now reset the flag and generate the call
8199 Set_Do_Discriminant_Check
(N
, False);
8200 Generate_Discriminant_Check
(N
);
8203 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
8204 -- function, then additional actuals must be passed.
8206 if Ada_Version
>= Ada_2005
8207 and then Is_Build_In_Place_Function_Call
(P
)
8209 Make_Build_In_Place_Call_In_Anonymous_Context
(P
);
8212 -- Gigi cannot handle unchecked conversions that are the prefix of a
8213 -- selected component with discriminants. This must be checked during
8214 -- expansion, because during analysis the type of the selector is not
8215 -- known at the point the prefix is analyzed. If the conversion is the
8216 -- target of an assignment, then we cannot force the evaluation.
8218 if Nkind
(Prefix
(N
)) = N_Unchecked_Type_Conversion
8219 and then Has_Discriminants
(Etype
(N
))
8220 and then not In_Left_Hand_Side
(N
)
8222 Force_Evaluation
(Prefix
(N
));
8225 -- Remaining processing applies only if selector is a discriminant
8227 if Ekind
(Entity
(Selector_Name
(N
))) = E_Discriminant
then
8229 -- If the selector is a discriminant of a constrained record type,
8230 -- we may be able to rewrite the expression with the actual value
8231 -- of the discriminant, a useful optimization in some cases.
8233 if Is_Record_Type
(Ptyp
)
8234 and then Has_Discriminants
(Ptyp
)
8235 and then Is_Constrained
(Ptyp
)
8237 -- Do this optimization for discrete types only, and not for
8238 -- access types (access discriminants get us into trouble!)
8240 if not Is_Discrete_Type
(Etype
(N
)) then
8243 -- Don't do this on the left hand of an assignment statement.
8244 -- Normally one would think that references like this would not
8245 -- occur, but they do in generated code, and mean that we really
8246 -- do want to assign the discriminant!
8248 elsif Nkind
(Par
) = N_Assignment_Statement
8249 and then Name
(Par
) = N
8253 -- Don't do this optimization for the prefix of an attribute or
8254 -- the name of an object renaming declaration since these are
8255 -- contexts where we do not want the value anyway.
8257 elsif (Nkind
(Par
) = N_Attribute_Reference
8258 and then Prefix
(Par
) = N
)
8259 or else Is_Renamed_Object
(N
)
8263 -- Don't do this optimization if we are within the code for a
8264 -- discriminant check, since the whole point of such a check may
8265 -- be to verify the condition on which the code below depends!
8267 elsif Is_In_Discriminant_Check
(N
) then
8270 -- Green light to see if we can do the optimization. There is
8271 -- still one condition that inhibits the optimization below but
8272 -- now is the time to check the particular discriminant.
8275 -- Loop through discriminants to find the matching discriminant
8276 -- constraint to see if we can copy it.
8278 Disc
:= First_Discriminant
(Ptyp
);
8279 Dcon
:= First_Elmt
(Discriminant_Constraint
(Ptyp
));
8280 Discr_Loop
: while Present
(Dcon
) loop
8281 Dval
:= Node
(Dcon
);
8283 -- Check if this is the matching discriminant and if the
8284 -- discriminant value is simple enough to make sense to
8285 -- copy. We don't want to copy complex expressions, and
8286 -- indeed to do so can cause trouble (before we put in
8287 -- this guard, a discriminant expression containing an
8288 -- AND THEN was copied, causing problems for coverage
8291 -- However, if the reference is part of the initialization
8292 -- code generated for an object declaration, we must use
8293 -- the discriminant value from the subtype constraint,
8294 -- because the selected component may be a reference to the
8295 -- object being initialized, whose discriminant is not yet
8296 -- set. This only happens in complex cases involving changes
8297 -- or representation.
8299 if Disc
= Entity
(Selector_Name
(N
))
8300 and then (Is_Entity_Name
(Dval
)
8301 or else Compile_Time_Known_Value
(Dval
)
8302 or else Is_Subtype_Declaration
)
8304 -- Here we have the matching discriminant. Check for
8305 -- the case of a discriminant of a component that is
8306 -- constrained by an outer discriminant, which cannot
8307 -- be optimized away.
8309 if Denotes_Discriminant
8310 (Dval
, Check_Concurrent
=> True)
8314 elsif Nkind
(Original_Node
(Dval
)) = N_Selected_Component
8316 Denotes_Discriminant
8317 (Selector_Name
(Original_Node
(Dval
)), True)
8321 -- Do not retrieve value if constraint is not static. It
8322 -- is generally not useful, and the constraint may be a
8323 -- rewritten outer discriminant in which case it is in
8326 elsif Is_Entity_Name
(Dval
)
8327 and then Nkind
(Parent
(Entity
(Dval
))) =
8328 N_Object_Declaration
8329 and then Present
(Expression
(Parent
(Entity
(Dval
))))
8331 not Is_Static_Expression
8332 (Expression
(Parent
(Entity
(Dval
))))
8336 -- In the context of a case statement, the expression may
8337 -- have the base type of the discriminant, and we need to
8338 -- preserve the constraint to avoid spurious errors on
8341 elsif Nkind
(Parent
(N
)) = N_Case_Statement
8342 and then Etype
(Dval
) /= Etype
(Disc
)
8345 Make_Qualified_Expression
(Loc
,
8347 New_Occurrence_Of
(Etype
(Disc
), Loc
),
8349 New_Copy_Tree
(Dval
)));
8350 Analyze_And_Resolve
(N
, Etype
(Disc
));
8352 -- In case that comes out as a static expression,
8353 -- reset it (a selected component is never static).
8355 Set_Is_Static_Expression
(N
, False);
8358 -- Otherwise we can just copy the constraint, but the
8359 -- result is certainly not static! In some cases the
8360 -- discriminant constraint has been analyzed in the
8361 -- context of the original subtype indication, but for
8362 -- itypes the constraint might not have been analyzed
8363 -- yet, and this must be done now.
8366 Rewrite
(N
, New_Copy_Tree
(Dval
));
8367 Analyze_And_Resolve
(N
);
8368 Set_Is_Static_Expression
(N
, False);
8374 Next_Discriminant
(Disc
);
8375 end loop Discr_Loop
;
8377 -- Note: the above loop should always find a matching
8378 -- discriminant, but if it does not, we just missed an
8379 -- optimization due to some glitch (perhaps a previous
8380 -- error), so ignore.
8385 -- The only remaining processing is in the case of a discriminant of
8386 -- a concurrent object, where we rewrite the prefix to denote the
8387 -- corresponding record type. If the type is derived and has renamed
8388 -- discriminants, use corresponding discriminant, which is the one
8389 -- that appears in the corresponding record.
8391 if not Is_Concurrent_Type
(Ptyp
) then
8395 Disc
:= Entity
(Selector_Name
(N
));
8397 if Is_Derived_Type
(Ptyp
)
8398 and then Present
(Corresponding_Discriminant
(Disc
))
8400 Disc
:= Corresponding_Discriminant
(Disc
);
8404 Make_Selected_Component
(Loc
,
8406 Unchecked_Convert_To
(Corresponding_Record_Type
(Ptyp
),
8408 Selector_Name
=> Make_Identifier
(Loc
, Chars
(Disc
)));
8414 -- Set Atomic_Sync_Required if necessary for atomic component
8416 if Nkind
(N
) = N_Selected_Component
then
8418 E
: constant Entity_Id
:= Entity
(Selector_Name
(N
));
8422 -- If component is atomic, but type is not, setting depends on
8423 -- disable/enable state for the component.
8425 if Is_Atomic
(E
) and then not Is_Atomic
(Etype
(E
)) then
8426 Set
:= not Atomic_Synchronization_Disabled
(E
);
8428 -- If component is not atomic, but its type is atomic, setting
8429 -- depends on disable/enable state for the type.
8431 elsif not Is_Atomic
(E
) and then Is_Atomic
(Etype
(E
)) then
8432 Set
:= not Atomic_Synchronization_Disabled
(Etype
(E
));
8434 -- If both component and type are atomic, we disable if either
8435 -- component or its type have sync disabled.
8437 elsif Is_Atomic
(E
) and then Is_Atomic
(Etype
(E
)) then
8438 Set
:= (not Atomic_Synchronization_Disabled
(E
))
8440 (not Atomic_Synchronization_Disabled
(Etype
(E
)));
8446 -- Set flag if required
8449 Activate_Atomic_Synchronization
(N
);
8453 end Expand_N_Selected_Component
;
8455 --------------------
8456 -- Expand_N_Slice --
8457 --------------------
8459 procedure Expand_N_Slice
(N
: Node_Id
) is
8460 Loc
: constant Source_Ptr
:= Sloc
(N
);
8461 Typ
: constant Entity_Id
:= Etype
(N
);
8462 Pfx
: constant Node_Id
:= Prefix
(N
);
8463 Ptp
: Entity_Id
:= Etype
(Pfx
);
8465 function Is_Procedure_Actual
(N
: Node_Id
) return Boolean;
8466 -- Check whether the argument is an actual for a procedure call, in
8467 -- which case the expansion of a bit-packed slice is deferred until the
8468 -- call itself is expanded. The reason this is required is that we might
8469 -- have an IN OUT or OUT parameter, and the copy out is essential, and
8470 -- that copy out would be missed if we created a temporary here in
8471 -- Expand_N_Slice. Note that we don't bother to test specifically for an
8472 -- IN OUT or OUT mode parameter, since it is a bit tricky to do, and it
8473 -- is harmless to defer expansion in the IN case, since the call
8474 -- processing will still generate the appropriate copy in operation,
8475 -- which will take care of the slice.
8477 procedure Make_Temporary_For_Slice
;
8478 -- Create a named variable for the value of the slice, in cases where
8479 -- the back-end cannot handle it properly, e.g. when packed types or
8480 -- unaligned slices are involved.
8482 -------------------------
8483 -- Is_Procedure_Actual --
8484 -------------------------
8486 function Is_Procedure_Actual
(N
: Node_Id
) return Boolean is
8487 Par
: Node_Id
:= Parent
(N
);
8491 -- If our parent is a procedure call we can return
8493 if Nkind
(Par
) = N_Procedure_Call_Statement
then
8496 -- If our parent is a type conversion, keep climbing the tree,
8497 -- since a type conversion can be a procedure actual. Also keep
8498 -- climbing if parameter association or a qualified expression,
8499 -- since these are additional cases that do can appear on
8500 -- procedure actuals.
8502 elsif Nkind_In
(Par
, N_Type_Conversion
,
8503 N_Parameter_Association
,
8504 N_Qualified_Expression
)
8506 Par
:= Parent
(Par
);
8508 -- Any other case is not what we are looking for
8514 end Is_Procedure_Actual
;
8516 ------------------------------
8517 -- Make_Temporary_For_Slice --
8518 ------------------------------
8520 procedure Make_Temporary_For_Slice
is
8522 Ent
: constant Entity_Id
:= Make_Temporary
(Loc
, 'T', N
);
8526 Make_Object_Declaration
(Loc
,
8527 Defining_Identifier
=> Ent
,
8528 Object_Definition
=> New_Occurrence_Of
(Typ
, Loc
));
8530 Set_No_Initialization
(Decl
);
8532 Insert_Actions
(N
, New_List
(
8534 Make_Assignment_Statement
(Loc
,
8535 Name
=> New_Occurrence_Of
(Ent
, Loc
),
8536 Expression
=> Relocate_Node
(N
))));
8538 Rewrite
(N
, New_Occurrence_Of
(Ent
, Loc
));
8539 Analyze_And_Resolve
(N
, Typ
);
8540 end Make_Temporary_For_Slice
;
8542 -- Start of processing for Expand_N_Slice
8545 -- Special handling for access types
8547 if Is_Access_Type
(Ptp
) then
8549 Ptp
:= Designated_Type
(Ptp
);
8552 Make_Explicit_Dereference
(Sloc
(N
),
8553 Prefix
=> Relocate_Node
(Pfx
)));
8555 Analyze_And_Resolve
(Pfx
, Ptp
);
8558 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
8559 -- function, then additional actuals must be passed.
8561 if Ada_Version
>= Ada_2005
8562 and then Is_Build_In_Place_Function_Call
(Pfx
)
8564 Make_Build_In_Place_Call_In_Anonymous_Context
(Pfx
);
8567 -- The remaining case to be handled is packed slices. We can leave
8568 -- packed slices as they are in the following situations:
8570 -- 1. Right or left side of an assignment (we can handle this
8571 -- situation correctly in the assignment statement expansion).
8573 -- 2. Prefix of indexed component (the slide is optimized away in this
8574 -- case, see the start of Expand_N_Slice.)
8576 -- 3. Object renaming declaration, since we want the name of the
8577 -- slice, not the value.
8579 -- 4. Argument to procedure call, since copy-in/copy-out handling may
8580 -- be required, and this is handled in the expansion of call
8583 -- 5. Prefix of an address attribute (this is an error which is caught
8584 -- elsewhere, and the expansion would interfere with generating the
8587 if not Is_Packed
(Typ
) then
8589 -- Apply transformation for actuals of a function call, where
8590 -- Expand_Actuals is not used.
8592 if Nkind
(Parent
(N
)) = N_Function_Call
8593 and then Is_Possibly_Unaligned_Slice
(N
)
8595 Make_Temporary_For_Slice
;
8598 elsif Nkind
(Parent
(N
)) = N_Assignment_Statement
8599 or else (Nkind
(Parent
(Parent
(N
))) = N_Assignment_Statement
8600 and then Parent
(N
) = Name
(Parent
(Parent
(N
))))
8604 elsif Nkind
(Parent
(N
)) = N_Indexed_Component
8605 or else Is_Renamed_Object
(N
)
8606 or else Is_Procedure_Actual
(N
)
8610 elsif Nkind
(Parent
(N
)) = N_Attribute_Reference
8611 and then Attribute_Name
(Parent
(N
)) = Name_Address
8616 Make_Temporary_For_Slice
;
8620 ------------------------------
8621 -- Expand_N_Type_Conversion --
8622 ------------------------------
8624 procedure Expand_N_Type_Conversion
(N
: Node_Id
) is
8625 Loc
: constant Source_Ptr
:= Sloc
(N
);
8626 Operand
: constant Node_Id
:= Expression
(N
);
8627 Target_Type
: constant Entity_Id
:= Etype
(N
);
8628 Operand_Type
: Entity_Id
:= Etype
(Operand
);
8630 procedure Handle_Changed_Representation
;
8631 -- This is called in the case of record and array type conversions to
8632 -- see if there is a change of representation to be handled. Change of
8633 -- representation is actually handled at the assignment statement level,
8634 -- and what this procedure does is rewrite node N conversion as an
8635 -- assignment to temporary. If there is no change of representation,
8636 -- then the conversion node is unchanged.
8638 procedure Raise_Accessibility_Error
;
8639 -- Called when we know that an accessibility check will fail. Rewrites
8640 -- node N to an appropriate raise statement and outputs warning msgs.
8641 -- The Etype of the raise node is set to Target_Type.
8643 procedure Real_Range_Check
;
8644 -- Handles generation of range check for real target value
8646 function Has_Extra_Accessibility
(Id
: Entity_Id
) return Boolean;
8647 -- True iff Present (Effective_Extra_Accessibility (Id)) successfully
8648 -- evaluates to True.
8650 -----------------------------------
8651 -- Handle_Changed_Representation --
8652 -----------------------------------
8654 procedure Handle_Changed_Representation
is
8663 -- Nothing else to do if no change of representation
8665 if Same_Representation
(Operand_Type
, Target_Type
) then
8668 -- The real change of representation work is done by the assignment
8669 -- statement processing. So if this type conversion is appearing as
8670 -- the expression of an assignment statement, nothing needs to be
8671 -- done to the conversion.
8673 elsif Nkind
(Parent
(N
)) = N_Assignment_Statement
then
8676 -- Otherwise we need to generate a temporary variable, and do the
8677 -- change of representation assignment into that temporary variable.
8678 -- The conversion is then replaced by a reference to this variable.
8683 -- If type is unconstrained we have to add a constraint, copied
8684 -- from the actual value of the left hand side.
8686 if not Is_Constrained
(Target_Type
) then
8687 if Has_Discriminants
(Operand_Type
) then
8688 Disc
:= First_Discriminant
(Operand_Type
);
8690 if Disc
/= First_Stored_Discriminant
(Operand_Type
) then
8691 Disc
:= First_Stored_Discriminant
(Operand_Type
);
8695 while Present
(Disc
) loop
8697 Make_Selected_Component
(Loc
,
8699 Duplicate_Subexpr_Move_Checks
(Operand
),
8701 Make_Identifier
(Loc
, Chars
(Disc
))));
8702 Next_Discriminant
(Disc
);
8705 elsif Is_Array_Type
(Operand_Type
) then
8706 N_Ix
:= First_Index
(Target_Type
);
8709 for J
in 1 .. Number_Dimensions
(Operand_Type
) loop
8711 -- We convert the bounds explicitly. We use an unchecked
8712 -- conversion because bounds checks are done elsewhere.
8717 Unchecked_Convert_To
(Etype
(N_Ix
),
8718 Make_Attribute_Reference
(Loc
,
8720 Duplicate_Subexpr_No_Checks
8721 (Operand
, Name_Req
=> True),
8722 Attribute_Name
=> Name_First
,
8723 Expressions
=> New_List
(
8724 Make_Integer_Literal
(Loc
, J
)))),
8727 Unchecked_Convert_To
(Etype
(N_Ix
),
8728 Make_Attribute_Reference
(Loc
,
8730 Duplicate_Subexpr_No_Checks
8731 (Operand
, Name_Req
=> True),
8732 Attribute_Name
=> Name_Last
,
8733 Expressions
=> New_List
(
8734 Make_Integer_Literal
(Loc
, J
))))));
8741 Odef
:= New_Occurrence_Of
(Target_Type
, Loc
);
8743 if Present
(Cons
) then
8745 Make_Subtype_Indication
(Loc
,
8746 Subtype_Mark
=> Odef
,
8748 Make_Index_Or_Discriminant_Constraint
(Loc
,
8749 Constraints
=> Cons
));
8752 Temp
:= Make_Temporary
(Loc
, 'C');
8754 Make_Object_Declaration
(Loc
,
8755 Defining_Identifier
=> Temp
,
8756 Object_Definition
=> Odef
);
8758 Set_No_Initialization
(Decl
, True);
8760 -- Insert required actions. It is essential to suppress checks
8761 -- since we have suppressed default initialization, which means
8762 -- that the variable we create may have no discriminants.
8767 Make_Assignment_Statement
(Loc
,
8768 Name
=> New_Occurrence_Of
(Temp
, Loc
),
8769 Expression
=> Relocate_Node
(N
))),
8770 Suppress
=> All_Checks
);
8772 Rewrite
(N
, New_Occurrence_Of
(Temp
, Loc
));
8775 end Handle_Changed_Representation
;
8777 -------------------------------
8778 -- Raise_Accessibility_Error --
8779 -------------------------------
8781 procedure Raise_Accessibility_Error
is
8784 Make_Raise_Program_Error
(Sloc
(N
),
8785 Reason
=> PE_Accessibility_Check_Failed
));
8786 Set_Etype
(N
, Target_Type
);
8788 Error_Msg_N
("?accessibility check failure", N
);
8790 ("\?& will be raised at run time", N
, Standard_Program_Error
);
8791 end Raise_Accessibility_Error
;
8793 ----------------------
8794 -- Real_Range_Check --
8795 ----------------------
8797 -- Case of conversions to floating-point or fixed-point. If range checks
8798 -- are enabled and the target type has a range constraint, we convert:
8804 -- Tnn : typ'Base := typ'Base (x);
8805 -- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
8808 -- This is necessary when there is a conversion of integer to float or
8809 -- to fixed-point to ensure that the correct checks are made. It is not
8810 -- necessary for float to float where it is enough to simply set the
8811 -- Do_Range_Check flag.
8813 procedure Real_Range_Check
is
8814 Btyp
: constant Entity_Id
:= Base_Type
(Target_Type
);
8815 Lo
: constant Node_Id
:= Type_Low_Bound
(Target_Type
);
8816 Hi
: constant Node_Id
:= Type_High_Bound
(Target_Type
);
8817 Xtyp
: constant Entity_Id
:= Etype
(Operand
);
8822 -- Nothing to do if conversion was rewritten
8824 if Nkind
(N
) /= N_Type_Conversion
then
8828 -- Nothing to do if range checks suppressed, or target has the same
8829 -- range as the base type (or is the base type).
8831 if Range_Checks_Suppressed
(Target_Type
)
8832 or else (Lo
= Type_Low_Bound
(Btyp
)
8834 Hi
= Type_High_Bound
(Btyp
))
8839 -- Nothing to do if expression is an entity on which checks have been
8842 if Is_Entity_Name
(Operand
)
8843 and then Range_Checks_Suppressed
(Entity
(Operand
))
8848 -- Nothing to do if bounds are all static and we can tell that the
8849 -- expression is within the bounds of the target. Note that if the
8850 -- operand is of an unconstrained floating-point type, then we do
8851 -- not trust it to be in range (might be infinite)
8854 S_Lo
: constant Node_Id
:= Type_Low_Bound
(Xtyp
);
8855 S_Hi
: constant Node_Id
:= Type_High_Bound
(Xtyp
);
8858 if (not Is_Floating_Point_Type
(Xtyp
)
8859 or else Is_Constrained
(Xtyp
))
8860 and then Compile_Time_Known_Value
(S_Lo
)
8861 and then Compile_Time_Known_Value
(S_Hi
)
8862 and then Compile_Time_Known_Value
(Hi
)
8863 and then Compile_Time_Known_Value
(Lo
)
8866 D_Lov
: constant Ureal
:= Expr_Value_R
(Lo
);
8867 D_Hiv
: constant Ureal
:= Expr_Value_R
(Hi
);
8872 if Is_Real_Type
(Xtyp
) then
8873 S_Lov
:= Expr_Value_R
(S_Lo
);
8874 S_Hiv
:= Expr_Value_R
(S_Hi
);
8876 S_Lov
:= UR_From_Uint
(Expr_Value
(S_Lo
));
8877 S_Hiv
:= UR_From_Uint
(Expr_Value
(S_Hi
));
8881 and then S_Lov
>= D_Lov
8882 and then S_Hiv
<= D_Hiv
8884 Set_Do_Range_Check
(Operand
, False);
8891 -- For float to float conversions, we are done
8893 if Is_Floating_Point_Type
(Xtyp
)
8895 Is_Floating_Point_Type
(Btyp
)
8900 -- Otherwise rewrite the conversion as described above
8902 Conv
:= Relocate_Node
(N
);
8903 Rewrite
(Subtype_Mark
(Conv
), New_Occurrence_Of
(Btyp
, Loc
));
8904 Set_Etype
(Conv
, Btyp
);
8906 -- Enable overflow except for case of integer to float conversions,
8907 -- where it is never required, since we can never have overflow in
8910 if not Is_Integer_Type
(Etype
(Operand
)) then
8911 Enable_Overflow_Check
(Conv
);
8914 Tnn
:= Make_Temporary
(Loc
, 'T', Conv
);
8916 Insert_Actions
(N
, New_List
(
8917 Make_Object_Declaration
(Loc
,
8918 Defining_Identifier
=> Tnn
,
8919 Object_Definition
=> New_Occurrence_Of
(Btyp
, Loc
),
8920 Constant_Present
=> True,
8921 Expression
=> Conv
),
8923 Make_Raise_Constraint_Error
(Loc
,
8928 Left_Opnd
=> New_Occurrence_Of
(Tnn
, Loc
),
8930 Make_Attribute_Reference
(Loc
,
8931 Attribute_Name
=> Name_First
,
8933 New_Occurrence_Of
(Target_Type
, Loc
))),
8937 Left_Opnd
=> New_Occurrence_Of
(Tnn
, Loc
),
8939 Make_Attribute_Reference
(Loc
,
8940 Attribute_Name
=> Name_Last
,
8942 New_Occurrence_Of
(Target_Type
, Loc
)))),
8943 Reason
=> CE_Range_Check_Failed
)));
8945 Rewrite
(N
, New_Occurrence_Of
(Tnn
, Loc
));
8946 Analyze_And_Resolve
(N
, Btyp
);
8947 end Real_Range_Check
;
8949 -----------------------------
8950 -- Has_Extra_Accessibility --
8951 -----------------------------
8953 -- Returns true for a formal of an anonymous access type or for
8954 -- an Ada 2012-style stand-alone object of an anonymous access type.
8956 function Has_Extra_Accessibility
(Id
: Entity_Id
) return Boolean is
8958 if Is_Formal
(Id
) or else Ekind_In
(Id
, E_Constant
, E_Variable
) then
8959 return Present
(Effective_Extra_Accessibility
(Id
));
8963 end Has_Extra_Accessibility
;
8965 -- Start of processing for Expand_N_Type_Conversion
8968 -- Nothing at all to do if conversion is to the identical type so remove
8969 -- the conversion completely, it is useless, except that it may carry
8970 -- an Assignment_OK attribute, which must be propagated to the operand.
8972 if Operand_Type
= Target_Type
then
8973 if Assignment_OK
(N
) then
8974 Set_Assignment_OK
(Operand
);
8977 Rewrite
(N
, Relocate_Node
(Operand
));
8981 -- Nothing to do if this is the second argument of read. This is a
8982 -- "backwards" conversion that will be handled by the specialized code
8983 -- in attribute processing.
8985 if Nkind
(Parent
(N
)) = N_Attribute_Reference
8986 and then Attribute_Name
(Parent
(N
)) = Name_Read
8987 and then Next
(First
(Expressions
(Parent
(N
)))) = N
8992 -- Check for case of converting to a type that has an invariant
8993 -- associated with it. This required an invariant check. We convert
8999 -- do invariant_check (typ (expr)) in typ (expr);
9001 -- using Duplicate_Subexpr to avoid multiple side effects
9003 -- Note: the Comes_From_Source check, and then the resetting of this
9004 -- flag prevents what would otherwise be an infinite recursion.
9006 if Has_Invariants
(Target_Type
)
9007 and then Present
(Invariant_Procedure
(Target_Type
))
9008 and then Comes_From_Source
(N
)
9010 Set_Comes_From_Source
(N
, False);
9012 Make_Expression_With_Actions
(Loc
,
9013 Actions
=> New_List
(
9014 Make_Invariant_Call
(Duplicate_Subexpr
(N
))),
9015 Expression
=> Duplicate_Subexpr_No_Checks
(N
)));
9016 Analyze_And_Resolve
(N
, Target_Type
);
9020 -- Here if we may need to expand conversion
9022 -- If the operand of the type conversion is an arithmetic operation on
9023 -- signed integers, and the based type of the signed integer type in
9024 -- question is smaller than Standard.Integer, we promote both of the
9025 -- operands to type Integer.
9027 -- For example, if we have
9029 -- target-type (opnd1 + opnd2)
9031 -- and opnd1 and opnd2 are of type short integer, then we rewrite
9034 -- target-type (integer(opnd1) + integer(opnd2))
9036 -- We do this because we are always allowed to compute in a larger type
9037 -- if we do the right thing with the result, and in this case we are
9038 -- going to do a conversion which will do an appropriate check to make
9039 -- sure that things are in range of the target type in any case. This
9040 -- avoids some unnecessary intermediate overflows.
9042 -- We might consider a similar transformation in the case where the
9043 -- target is a real type or a 64-bit integer type, and the operand
9044 -- is an arithmetic operation using a 32-bit integer type. However,
9045 -- we do not bother with this case, because it could cause significant
9046 -- inefficiencies on 32-bit machines. On a 64-bit machine it would be
9047 -- much cheaper, but we don't want different behavior on 32-bit and
9048 -- 64-bit machines. Note that the exclusion of the 64-bit case also
9049 -- handles the configurable run-time cases where 64-bit arithmetic
9050 -- may simply be unavailable.
9052 -- Note: this circuit is partially redundant with respect to the circuit
9053 -- in Checks.Apply_Arithmetic_Overflow_Check, but we catch more cases in
9054 -- the processing here. Also we still need the Checks circuit, since we
9055 -- have to be sure not to generate junk overflow checks in the first
9056 -- place, since it would be trick to remove them here!
9058 if Integer_Promotion_Possible
(N
) then
9060 -- All conditions met, go ahead with transformation
9068 Make_Type_Conversion
(Loc
,
9069 Subtype_Mark
=> New_Reference_To
(Standard_Integer
, Loc
),
9070 Expression
=> Relocate_Node
(Right_Opnd
(Operand
)));
9072 Opnd
:= New_Op_Node
(Nkind
(Operand
), Loc
);
9073 Set_Right_Opnd
(Opnd
, R
);
9075 if Nkind
(Operand
) in N_Binary_Op
then
9077 Make_Type_Conversion
(Loc
,
9078 Subtype_Mark
=> New_Reference_To
(Standard_Integer
, Loc
),
9079 Expression
=> Relocate_Node
(Left_Opnd
(Operand
)));
9081 Set_Left_Opnd
(Opnd
, L
);
9085 Make_Type_Conversion
(Loc
,
9086 Subtype_Mark
=> Relocate_Node
(Subtype_Mark
(N
)),
9087 Expression
=> Opnd
));
9089 Analyze_And_Resolve
(N
, Target_Type
);
9094 -- Do validity check if validity checking operands
9096 if Validity_Checks_On
9097 and then Validity_Check_Operands
9099 Ensure_Valid
(Operand
);
9102 -- Special case of converting from non-standard boolean type
9104 if Is_Boolean_Type
(Operand_Type
)
9105 and then (Nonzero_Is_True
(Operand_Type
))
9107 Adjust_Condition
(Operand
);
9108 Set_Etype
(Operand
, Standard_Boolean
);
9109 Operand_Type
:= Standard_Boolean
;
9112 -- Case of converting to an access type
9114 if Is_Access_Type
(Target_Type
) then
9116 -- Apply an accessibility check when the conversion operand is an
9117 -- access parameter (or a renaming thereof), unless conversion was
9118 -- expanded from an Unchecked_ or Unrestricted_Access attribute.
9119 -- Note that other checks may still need to be applied below (such
9120 -- as tagged type checks).
9122 if Is_Entity_Name
(Operand
)
9123 and then Has_Extra_Accessibility
(Entity
(Operand
))
9124 and then Ekind
(Etype
(Operand
)) = E_Anonymous_Access_Type
9125 and then (Nkind
(Original_Node
(N
)) /= N_Attribute_Reference
9126 or else Attribute_Name
(Original_Node
(N
)) = Name_Access
)
9128 Apply_Accessibility_Check
9129 (Operand
, Target_Type
, Insert_Node
=> Operand
);
9131 -- If the level of the operand type is statically deeper than the
9132 -- level of the target type, then force Program_Error. Note that this
9133 -- can only occur for cases where the attribute is within the body of
9134 -- an instantiation (otherwise the conversion will already have been
9135 -- rejected as illegal). Note: warnings are issued by the analyzer
9136 -- for the instance cases.
9138 elsif In_Instance_Body
9139 and then Type_Access_Level
(Operand_Type
) >
9140 Type_Access_Level
(Target_Type
)
9142 Raise_Accessibility_Error
;
9144 -- When the operand is a selected access discriminant the check needs
9145 -- to be made against the level of the object denoted by the prefix
9146 -- of the selected name. Force Program_Error for this case as well
9147 -- (this accessibility violation can only happen if within the body
9148 -- of an instantiation).
9150 elsif In_Instance_Body
9151 and then Ekind
(Operand_Type
) = E_Anonymous_Access_Type
9152 and then Nkind
(Operand
) = N_Selected_Component
9153 and then Object_Access_Level
(Operand
) >
9154 Type_Access_Level
(Target_Type
)
9156 Raise_Accessibility_Error
;
9161 -- Case of conversions of tagged types and access to tagged types
9163 -- When needed, that is to say when the expression is class-wide, Add
9164 -- runtime a tag check for (strict) downward conversion by using the
9165 -- membership test, generating:
9167 -- [constraint_error when Operand not in Target_Type'Class]
9169 -- or in the access type case
9171 -- [constraint_error
9172 -- when Operand /= null
9173 -- and then Operand.all not in
9174 -- Designated_Type (Target_Type)'Class]
9176 if (Is_Access_Type
(Target_Type
)
9177 and then Is_Tagged_Type
(Designated_Type
(Target_Type
)))
9178 or else Is_Tagged_Type
(Target_Type
)
9180 -- Do not do any expansion in the access type case if the parent is a
9181 -- renaming, since this is an error situation which will be caught by
9182 -- Sem_Ch8, and the expansion can interfere with this error check.
9184 if Is_Access_Type
(Target_Type
) and then Is_Renamed_Object
(N
) then
9188 -- Otherwise, proceed with processing tagged conversion
9190 Tagged_Conversion
: declare
9191 Actual_Op_Typ
: Entity_Id
;
9192 Actual_Targ_Typ
: Entity_Id
;
9193 Make_Conversion
: Boolean := False;
9194 Root_Op_Typ
: Entity_Id
;
9196 procedure Make_Tag_Check
(Targ_Typ
: Entity_Id
);
9197 -- Create a membership check to test whether Operand is a member
9198 -- of Targ_Typ. If the original Target_Type is an access, include
9199 -- a test for null value. The check is inserted at N.
9201 --------------------
9202 -- Make_Tag_Check --
9203 --------------------
9205 procedure Make_Tag_Check
(Targ_Typ
: Entity_Id
) is
9210 -- [Constraint_Error
9211 -- when Operand /= null
9212 -- and then Operand.all not in Targ_Typ]
9214 if Is_Access_Type
(Target_Type
) then
9219 Left_Opnd
=> Duplicate_Subexpr_No_Checks
(Operand
),
9220 Right_Opnd
=> Make_Null
(Loc
)),
9225 Make_Explicit_Dereference
(Loc
,
9226 Prefix
=> Duplicate_Subexpr_No_Checks
(Operand
)),
9227 Right_Opnd
=> New_Reference_To
(Targ_Typ
, Loc
)));
9230 -- [Constraint_Error when Operand not in Targ_Typ]
9235 Left_Opnd
=> Duplicate_Subexpr_No_Checks
(Operand
),
9236 Right_Opnd
=> New_Reference_To
(Targ_Typ
, Loc
));
9240 Make_Raise_Constraint_Error
(Loc
,
9242 Reason
=> CE_Tag_Check_Failed
));
9245 -- Start of processing for Tagged_Conversion
9248 -- Handle entities from the limited view
9250 if Is_Access_Type
(Operand_Type
) then
9252 Available_View
(Designated_Type
(Operand_Type
));
9254 Actual_Op_Typ
:= Operand_Type
;
9257 if Is_Access_Type
(Target_Type
) then
9259 Available_View
(Designated_Type
(Target_Type
));
9261 Actual_Targ_Typ
:= Target_Type
;
9264 Root_Op_Typ
:= Root_Type
(Actual_Op_Typ
);
9266 -- Ada 2005 (AI-251): Handle interface type conversion
9268 if Is_Interface
(Actual_Op_Typ
) then
9269 Expand_Interface_Conversion
(N
, Is_Static
=> False);
9273 if not Tag_Checks_Suppressed
(Actual_Targ_Typ
) then
9275 -- Create a runtime tag check for a downward class-wide type
9278 if Is_Class_Wide_Type
(Actual_Op_Typ
)
9279 and then Actual_Op_Typ
/= Actual_Targ_Typ
9280 and then Root_Op_Typ
/= Actual_Targ_Typ
9281 and then Is_Ancestor
(Root_Op_Typ
, Actual_Targ_Typ
,
9282 Use_Full_View
=> True)
9284 Make_Tag_Check
(Class_Wide_Type
(Actual_Targ_Typ
));
9285 Make_Conversion
:= True;
9288 -- AI05-0073: If the result subtype of the function is defined
9289 -- by an access_definition designating a specific tagged type
9290 -- T, a check is made that the result value is null or the tag
9291 -- of the object designated by the result value identifies T.
9292 -- Constraint_Error is raised if this check fails.
9294 if Nkind
(Parent
(N
)) = Sinfo
.N_Return_Statement
then
9297 Func_Typ
: Entity_Id
;
9300 -- Climb scope stack looking for the enclosing function
9302 Func
:= Current_Scope
;
9303 while Present
(Func
)
9304 and then Ekind
(Func
) /= E_Function
9306 Func
:= Scope
(Func
);
9309 -- The function's return subtype must be defined using
9310 -- an access definition.
9312 if Nkind
(Result_Definition
(Parent
(Func
))) =
9315 Func_Typ
:= Directly_Designated_Type
(Etype
(Func
));
9317 -- The return subtype denotes a specific tagged type,
9318 -- in other words, a non class-wide type.
9320 if Is_Tagged_Type
(Func_Typ
)
9321 and then not Is_Class_Wide_Type
(Func_Typ
)
9323 Make_Tag_Check
(Actual_Targ_Typ
);
9324 Make_Conversion
:= True;
9330 -- We have generated a tag check for either a class-wide type
9331 -- conversion or for AI05-0073.
9333 if Make_Conversion
then
9338 Make_Unchecked_Type_Conversion
(Loc
,
9339 Subtype_Mark
=> New_Occurrence_Of
(Target_Type
, Loc
),
9340 Expression
=> Relocate_Node
(Expression
(N
)));
9342 Analyze_And_Resolve
(N
, Target_Type
);
9346 end Tagged_Conversion
;
9348 -- Case of other access type conversions
9350 elsif Is_Access_Type
(Target_Type
) then
9351 Apply_Constraint_Check
(Operand
, Target_Type
);
9353 -- Case of conversions from a fixed-point type
9355 -- These conversions require special expansion and processing, found in
9356 -- the Exp_Fixd package. We ignore cases where Conversion_OK is set,
9357 -- since from a semantic point of view, these are simple integer
9358 -- conversions, which do not need further processing.
9360 elsif Is_Fixed_Point_Type
(Operand_Type
)
9361 and then not Conversion_OK
(N
)
9363 -- We should never see universal fixed at this case, since the
9364 -- expansion of the constituent divide or multiply should have
9365 -- eliminated the explicit mention of universal fixed.
9367 pragma Assert
(Operand_Type
/= Universal_Fixed
);
9369 -- Check for special case of the conversion to universal real that
9370 -- occurs as a result of the use of a round attribute. In this case,
9371 -- the real type for the conversion is taken from the target type of
9372 -- the Round attribute and the result must be marked as rounded.
9374 if Target_Type
= Universal_Real
9375 and then Nkind
(Parent
(N
)) = N_Attribute_Reference
9376 and then Attribute_Name
(Parent
(N
)) = Name_Round
9378 Set_Rounded_Result
(N
);
9379 Set_Etype
(N
, Etype
(Parent
(N
)));
9382 -- Otherwise do correct fixed-conversion, but skip these if the
9383 -- Conversion_OK flag is set, because from a semantic point of view
9384 -- these are simple integer conversions needing no further processing
9385 -- (the backend will simply treat them as integers).
9387 if not Conversion_OK
(N
) then
9388 if Is_Fixed_Point_Type
(Etype
(N
)) then
9389 Expand_Convert_Fixed_To_Fixed
(N
);
9392 elsif Is_Integer_Type
(Etype
(N
)) then
9393 Expand_Convert_Fixed_To_Integer
(N
);
9396 pragma Assert
(Is_Floating_Point_Type
(Etype
(N
)));
9397 Expand_Convert_Fixed_To_Float
(N
);
9402 -- Case of conversions to a fixed-point type
9404 -- These conversions require special expansion and processing, found in
9405 -- the Exp_Fixd package. Again, ignore cases where Conversion_OK is set,
9406 -- since from a semantic point of view, these are simple integer
9407 -- conversions, which do not need further processing.
9409 elsif Is_Fixed_Point_Type
(Target_Type
)
9410 and then not Conversion_OK
(N
)
9412 if Is_Integer_Type
(Operand_Type
) then
9413 Expand_Convert_Integer_To_Fixed
(N
);
9416 pragma Assert
(Is_Floating_Point_Type
(Operand_Type
));
9417 Expand_Convert_Float_To_Fixed
(N
);
9421 -- Case of float-to-integer conversions
9423 -- We also handle float-to-fixed conversions with Conversion_OK set
9424 -- since semantically the fixed-point target is treated as though it
9425 -- were an integer in such cases.
9427 elsif Is_Floating_Point_Type
(Operand_Type
)
9429 (Is_Integer_Type
(Target_Type
)
9431 (Is_Fixed_Point_Type
(Target_Type
) and then Conversion_OK
(N
)))
9433 -- One more check here, gcc is still not able to do conversions of
9434 -- this type with proper overflow checking, and so gigi is doing an
9435 -- approximation of what is required by doing floating-point compares
9436 -- with the end-point. But that can lose precision in some cases, and
9437 -- give a wrong result. Converting the operand to Universal_Real is
9438 -- helpful, but still does not catch all cases with 64-bit integers
9439 -- on targets with only 64-bit floats.
9441 -- The above comment seems obsoleted by Apply_Float_Conversion_Check
9442 -- Can this code be removed ???
9444 if Do_Range_Check
(Operand
) then
9446 Make_Type_Conversion
(Loc
,
9448 New_Occurrence_Of
(Universal_Real
, Loc
),
9450 Relocate_Node
(Operand
)));
9452 Set_Etype
(Operand
, Universal_Real
);
9453 Enable_Range_Check
(Operand
);
9454 Set_Do_Range_Check
(Expression
(Operand
), False);
9457 -- Case of array conversions
9459 -- Expansion of array conversions, add required length/range checks but
9460 -- only do this if there is no change of representation. For handling of
9461 -- this case, see Handle_Changed_Representation.
9463 elsif Is_Array_Type
(Target_Type
) then
9464 if Is_Constrained
(Target_Type
) then
9465 Apply_Length_Check
(Operand
, Target_Type
);
9467 Apply_Range_Check
(Operand
, Target_Type
);
9470 Handle_Changed_Representation
;
9472 -- Case of conversions of discriminated types
9474 -- Add required discriminant checks if target is constrained. Again this
9475 -- change is skipped if we have a change of representation.
9477 elsif Has_Discriminants
(Target_Type
)
9478 and then Is_Constrained
(Target_Type
)
9480 Apply_Discriminant_Check
(Operand
, Target_Type
);
9481 Handle_Changed_Representation
;
9483 -- Case of all other record conversions. The only processing required
9484 -- is to check for a change of representation requiring the special
9485 -- assignment processing.
9487 elsif Is_Record_Type
(Target_Type
) then
9489 -- Ada 2005 (AI-216): Program_Error is raised when converting from
9490 -- a derived Unchecked_Union type to an unconstrained type that is
9491 -- not Unchecked_Union if the operand lacks inferable discriminants.
9493 if Is_Derived_Type
(Operand_Type
)
9494 and then Is_Unchecked_Union
(Base_Type
(Operand_Type
))
9495 and then not Is_Constrained
(Target_Type
)
9496 and then not Is_Unchecked_Union
(Base_Type
(Target_Type
))
9497 and then not Has_Inferable_Discriminants
(Operand
)
9499 -- To prevent Gigi from generating illegal code, we generate a
9500 -- Program_Error node, but we give it the target type of the
9504 PE
: constant Node_Id
:= Make_Raise_Program_Error
(Loc
,
9505 Reason
=> PE_Unchecked_Union_Restriction
);
9508 Set_Etype
(PE
, Target_Type
);
9513 Handle_Changed_Representation
;
9516 -- Case of conversions of enumeration types
9518 elsif Is_Enumeration_Type
(Target_Type
) then
9520 -- Special processing is required if there is a change of
9521 -- representation (from enumeration representation clauses).
9523 if not Same_Representation
(Target_Type
, Operand_Type
) then
9525 -- Convert: x(y) to x'val (ytyp'val (y))
9528 Make_Attribute_Reference
(Loc
,
9529 Prefix
=> New_Occurrence_Of
(Target_Type
, Loc
),
9530 Attribute_Name
=> Name_Val
,
9531 Expressions
=> New_List
(
9532 Make_Attribute_Reference
(Loc
,
9533 Prefix
=> New_Occurrence_Of
(Operand_Type
, Loc
),
9534 Attribute_Name
=> Name_Pos
,
9535 Expressions
=> New_List
(Operand
)))));
9537 Analyze_And_Resolve
(N
, Target_Type
);
9540 -- Case of conversions to floating-point
9542 elsif Is_Floating_Point_Type
(Target_Type
) then
9546 -- At this stage, either the conversion node has been transformed into
9547 -- some other equivalent expression, or left as a conversion that can be
9548 -- handled by Gigi, in the following cases:
9550 -- Conversions with no change of representation or type
9552 -- Numeric conversions involving integer, floating- and fixed-point
9553 -- values. Fixed-point values are allowed only if Conversion_OK is
9554 -- set, i.e. if the fixed-point values are to be treated as integers.
9556 -- No other conversions should be passed to Gigi
9558 -- Check: are these rules stated in sinfo??? if so, why restate here???
9560 -- The only remaining step is to generate a range check if we still have
9561 -- a type conversion at this stage and Do_Range_Check is set. For now we
9562 -- do this only for conversions of discrete types.
9564 if Nkind
(N
) = N_Type_Conversion
9565 and then Is_Discrete_Type
(Etype
(N
))
9568 Expr
: constant Node_Id
:= Expression
(N
);
9573 if Do_Range_Check
(Expr
)
9574 and then Is_Discrete_Type
(Etype
(Expr
))
9576 Set_Do_Range_Check
(Expr
, False);
9578 -- Before we do a range check, we have to deal with treating a
9579 -- fixed-point operand as an integer. The way we do this is
9580 -- simply to do an unchecked conversion to an appropriate
9581 -- integer type large enough to hold the result.
9583 -- This code is not active yet, because we are only dealing
9584 -- with discrete types so far ???
9586 if Nkind
(Expr
) in N_Has_Treat_Fixed_As_Integer
9587 and then Treat_Fixed_As_Integer
(Expr
)
9589 Ftyp
:= Base_Type
(Etype
(Expr
));
9591 if Esize
(Ftyp
) >= Esize
(Standard_Integer
) then
9592 Ityp
:= Standard_Long_Long_Integer
;
9594 Ityp
:= Standard_Integer
;
9597 Rewrite
(Expr
, Unchecked_Convert_To
(Ityp
, Expr
));
9600 -- Reset overflow flag, since the range check will include
9601 -- dealing with possible overflow, and generate the check. If
9602 -- Address is either a source type or target type, suppress
9603 -- range check to avoid typing anomalies when it is a visible
9606 Set_Do_Overflow_Check
(N
, False);
9607 if not Is_Descendent_Of_Address
(Etype
(Expr
))
9608 and then not Is_Descendent_Of_Address
(Target_Type
)
9610 Generate_Range_Check
9611 (Expr
, Target_Type
, CE_Range_Check_Failed
);
9617 -- Final step, if the result is a type conversion involving Vax_Float
9618 -- types, then it is subject for further special processing.
9620 if Nkind
(N
) = N_Type_Conversion
9621 and then (Vax_Float
(Operand_Type
) or else Vax_Float
(Target_Type
))
9623 Expand_Vax_Conversion
(N
);
9627 -- Here at end of processing
9630 -- Apply predicate check if required. Note that we can't just call
9631 -- Apply_Predicate_Check here, because the type looks right after
9632 -- the conversion and it would omit the check. The Comes_From_Source
9633 -- guard is necessary to prevent infinite recursions when we generate
9634 -- internal conversions for the purpose of checking predicates.
9636 if Present
(Predicate_Function
(Target_Type
))
9637 and then Target_Type
/= Operand_Type
9638 and then Comes_From_Source
(N
)
9641 New_Expr
: constant Node_Id
:= Duplicate_Subexpr
(N
);
9644 -- Avoid infinite recursion on the subsequent expansion of
9645 -- of the copy of the original type conversion.
9647 Set_Comes_From_Source
(New_Expr
, False);
9648 Insert_Action
(N
, Make_Predicate_Check
(Target_Type
, New_Expr
));
9651 end Expand_N_Type_Conversion
;
9653 -----------------------------------
9654 -- Expand_N_Unchecked_Expression --
9655 -----------------------------------
9657 -- Remove the unchecked expression node from the tree. Its job was simply
9658 -- to make sure that its constituent expression was handled with checks
9659 -- off, and now that that is done, we can remove it from the tree, and
9660 -- indeed must, since Gigi does not expect to see these nodes.
9662 procedure Expand_N_Unchecked_Expression
(N
: Node_Id
) is
9663 Exp
: constant Node_Id
:= Expression
(N
);
9665 Set_Assignment_OK
(Exp
, Assignment_OK
(N
) or else Assignment_OK
(Exp
));
9667 end Expand_N_Unchecked_Expression
;
9669 ----------------------------------------
9670 -- Expand_N_Unchecked_Type_Conversion --
9671 ----------------------------------------
9673 -- If this cannot be handled by Gigi and we haven't already made a
9674 -- temporary for it, do it now.
9676 procedure Expand_N_Unchecked_Type_Conversion
(N
: Node_Id
) is
9677 Target_Type
: constant Entity_Id
:= Etype
(N
);
9678 Operand
: constant Node_Id
:= Expression
(N
);
9679 Operand_Type
: constant Entity_Id
:= Etype
(Operand
);
9682 -- Nothing at all to do if conversion is to the identical type so remove
9683 -- the conversion completely, it is useless, except that it may carry
9684 -- an Assignment_OK indication which must be propagated to the operand.
9686 if Operand_Type
= Target_Type
then
9688 -- Code duplicates Expand_N_Unchecked_Expression above, factor???
9690 if Assignment_OK
(N
) then
9691 Set_Assignment_OK
(Operand
);
9694 Rewrite
(N
, Relocate_Node
(Operand
));
9698 -- If we have a conversion of a compile time known value to a target
9699 -- type and the value is in range of the target type, then we can simply
9700 -- replace the construct by an integer literal of the correct type. We
9701 -- only apply this to integer types being converted. Possibly it may
9702 -- apply in other cases, but it is too much trouble to worry about.
9704 -- Note that we do not do this transformation if the Kill_Range_Check
9705 -- flag is set, since then the value may be outside the expected range.
9706 -- This happens in the Normalize_Scalars case.
9708 -- We also skip this if either the target or operand type is biased
9709 -- because in this case, the unchecked conversion is supposed to
9710 -- preserve the bit pattern, not the integer value.
9712 if Is_Integer_Type
(Target_Type
)
9713 and then not Has_Biased_Representation
(Target_Type
)
9714 and then Is_Integer_Type
(Operand_Type
)
9715 and then not Has_Biased_Representation
(Operand_Type
)
9716 and then Compile_Time_Known_Value
(Operand
)
9717 and then not Kill_Range_Check
(N
)
9720 Val
: constant Uint
:= Expr_Value
(Operand
);
9723 if Compile_Time_Known_Value
(Type_Low_Bound
(Target_Type
))
9725 Compile_Time_Known_Value
(Type_High_Bound
(Target_Type
))
9727 Val
>= Expr_Value
(Type_Low_Bound
(Target_Type
))
9729 Val
<= Expr_Value
(Type_High_Bound
(Target_Type
))
9731 Rewrite
(N
, Make_Integer_Literal
(Sloc
(N
), Val
));
9733 -- If Address is the target type, just set the type to avoid a
9734 -- spurious type error on the literal when Address is a visible
9737 if Is_Descendent_Of_Address
(Target_Type
) then
9738 Set_Etype
(N
, Target_Type
);
9740 Analyze_And_Resolve
(N
, Target_Type
);
9748 -- Nothing to do if conversion is safe
9750 if Safe_Unchecked_Type_Conversion
(N
) then
9754 -- Otherwise force evaluation unless Assignment_OK flag is set (this
9755 -- flag indicates ??? -- more comments needed here)
9757 if Assignment_OK
(N
) then
9760 Force_Evaluation
(N
);
9762 end Expand_N_Unchecked_Type_Conversion
;
9764 ----------------------------
9765 -- Expand_Record_Equality --
9766 ----------------------------
9768 -- For non-variant records, Equality is expanded when needed into:
9770 -- and then Lhs.Discr1 = Rhs.Discr1
9772 -- and then Lhs.Discrn = Rhs.Discrn
9773 -- and then Lhs.Cmp1 = Rhs.Cmp1
9775 -- and then Lhs.Cmpn = Rhs.Cmpn
9777 -- The expression is folded by the back-end for adjacent fields. This
9778 -- function is called for tagged record in only one occasion: for imple-
9779 -- menting predefined primitive equality (see Predefined_Primitives_Bodies)
9780 -- otherwise the primitive "=" is used directly.
9782 function Expand_Record_Equality
9787 Bodies
: List_Id
) return Node_Id
9789 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
9794 First_Time
: Boolean := True;
9796 function Suitable_Element
(C
: Entity_Id
) return Entity_Id
;
9797 -- Return the first field to compare beginning with C, skipping the
9798 -- inherited components.
9800 ----------------------
9801 -- Suitable_Element --
9802 ----------------------
9804 function Suitable_Element
(C
: Entity_Id
) return Entity_Id
is
9809 elsif Ekind
(C
) /= E_Discriminant
9810 and then Ekind
(C
) /= E_Component
9812 return Suitable_Element
(Next_Entity
(C
));
9814 elsif Is_Tagged_Type
(Typ
)
9815 and then C
/= Original_Record_Component
(C
)
9817 return Suitable_Element
(Next_Entity
(C
));
9819 elsif Chars
(C
) = Name_uTag
then
9820 return Suitable_Element
(Next_Entity
(C
));
9822 -- The .NET/JVM version of type Root_Controlled contains two fields
9823 -- which should not be considered part of the object. To achieve
9824 -- proper equiality between two controlled objects on .NET/JVM, skip
9825 -- field _parent whenever it is of type Root_Controlled.
9827 elsif Chars
(C
) = Name_uParent
9828 and then VM_Target
/= No_VM
9829 and then Etype
(C
) = RTE
(RE_Root_Controlled
)
9831 return Suitable_Element
(Next_Entity
(C
));
9833 elsif Is_Interface
(Etype
(C
)) then
9834 return Suitable_Element
(Next_Entity
(C
));
9839 end Suitable_Element
;
9841 -- Start of processing for Expand_Record_Equality
9844 -- Generates the following code: (assuming that Typ has one Discr and
9845 -- component C2 is also a record)
9848 -- and then Lhs.Discr1 = Rhs.Discr1
9849 -- and then Lhs.C1 = Rhs.C1
9850 -- and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
9852 -- and then Lhs.Cmpn = Rhs.Cmpn
9854 Result
:= New_Reference_To
(Standard_True
, Loc
);
9855 C
:= Suitable_Element
(First_Entity
(Typ
));
9856 while Present
(C
) loop
9864 First_Time
:= False;
9868 New_Lhs
:= New_Copy_Tree
(Lhs
);
9869 New_Rhs
:= New_Copy_Tree
(Rhs
);
9873 Expand_Composite_Equality
(Nod
, Etype
(C
),
9875 Make_Selected_Component
(Loc
,
9877 Selector_Name
=> New_Reference_To
(C
, Loc
)),
9879 Make_Selected_Component
(Loc
,
9881 Selector_Name
=> New_Reference_To
(C
, Loc
)),
9884 -- If some (sub)component is an unchecked_union, the whole
9885 -- operation will raise program error.
9887 if Nkind
(Check
) = N_Raise_Program_Error
then
9889 Set_Etype
(Result
, Standard_Boolean
);
9894 Left_Opnd
=> Result
,
9895 Right_Opnd
=> Check
);
9899 C
:= Suitable_Element
(Next_Entity
(C
));
9903 end Expand_Record_Equality
;
9905 ---------------------------
9906 -- Expand_Set_Membership --
9907 ---------------------------
9909 procedure Expand_Set_Membership
(N
: Node_Id
) is
9910 Lop
: constant Node_Id
:= Left_Opnd
(N
);
9914 function Make_Cond
(Alt
: Node_Id
) return Node_Id
;
9915 -- If the alternative is a subtype mark, create a simple membership
9916 -- test. Otherwise create an equality test for it.
9922 function Make_Cond
(Alt
: Node_Id
) return Node_Id
is
9924 L
: constant Node_Id
:= New_Copy
(Lop
);
9925 R
: constant Node_Id
:= Relocate_Node
(Alt
);
9928 if (Is_Entity_Name
(Alt
) and then Is_Type
(Entity
(Alt
)))
9929 or else Nkind
(Alt
) = N_Range
9932 Make_In
(Sloc
(Alt
),
9937 Make_Op_Eq
(Sloc
(Alt
),
9945 -- Start of processing for Expand_Set_Membership
9948 Remove_Side_Effects
(Lop
);
9950 Alt
:= Last
(Alternatives
(N
));
9951 Res
:= Make_Cond
(Alt
);
9954 while Present
(Alt
) loop
9956 Make_Or_Else
(Sloc
(Alt
),
9957 Left_Opnd
=> Make_Cond
(Alt
),
9963 Analyze_And_Resolve
(N
, Standard_Boolean
);
9964 end Expand_Set_Membership
;
9966 -----------------------------------
9967 -- Expand_Short_Circuit_Operator --
9968 -----------------------------------
9970 -- Deal with special expansion if actions are present for the right operand
9971 -- and deal with optimizing case of arguments being True or False. We also
9972 -- deal with the special case of non-standard boolean values.
9974 procedure Expand_Short_Circuit_Operator
(N
: Node_Id
) is
9975 Loc
: constant Source_Ptr
:= Sloc
(N
);
9976 Typ
: constant Entity_Id
:= Etype
(N
);
9977 Left
: constant Node_Id
:= Left_Opnd
(N
);
9978 Right
: constant Node_Id
:= Right_Opnd
(N
);
9979 LocR
: constant Source_Ptr
:= Sloc
(Right
);
9982 Shortcut_Value
: constant Boolean := Nkind
(N
) = N_Or_Else
;
9983 Shortcut_Ent
: constant Entity_Id
:= Boolean_Literals
(Shortcut_Value
);
9984 -- If Left = Shortcut_Value then Right need not be evaluated
9986 function Make_Test_Expr
(Opnd
: Node_Id
) return Node_Id
;
9987 -- For Opnd a boolean expression, return a Boolean expression equivalent
9988 -- to Opnd /= Shortcut_Value.
9990 --------------------
9991 -- Make_Test_Expr --
9992 --------------------
9994 function Make_Test_Expr
(Opnd
: Node_Id
) return Node_Id
is
9996 if Shortcut_Value
then
9997 return Make_Op_Not
(Sloc
(Opnd
), Opnd
);
10001 end Make_Test_Expr
;
10003 Op_Var
: Entity_Id
;
10004 -- Entity for a temporary variable holding the value of the operator,
10005 -- used for expansion in the case where actions are present.
10007 -- Start of processing for Expand_Short_Circuit_Operator
10010 -- Deal with non-standard booleans
10012 if Is_Boolean_Type
(Typ
) then
10013 Adjust_Condition
(Left
);
10014 Adjust_Condition
(Right
);
10015 Set_Etype
(N
, Standard_Boolean
);
10018 -- Check for cases where left argument is known to be True or False
10020 if Compile_Time_Known_Value
(Left
) then
10022 -- Mark SCO for left condition as compile time known
10024 if Generate_SCO
and then Comes_From_Source
(Left
) then
10025 Set_SCO_Condition
(Left
, Expr_Value_E
(Left
) = Standard_True
);
10028 -- Rewrite True AND THEN Right / False OR ELSE Right to Right.
10029 -- Any actions associated with Right will be executed unconditionally
10030 -- and can thus be inserted into the tree unconditionally.
10032 if Expr_Value_E
(Left
) /= Shortcut_Ent
then
10033 if Present
(Actions
(N
)) then
10034 Insert_Actions
(N
, Actions
(N
));
10037 Rewrite
(N
, Right
);
10039 -- Rewrite False AND THEN Right / True OR ELSE Right to Left.
10040 -- In this case we can forget the actions associated with Right,
10041 -- since they will never be executed.
10044 Kill_Dead_Code
(Right
);
10045 Kill_Dead_Code
(Actions
(N
));
10046 Rewrite
(N
, New_Occurrence_Of
(Shortcut_Ent
, Loc
));
10049 Adjust_Result_Type
(N
, Typ
);
10053 -- If Actions are present for the right operand, we have to do some
10054 -- special processing. We can't just let these actions filter back into
10055 -- code preceding the short circuit (which is what would have happened
10056 -- if we had not trapped them in the short-circuit form), since they
10057 -- must only be executed if the right operand of the short circuit is
10058 -- executed and not otherwise.
10060 -- the temporary variable C.
10062 if Present
(Actions
(N
)) then
10063 Actlist
:= Actions
(N
);
10065 -- The old approach is to expand:
10067 -- left AND THEN right
10071 -- C : Boolean := False;
10079 -- and finally rewrite the operator into a reference to C. Similarly
10080 -- for left OR ELSE right, with negated values. Note that this
10081 -- rewrite causes some difficulties for coverage analysis because
10082 -- of the introduction of the new variable C, which obscures the
10083 -- structure of the test.
10085 -- We use this "old approach" if use of N_Expression_With_Actions
10086 -- is False (see description in Opt of when this is or is not set).
10088 if not Use_Expression_With_Actions
then
10089 Op_Var
:= Make_Temporary
(Loc
, 'C', Related_Node
=> N
);
10092 Make_Object_Declaration
(Loc
,
10093 Defining_Identifier
=>
10095 Object_Definition
=>
10096 New_Occurrence_Of
(Standard_Boolean
, Loc
),
10098 New_Occurrence_Of
(Shortcut_Ent
, Loc
)));
10100 Append_To
(Actlist
,
10101 Make_Implicit_If_Statement
(Right
,
10102 Condition
=> Make_Test_Expr
(Right
),
10103 Then_Statements
=> New_List
(
10104 Make_Assignment_Statement
(LocR
,
10105 Name
=> New_Occurrence_Of
(Op_Var
, LocR
),
10108 (Boolean_Literals
(not Shortcut_Value
), LocR
)))));
10111 Make_Implicit_If_Statement
(Left
,
10112 Condition
=> Make_Test_Expr
(Left
),
10113 Then_Statements
=> Actlist
));
10115 Rewrite
(N
, New_Occurrence_Of
(Op_Var
, Loc
));
10116 Analyze_And_Resolve
(N
, Standard_Boolean
);
10118 -- The new approach, activated for now by the use of debug flag
10119 -- -gnatd.X is to use the new Expression_With_Actions node for the
10120 -- right operand of the short-circuit form. This should solve the
10121 -- traceability problems for coverage analysis.
10125 Make_Expression_With_Actions
(LocR
,
10126 Expression
=> Relocate_Node
(Right
),
10127 Actions
=> Actlist
));
10128 Set_Actions
(N
, No_List
);
10129 Analyze_And_Resolve
(Right
, Standard_Boolean
);
10132 Adjust_Result_Type
(N
, Typ
);
10136 -- No actions present, check for cases of right argument True/False
10138 if Compile_Time_Known_Value
(Right
) then
10140 -- Mark SCO for left condition as compile time known
10142 if Generate_SCO
and then Comes_From_Source
(Right
) then
10143 Set_SCO_Condition
(Right
, Expr_Value_E
(Right
) = Standard_True
);
10146 -- Change (Left and then True), (Left or else False) to Left.
10147 -- Note that we know there are no actions associated with the right
10148 -- operand, since we just checked for this case above.
10150 if Expr_Value_E
(Right
) /= Shortcut_Ent
then
10153 -- Change (Left and then False), (Left or else True) to Right,
10154 -- making sure to preserve any side effects associated with the Left
10158 Remove_Side_Effects
(Left
);
10159 Rewrite
(N
, New_Occurrence_Of
(Shortcut_Ent
, Loc
));
10163 Adjust_Result_Type
(N
, Typ
);
10164 end Expand_Short_Circuit_Operator
;
10166 -------------------------------------
10167 -- Fixup_Universal_Fixed_Operation --
10168 -------------------------------------
10170 procedure Fixup_Universal_Fixed_Operation
(N
: Node_Id
) is
10171 Conv
: constant Node_Id
:= Parent
(N
);
10174 -- We must have a type conversion immediately above us
10176 pragma Assert
(Nkind
(Conv
) = N_Type_Conversion
);
10178 -- Normally the type conversion gives our target type. The exception
10179 -- occurs in the case of the Round attribute, where the conversion
10180 -- will be to universal real, and our real type comes from the Round
10181 -- attribute (as well as an indication that we must round the result)
10183 if Nkind
(Parent
(Conv
)) = N_Attribute_Reference
10184 and then Attribute_Name
(Parent
(Conv
)) = Name_Round
10186 Set_Etype
(N
, Etype
(Parent
(Conv
)));
10187 Set_Rounded_Result
(N
);
10189 -- Normal case where type comes from conversion above us
10192 Set_Etype
(N
, Etype
(Conv
));
10194 end Fixup_Universal_Fixed_Operation
;
10196 ---------------------------------
10197 -- Has_Inferable_Discriminants --
10198 ---------------------------------
10200 function Has_Inferable_Discriminants
(N
: Node_Id
) return Boolean is
10202 function Prefix_Is_Formal_Parameter
(N
: Node_Id
) return Boolean;
10203 -- Determines whether the left-most prefix of a selected component is a
10204 -- formal parameter in a subprogram. Assumes N is a selected component.
10206 --------------------------------
10207 -- Prefix_Is_Formal_Parameter --
10208 --------------------------------
10210 function Prefix_Is_Formal_Parameter
(N
: Node_Id
) return Boolean is
10211 Sel_Comp
: Node_Id
;
10214 -- Move to the left-most prefix by climbing up the tree
10217 while Present
(Parent
(Sel_Comp
))
10218 and then Nkind
(Parent
(Sel_Comp
)) = N_Selected_Component
10220 Sel_Comp
:= Parent
(Sel_Comp
);
10223 return Ekind
(Entity
(Prefix
(Sel_Comp
))) in Formal_Kind
;
10224 end Prefix_Is_Formal_Parameter
;
10226 -- Start of processing for Has_Inferable_Discriminants
10229 -- For selected components, the subtype of the selector must be a
10230 -- constrained Unchecked_Union. If the component is subject to a
10231 -- per-object constraint, then the enclosing object must have inferable
10234 if Nkind
(N
) = N_Selected_Component
then
10235 if Has_Per_Object_Constraint
(Entity
(Selector_Name
(N
))) then
10237 -- A small hack. If we have a per-object constrained selected
10238 -- component of a formal parameter, return True since we do not
10239 -- know the actual parameter association yet.
10241 if Prefix_Is_Formal_Parameter
(N
) then
10244 -- Otherwise, check the enclosing object and the selector
10247 return Has_Inferable_Discriminants
(Prefix
(N
))
10248 and then Has_Inferable_Discriminants
(Selector_Name
(N
));
10251 -- The call to Has_Inferable_Discriminants will determine whether
10252 -- the selector has a constrained Unchecked_Union nominal type.
10255 return Has_Inferable_Discriminants
(Selector_Name
(N
));
10258 -- A qualified expression has inferable discriminants if its subtype
10259 -- mark is a constrained Unchecked_Union subtype.
10261 elsif Nkind
(N
) = N_Qualified_Expression
then
10262 return Is_Unchecked_Union
(Etype
(Subtype_Mark
(N
)))
10263 and then Is_Constrained
(Etype
(Subtype_Mark
(N
)));
10265 -- For all other names, it is sufficient to have a constrained
10266 -- Unchecked_Union nominal subtype.
10269 return Is_Unchecked_Union
(Base_Type
(Etype
(N
)))
10270 and then Is_Constrained
(Etype
(N
));
10272 end Has_Inferable_Discriminants
;
10274 -------------------------------
10275 -- Insert_Dereference_Action --
10276 -------------------------------
10278 procedure Insert_Dereference_Action
(N
: Node_Id
) is
10280 function Is_Checked_Storage_Pool
(P
: Entity_Id
) return Boolean;
10281 -- Return true if type of P is derived from Checked_Pool;
10283 -----------------------------
10284 -- Is_Checked_Storage_Pool --
10285 -----------------------------
10287 function Is_Checked_Storage_Pool
(P
: Entity_Id
) return Boolean is
10296 while T
/= Etype
(T
) loop
10297 if Is_RTE
(T
, RE_Checked_Pool
) then
10305 end Is_Checked_Storage_Pool
;
10309 Typ
: constant Entity_Id
:= Etype
(N
);
10310 Desig
: constant Entity_Id
:= Available_View
(Designated_Type
(Typ
));
10311 Loc
: constant Source_Ptr
:= Sloc
(N
);
10312 Pool
: constant Entity_Id
:= Associated_Storage_Pool
(Typ
);
10313 Pnod
: constant Node_Id
:= Parent
(N
);
10321 -- Start of processing for Insert_Dereference_Action
10324 pragma Assert
(Nkind
(Pnod
) = N_Explicit_Dereference
);
10326 -- Do not re-expand a dereference which has already been processed by
10329 if Has_Dereference_Action
(Pnod
) then
10332 -- Do not perform this type of expansion for internally-generated
10335 elsif not Comes_From_Source
(Original_Node
(Pnod
)) then
10338 -- A dereference action is only applicable to objects which have been
10339 -- allocated on a checked pool.
10341 elsif not Is_Checked_Storage_Pool
(Pool
) then
10345 -- Extract the address of the dereferenced object. Generate:
10347 -- Addr : System.Address := <N>'Pool_Address;
10349 Addr
:= Make_Temporary
(Loc
, 'P');
10352 Make_Object_Declaration
(Loc
,
10353 Defining_Identifier
=> Addr
,
10354 Object_Definition
=>
10355 New_Reference_To
(RTE
(RE_Address
), Loc
),
10357 Make_Attribute_Reference
(Loc
,
10358 Prefix
=> Duplicate_Subexpr_Move_Checks
(N
),
10359 Attribute_Name
=> Name_Pool_Address
)));
10361 -- Calculate the size of the dereferenced object. Generate:
10363 -- Size : Storage_Count := <N>.all'Size / Storage_Unit;
10366 Make_Explicit_Dereference
(Loc
,
10367 Prefix
=> Duplicate_Subexpr_Move_Checks
(N
));
10368 Set_Has_Dereference_Action
(Deref
);
10370 Size
:= Make_Temporary
(Loc
, 'S');
10373 Make_Object_Declaration
(Loc
,
10374 Defining_Identifier
=> Size
,
10376 Object_Definition
=>
10377 New_Reference_To
(RTE
(RE_Storage_Count
), Loc
),
10380 Make_Op_Divide
(Loc
,
10382 Make_Attribute_Reference
(Loc
,
10384 Attribute_Name
=> Name_Size
),
10386 Make_Integer_Literal
(Loc
, System_Storage_Unit
))));
10388 -- Calculate the alignment of the dereferenced object. Generate:
10389 -- Alig : constant Storage_Count := <N>.all'Alignment;
10392 Make_Explicit_Dereference
(Loc
,
10393 Prefix
=> Duplicate_Subexpr_Move_Checks
(N
));
10394 Set_Has_Dereference_Action
(Deref
);
10396 Alig
:= Make_Temporary
(Loc
, 'A');
10399 Make_Object_Declaration
(Loc
,
10400 Defining_Identifier
=> Alig
,
10401 Object_Definition
=>
10402 New_Reference_To
(RTE
(RE_Storage_Count
), Loc
),
10404 Make_Attribute_Reference
(Loc
,
10406 Attribute_Name
=> Name_Alignment
)));
10408 -- A dereference of a controlled object requires special processing. The
10409 -- finalization machinery requests additional space from the underlying
10410 -- pool to allocate and hide two pointers. As a result, a checked pool
10411 -- may mark the wrong memory as valid. Since checked pools do not have
10412 -- knowledge of hidden pointers, we have to bring the two pointers back
10413 -- in view in order to restore the original state of the object.
10415 if Needs_Finalization
(Desig
) then
10417 -- Adjust the address and size of the dereferenced object. Generate:
10418 -- Adjust_Controlled_Dereference (Addr, Size, Alig);
10421 Make_Procedure_Call_Statement
(Loc
,
10423 New_Reference_To
(RTE
(RE_Adjust_Controlled_Dereference
), Loc
),
10424 Parameter_Associations
=> New_List
(
10425 New_Reference_To
(Addr
, Loc
),
10426 New_Reference_To
(Size
, Loc
),
10427 New_Reference_To
(Alig
, Loc
)));
10429 -- Class-wide types complicate things because we cannot determine
10430 -- statically whether the actual object is truly controlled. We must
10431 -- generate a runtime check to detect this property. Generate:
10433 -- if Needs_Finalization (<N>.all'Tag) then
10437 if Is_Class_Wide_Type
(Desig
) then
10439 Make_Explicit_Dereference
(Loc
,
10440 Prefix
=> Duplicate_Subexpr_Move_Checks
(N
));
10441 Set_Has_Dereference_Action
(Deref
);
10444 Make_If_Statement
(Loc
,
10446 Make_Function_Call
(Loc
,
10448 New_Reference_To
(RTE
(RE_Needs_Finalization
), Loc
),
10449 Parameter_Associations
=> New_List
(
10450 Make_Attribute_Reference
(Loc
,
10452 Attribute_Name
=> Name_Tag
))),
10453 Then_Statements
=> New_List
(Stmt
));
10456 Insert_Action
(N
, Stmt
);
10460 -- Dereference (Pool, Addr, Size, Alig);
10463 Make_Procedure_Call_Statement
(Loc
,
10466 (Find_Prim_Op
(Etype
(Pool
), Name_Dereference
), Loc
),
10467 Parameter_Associations
=> New_List
(
10468 New_Reference_To
(Pool
, Loc
),
10469 New_Reference_To
(Addr
, Loc
),
10470 New_Reference_To
(Size
, Loc
),
10471 New_Reference_To
(Alig
, Loc
))));
10473 -- Mark the explicit dereference as processed to avoid potential
10474 -- infinite expansion.
10476 Set_Has_Dereference_Action
(Pnod
);
10479 when RE_Not_Available
=>
10481 end Insert_Dereference_Action
;
10483 --------------------------------
10484 -- Integer_Promotion_Possible --
10485 --------------------------------
10487 function Integer_Promotion_Possible
(N
: Node_Id
) return Boolean is
10488 Operand
: constant Node_Id
:= Expression
(N
);
10489 Operand_Type
: constant Entity_Id
:= Etype
(Operand
);
10490 Root_Operand_Type
: constant Entity_Id
:= Root_Type
(Operand_Type
);
10493 pragma Assert
(Nkind
(N
) = N_Type_Conversion
);
10497 -- We only do the transformation for source constructs. We assume
10498 -- that the expander knows what it is doing when it generates code.
10500 Comes_From_Source
(N
)
10502 -- If the operand type is Short_Integer or Short_Short_Integer,
10503 -- then we will promote to Integer, which is available on all
10504 -- targets, and is sufficient to ensure no intermediate overflow.
10505 -- Furthermore it is likely to be as efficient or more efficient
10506 -- than using the smaller type for the computation so we do this
10507 -- unconditionally.
10510 (Root_Operand_Type
= Base_Type
(Standard_Short_Integer
)
10512 Root_Operand_Type
= Base_Type
(Standard_Short_Short_Integer
))
10514 -- Test for interesting operation, which includes addition,
10515 -- division, exponentiation, multiplication, subtraction, absolute
10516 -- value and unary negation. Unary "+" is omitted since it is a
10517 -- no-op and thus can't overflow.
10519 and then Nkind_In
(Operand
, N_Op_Abs
,
10526 end Integer_Promotion_Possible
;
10528 ------------------------------
10529 -- Make_Array_Comparison_Op --
10530 ------------------------------
10532 -- This is a hand-coded expansion of the following generic function:
10535 -- type elem is (<>);
10536 -- type index is (<>);
10537 -- type a is array (index range <>) of elem;
10539 -- function Gnnn (X : a; Y: a) return boolean is
10540 -- J : index := Y'first;
10543 -- if X'length = 0 then
10546 -- elsif Y'length = 0 then
10550 -- for I in X'range loop
10551 -- if X (I) = Y (J) then
10552 -- if J = Y'last then
10555 -- J := index'succ (J);
10559 -- return X (I) > Y (J);
10563 -- return X'length > Y'length;
10567 -- Note that since we are essentially doing this expansion by hand, we
10568 -- do not need to generate an actual or formal generic part, just the
10569 -- instantiated function itself.
10571 function Make_Array_Comparison_Op
10573 Nod
: Node_Id
) return Node_Id
10575 Loc
: constant Source_Ptr
:= Sloc
(Nod
);
10577 X
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uX
);
10578 Y
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uY
);
10579 I
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uI
);
10580 J
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uJ
);
10582 Index
: constant Entity_Id
:= Base_Type
(Etype
(First_Index
(Typ
)));
10584 Loop_Statement
: Node_Id
;
10585 Loop_Body
: Node_Id
;
10587 Inner_If
: Node_Id
;
10588 Final_Expr
: Node_Id
;
10589 Func_Body
: Node_Id
;
10590 Func_Name
: Entity_Id
;
10596 -- if J = Y'last then
10599 -- J := index'succ (J);
10603 Make_Implicit_If_Statement
(Nod
,
10606 Left_Opnd
=> New_Reference_To
(J
, Loc
),
10608 Make_Attribute_Reference
(Loc
,
10609 Prefix
=> New_Reference_To
(Y
, Loc
),
10610 Attribute_Name
=> Name_Last
)),
10612 Then_Statements
=> New_List
(
10613 Make_Exit_Statement
(Loc
)),
10617 Make_Assignment_Statement
(Loc
,
10618 Name
=> New_Reference_To
(J
, Loc
),
10620 Make_Attribute_Reference
(Loc
,
10621 Prefix
=> New_Reference_To
(Index
, Loc
),
10622 Attribute_Name
=> Name_Succ
,
10623 Expressions
=> New_List
(New_Reference_To
(J
, Loc
))))));
10625 -- if X (I) = Y (J) then
10628 -- return X (I) > Y (J);
10632 Make_Implicit_If_Statement
(Nod
,
10636 Make_Indexed_Component
(Loc
,
10637 Prefix
=> New_Reference_To
(X
, Loc
),
10638 Expressions
=> New_List
(New_Reference_To
(I
, Loc
))),
10641 Make_Indexed_Component
(Loc
,
10642 Prefix
=> New_Reference_To
(Y
, Loc
),
10643 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)))),
10645 Then_Statements
=> New_List
(Inner_If
),
10647 Else_Statements
=> New_List
(
10648 Make_Simple_Return_Statement
(Loc
,
10652 Make_Indexed_Component
(Loc
,
10653 Prefix
=> New_Reference_To
(X
, Loc
),
10654 Expressions
=> New_List
(New_Reference_To
(I
, Loc
))),
10657 Make_Indexed_Component
(Loc
,
10658 Prefix
=> New_Reference_To
(Y
, Loc
),
10659 Expressions
=> New_List
(
10660 New_Reference_To
(J
, Loc
)))))));
10662 -- for I in X'range loop
10667 Make_Implicit_Loop_Statement
(Nod
,
10668 Identifier
=> Empty
,
10670 Iteration_Scheme
=>
10671 Make_Iteration_Scheme
(Loc
,
10672 Loop_Parameter_Specification
=>
10673 Make_Loop_Parameter_Specification
(Loc
,
10674 Defining_Identifier
=> I
,
10675 Discrete_Subtype_Definition
=>
10676 Make_Attribute_Reference
(Loc
,
10677 Prefix
=> New_Reference_To
(X
, Loc
),
10678 Attribute_Name
=> Name_Range
))),
10680 Statements
=> New_List
(Loop_Body
));
10682 -- if X'length = 0 then
10684 -- elsif Y'length = 0 then
10687 -- for ... loop ... end loop;
10688 -- return X'length > Y'length;
10692 Make_Attribute_Reference
(Loc
,
10693 Prefix
=> New_Reference_To
(X
, Loc
),
10694 Attribute_Name
=> Name_Length
);
10697 Make_Attribute_Reference
(Loc
,
10698 Prefix
=> New_Reference_To
(Y
, Loc
),
10699 Attribute_Name
=> Name_Length
);
10703 Left_Opnd
=> Length1
,
10704 Right_Opnd
=> Length2
);
10707 Make_Implicit_If_Statement
(Nod
,
10711 Make_Attribute_Reference
(Loc
,
10712 Prefix
=> New_Reference_To
(X
, Loc
),
10713 Attribute_Name
=> Name_Length
),
10715 Make_Integer_Literal
(Loc
, 0)),
10719 Make_Simple_Return_Statement
(Loc
,
10720 Expression
=> New_Reference_To
(Standard_False
, Loc
))),
10722 Elsif_Parts
=> New_List
(
10723 Make_Elsif_Part
(Loc
,
10727 Make_Attribute_Reference
(Loc
,
10728 Prefix
=> New_Reference_To
(Y
, Loc
),
10729 Attribute_Name
=> Name_Length
),
10731 Make_Integer_Literal
(Loc
, 0)),
10735 Make_Simple_Return_Statement
(Loc
,
10736 Expression
=> New_Reference_To
(Standard_True
, Loc
))))),
10738 Else_Statements
=> New_List
(
10740 Make_Simple_Return_Statement
(Loc
,
10741 Expression
=> Final_Expr
)));
10745 Formals
:= New_List
(
10746 Make_Parameter_Specification
(Loc
,
10747 Defining_Identifier
=> X
,
10748 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)),
10750 Make_Parameter_Specification
(Loc
,
10751 Defining_Identifier
=> Y
,
10752 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)));
10754 -- function Gnnn (...) return boolean is
10755 -- J : index := Y'first;
10760 Func_Name
:= Make_Temporary
(Loc
, 'G');
10763 Make_Subprogram_Body
(Loc
,
10765 Make_Function_Specification
(Loc
,
10766 Defining_Unit_Name
=> Func_Name
,
10767 Parameter_Specifications
=> Formals
,
10768 Result_Definition
=> New_Reference_To
(Standard_Boolean
, Loc
)),
10770 Declarations
=> New_List
(
10771 Make_Object_Declaration
(Loc
,
10772 Defining_Identifier
=> J
,
10773 Object_Definition
=> New_Reference_To
(Index
, Loc
),
10775 Make_Attribute_Reference
(Loc
,
10776 Prefix
=> New_Reference_To
(Y
, Loc
),
10777 Attribute_Name
=> Name_First
))),
10779 Handled_Statement_Sequence
=>
10780 Make_Handled_Sequence_Of_Statements
(Loc
,
10781 Statements
=> New_List
(If_Stat
)));
10784 end Make_Array_Comparison_Op
;
10786 ---------------------------
10787 -- Make_Boolean_Array_Op --
10788 ---------------------------
10790 -- For logical operations on boolean arrays, expand in line the following,
10791 -- replacing 'and' with 'or' or 'xor' where needed:
10793 -- function Annn (A : typ; B: typ) return typ is
10796 -- for J in A'range loop
10797 -- C (J) := A (J) op B (J);
10802 -- Here typ is the boolean array type
10804 function Make_Boolean_Array_Op
10806 N
: Node_Id
) return Node_Id
10808 Loc
: constant Source_Ptr
:= Sloc
(N
);
10810 A
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uA
);
10811 B
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uB
);
10812 C
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uC
);
10813 J
: constant Entity_Id
:= Make_Defining_Identifier
(Loc
, Name_uJ
);
10821 Func_Name
: Entity_Id
;
10822 Func_Body
: Node_Id
;
10823 Loop_Statement
: Node_Id
;
10827 Make_Indexed_Component
(Loc
,
10828 Prefix
=> New_Reference_To
(A
, Loc
),
10829 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
10832 Make_Indexed_Component
(Loc
,
10833 Prefix
=> New_Reference_To
(B
, Loc
),
10834 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
10837 Make_Indexed_Component
(Loc
,
10838 Prefix
=> New_Reference_To
(C
, Loc
),
10839 Expressions
=> New_List
(New_Reference_To
(J
, Loc
)));
10841 if Nkind
(N
) = N_Op_And
then
10845 Right_Opnd
=> B_J
);
10847 elsif Nkind
(N
) = N_Op_Or
then
10851 Right_Opnd
=> B_J
);
10857 Right_Opnd
=> B_J
);
10861 Make_Implicit_Loop_Statement
(N
,
10862 Identifier
=> Empty
,
10864 Iteration_Scheme
=>
10865 Make_Iteration_Scheme
(Loc
,
10866 Loop_Parameter_Specification
=>
10867 Make_Loop_Parameter_Specification
(Loc
,
10868 Defining_Identifier
=> J
,
10869 Discrete_Subtype_Definition
=>
10870 Make_Attribute_Reference
(Loc
,
10871 Prefix
=> New_Reference_To
(A
, Loc
),
10872 Attribute_Name
=> Name_Range
))),
10874 Statements
=> New_List
(
10875 Make_Assignment_Statement
(Loc
,
10877 Expression
=> Op
)));
10879 Formals
:= New_List
(
10880 Make_Parameter_Specification
(Loc
,
10881 Defining_Identifier
=> A
,
10882 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)),
10884 Make_Parameter_Specification
(Loc
,
10885 Defining_Identifier
=> B
,
10886 Parameter_Type
=> New_Reference_To
(Typ
, Loc
)));
10888 Func_Name
:= Make_Temporary
(Loc
, 'A');
10889 Set_Is_Inlined
(Func_Name
);
10892 Make_Subprogram_Body
(Loc
,
10894 Make_Function_Specification
(Loc
,
10895 Defining_Unit_Name
=> Func_Name
,
10896 Parameter_Specifications
=> Formals
,
10897 Result_Definition
=> New_Reference_To
(Typ
, Loc
)),
10899 Declarations
=> New_List
(
10900 Make_Object_Declaration
(Loc
,
10901 Defining_Identifier
=> C
,
10902 Object_Definition
=> New_Reference_To
(Typ
, Loc
))),
10904 Handled_Statement_Sequence
=>
10905 Make_Handled_Sequence_Of_Statements
(Loc
,
10906 Statements
=> New_List
(
10908 Make_Simple_Return_Statement
(Loc
,
10909 Expression
=> New_Reference_To
(C
, Loc
)))));
10912 end Make_Boolean_Array_Op
;
10914 --------------------------------
10915 -- Optimize_Length_Comparison --
10916 --------------------------------
10918 procedure Optimize_Length_Comparison
(N
: Node_Id
) is
10919 Loc
: constant Source_Ptr
:= Sloc
(N
);
10920 Typ
: constant Entity_Id
:= Etype
(N
);
10925 -- First and Last attribute reference nodes, which end up as left and
10926 -- right operands of the optimized result.
10929 -- True for comparison operand of zero
10932 -- Comparison operand, set only if Is_Zero is false
10935 -- Entity whose length is being compared
10938 -- Integer_Literal node for length attribute expression, or Empty
10939 -- if there is no such expression present.
10942 -- Type of array index to which 'Length is applied
10944 Op
: Node_Kind
:= Nkind
(N
);
10945 -- Kind of comparison operator, gets flipped if operands backwards
10947 function Is_Optimizable
(N
: Node_Id
) return Boolean;
10948 -- Tests N to see if it is an optimizable comparison value (defined as
10949 -- constant zero or one, or something else where the value is known to
10950 -- be positive and in the range of 32-bits, and where the corresponding
10951 -- Length value is also known to be 32-bits. If result is true, sets
10952 -- Is_Zero, Ityp, and Comp accordingly.
10954 function Is_Entity_Length
(N
: Node_Id
) return Boolean;
10955 -- Tests if N is a length attribute applied to a simple entity. If so,
10956 -- returns True, and sets Ent to the entity, and Index to the integer
10957 -- literal provided as an attribute expression, or to Empty if none.
10958 -- Also returns True if the expression is a generated type conversion
10959 -- whose expression is of the desired form. This latter case arises
10960 -- when Apply_Universal_Integer_Attribute_Check installs a conversion
10961 -- to check for being in range, which is not needed in this context.
10962 -- Returns False if neither condition holds.
10964 function Prepare_64
(N
: Node_Id
) return Node_Id
;
10965 -- Given a discrete expression, returns a Long_Long_Integer typed
10966 -- expression representing the underlying value of the expression.
10967 -- This is done with an unchecked conversion to the result type. We
10968 -- use unchecked conversion to handle the enumeration type case.
10970 ----------------------
10971 -- Is_Entity_Length --
10972 ----------------------
10974 function Is_Entity_Length
(N
: Node_Id
) return Boolean is
10976 if Nkind
(N
) = N_Attribute_Reference
10977 and then Attribute_Name
(N
) = Name_Length
10978 and then Is_Entity_Name
(Prefix
(N
))
10980 Ent
:= Entity
(Prefix
(N
));
10982 if Present
(Expressions
(N
)) then
10983 Index
:= First
(Expressions
(N
));
10990 elsif Nkind
(N
) = N_Type_Conversion
10991 and then not Comes_From_Source
(N
)
10993 return Is_Entity_Length
(Expression
(N
));
10998 end Is_Entity_Length
;
11000 --------------------
11001 -- Is_Optimizable --
11002 --------------------
11004 function Is_Optimizable
(N
: Node_Id
) return Boolean is
11012 if Compile_Time_Known_Value
(N
) then
11013 Val
:= Expr_Value
(N
);
11015 if Val
= Uint_0
then
11020 elsif Val
= Uint_1
then
11027 -- Here we have to make sure of being within 32-bits
11029 Determine_Range
(N
, OK
, Lo
, Hi
, Assume_Valid
=> True);
11032 or else Lo
< Uint_1
11033 or else Hi
> UI_From_Int
(Int
'Last)
11038 -- Comparison value was within range, so now we must check the index
11039 -- value to make sure it is also within 32-bits.
11041 Indx
:= First_Index
(Etype
(Ent
));
11043 if Present
(Index
) then
11044 for J
in 2 .. UI_To_Int
(Intval
(Index
)) loop
11049 Ityp
:= Etype
(Indx
);
11051 if Esize
(Ityp
) > 32 then
11058 end Is_Optimizable
;
11064 function Prepare_64
(N
: Node_Id
) return Node_Id
is
11066 return Unchecked_Convert_To
(Standard_Long_Long_Integer
, N
);
11069 -- Start of processing for Optimize_Length_Comparison
11072 -- Nothing to do if not a comparison
11074 if Op
not in N_Op_Compare
then
11078 -- Nothing to do if special -gnatd.P debug flag set
11080 if Debug_Flag_Dot_PP
then
11084 -- Ent'Length op 0/1
11086 if Is_Entity_Length
(Left_Opnd
(N
))
11087 and then Is_Optimizable
(Right_Opnd
(N
))
11091 -- 0/1 op Ent'Length
11093 elsif Is_Entity_Length
(Right_Opnd
(N
))
11094 and then Is_Optimizable
(Left_Opnd
(N
))
11096 -- Flip comparison to opposite sense
11099 when N_Op_Lt
=> Op
:= N_Op_Gt
;
11100 when N_Op_Le
=> Op
:= N_Op_Ge
;
11101 when N_Op_Gt
=> Op
:= N_Op_Lt
;
11102 when N_Op_Ge
=> Op
:= N_Op_Le
;
11103 when others => null;
11106 -- Else optimization not possible
11112 -- Fall through if we will do the optimization
11114 -- Cases to handle:
11116 -- X'Length = 0 => X'First > X'Last
11117 -- X'Length = 1 => X'First = X'Last
11118 -- X'Length = n => X'First + (n - 1) = X'Last
11120 -- X'Length /= 0 => X'First <= X'Last
11121 -- X'Length /= 1 => X'First /= X'Last
11122 -- X'Length /= n => X'First + (n - 1) /= X'Last
11124 -- X'Length >= 0 => always true, warn
11125 -- X'Length >= 1 => X'First <= X'Last
11126 -- X'Length >= n => X'First + (n - 1) <= X'Last
11128 -- X'Length > 0 => X'First <= X'Last
11129 -- X'Length > 1 => X'First < X'Last
11130 -- X'Length > n => X'First + (n - 1) < X'Last
11132 -- X'Length <= 0 => X'First > X'Last (warn, could be =)
11133 -- X'Length <= 1 => X'First >= X'Last
11134 -- X'Length <= n => X'First + (n - 1) >= X'Last
11136 -- X'Length < 0 => always false (warn)
11137 -- X'Length < 1 => X'First > X'Last
11138 -- X'Length < n => X'First + (n - 1) > X'Last
11140 -- Note: for the cases of n (not constant 0,1), we require that the
11141 -- corresponding index type be integer or shorter (i.e. not 64-bit),
11142 -- and the same for the comparison value. Then we do the comparison
11143 -- using 64-bit arithmetic (actually long long integer), so that we
11144 -- cannot have overflow intefering with the result.
11146 -- First deal with warning cases
11155 Convert_To
(Typ
, New_Occurrence_Of
(Standard_True
, Loc
)));
11156 Analyze_And_Resolve
(N
, Typ
);
11157 Warn_On_Known_Condition
(N
);
11164 Convert_To
(Typ
, New_Occurrence_Of
(Standard_False
, Loc
)));
11165 Analyze_And_Resolve
(N
, Typ
);
11166 Warn_On_Known_Condition
(N
);
11170 if Constant_Condition_Warnings
11171 and then Comes_From_Source
(Original_Node
(N
))
11173 Error_Msg_N
("could replace by ""'=""?", N
);
11183 -- Build the First reference we will use
11186 Make_Attribute_Reference
(Loc
,
11187 Prefix
=> New_Occurrence_Of
(Ent
, Loc
),
11188 Attribute_Name
=> Name_First
);
11190 if Present
(Index
) then
11191 Set_Expressions
(Left
, New_List
(New_Copy
(Index
)));
11194 -- If general value case, then do the addition of (n - 1), and
11195 -- also add the needed conversions to type Long_Long_Integer.
11197 if Present
(Comp
) then
11200 Left_Opnd
=> Prepare_64
(Left
),
11202 Make_Op_Subtract
(Loc
,
11203 Left_Opnd
=> Prepare_64
(Comp
),
11204 Right_Opnd
=> Make_Integer_Literal
(Loc
, 1)));
11207 -- Build the Last reference we will use
11210 Make_Attribute_Reference
(Loc
,
11211 Prefix
=> New_Occurrence_Of
(Ent
, Loc
),
11212 Attribute_Name
=> Name_Last
);
11214 if Present
(Index
) then
11215 Set_Expressions
(Right
, New_List
(New_Copy
(Index
)));
11218 -- If general operand, convert Last reference to Long_Long_Integer
11220 if Present
(Comp
) then
11221 Right
:= Prepare_64
(Right
);
11224 -- Check for cases to optimize
11226 -- X'Length = 0 => X'First > X'Last
11227 -- X'Length < 1 => X'First > X'Last
11228 -- X'Length < n => X'First + (n - 1) > X'Last
11230 if (Is_Zero
and then Op
= N_Op_Eq
)
11231 or else (not Is_Zero
and then Op
= N_Op_Lt
)
11236 Right_Opnd
=> Right
);
11238 -- X'Length = 1 => X'First = X'Last
11239 -- X'Length = n => X'First + (n - 1) = X'Last
11241 elsif not Is_Zero
and then Op
= N_Op_Eq
then
11245 Right_Opnd
=> Right
);
11247 -- X'Length /= 0 => X'First <= X'Last
11248 -- X'Length > 0 => X'First <= X'Last
11250 elsif Is_Zero
and (Op
= N_Op_Ne
or else Op
= N_Op_Gt
) then
11254 Right_Opnd
=> Right
);
11256 -- X'Length /= 1 => X'First /= X'Last
11257 -- X'Length /= n => X'First + (n - 1) /= X'Last
11259 elsif not Is_Zero
and then Op
= N_Op_Ne
then
11263 Right_Opnd
=> Right
);
11265 -- X'Length >= 1 => X'First <= X'Last
11266 -- X'Length >= n => X'First + (n - 1) <= X'Last
11268 elsif not Is_Zero
and then Op
= N_Op_Ge
then
11272 Right_Opnd
=> Right
);
11274 -- X'Length > 1 => X'First < X'Last
11275 -- X'Length > n => X'First + (n = 1) < X'Last
11277 elsif not Is_Zero
and then Op
= N_Op_Gt
then
11281 Right_Opnd
=> Right
);
11283 -- X'Length <= 1 => X'First >= X'Last
11284 -- X'Length <= n => X'First + (n - 1) >= X'Last
11286 elsif not Is_Zero
and then Op
= N_Op_Le
then
11290 Right_Opnd
=> Right
);
11292 -- Should not happen at this stage
11295 raise Program_Error
;
11298 -- Rewrite and finish up
11300 Rewrite
(N
, Result
);
11301 Analyze_And_Resolve
(N
, Typ
);
11303 end Optimize_Length_Comparison
;
11305 ------------------------
11306 -- Rewrite_Comparison --
11307 ------------------------
11309 procedure Rewrite_Comparison
(N
: Node_Id
) is
11310 Warning_Generated
: Boolean := False;
11311 -- Set to True if first pass with Assume_Valid generates a warning in
11312 -- which case we skip the second pass to avoid warning overloaded.
11315 -- Set to Standard_True or Standard_False
11318 if Nkind
(N
) = N_Type_Conversion
then
11319 Rewrite_Comparison
(Expression
(N
));
11322 elsif Nkind
(N
) not in N_Op_Compare
then
11326 -- Now start looking at the comparison in detail. We potentially go
11327 -- through this loop twice. The first time, Assume_Valid is set False
11328 -- in the call to Compile_Time_Compare. If this call results in a
11329 -- clear result of always True or Always False, that's decisive and
11330 -- we are done. Otherwise we repeat the processing with Assume_Valid
11331 -- set to True to generate additional warnings. We can skip that step
11332 -- if Constant_Condition_Warnings is False.
11334 for AV
in False .. True loop
11336 Typ
: constant Entity_Id
:= Etype
(N
);
11337 Op1
: constant Node_Id
:= Left_Opnd
(N
);
11338 Op2
: constant Node_Id
:= Right_Opnd
(N
);
11340 Res
: constant Compare_Result
:=
11341 Compile_Time_Compare
(Op1
, Op2
, Assume_Valid
=> AV
);
11342 -- Res indicates if compare outcome can be compile time determined
11344 True_Result
: Boolean;
11345 False_Result
: Boolean;
11348 case N_Op_Compare
(Nkind
(N
)) is
11350 True_Result
:= Res
= EQ
;
11351 False_Result
:= Res
= LT
or else Res
= GT
or else Res
= NE
;
11354 True_Result
:= Res
in Compare_GE
;
11355 False_Result
:= Res
= LT
;
11358 and then Constant_Condition_Warnings
11359 and then Comes_From_Source
(Original_Node
(N
))
11360 and then Nkind
(Original_Node
(N
)) = N_Op_Ge
11361 and then not In_Instance
11362 and then Is_Integer_Type
(Etype
(Left_Opnd
(N
)))
11363 and then not Has_Warnings_Off
(Etype
(Left_Opnd
(N
)))
11366 ("can never be greater than, could replace by ""'=""?", N
);
11367 Warning_Generated
:= True;
11371 True_Result
:= Res
= GT
;
11372 False_Result
:= Res
in Compare_LE
;
11375 True_Result
:= Res
= LT
;
11376 False_Result
:= Res
in Compare_GE
;
11379 True_Result
:= Res
in Compare_LE
;
11380 False_Result
:= Res
= GT
;
11383 and then Constant_Condition_Warnings
11384 and then Comes_From_Source
(Original_Node
(N
))
11385 and then Nkind
(Original_Node
(N
)) = N_Op_Le
11386 and then not In_Instance
11387 and then Is_Integer_Type
(Etype
(Left_Opnd
(N
)))
11388 and then not Has_Warnings_Off
(Etype
(Left_Opnd
(N
)))
11391 ("can never be less than, could replace by ""'=""?", N
);
11392 Warning_Generated
:= True;
11396 True_Result
:= Res
= NE
or else Res
= GT
or else Res
= LT
;
11397 False_Result
:= Res
= EQ
;
11400 -- If this is the first iteration, then we actually convert the
11401 -- comparison into True or False, if the result is certain.
11404 if True_Result
or False_Result
then
11405 Result
:= Boolean_Literals
(True_Result
);
11408 New_Occurrence_Of
(Result
, Sloc
(N
))));
11409 Analyze_And_Resolve
(N
, Typ
);
11410 Warn_On_Known_Condition
(N
);
11414 -- If this is the second iteration (AV = True), and the original
11415 -- node comes from source and we are not in an instance, then give
11416 -- a warning if we know result would be True or False. Note: we
11417 -- know Constant_Condition_Warnings is set if we get here.
11419 elsif Comes_From_Source
(Original_Node
(N
))
11420 and then not In_Instance
11422 if True_Result
then
11424 ("condition can only be False if invalid values present?",
11426 elsif False_Result
then
11428 ("condition can only be True if invalid values present?",
11434 -- Skip second iteration if not warning on constant conditions or
11435 -- if the first iteration already generated a warning of some kind or
11436 -- if we are in any case assuming all values are valid (so that the
11437 -- first iteration took care of the valid case).
11439 exit when not Constant_Condition_Warnings
;
11440 exit when Warning_Generated
;
11441 exit when Assume_No_Invalid_Values
;
11443 end Rewrite_Comparison
;
11445 ----------------------------
11446 -- Safe_In_Place_Array_Op --
11447 ----------------------------
11449 function Safe_In_Place_Array_Op
11452 Op2
: Node_Id
) return Boolean
11454 Target
: Entity_Id
;
11456 function Is_Safe_Operand
(Op
: Node_Id
) return Boolean;
11457 -- Operand is safe if it cannot overlap part of the target of the
11458 -- operation. If the operand and the target are identical, the operand
11459 -- is safe. The operand can be empty in the case of negation.
11461 function Is_Unaliased
(N
: Node_Id
) return Boolean;
11462 -- Check that N is a stand-alone entity
11468 function Is_Unaliased
(N
: Node_Id
) return Boolean is
11472 and then No
(Address_Clause
(Entity
(N
)))
11473 and then No
(Renamed_Object
(Entity
(N
)));
11476 ---------------------
11477 -- Is_Safe_Operand --
11478 ---------------------
11480 function Is_Safe_Operand
(Op
: Node_Id
) return Boolean is
11485 elsif Is_Entity_Name
(Op
) then
11486 return Is_Unaliased
(Op
);
11488 elsif Nkind_In
(Op
, N_Indexed_Component
, N_Selected_Component
) then
11489 return Is_Unaliased
(Prefix
(Op
));
11491 elsif Nkind
(Op
) = N_Slice
then
11493 Is_Unaliased
(Prefix
(Op
))
11494 and then Entity
(Prefix
(Op
)) /= Target
;
11496 elsif Nkind
(Op
) = N_Op_Not
then
11497 return Is_Safe_Operand
(Right_Opnd
(Op
));
11502 end Is_Safe_Operand
;
11504 -- Start of processing for Is_Safe_In_Place_Array_Op
11507 -- Skip this processing if the component size is different from system
11508 -- storage unit (since at least for NOT this would cause problems).
11510 if Component_Size
(Etype
(Lhs
)) /= System_Storage_Unit
then
11513 -- Cannot do in place stuff on VM_Target since cannot pass addresses
11515 elsif VM_Target
/= No_VM
then
11518 -- Cannot do in place stuff if non-standard Boolean representation
11520 elsif Has_Non_Standard_Rep
(Component_Type
(Etype
(Lhs
))) then
11523 elsif not Is_Unaliased
(Lhs
) then
11527 Target
:= Entity
(Lhs
);
11528 return Is_Safe_Operand
(Op1
) and then Is_Safe_Operand
(Op2
);
11530 end Safe_In_Place_Array_Op
;
11532 -----------------------
11533 -- Tagged_Membership --
11534 -----------------------
11536 -- There are two different cases to consider depending on whether the right
11537 -- operand is a class-wide type or not. If not we just compare the actual
11538 -- tag of the left expr to the target type tag:
11540 -- Left_Expr.Tag = Right_Type'Tag;
11542 -- If it is a class-wide type we use the RT function CW_Membership which is
11543 -- usually implemented by looking in the ancestor tables contained in the
11544 -- dispatch table pointed by Left_Expr.Tag for Typ'Tag
11546 -- Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
11547 -- function IW_Membership which is usually implemented by looking in the
11548 -- table of abstract interface types plus the ancestor table contained in
11549 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
11551 procedure Tagged_Membership
11553 SCIL_Node
: out Node_Id
;
11554 Result
: out Node_Id
)
11556 Left
: constant Node_Id
:= Left_Opnd
(N
);
11557 Right
: constant Node_Id
:= Right_Opnd
(N
);
11558 Loc
: constant Source_Ptr
:= Sloc
(N
);
11560 Full_R_Typ
: Entity_Id
;
11561 Left_Type
: Entity_Id
;
11562 New_Node
: Node_Id
;
11563 Right_Type
: Entity_Id
;
11567 SCIL_Node
:= Empty
;
11569 -- Handle entities from the limited view
11571 Left_Type
:= Available_View
(Etype
(Left
));
11572 Right_Type
:= Available_View
(Etype
(Right
));
11574 -- In the case where the type is an access type, the test is applied
11575 -- using the designated types (needed in Ada 2012 for implicit anonymous
11576 -- access conversions, for AI05-0149).
11578 if Is_Access_Type
(Right_Type
) then
11579 Left_Type
:= Designated_Type
(Left_Type
);
11580 Right_Type
:= Designated_Type
(Right_Type
);
11583 if Is_Class_Wide_Type
(Left_Type
) then
11584 Left_Type
:= Root_Type
(Left_Type
);
11587 if Is_Class_Wide_Type
(Right_Type
) then
11588 Full_R_Typ
:= Underlying_Type
(Root_Type
(Right_Type
));
11590 Full_R_Typ
:= Underlying_Type
(Right_Type
);
11594 Make_Selected_Component
(Loc
,
11595 Prefix
=> Relocate_Node
(Left
),
11597 New_Reference_To
(First_Tag_Component
(Left_Type
), Loc
));
11599 if Is_Class_Wide_Type
(Right_Type
) then
11601 -- No need to issue a run-time check if we statically know that the
11602 -- result of this membership test is always true. For example,
11603 -- considering the following declarations:
11605 -- type Iface is interface;
11606 -- type T is tagged null record;
11607 -- type DT is new T and Iface with null record;
11612 -- These membership tests are always true:
11615 -- Obj2 in T'Class;
11616 -- Obj2 in Iface'Class;
11618 -- We do not need to handle cases where the membership is illegal.
11621 -- Obj1 in DT'Class; -- Compile time error
11622 -- Obj1 in Iface'Class; -- Compile time error
11624 if not Is_Class_Wide_Type
(Left_Type
)
11625 and then (Is_Ancestor
(Etype
(Right_Type
), Left_Type
,
11626 Use_Full_View
=> True)
11627 or else (Is_Interface
(Etype
(Right_Type
))
11628 and then Interface_Present_In_Ancestor
11630 Iface
=> Etype
(Right_Type
))))
11632 Result
:= New_Reference_To
(Standard_True
, Loc
);
11636 -- Ada 2005 (AI-251): Class-wide applied to interfaces
11638 if Is_Interface
(Etype
(Class_Wide_Type
(Right_Type
)))
11640 -- Support to: "Iface_CW_Typ in Typ'Class"
11642 or else Is_Interface
(Left_Type
)
11644 -- Issue error if IW_Membership operation not available in a
11645 -- configurable run time setting.
11647 if not RTE_Available
(RE_IW_Membership
) then
11649 ("dynamic membership test on interface types", N
);
11655 Make_Function_Call
(Loc
,
11656 Name
=> New_Occurrence_Of
(RTE
(RE_IW_Membership
), Loc
),
11657 Parameter_Associations
=> New_List
(
11658 Make_Attribute_Reference
(Loc
,
11660 Attribute_Name
=> Name_Address
),
11662 Node
(First_Elmt
(Access_Disp_Table
(Full_R_Typ
))),
11665 -- Ada 95: Normal case
11668 Build_CW_Membership
(Loc
,
11669 Obj_Tag_Node
=> Obj_Tag
,
11672 Node
(First_Elmt
(Access_Disp_Table
(Full_R_Typ
))), Loc
),
11674 New_Node
=> New_Node
);
11676 -- Generate the SCIL node for this class-wide membership test.
11677 -- Done here because the previous call to Build_CW_Membership
11678 -- relocates Obj_Tag.
11680 if Generate_SCIL
then
11681 SCIL_Node
:= Make_SCIL_Membership_Test
(Sloc
(N
));
11682 Set_SCIL_Entity
(SCIL_Node
, Etype
(Right_Type
));
11683 Set_SCIL_Tag_Value
(SCIL_Node
, Obj_Tag
);
11686 Result
:= New_Node
;
11689 -- Right_Type is not a class-wide type
11692 -- No need to check the tag of the object if Right_Typ is abstract
11694 if Is_Abstract_Type
(Right_Type
) then
11695 Result
:= New_Reference_To
(Standard_False
, Loc
);
11700 Left_Opnd
=> Obj_Tag
,
11703 (Node
(First_Elmt
(Access_Disp_Table
(Full_R_Typ
))), Loc
));
11706 end Tagged_Membership
;
11708 ------------------------------
11709 -- Unary_Op_Validity_Checks --
11710 ------------------------------
11712 procedure Unary_Op_Validity_Checks
(N
: Node_Id
) is
11714 if Validity_Checks_On
and Validity_Check_Operands
then
11715 Ensure_Valid
(Right_Opnd
(N
));
11717 end Unary_Op_Validity_Checks
;